Form Validation
layout fixing
This commit is contained in:
parent
5ce98da559
commit
b7b65e9d16
@ -20,10 +20,59 @@ open class RadioBox: Control {
|
|||||||
private var strikeLayer: CALayer?
|
private var strikeLayer: CALayer?
|
||||||
private var maskLayer: CALayer?
|
private var maskLayer: CALayer?
|
||||||
|
|
||||||
|
public var subTextLabelHeightConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
public var radioBoxModel: RadioBoxModel? {
|
public var radioBoxModel: RadioBoxModel? {
|
||||||
return model as? RadioBoxModel
|
return model as? RadioBoxModel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - MVMCoreViewProtocol
|
||||||
|
|
||||||
|
open override func updateView(_ size: CGFloat) {
|
||||||
|
super.updateView(size)
|
||||||
|
label.updateView(size)
|
||||||
|
subTextLabel.updateView(size)
|
||||||
|
layer.setNeedsDisplay()
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
|
||||||
|
layer.delegate = self
|
||||||
|
layer.borderColor = UIColor.black.cgColor
|
||||||
|
layer.borderWidth = 1
|
||||||
|
|
||||||
|
label.numberOfLines = 1
|
||||||
|
addSubview(label)
|
||||||
|
NSLayoutConstraint.constraintPinSubview(label, pinTop: true, topConstant: innerPadding, pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: innerPadding, pinRight: true, rightConstant: innerPadding)
|
||||||
|
|
||||||
|
subTextLabel.textColor = .mvmCoolGray6
|
||||||
|
subTextLabel.numberOfLines = 1
|
||||||
|
addSubview(subTextLabel)
|
||||||
|
NSLayoutConstraint.constraintPinSubview(subTextLabel, pinTop: false, topConstant:0, pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: innerPadding, pinRight: true, rightConstant: innerPadding)
|
||||||
|
bottomAnchor.constraint(greaterThanOrEqualTo: subTextLabel.bottomAnchor, constant: innerPadding).isActive = true
|
||||||
|
subTextLabel.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 2).isActive = true
|
||||||
|
subTextLabelHeightConstraint = subTextLabel.heightAnchor.constraint(equalToConstant: 0)
|
||||||
|
subTextLabelHeightConstraint?.isActive = true
|
||||||
|
|
||||||
|
addTarget(self, action: #selector(selectBox), for: .touchUpInside)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - MoleculeViewProtocol
|
||||||
|
|
||||||
|
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
guard let model = model as? RadioBoxModel else { return }
|
||||||
|
isSelected = model.selected
|
||||||
|
isEnabled = model.enabled
|
||||||
|
label.text = model.text
|
||||||
|
subTextLabel.text = model.subText
|
||||||
|
isOutOfStock = model.strikethrough
|
||||||
|
subTextLabelHeightConstraint?.isActive = (subTextLabel.text?.count ?? 0) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - State Handling
|
||||||
|
|
||||||
open override func draw(_ layer: CALayer, in ctx: CGContext) {
|
open override func draw(_ layer: CALayer, in ctx: CGContext) {
|
||||||
// Draw the strikethrough
|
// Draw the strikethrough
|
||||||
strikeLayer?.removeFromSuperlayer()
|
strikeLayer?.removeFromSuperlayer()
|
||||||
@ -52,46 +101,21 @@ open class RadioBox: Control {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func updateView(_ size: CGFloat) {
|
open override func layoutSubviews() {
|
||||||
super.updateView(size)
|
super.layoutSubviews()
|
||||||
label.updateView(size)
|
// Accounts for any size changes
|
||||||
subTextLabel.updateView(size)
|
|
||||||
layer.setNeedsDisplay()
|
layer.setNeedsDisplay()
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func setupView() {
|
@objc open func selectBox() {
|
||||||
super.setupView()
|
isSelected = true
|
||||||
|
radioBoxModel?.selected = isSelected
|
||||||
layer.delegate = self
|
layer.setNeedsDisplay()
|
||||||
layer.borderColor = UIColor.black.cgColor
|
|
||||||
layer.borderWidth = 1
|
|
||||||
|
|
||||||
label.numberOfLines = 1
|
|
||||||
addSubview(label)
|
|
||||||
NSLayoutConstraint.constraintPinSubview(label, pinTop: true, topConstant: innerPadding, pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: innerPadding, pinRight: true, rightConstant: innerPadding)
|
|
||||||
|
|
||||||
subTextLabel.textColor = .mvmCoolGray6
|
|
||||||
subTextLabel.numberOfLines = 1
|
|
||||||
addSubview(subTextLabel)
|
|
||||||
NSLayoutConstraint.constraintPinSubview(subTextLabel, pinTop: false, topConstant:0, pinBottom: false, bottomConstant: 0, pinLeft: true, leftConstant: innerPadding, pinRight: true, rightConstant: innerPadding)
|
|
||||||
bottomAnchor.constraint(lessThanOrEqualTo: subTextLabel.bottomAnchor, constant: innerPadding).isActive = true
|
|
||||||
subTextLabel.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 2).isActive = true
|
|
||||||
|
|
||||||
addTarget(self, action: #selector(touched), for: .touchUpInside)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
@objc open func deselectBox() {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
isSelected = false
|
||||||
guard let model = model as? RadioBoxModel else { return }
|
radioBoxModel?.selected = isSelected
|
||||||
isSelected = model.selected
|
|
||||||
isEnabled = model.enabled
|
|
||||||
label.text = model.text
|
|
||||||
subTextLabel.text = model.subText
|
|
||||||
isOutOfStock = model.strikethrough
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc open func touched() {
|
|
||||||
isSelected = !isSelected
|
|
||||||
layer.setNeedsDisplay()
|
layer.setNeedsDisplay()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
@objcMembers public class RadioBoxModel: MoleculeModelProtocol {
|
@objcMembers public class RadioBoxModel: MoleculeModelProtocol, FormFieldProtocol {
|
||||||
public static var identifier: String = "radioBox"
|
public static var identifier: String = "radioBox"
|
||||||
public var text: String
|
public var text: String
|
||||||
public var subText: String?
|
public var subText: String?
|
||||||
@ -18,8 +18,9 @@ import Foundation
|
|||||||
public var strikethrough: Bool = false
|
public var strikethrough: Bool = false
|
||||||
public var fieldValue: String?
|
public var fieldValue: String?
|
||||||
public var fieldKey: String?
|
public var fieldKey: String?
|
||||||
public var groupName: String?
|
public var groupName: String = FormValidator.defaultGroupName
|
||||||
|
public var baseValue: AnyHashable?
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
case text
|
case text
|
||||||
@ -34,6 +35,10 @@ import Foundation
|
|||||||
case groupName
|
case groupName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func formFieldValue() -> AnyHashable? {
|
||||||
|
return selected
|
||||||
|
}
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
text = try typeContainer.decode(String.self, forKey: .text)
|
text = try typeContainer.decode(String.self, forKey: .text)
|
||||||
@ -53,9 +58,13 @@ import Foundation
|
|||||||
if let isStrikeTrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) {
|
if let isStrikeTrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) {
|
||||||
strikethrough = isStrikeTrough
|
strikethrough = isStrikeTrough
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue)
|
fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue)
|
||||||
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||||
groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName)
|
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||||
|
self.groupName = groupName
|
||||||
|
}
|
||||||
|
baseValue = selected
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -70,6 +79,6 @@ import Foundation
|
|||||||
try container.encode(strikethrough, forKey: .strikethrough)
|
try container.encode(strikethrough, forKey: .strikethrough)
|
||||||
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
|
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
|
||||||
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||||
try container.encodeIfPresent(groupName, forKey: .groupName)
|
try container.encode(groupName, forKey: .groupName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,28 +10,31 @@ import Foundation
|
|||||||
|
|
||||||
open class RadioBoxes: View {
|
open class RadioBoxes: View {
|
||||||
|
|
||||||
public let collectionView = CollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
|
public var collectionView: CollectionView!
|
||||||
|
public var collectionViewHeight: NSLayoutConstraint!
|
||||||
|
private let boxWidth: CGFloat = 151.0
|
||||||
|
private let boxHeight: CGFloat = 64.0
|
||||||
|
private let itemSpacing: CGFloat = 8.0
|
||||||
|
|
||||||
|
private var delegateObject: MVMCoreUIDelegateObject?
|
||||||
|
|
||||||
/// The models for the molecules.
|
/// The models for the molecules.
|
||||||
public var boxes: [RadioBoxModel]?
|
public var boxes: [RadioBoxModel]?
|
||||||
public var collectionViewHeight: NSLayoutConstraint?
|
|
||||||
private let boxWidth: Double = 151.0
|
private var size: CGFloat?
|
||||||
private let boxHeight: Double = 64.0
|
|
||||||
private let itemSpacing: Double = 10.0
|
open override func layoutSubviews() {
|
||||||
private let leadingSpacing: Double = 0
|
super.layoutSubviews()
|
||||||
|
// Accounts for any collection size changes
|
||||||
public var selectedBox: RadioBoxModel? {
|
DispatchQueue.main.async {
|
||||||
get{
|
self.collectionView.collectionViewLayout.invalidateLayout()
|
||||||
guard let selectedItem = collectionView.indexPathsForSelectedItems?.first else {return nil}
|
|
||||||
return boxes?[selectedItem.item]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - MVMCoreViewProtocol
|
// MARK: - MVMCoreViewProtocol
|
||||||
open override func setupView() {
|
open override func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
collectionView.dataSource = self
|
collectionView = createCollectionView()
|
||||||
collectionView.delegate = self
|
|
||||||
addSubview(collectionView)
|
addSubview(collectionView)
|
||||||
NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView)
|
NSLayoutConstraint.constraintPinSubview(toSuperview: collectionView)
|
||||||
collectionViewHeight = collectionView.heightAnchor.constraint(equalToConstant: 300)
|
collectionViewHeight = collectionView.heightAnchor.constraint(equalToConstant: 300)
|
||||||
@ -41,62 +44,66 @@ open class RadioBoxes: View {
|
|||||||
// MARK: - MoleculeViewProtocol
|
// MARK: - MoleculeViewProtocol
|
||||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
self.delegateObject = delegateObject
|
||||||
|
|
||||||
guard let radioBoxesModel = model as? RadioBoxesModel else { return }
|
guard let radioBoxesModel = model as? RadioBoxesModel else { return }
|
||||||
|
boxes = radioBoxesModel.boxes
|
||||||
|
FormValidator.setupValidation(for: radioBoxesModel, delegate: delegateObject?.formHolderDelegate)
|
||||||
|
|
||||||
backgroundColor = radioBoxesModel.backgroundColor?.uiColor
|
backgroundColor = radioBoxesModel.backgroundColor?.uiColor
|
||||||
registerCells()
|
registerCells()
|
||||||
setupLayout(with: radioBoxesModel)
|
setHeight()
|
||||||
prepareMolecules(with: radioBoxesModel)
|
|
||||||
collectionView.reloadData()
|
collectionView.reloadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc override open func updateView(_ size: CGFloat) {
|
@objc override open func updateView(_ size: CGFloat) {
|
||||||
collectionView.collectionViewLayout.invalidateLayout()
|
super.updateView(size)
|
||||||
DispatchQueue.main.async { [weak self] in
|
self.size = size
|
||||||
guard let self = self else { return }
|
collectionView.updateView(size)
|
||||||
self.setNeedsDisplay()
|
|
||||||
self.collectionView.layoutIfNeeded()
|
|
||||||
self.collectionView.reloadData()
|
|
||||||
guard let firstSelectedIndex = self.boxes?.firstIndex(where: {$0.selected == true}) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
self.collectionView.selectItem(at: IndexPath(item: firstSelectedIndex, section: 0), animated: true, scrollPosition: .centeredHorizontally)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - JSON Setters
|
|
||||||
/// Updates the layout being used
|
|
||||||
|
|
||||||
func setupLayout(with radioBoxesModel: RadioBoxesModel?) {
|
|
||||||
let layout = UICollectionViewFlowLayout()
|
|
||||||
layout.scrollDirection = .vertical
|
|
||||||
layout.sectionInset = UIEdgeInsets.init(top: CGFloat(leadingSpacing), left: CGFloat(leadingSpacing), bottom: CGFloat(leadingSpacing), right: CGFloat(leadingSpacing))
|
|
||||||
layout.minimumLineSpacing = 10
|
|
||||||
layout.minimumInteritemSpacing = 10
|
|
||||||
collectionView.collectionViewLayout = layout
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareMolecules(with radioBoxesModel: RadioBoxesModel?) {
|
// MARK: - Creation
|
||||||
guard let newMolecules = radioBoxesModel?.boxes else {
|
|
||||||
boxes = nil
|
/// Creates the layout for the collection.
|
||||||
return
|
open func createCollectionViewLayout() -> UICollectionViewLayout {
|
||||||
}
|
let layout = UICollectionViewFlowLayout()
|
||||||
boxes = newMolecules
|
layout.scrollDirection = .vertical
|
||||||
let height = Double(round(Double((boxes?.count ?? Int(0.0)))/2.0))*(boxHeight+10.0)
|
layout.minimumLineSpacing = itemSpacing
|
||||||
collectionViewHeight?.constant = CGFloat(height)
|
layout.minimumInteritemSpacing = itemSpacing
|
||||||
collectionViewHeight?.isActive = true
|
return layout
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates the collection view.
|
||||||
|
open func createCollectionView() -> CollectionView {
|
||||||
|
let collection = CollectionView(frame: .zero, collectionViewLayout: createCollectionViewLayout())
|
||||||
|
collection.dataSource = self
|
||||||
|
collection.delegate = self
|
||||||
|
return collection
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Registers the cells with the collection view
|
/// Registers the cells with the collection view
|
||||||
func registerCells() {
|
open func registerCells() {
|
||||||
collectionView.register(RadioBoxCollectionViewCell.self, forCellWithReuseIdentifier: "RadioBoxCollectionViewCell")
|
collectionView.register(RadioBoxCollectionViewCell.self, forCellWithReuseIdentifier: "RadioBoxCollectionViewCell")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - JSON Setters
|
||||||
|
open func setHeight() {
|
||||||
|
guard let boxes = boxes, boxes.count > 0 else {
|
||||||
|
collectionViewHeight.constant = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the height
|
||||||
|
let rows = ceil(CGFloat(boxes.count) / 2.0)
|
||||||
|
let height = (rows * boxHeight) + ((rows - 1) * itemSpacing)
|
||||||
|
collectionViewHeight?.constant = height
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension RadioBoxes: UICollectionViewDelegateFlowLayout {
|
extension RadioBoxes: UICollectionViewDelegateFlowLayout {
|
||||||
open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
|
open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
|
||||||
let itemWidth = (Double(collectionView.bounds.width) - itemSpacing)/2
|
let itemWidth: CGFloat = (collectionView.bounds.width - itemSpacing) / 2
|
||||||
return CGSize(width: CGFloat(itemWidth), height: CGFloat(boxHeight))
|
return CGSize(width: itemWidth, height: boxHeight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,23 +113,31 @@ extension RadioBoxes: UICollectionViewDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||||
guard let molecule = boxes?[indexPath.row], let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioBoxCollectionViewCell", for: indexPath) as? RadioBoxCollectionViewCell else {
|
guard let molecule = boxes?[indexPath.row],
|
||||||
return UICollectionViewCell()
|
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "RadioBoxCollectionViewCell", for: indexPath) as? RadioBoxCollectionViewCell else {
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
cell.radioBox.isUserInteractionEnabled = false
|
||||||
|
cell.set(with: molecule, delegateObject, nil)
|
||||||
|
cell.updateView(size ?? collectionView.bounds.width)
|
||||||
|
if molecule.selected {
|
||||||
|
collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredVertically)
|
||||||
}
|
}
|
||||||
cell.set(with: molecule, nil, nil)
|
|
||||||
cell.updateView(collectionView.bounds.width)
|
|
||||||
cell.layoutIfNeeded()
|
cell.layoutIfNeeded()
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension RadioBoxes: UICollectionViewDelegate {
|
extension RadioBoxes: UICollectionViewDelegate {
|
||||||
public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||||
guard let boxItem = boxes?[indexPath.row] else { return }
|
guard let cell = collectionView.cellForItem(at: indexPath) as? RadioBoxCollectionViewCell else { return }
|
||||||
boxItem.selected = true
|
cell.radioBox.selectBox()
|
||||||
|
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
|
public func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
|
||||||
guard let boxItem = boxes?[indexPath.row] else { return }
|
guard let cell = collectionView.cellForItem(at: indexPath) as? RadioBoxCollectionViewCell else { return }
|
||||||
boxItem.selected = false
|
cell.radioBox.deselectBox()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,13 +7,22 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
@objcMembers public class RadioBoxesModel: MoleculeModelProtocol {
|
@objcMembers public class RadioBoxesModel: MoleculeModelProtocol, FormFieldProtocol {
|
||||||
public static var identifier: String = "radioBoxes"
|
public static var identifier: String = "radioBoxes"
|
||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
public var selectedAccentColor: Color?
|
public var selectedAccentColor: Color?
|
||||||
public var boxes: [RadioBoxModel]
|
public var boxes: [RadioBoxModel]
|
||||||
public var fieldKey: String?
|
public var fieldKey: String?
|
||||||
public var groupName: String?
|
public var groupName: String = FormValidator.defaultGroupName
|
||||||
|
public var baseValue: AnyHashable?
|
||||||
|
|
||||||
|
/// Returns the fieldValue of the selected box, otherwise the text of the selected box.
|
||||||
|
public func formFieldValue() -> AnyHashable? {
|
||||||
|
let selectedBox = boxes.first { (box) -> Bool in
|
||||||
|
return box.selected
|
||||||
|
}
|
||||||
|
return selectedBox?.fieldValue ?? selectedBox?.text
|
||||||
|
}
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
@ -30,7 +39,10 @@ import Foundation
|
|||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
boxes = try typeContainer.decode([RadioBoxModel].self, forKey: .boxes)
|
boxes = try typeContainer.decode([RadioBoxModel].self, forKey: .boxes)
|
||||||
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||||
groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName)
|
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||||
|
self.groupName = groupName
|
||||||
|
}
|
||||||
|
baseValue = formFieldValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -40,6 +52,6 @@ import Foundation
|
|||||||
try container.encodeIfPresent(selectedAccentColor, forKey: .selectedAccentColor)
|
try container.encodeIfPresent(selectedAccentColor, forKey: .selectedAccentColor)
|
||||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||||
try container.encodeIfPresent(groupName, forKey: .groupName)
|
try container.encode(groupName, forKey: .groupName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import UIKit
|
|||||||
|
|
||||||
open class Carousel: View {
|
open class Carousel: View {
|
||||||
|
|
||||||
public let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
|
public let collectionView = CollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
|
||||||
|
|
||||||
/// The current index of the collection view. Includes dummy cells when looping.
|
/// The current index of the collection view. Includes dummy cells when looping.
|
||||||
public var currentIndex = 0
|
public var currentIndex = 0
|
||||||
|
|||||||
@ -39,6 +39,7 @@ open class CollectionView: UICollectionView, MVMCoreViewProtocol {
|
|||||||
public func setupView() {
|
public func setupView() {
|
||||||
translatesAutoresizingMaskIntoConstraints = false
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
showsHorizontalScrollIndicator = false
|
showsHorizontalScrollIndicator = false
|
||||||
|
showsVerticalScrollIndicator = false
|
||||||
backgroundColor = .clear
|
backgroundColor = .clear
|
||||||
isAccessibilityElement = false
|
isAccessibilityElement = false
|
||||||
contentInsetAdjustmentBehavior = .always
|
contentInsetAdjustmentBehavior = .always
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user