commented out stuff dealing with width since this doesn't apply to this view for now
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
a1d25b0dfc
commit
7fa75eb519
@ -9,7 +9,7 @@ import Foundation
|
|||||||
import UIKit
|
import UIKit
|
||||||
import VDSColorTokens
|
import VDSColorTokens
|
||||||
|
|
||||||
public class Tabs: View {
|
open class Tabs: View {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Enums
|
// MARK: - Enums
|
||||||
@ -61,49 +61,77 @@ public class Tabs: View {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Public Properties
|
// MARK: - Public Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
public var onTabChange: ((Int) -> Void)?
|
///An optional callback that is called when the selectedIndex changes. Passes parameters (event, tabIndex).
|
||||||
public var orientation: Orientation = .horizontal { didSet { updateTabItems() } }
|
open var onTabChange: ((Int) -> Void)?
|
||||||
public var borderLine: Bool = true { didSet { setNeedsUpdate() } }
|
|
||||||
public var fillContainer: Bool = false { didSet { updateTabItems() } }
|
//Determines the layout of the Tabs, defaults to horizontal
|
||||||
public var indicatorFillTab: Bool = false { didSet { setNeedsUpdate() } }
|
open var orientation: Orientation = .horizontal { didSet { if oldValue != orientation { updateTabItems() } } }
|
||||||
public var indicatorPosition: IndicatorPosition = .bottom { didSet { setNeedsUpdate() } }
|
|
||||||
public var minWidth: CGFloat = 44.0 { didSet { setNeedsUpdate() } }
|
///When true, Tabs will have border line. If false is passed then the border line won't be visible.
|
||||||
public var overflow: Overflow = .scroll { didSet { updateTabItems() } }
|
open var borderLine: Bool = true { didSet { setNeedsUpdate() } }
|
||||||
public var selectedIndex: Int = 0 { didSet { setNeedsUpdate() } }
|
|
||||||
public var size: Size = .medium { didSet { setNeedsUpdate() } }
|
///It will fill the Tabs to the width of the compoent and all Tabs will be in equal width when orientation is horizontal. This is recommended when there are no more than 2-3 tabs.
|
||||||
public var sticky: Bool = false { didSet { setNeedsUpdate() } }
|
open var fillContainer: Bool = false { didSet { updateTabItems() } }
|
||||||
public var tabModels: [TabModel] = [] { didSet { updateTabItems() } }
|
|
||||||
|
///When true, Tabs will be sticky to top of page, when orientation is vertical.
|
||||||
|
open var indicatorFillTab: Bool = false { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
|
///Sets the Position of the Selected/Hover Border Accent for All Tabs, only for Horizontal Orientation
|
||||||
|
open var indicatorPosition: IndicatorPosition = .bottom { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
|
///Minimum Width for All Tabs, when orientation is horizontal.
|
||||||
|
open var minWidth: CGFloat = 44.0 { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
|
///If set to 'scroll', Tabs can be overflow and scrollable. With 'none', tabs will not overflow and labels will be wrapped to multiple lines if the label text is long.
|
||||||
|
open var overflow: Overflow = .scroll { didSet { updateTabItems() } }
|
||||||
|
|
||||||
|
///The initial Selected Tab's index and is set once a Tab is clicked
|
||||||
|
open var selectedIndex: Int = 0 { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
//rules for width
|
///Determines the size of the Tabs TextStyle
|
||||||
private var _width: Width = .percentage(0.25)
|
open var size: Size = .medium { didSet { updateTabItems() } }
|
||||||
public var width: Width {
|
|
||||||
get {
|
///When true, Tabs will be sticky to top of page, when orientation is vertical.
|
||||||
return _width
|
open var sticky: Bool = false { didSet { setNeedsUpdate() } }
|
||||||
}
|
|
||||||
set {
|
///Model of the Tabs you are wanting to show.
|
||||||
switch newValue {
|
open var tabModels: [TabModel] = [] { didSet { updateTabItems() } }
|
||||||
case .percentage(let percentage):
|
|
||||||
if percentage >= 0 && percentage <= 1 {
|
// //rules for width
|
||||||
_width = newValue
|
// private var _width: Width? = .percentage(0.25)
|
||||||
setNeedsUpdate()
|
//
|
||||||
} else {
|
// ///Width of all Tabs when orientation is vertical, defaults to 25%.
|
||||||
print("Invalid percentage value. It should be between 0 and 1.")
|
// open var width: Width? {
|
||||||
}
|
// get {
|
||||||
case .value(let value):
|
// return _width
|
||||||
if value >= minWidth {
|
// }
|
||||||
_width = newValue
|
// set {
|
||||||
setNeedsUpdate()
|
// if let newValue {
|
||||||
} else {
|
// switch newValue {
|
||||||
print("Invalid value. It should be greater than or equal to \(minWidth).")
|
// case .percentage(let percentage):
|
||||||
}
|
// if percentage >= 0 && percentage <= 1 {
|
||||||
}
|
// _width = newValue
|
||||||
}
|
// setNeedsUpdate()
|
||||||
}
|
// } else {
|
||||||
|
// print("Invalid percentage value. It should be between 0 and 1.")
|
||||||
|
// }
|
||||||
|
// case .value(let value):
|
||||||
|
// if value >= minWidth {
|
||||||
|
// _width = newValue
|
||||||
|
// setNeedsUpdate()
|
||||||
|
// } else {
|
||||||
|
// print("Invalid value. It should be greater than or equal to \(minWidth).")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
open var tabItems: [TabItem] = []
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Private Properties
|
// MARK: - Private Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
private var tabItems: [TabItem] = []
|
|
||||||
private var tabStackView: UIStackView!
|
private var tabStackView: UIStackView!
|
||||||
private var scrollView: UIScrollView!
|
private var scrollView: UIScrollView!
|
||||||
private var contentView: View!
|
private var contentView: View!
|
||||||
@ -162,7 +190,6 @@ public class Tabs: View {
|
|||||||
tabItem.removeFromSuperview()
|
tabItem.removeFromSuperview()
|
||||||
}
|
}
|
||||||
tabItems.removeAll()
|
tabItems.removeAll()
|
||||||
|
|
||||||
// Create new tab items from the models
|
// Create new tab items from the models
|
||||||
for model in models {
|
for model in models {
|
||||||
let tabItem = TabItem()
|
let tabItem = TabItem()
|
||||||
@ -195,38 +222,43 @@ public class Tabs: View {
|
|||||||
|
|
||||||
open override func updateView() {
|
open override func updateView() {
|
||||||
super.updateView()
|
super.updateView()
|
||||||
|
|
||||||
|
// Update the stackview properties
|
||||||
if orientation == .horizontal && fillContainer {
|
if orientation == .horizontal && fillContainer {
|
||||||
tabStackView.distribution = .fillEqually
|
tabStackView.distribution = .fillEqually
|
||||||
} else {
|
} else {
|
||||||
tabStackView.distribution = .fill
|
tabStackView.distribution = .fillProportionally
|
||||||
}
|
|
||||||
|
|
||||||
// Update tab appearance based on properties
|
|
||||||
for (index, tabItem) in tabItems.enumerated() {
|
|
||||||
tabItem.selected = selectedIndex == index
|
|
||||||
tabItem.size = size
|
|
||||||
tabItem.orientation = orientation
|
|
||||||
tabItem.surface = surface
|
|
||||||
tabItem.indicatorPosition = indicatorPosition
|
|
||||||
tabItem.width = tabWidth(for: tabItem)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tabStackView.axis = orientation == .horizontal ? .horizontal : .vertical
|
tabStackView.axis = orientation == .horizontal ? .horizontal : .vertical
|
||||||
tabStackView.alignment = orientation == .horizontal ? .fill : .leading
|
tabStackView.alignment = orientation == .horizontal ? .fill : .leading
|
||||||
tabStackView.spacing = orientation == .horizontal ? VDSLayout.Spacing.space6X.value : VDSLayout.Spacing.space4X.value
|
tabStackView.spacing = orientation == .horizontal ? VDSLayout.Spacing.space6X.value : VDSLayout.Spacing.space4X.value
|
||||||
|
|
||||||
|
// Update tab appearance based on properties
|
||||||
|
for (index, tabItem) in tabItems.enumerated() {
|
||||||
|
tabItem.selected = selectedIndex == index
|
||||||
|
tabItem.index = index
|
||||||
|
tabItem.minWidth = minWidth
|
||||||
|
tabItem.size = size
|
||||||
|
tabItem.textPosition = orientation == .horizontal && fillContainer ? .center : .left
|
||||||
|
tabItem.orientation = orientation
|
||||||
|
tabItem.surface = surface
|
||||||
|
tabItem.indicatorPosition = indicatorPosition
|
||||||
|
}
|
||||||
|
|
||||||
// Deactivate old constraint
|
// Deactivate old constraint
|
||||||
contentViewWidthConstraint?.isActive = false
|
contentViewWidthConstraint?.isActive = false
|
||||||
|
|
||||||
// Apply width
|
// Apply width
|
||||||
if orientation == .vertical {
|
if orientation == .vertical {
|
||||||
scrollView.isScrollEnabled = false
|
scrollView.isScrollEnabled = false
|
||||||
switch width {
|
// switch width {
|
||||||
case .percentage(let amount):
|
// case .percentage(let amount):
|
||||||
contentViewWidthConstraint = contentView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: amount)
|
// contentViewWidthConstraint = contentView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: amount)
|
||||||
case .value(let amount):
|
// case .value(let amount):
|
||||||
contentViewWidthConstraint = contentView.widthAnchor.constraint(equalToConstant: amount)
|
// contentViewWidthConstraint = contentView.widthAnchor.constraint(equalToConstant: amount)
|
||||||
}
|
// }
|
||||||
|
contentViewWidthConstraint = contentView.widthAnchor.constraint(equalTo: widthAnchor)
|
||||||
} else {
|
} else {
|
||||||
// Apply overflow
|
// Apply overflow
|
||||||
if overflow == .scroll && !fillContainer {
|
if overflow == .scroll && !fillContainer {
|
||||||
@ -278,20 +310,20 @@ public class Tabs: View {
|
|||||||
scrollToSelectedIndex(animated: true)
|
scrollToSelectedIndex(animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
// //--------------------------------------------------
|
||||||
// MARK: - Private Methods
|
// // MARK: - Private Methods
|
||||||
//--------------------------------------------------
|
// //--------------------------------------------------
|
||||||
private func tabWidth(for item: TabItem) -> CGFloat? {
|
// private func tabWidth(for item: TabItem) -> CGFloat? {
|
||||||
guard orientation == .vertical else { return item.width }
|
// guard orientation == .vertical else { return item.width }
|
||||||
var calculated: CGFloat
|
// var calculated: CGFloat
|
||||||
switch width {
|
// switch width {
|
||||||
case .percentage(let percent):
|
// case .percentage(let percent):
|
||||||
calculated = (bounds.width * percent) - tabStackView.spacing
|
// calculated = (bounds.width * percent) - tabStackView.spacing
|
||||||
case .value(let value):
|
// case .value(let value):
|
||||||
calculated = value - tabStackView.spacing
|
// calculated = value - tabStackView.spacing
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return calculated > minWidth ? calculated : minWidth
|
// return calculated > minWidth ? calculated : minWidth
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user