updated tabsModel and Tabs
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
8a90a8ce4a
commit
7c0e8bb106
@ -8,379 +8,64 @@
|
||||
|
||||
import UIKit
|
||||
import VDSColorTokens
|
||||
import VDS
|
||||
|
||||
@objc public protocol TabsDelegate {
|
||||
func shouldSelectItem(_ indexPath: IndexPath, tabs: Tabs) -> Bool
|
||||
func didSelectItem(_ indexPath: IndexPath, tabs: Tabs)
|
||||
}
|
||||
|
||||
@objcMembers open class Tabs: View, MVMCoreUIViewConstrainingProtocol, MFButtonProtocol {
|
||||
@objcMembers open class Tabs: VDS.Tabs, VDSMoleculeViewProtocol, MVMCoreUIViewConstrainingProtocol, MFButtonProtocol {
|
||||
|
||||
public var tabsModel: TabsModel? {
|
||||
get { return model as? TabsModel }
|
||||
}
|
||||
|
||||
var delegateObject: MVMCoreUIDelegateObject?
|
||||
var additionalData: [AnyHashable: Any]?
|
||||
|
||||
let layout = UICollectionViewFlowLayout()
|
||||
public var collectionView: CollectionView?
|
||||
|
||||
let bottomScrollView = UIScrollView(frame: .zero)
|
||||
let bottomContentView = View()
|
||||
let bottomLine = Line()
|
||||
let selectionLine = View()
|
||||
var selectionLineLeftConstraint: NSLayoutConstraint?
|
||||
var selectionLineWidthConstraint: NSLayoutConstraint?
|
||||
|
||||
private var widthLabel = Label()
|
||||
//--------------------------------------------------
|
||||
// MARK: - Public Properties
|
||||
//--------------------------------------------------
|
||||
open var viewModel: TabsModel!
|
||||
open var delegateObject: MVMCoreUIDelegateObject?
|
||||
open var additionalData: [AnyHashable : Any]?
|
||||
|
||||
//delegate
|
||||
weak public var delegate: TabsDelegate?
|
||||
|
||||
//control var
|
||||
public var selectedIndex: Int = 0
|
||||
public var paddingBeforeFirstTab: Bool = true
|
||||
|
||||
//constant
|
||||
let TabCellId = "TabCell"
|
||||
public let itemSpacing: CGFloat = 20.0
|
||||
public let cellHeight: CGFloat = 28.0
|
||||
public let selectionLineHeight: CGFloat = 4.0
|
||||
public let minimumItemWidth: CGFloat = 32.0
|
||||
public let selectionLineMovingTime: TimeInterval = 0.2
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// MARK: - Layout Views
|
||||
//-------------------------------------------------
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
selectedIndex = 0
|
||||
paddingBeforeFirstTab = true
|
||||
}
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
collectionView?.updateView(size)
|
||||
}
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
backgroundColor = VDSColor.backgroundPrimaryLight
|
||||
addSubview(bottomLine)
|
||||
setupCollectionView()
|
||||
setupSelectionLine()
|
||||
setupConstraints()
|
||||
}
|
||||
|
||||
func setupCollectionView () {
|
||||
layout.scrollDirection = .horizontal
|
||||
layout.minimumLineSpacing = 0
|
||||
open func updateView(_ size: CGFloat) {}
|
||||
|
||||
let collectionView = CollectionView(frame: .zero, collectionViewLayout: layout)
|
||||
collectionView.translatesAutoresizingMaskIntoConstraints = false
|
||||
collectionView.register(TabItemCell.self, forCellWithReuseIdentifier: TabCellId)
|
||||
collectionView.backgroundColor = .clear
|
||||
collectionView.showsVerticalScrollIndicator = false
|
||||
collectionView.showsHorizontalScrollIndicator = false
|
||||
collectionView.dataSource = self
|
||||
collectionView.delegate = self
|
||||
addSubview(collectionView)
|
||||
self.collectionView = collectionView
|
||||
}
|
||||
|
||||
func setupSelectionLine() {
|
||||
bottomScrollView.translatesAutoresizingMaskIntoConstraints = false
|
||||
bottomScrollView.delegate = self
|
||||
addSubview(bottomScrollView)
|
||||
bottomScrollView.addSubview(bottomContentView)
|
||||
selectionLine.backgroundColor = VDSColor.paletteRed
|
||||
bottomContentView.addSubview(selectionLine)
|
||||
bringSubviewToFront(bottomScrollView)
|
||||
}
|
||||
|
||||
func setupConstraints() {
|
||||
//collection view
|
||||
NSLayoutConstraint.constraintPinSubview(collectionView, pinTop: true, pinBottom: false, pinLeft: true, pinRight: true)
|
||||
collectionView?.heightAnchor.constraint(equalToConstant: cellHeight).isActive = true
|
||||
|
||||
//selection line
|
||||
bottomScrollView.topAnchor.constraint(equalTo: collectionView!.bottomAnchor).isActive = true;
|
||||
NSLayoutConstraint.constraintPinSubview(bottomScrollView, pinTop: false, pinBottom: false, pinLeft: true, pinRight: true)
|
||||
bottomScrollView.heightAnchor.constraint(equalToConstant: selectionLineHeight).isActive = true
|
||||
NSLayoutConstraint.constraintPinSubview(selectionLine, pinTop: true, pinBottom: true, pinLeft: false, pinRight: false)
|
||||
selectionLine.heightAnchor.constraint(equalToConstant: selectionLineHeight).isActive = true
|
||||
selectionLineLeftConstraint = selectionLine.leftAnchor.constraint(equalTo: bottomContentView.leftAnchor)
|
||||
selectionLineLeftConstraint?.isActive = true
|
||||
selectionLineWidthConstraint = selectionLine.widthAnchor.constraint(equalToConstant: minimumItemWidth)
|
||||
selectionLineWidthConstraint?.isActive = true
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: bottomContentView)
|
||||
|
||||
//bottom line
|
||||
bottomLine.topAnchor.constraint(equalTo: bottomScrollView.bottomAnchor).isActive = true;
|
||||
NSLayoutConstraint.constraintPinSubview(bottomLine, pinTop: false, pinBottom: true, pinLeft: true, pinRight: true)
|
||||
}
|
||||
|
||||
open override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
// Accounts for any collection size changes
|
||||
DispatchQueue.main.async {
|
||||
self.layoutCollection()
|
||||
}
|
||||
}
|
||||
|
||||
/// Invalidates the layout and ensures we are paged to the correct cell.
|
||||
open func layoutCollection() {
|
||||
collectionView?.collectionViewLayout.invalidateLayout()
|
||||
|
||||
// Go to current cell. layoutIfNeeded is needed otherwise cellForItem returns nil for peaking logic. The dispatch is a sad way to ensure the collection view is ready to be scrolled.
|
||||
DispatchQueue.main.async {
|
||||
self.collectionView?.scrollToItem(at: IndexPath(row: self.selectedIndex, section: 0), at: .left, animated: false)
|
||||
self.collectionView?.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// MARK: - Control Methods
|
||||
//-------------------------------------------------
|
||||
|
||||
public func selectIndex(_ index: Int, animated: Bool) {
|
||||
guard let _ = collectionView, tabsModel?.tabs.count ?? 0 > 0 else {
|
||||
selectedIndex = index
|
||||
tabsModel?.selectedIndex = index
|
||||
return
|
||||
}
|
||||
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
||||
let currentIndex = self.selectedIndex
|
||||
self.selectedIndex = index
|
||||
self.tabsModel?.selectedIndex = index
|
||||
self.deselect(indexPath: IndexPath(row: currentIndex, section: 0))
|
||||
self.selectItem(atIndexPath: IndexPath(row: index, section: 0), animated: animated)
|
||||
})
|
||||
self.selectedIndex = index
|
||||
}
|
||||
|
||||
public func reloadData() {
|
||||
collectionView?.reloadData()
|
||||
}
|
||||
public func reloadData() { setNeedsUpdate() }
|
||||
|
||||
//-------------------------------------------------
|
||||
// MARK: - Molecule Setup
|
||||
//-------------------------------------------------
|
||||
|
||||
override open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
self.delegateObject = delegateObject
|
||||
self.additionalData = additionalData
|
||||
selectedIndex = tabsModel?.selectedIndex ?? 0
|
||||
selectionLine.backgroundColor = tabsModel?.selectedBarColor.uiColor
|
||||
let lineModel = bottomLine.viewModel ?? LineModel(type: .secondary)
|
||||
lineModel.inverted = tabsModel?.style == .dark
|
||||
bottomLine.set(with: lineModel, delegateObject, additionalData)
|
||||
reloadData()
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// MARK: - Collection View Methods
|
||||
//-------------------------------------------------
|
||||
|
||||
extension Tabs: UICollectionViewDataSource {
|
||||
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
return tabsModel?.tabs.count ?? 0
|
||||
}
|
||||
|
||||
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TabCellId, for: indexPath) as? TabItemCell else {
|
||||
return UICollectionViewCell()
|
||||
}
|
||||
cell.updateCell(indexPath: indexPath, delegateObject: delegateObject, additionalData: additionalData, selected: indexPath.row == selectedIndex, tabsModel: tabsModel)
|
||||
updateView(collectionView.bounds.width)
|
||||
return cell
|
||||
}
|
||||
}
|
||||
|
||||
extension Tabs: UICollectionViewDelegateFlowLayout {
|
||||
|
||||
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
|
||||
guard self.collectionView(collectionView, numberOfItemsInSection: indexPath.section) != 2 else {
|
||||
// If two tabs, take up the screen
|
||||
let insets = self.collectionView(collectionView, layout: collectionViewLayout, insetForSectionAt: indexPath.section)
|
||||
let width = (collectionView.bounds.width / 2.0) - insets.left - insets.right
|
||||
return CGSize(width: width, height: cellHeight)
|
||||
}
|
||||
guard let labelModel = tabsModel?.tabs[indexPath.row].label else {
|
||||
return .zero
|
||||
}
|
||||
return CGSize(width: max(minimumItemWidth, getLabelWidth(labelModel).width), height: cellHeight)
|
||||
}
|
||||
|
||||
//pre calculate the width of the collection cell
|
||||
//when user select tabs, it will reload related collectionview, if we use autosize, it would relayout the width, need to keep the cell width constant.
|
||||
func getLabelWidth(_ labelModel: LabelModel?) -> CGSize {
|
||||
guard let labelModel = labelModel else { return .zero}
|
||||
widthLabel.set(with: labelModel, nil, nil)
|
||||
let cgSize = widthLabel.intrinsicContentSize
|
||||
widthLabel.reset()
|
||||
return cgSize
|
||||
}
|
||||
|
||||
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
|
||||
guard section == 0 else {
|
||||
return UIEdgeInsets(top: 0, left: itemSpacing, bottom: 0, right: 0)
|
||||
}
|
||||
guard paddingBeforeFirstTab else {
|
||||
return .zero
|
||||
}
|
||||
return UIEdgeInsets(top: 0, left: Padding.Component.horizontalPaddingForApplicationWidth, bottom: 0, right: 0)
|
||||
}
|
||||
|
||||
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
|
||||
// If two tabs, take up the screen, no space between items
|
||||
guard self.collectionView(collectionView, numberOfItemsInSection: section) != 2 else {
|
||||
return 0
|
||||
}
|
||||
return itemSpacing
|
||||
}
|
||||
|
||||
public func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
|
||||
return delegate?.shouldSelectItem(indexPath, tabs: self) ?? true
|
||||
}
|
||||
|
||||
public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||
selectIndex(indexPath.row, animated: true)
|
||||
}
|
||||
|
||||
public func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
|
||||
guard let tabCell = cell as? TabItemCell else { return }
|
||||
if indexPath.row == selectedIndex {
|
||||
DispatchQueue.main.async {
|
||||
self.moveSelectionLine(toIndex: indexPath, animated: false, cell: tabCell)
|
||||
open func viewModelDidUpdate() {
|
||||
orientation = viewModel.orientation
|
||||
indicatorPosition = viewModel.indicatorPosition
|
||||
overflow = viewModel.overflow
|
||||
size = viewModel.size
|
||||
selectedIndex = viewModel.selectedIndex
|
||||
surface = viewModel.style ?? .light
|
||||
tabModels = viewModel.tabs.compactMap { TabModel(text: $0.label.text) }
|
||||
|
||||
if let delegate {
|
||||
onTabChange = { [weak self] index in
|
||||
guard let self else { return }
|
||||
delegate.didSelectItem(.init(row: index, section: 0), tabs: self)
|
||||
}
|
||||
|
||||
onTabShouldSelect = { [weak self] index in
|
||||
guard let self else { return true }
|
||||
return delegate.shouldSelectItem(.init(row: index, section: 0), tabs: self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func deselect(indexPath:IndexPath) {
|
||||
collectionView?.deselectItem(at: indexPath, animated: false)
|
||||
collectionView?.reloadItems(at: [indexPath])
|
||||
}
|
||||
|
||||
func selectItem(atIndexPath indexPath: IndexPath, animated: Bool) {
|
||||
|
||||
guard let collect = collectionView, tabsModel?.tabs.count ?? 0 > 0 else { return }
|
||||
|
||||
collect.selectItem(at: indexPath, animated: animated, scrollPosition: .centeredHorizontally)
|
||||
guard let tabCell = collect.cellForItem(at: indexPath) as? TabItemCell, let tabsModel = tabsModel else { return }
|
||||
moveSelectionLine(toIndex: indexPath, animated: animated, cell: tabCell)
|
||||
tabCell.label.textColor = tabsModel.selectedColor.uiColor
|
||||
tabCell.updateAccessibility(indexPath: indexPath, selected: true, tabsModel: tabsModel)
|
||||
tabCell.setNeedsDisplay()
|
||||
tabCell.setNeedsLayout()
|
||||
tabCell.layoutIfNeeded()
|
||||
if let delegate = delegate {
|
||||
delegate.didSelectItem(indexPath, tabs: self)
|
||||
} else if let action = tabsModel.tabs[selectedIndex].action {
|
||||
MVMCoreUIActionHandler.performActionUnstructured(with: action, sourceModel: tabsModel, additionalData: nil, delegateObject: delegateObject)
|
||||
}
|
||||
if UIAccessibility.isVoiceOverRunning {
|
||||
UIAccessibility.post(notification: .layoutChanged, argument: tabCell)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension Tabs: UIScrollViewDelegate {
|
||||
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
/*bottomScrollview is subview of self, it's not belongs to collectionview.
|
||||
When collectionview is scrolling, bottomScrollView will stay without moving
|
||||
Adding collectionview's offset to bottomScrollView, will make the bottomScrollview looks like scrolling with the selected tab item.
|
||||
*/
|
||||
guard let offsetX = collectionView?.contentOffset.x else { return }
|
||||
bottomScrollView.setContentOffset(CGPoint(x: offsetX, y: bottomScrollView.contentOffset.y), animated: false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// MARK: - Bottom Line Methods
|
||||
//-------------------------------------------------
|
||||
extension Tabs {
|
||||
func moveSelectionLine(toIndex indexPath: IndexPath, animated: Bool, cell: TabItemCell) {
|
||||
guard let collect = collectionView else {return}
|
||||
|
||||
let size = collectionView(collect, layout: layout, sizeForItemAt: indexPath)
|
||||
let animationBlock = {
|
||||
[weak self] in
|
||||
self?.selectionLineWidthConstraint?.constant = size.width
|
||||
self?.selectionLineLeftConstraint?.constant = cell.frame.origin.x
|
||||
self?.bottomContentView.layoutIfNeeded()
|
||||
}
|
||||
if animated {
|
||||
UIView.animate(withDuration: selectionLineMovingTime, animations: animationBlock)
|
||||
} else {
|
||||
animationBlock()
|
||||
}
|
||||
}
|
||||
|
||||
/// Adjust the line based on the percentage
|
||||
func progress(from index: Int, toIndex: Int, percentage: CGFloat) {
|
||||
let fromIndexPath = IndexPath(row: index, section: 0)
|
||||
let toIndexPath = IndexPath(row: toIndex, section: 0)
|
||||
guard let collection = collectionView,
|
||||
let fromCell = collection.cellForItem(at: fromIndexPath),
|
||||
let toCell = collection.cellForItem(at: toIndexPath) else { return }
|
||||
|
||||
// setting the width for percentage
|
||||
selectionLineWidthConstraint?.constant = (toCell.bounds.width - fromCell.bounds.width) * percentage + fromCell.bounds.width
|
||||
|
||||
// setting the x for percentage
|
||||
let originalX = fromCell.frame.origin.x
|
||||
let toX = toCell.frame.origin.x
|
||||
let xDifference = toX - originalX
|
||||
let finalX = (xDifference * percentage) + originalX
|
||||
selectionLineLeftConstraint?.constant = finalX
|
||||
|
||||
bottomContentView.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
@objcMembers public class TabItemCell: CollectionViewCell {
|
||||
public let label = Label()
|
||||
|
||||
public override func setupView() {
|
||||
super.setupView()
|
||||
contentView.addSubview(label)
|
||||
NSLayoutConstraint.constraintPinSubview(label, pinTop: false, topConstant: 0, pinBottom: true, bottomConstant: 6, pinLeft: true, leftConstant: 0, pinRight: true, rightConstant: 0)
|
||||
label.baselineAdjustment = .alignCenters
|
||||
}
|
||||
|
||||
public override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
label.updateView(size)
|
||||
}
|
||||
|
||||
public func updateCell(indexPath: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?, selected: Bool, tabsModel: TabsModel?) {
|
||||
guard let tabsModel = tabsModel else { return }
|
||||
label.reset()
|
||||
label.set(with: tabsModel.tabs[indexPath.row].label, delegateObject, additionalData)
|
||||
if selected {
|
||||
label.textColor = tabsModel.selectedColor.uiColor
|
||||
} else {
|
||||
label.textColor = tabsModel.unselectedColor.uiColor
|
||||
}
|
||||
updateAccessibility(indexPath: indexPath, selected: selected, tabsModel: tabsModel)
|
||||
}
|
||||
|
||||
public func updateAccessibility(indexPath: IndexPath, selected: Bool, tabsModel: TabsModel?) {
|
||||
//Accessibility
|
||||
isAccessibilityElement = false
|
||||
contentView.isAccessibilityElement = true
|
||||
let accKey = selected ? "toptabbar_tab_selected" : "AccTab"
|
||||
let accLabel = "\(label.text ?? "") \(MVMCoreUIUtility.hardcodedString(withKey: accKey) ?? "")"
|
||||
let accOrder = String(format: MVMCoreUIUtility.hardcodedString(withKey: "AccTabIndex") ?? "", indexPath.row + 1, tabsModel?.tabs.count ?? 0)
|
||||
contentView.accessibilityLabel = "\(accLabel) \(accOrder)"
|
||||
contentView.accessibilityHint = selected ? nil : MVMCoreUIUtility.hardcodedString(withKey: "AccTabHint")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -8,67 +8,22 @@
|
||||
|
||||
import UIKit
|
||||
import VDSColorTokens
|
||||
|
||||
import VDS
|
||||
open class TabsModel: MoleculeModelProtocol {
|
||||
|
||||
public static var identifier: String = "tabs"
|
||||
public var id: String = UUID().uuidString
|
||||
|
||||
open var tabs: [TabItemModel]
|
||||
|
||||
open var style: NavigationItemStyle?
|
||||
|
||||
private var _backgroundColor: Color?
|
||||
open var backgroundColor: Color? {
|
||||
get {
|
||||
if let backgroundColor = _backgroundColor { return backgroundColor }
|
||||
if let style = style,
|
||||
style == .dark { return Color(uiColor: VDSColor.backgroundPrimaryDark) }
|
||||
return Color(uiColor: VDSColor.backgroundPrimaryLight)
|
||||
}
|
||||
set {
|
||||
_backgroundColor = newValue
|
||||
}
|
||||
}
|
||||
|
||||
private var _selectedColor: Color?
|
||||
open var selectedColor: Color {
|
||||
get {
|
||||
if let selectedColor = _selectedColor { return selectedColor }
|
||||
if let style = style,
|
||||
style == .dark { return Color(uiColor: VDSColor.elementsPrimaryOndark) }
|
||||
return Color(uiColor: VDSColor.elementsPrimaryOnlight)
|
||||
}
|
||||
set {
|
||||
_selectedColor = newValue
|
||||
}
|
||||
}
|
||||
|
||||
private var _unselectedColor: Color?
|
||||
open var unselectedColor: Color {
|
||||
get {
|
||||
if let unselectedColor = _unselectedColor { return unselectedColor }
|
||||
if let style = style,
|
||||
style == .dark { return Color(uiColor: VDSColor.elementsSecondaryOndark) }
|
||||
return Color(uiColor: VDSColor.elementsSecondaryOnlight)
|
||||
}
|
||||
set {
|
||||
_unselectedColor = newValue
|
||||
}
|
||||
}
|
||||
|
||||
private var _selectedBarColor: Color?
|
||||
open var selectedBarColor: Color {
|
||||
get {
|
||||
if let selectedBarColor = _selectedBarColor { return selectedBarColor }
|
||||
if let style = style,
|
||||
style == .dark { return Color(uiColor: VDSColor.elementsPrimaryOndark) }
|
||||
return Color(uiColor: VDSColor.paletteRed)
|
||||
}
|
||||
set {
|
||||
_selectedBarColor = newValue
|
||||
}
|
||||
}
|
||||
|
||||
open var style: Surface?
|
||||
|
||||
open var orientation: Tabs.Orientation = .horizontal
|
||||
open var indicatorPosition: Tabs.IndicatorPosition = .bottom
|
||||
open var overflow: Tabs.Overflow = .scroll
|
||||
open var size: Tabs.Size = .medium
|
||||
public var backgroundColor: Color?
|
||||
|
||||
// Must be capped to 0...(tabs.count - 1)
|
||||
open var selectedIndex: Int = 0
|
||||
|
||||
@ -77,10 +32,11 @@ open class TabsModel: MoleculeModelProtocol {
|
||||
case moleculeName
|
||||
case tabs
|
||||
case backgroundColor
|
||||
case selectedColor
|
||||
case unselectedColor
|
||||
case selectedBarColor
|
||||
case selectedIndex
|
||||
case orientation
|
||||
case indicatorPosition
|
||||
case overflow
|
||||
case size
|
||||
case style
|
||||
}
|
||||
|
||||
@ -92,14 +48,26 @@ open class TabsModel: MoleculeModelProtocol {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
|
||||
tabs = try typeContainer.decode([TabItemModel].self, forKey: .tabs)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
_selectedColor = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedColor)
|
||||
_unselectedColor = try typeContainer.decodeIfPresent(Color.self, forKey: .unselectedColor)
|
||||
_selectedBarColor = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedBarColor)
|
||||
style = try typeContainer.decodeIfPresent(NavigationItemStyle.self, forKey: .style)
|
||||
style = try typeContainer.decodeIfPresent(Surface.self, forKey: .style)
|
||||
if let index = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedIndex) {
|
||||
selectedIndex = index
|
||||
}
|
||||
|
||||
if let orientation = try typeContainer.decodeIfPresent(VDS.Tabs.Orientation.self, forKey: .orientation) {
|
||||
self.orientation = orientation
|
||||
}
|
||||
|
||||
if let indicatorPosition = try typeContainer.decodeIfPresent(VDS.Tabs.IndicatorPosition.self, forKey: .indicatorPosition) {
|
||||
self.indicatorPosition = indicatorPosition
|
||||
}
|
||||
|
||||
if let overflow = try typeContainer.decodeIfPresent(VDS.Tabs.Overflow.self, forKey: .overflow) {
|
||||
self.overflow = overflow
|
||||
}
|
||||
|
||||
if let size = try typeContainer.decodeIfPresent(VDS.Tabs.Size.self, forKey: .orientation) {
|
||||
self.size = size
|
||||
}
|
||||
}
|
||||
|
||||
open func encode(to encoder: Encoder) throws {
|
||||
@ -107,12 +75,13 @@ open class TabsModel: MoleculeModelProtocol {
|
||||
try container.encode(id, forKey: .id)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encode(tabs, forKey: .tabs)
|
||||
try container.encodeIfPresent(_backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(_selectedColor, forKey: .selectedColor)
|
||||
try container.encodeIfPresent(_unselectedColor, forKey: .unselectedColor)
|
||||
try container.encodeIfPresent(_selectedBarColor, forKey: .selectedBarColor)
|
||||
try container.encode(selectedIndex, forKey: .selectedIndex)
|
||||
try container.encodeIfPresent(style, forKey: .style)
|
||||
try container.encode(orientation, forKey: .orientation)
|
||||
try container.encode(overflow, forKey: .overflow)
|
||||
try container.encode(size, forKey: .size)
|
||||
try container.encode(indicatorPosition, forKey: .indicatorPosition)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user