Merge branch 'mbruce/bugfixes' into 'develop'
updated version / release notes for typopgraphy update See merge request BPHV_MIPS/vds_ios!102
This commit is contained in:
commit
309a74196b
@ -1167,7 +1167,7 @@
|
|||||||
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
|
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
|
||||||
CODE_SIGN_IDENTITY = "";
|
CODE_SIGN_IDENTITY = "";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 37;
|
CURRENT_PROJECT_VERSION = 39;
|
||||||
DEFINES_MODULE = YES;
|
DEFINES_MODULE = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
@ -1204,7 +1204,7 @@
|
|||||||
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
|
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
|
||||||
CODE_SIGN_IDENTITY = "";
|
CODE_SIGN_IDENTITY = "";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 37;
|
CURRENT_PROJECT_VERSION = 39;
|
||||||
DEFINES_MODULE = YES;
|
DEFINES_MODULE = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
|
|||||||
@ -165,7 +165,10 @@ open class BadgeIndicator: View {
|
|||||||
|
|
||||||
/// Character that is always at the begging. Accepts any character and if unaffected by maximumDigits.
|
/// Character that is always at the begging. Accepts any character and if unaffected by maximumDigits.
|
||||||
open var leadingCharacter: String? { didSet { setNeedsUpdate() }}
|
open var leadingCharacter: String? { didSet { setNeedsUpdate() }}
|
||||||
|
|
||||||
|
/// Accepts any text or character. It is unaffected by maximumDigits.
|
||||||
|
open var trailingText: String? { didSet { setNeedsUpdate() }}
|
||||||
|
|
||||||
/// Determines the size of the Badge Indicator as well as the textStyle and padding used.
|
/// Determines the size of the Badge Indicator as well as the textStyle and padding used.
|
||||||
open var size: Size = .xxlarge { didSet { setNeedsUpdate() }}
|
open var size: Size = .xxlarge { didSet { setNeedsUpdate() }}
|
||||||
|
|
||||||
@ -359,10 +362,23 @@ open class BadgeIndicator: View {
|
|||||||
let formatter = NumberFormatter()
|
let formatter = NumberFormatter()
|
||||||
formatter.numberStyle = .decimal
|
formatter.numberStyle = .decimal
|
||||||
text = formatter.string(from: .init(integerLiteral: maxBadgetCount))!
|
text = formatter.string(from: .init(integerLiteral: maxBadgetCount))!
|
||||||
|
|
||||||
if let leadingCharacter {
|
//leading
|
||||||
|
if let leadingCharacter, !leadingCharacter.isEmpty {
|
||||||
text = "\(leadingCharacter)\(text)"
|
text = "\(leadingCharacter)\(text)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//maximumDigits
|
||||||
|
if maximumDigits.value < "\(badgeCount)".count {
|
||||||
|
let formatter = NumberFormatter()
|
||||||
|
formatter.numberStyle = .decimal
|
||||||
|
text = "\(text)+"
|
||||||
|
}
|
||||||
|
|
||||||
|
//trailing
|
||||||
|
if let trailingText, !trailingText.isEmpty {
|
||||||
|
text = "\(text) \(trailingText)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,11 @@ extension Tabs {
|
|||||||
open var index: Int = 0
|
open var index: Int = 0
|
||||||
|
|
||||||
///label to write out the text
|
///label to write out the text
|
||||||
open var label: Label = Label().with { $0.isUserInteractionEnabled = false }
|
open var label: Label = Label().with {
|
||||||
|
$0.isUserInteractionEnabled = false
|
||||||
|
$0.setContentCompressionResistancePriority(.required, for: .horizontal)
|
||||||
|
$0.setContentHuggingPriority(.required, for: .horizontal)
|
||||||
|
}
|
||||||
|
|
||||||
///orientation of the tabs
|
///orientation of the tabs
|
||||||
open var orientation: Tabs.Orientation = .horizontal { didSet { setNeedsUpdate() } }
|
open var orientation: Tabs.Orientation = .horizontal { didSet { setNeedsUpdate() } }
|
||||||
@ -38,7 +42,7 @@ extension Tabs {
|
|||||||
open var width: CGFloat? { didSet { setNeedsUpdate() } }
|
open var width: CGFloat? { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
///The text label of the tab.
|
///The text label of the tab.
|
||||||
open var text: String = "" { didSet { setNeedsUpdate() } }
|
open var text: String = "Tab" { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
///Minimum width for the tab
|
///Minimum width for the tab
|
||||||
open var minWidth: CGFloat = 44.0 { didSet { setNeedsUpdate() } }
|
open var minWidth: CGFloat = 44.0 { didSet { setNeedsUpdate() } }
|
||||||
@ -88,12 +92,14 @@ extension Tabs {
|
|||||||
return VDSLayout.Spacing.space2X.value
|
return VDSLayout.Spacing.space2X.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private let layoutGuide = UILayoutGuide()
|
||||||
|
|
||||||
private var widthConstraint: NSLayoutConstraint {
|
private var widthConstraint: NSLayoutConstraint? {
|
||||||
if let width, orientation == .vertical {
|
if let width, orientation == .vertical {
|
||||||
return label.widthAnchor.constraint(equalToConstant: width)
|
return layoutGuide.widthAnchor.constraint(equalToConstant: width)
|
||||||
} else {
|
} else {
|
||||||
return label.widthAnchor.constraint(greaterThanOrEqualToConstant: minWidth)
|
return layoutGuide.widthAnchor.constraint(greaterThanOrEqualToConstant: minWidth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,35 +121,30 @@ extension Tabs {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Overrides
|
// MARK: - Overrides
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
open override func setup() {
|
open override func setup() {
|
||||||
super.setup()
|
super.setup()
|
||||||
|
addLayoutGuide(layoutGuide)
|
||||||
addSubview(label)
|
addSubview(label)
|
||||||
accessibilityTraits = .button
|
accessibilityTraits = .button
|
||||||
isAccessibilityElement = true
|
isAccessibilityElement = true
|
||||||
|
|
||||||
label.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
label.pinTrailing()
|
|
||||||
|
|
||||||
labelTopConstraint = label.topAnchor.constraint(equalTo: topAnchor)
|
|
||||||
labelTopConstraint?.isActive = true
|
|
||||||
|
|
||||||
labelBottomConstraint = label.bottomAnchor.constraint(equalTo: bottomAnchor)
|
|
||||||
labelBottomConstraint?.isActive = true
|
|
||||||
|
|
||||||
labelLeadingConstraint = label.leadingAnchor.constraint(equalTo: leadingAnchor)
|
|
||||||
labelLeadingConstraint?.isActive = true
|
|
||||||
|
|
||||||
let layoutGuide = UILayoutGuide()
|
|
||||||
addLayoutGuide(layoutGuide)
|
|
||||||
|
|
||||||
labelWidthConstraint = layoutGuide.widthAnchor.constraint(greaterThanOrEqualToConstant: minWidth)
|
|
||||||
labelWidthConstraint?.isActive = true
|
|
||||||
|
|
||||||
//activate the constraints
|
//activate the constraints
|
||||||
NSLayoutConstraint.activate([layoutGuide.topAnchor.constraint(equalTo: topAnchor),
|
NSLayoutConstraint.activate([layoutGuide.topAnchor.constraint(equalTo: topAnchor),
|
||||||
layoutGuide.bottomAnchor.constraint(equalTo: bottomAnchor),
|
layoutGuide.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||||
layoutGuide.leadingAnchor.constraint(equalTo: leadingAnchor),
|
layoutGuide.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||||
layoutGuide.trailingAnchor.constraint(equalTo: trailingAnchor)])
|
layoutGuide.trailingAnchor.constraint(equalTo: trailingAnchor)])
|
||||||
|
|
||||||
|
label.pinTrailing(layoutGuide.trailingAnchor)
|
||||||
|
|
||||||
|
labelTopConstraint = label.topAnchor.constraint(equalTo: layoutGuide.topAnchor)
|
||||||
|
labelTopConstraint?.isActive = true
|
||||||
|
|
||||||
|
labelBottomConstraint = label.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor)
|
||||||
|
labelBottomConstraint?.isActive = true
|
||||||
|
|
||||||
|
labelLeadingConstraint = label.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor)
|
||||||
|
labelLeadingConstraint?.isActive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Function used to make changes to the View based off a change events or from local properties.
|
/// Function used to make changes to the View based off a change events or from local properties.
|
||||||
@ -151,12 +152,8 @@ extension Tabs {
|
|||||||
super.updateView()
|
super.updateView()
|
||||||
|
|
||||||
guard !text.isEmpty else { return }
|
guard !text.isEmpty else { return }
|
||||||
|
|
||||||
//label properties
|
accessibilityIdentifier = "VDSTab:\(text)"
|
||||||
label.text = text
|
|
||||||
label.textStyle = textStyle
|
|
||||||
label.textPosition = textPosition
|
|
||||||
label.textColorConfiguration = textColorConfiguration.eraseToAnyColorable()
|
|
||||||
|
|
||||||
//constaints
|
//constaints
|
||||||
labelWidthConstraint?.isActive = false
|
labelWidthConstraint?.isActive = false
|
||||||
@ -165,8 +162,17 @@ extension Tabs {
|
|||||||
labelLeadingConstraint?.constant = leadingSpace
|
labelLeadingConstraint?.constant = leadingSpace
|
||||||
labelTopConstraint?.constant = otherSpace
|
labelTopConstraint?.constant = otherSpace
|
||||||
labelBottomConstraint?.constant = -otherSpace
|
labelBottomConstraint?.constant = -otherSpace
|
||||||
|
|
||||||
|
//label properties
|
||||||
|
label.text = text
|
||||||
|
label.surface = surface
|
||||||
|
label.textStyle = textStyle
|
||||||
|
label.textPosition = textPosition
|
||||||
|
label.textColorConfiguration = textColorConfiguration.eraseToAnyColorable()
|
||||||
|
|
||||||
setNeedsLayout()
|
setNeedsLayout()
|
||||||
|
layoutIfNeeded()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func updateAccessibility() {
|
open override func updateAccessibility() {
|
||||||
@ -176,7 +182,7 @@ extension Tabs {
|
|||||||
|
|
||||||
open override func layoutSubviews() {
|
open override func layoutSubviews() {
|
||||||
super.layoutSubviews()
|
super.layoutSubviews()
|
||||||
|
|
||||||
removeBorders()
|
removeBorders()
|
||||||
|
|
||||||
if isSelected {
|
if isSelected {
|
||||||
@ -185,5 +191,3 @@ extension Tabs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,7 @@ open class Tabs: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Type of behavior for Scrolling
|
//Type of behavior for Scrolling
|
||||||
public enum Overflow: String, CaseIterable {
|
public enum Overflow: String, CaseIterable {
|
||||||
case scroll
|
case scroll
|
||||||
@ -48,7 +48,7 @@ open class Tabs: View {
|
|||||||
case medium
|
case medium
|
||||||
case large
|
case large
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Public Properties
|
// MARK: - Public Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -57,13 +57,13 @@ open class Tabs: View {
|
|||||||
open var onTabChange: ((Int) -> Void)?
|
open var onTabChange: ((Int) -> Void)?
|
||||||
|
|
||||||
//Determines the layout of the Tabs, defaults to horizontal
|
//Determines the layout of the Tabs, defaults to horizontal
|
||||||
open var orientation: Orientation = .horizontal { didSet { if oldValue != orientation { updateTabItems() } } }
|
open var orientation: Orientation = .horizontal { didSet { if oldValue != orientation { setNeedsUpdate() } } }
|
||||||
|
|
||||||
///When true, Tabs will have border line. If false is passed then the border line won't be visible.
|
///When true, Tabs will have border line. If false is passed then the border line won't be visible.
|
||||||
open var borderLine: Bool = true { didSet { setNeedsUpdate() } }
|
open var borderLine: Bool = true { 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.
|
///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.
|
||||||
open var fillContainer: Bool = false { didSet { updateTabItems() } }
|
open var fillContainer: Bool = false { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
///When true, Tabs will be sticky to top of page, when orientation is vertical.
|
///When true, Tabs will be sticky to top of page, when orientation is vertical.
|
||||||
open var indicatorFillTab: Bool = false { didSet { setNeedsUpdate() } }
|
open var indicatorFillTab: Bool = false { didSet { setNeedsUpdate() } }
|
||||||
@ -75,22 +75,22 @@ open class Tabs: View {
|
|||||||
open var minWidth: CGFloat = 44.0 { didSet { setNeedsUpdate() } }
|
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.
|
///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() } }
|
open var overflow: Overflow = .scroll { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
///The initial Selected Tab's index and is set once a Tab is clicked
|
///The initial Selected Tab's index and is set once a Tab is clicked
|
||||||
open var selectedIndex: Int = 0 { didSet { setNeedsUpdate() } }
|
open var selectedIndex: Int = 0 { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
///Determines the size of the Tabs TextStyle
|
///Determines the size of the Tabs TextStyle
|
||||||
open var size: Size = .medium { didSet { updateTabItems() } }
|
open var size: Size = .medium { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
///When true, Tabs will be sticky to top of page, when orientation is vertical.
|
///When true, Tabs will be sticky to top of page, when orientation is vertical.
|
||||||
open var sticky: Bool = false { didSet { setNeedsUpdate() } }
|
open var sticky: Bool = false { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
///Model of the Tabs you are wanting to show.
|
///Model of the Tabs you are wanting to show.
|
||||||
open var tabModels: [TabModel] = [] { didSet { updateTabItems() } }
|
open var tabModels: [TabModel] = [] { didSet { updateTabItems() } }
|
||||||
|
|
||||||
open var tabViews: [Tab] = []
|
open var tabViews: [Tab] = []
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Private Properties
|
// MARK: - Private Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -107,7 +107,7 @@ open class Tabs: View {
|
|||||||
private var borderlineViewHeightConstraint: NSLayoutConstraint?
|
private var borderlineViewHeightConstraint: NSLayoutConstraint?
|
||||||
private var borderlineViewWidthConstraint: NSLayoutConstraint?
|
private var borderlineViewWidthConstraint: NSLayoutConstraint?
|
||||||
private var contentViewWidthConstraint: NSLayoutConstraint?
|
private var contentViewWidthConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Configuration Properties
|
// MARK: - Configuration Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -123,7 +123,7 @@ open class Tabs: View {
|
|||||||
if orientation == .horizontal && fillContainer {
|
if orientation == .horizontal && fillContainer {
|
||||||
return .fillEqually
|
return .fillEqually
|
||||||
} else {
|
} else {
|
||||||
return orientation == .horizontal ? .fillProportionally : .fill
|
return .fill //orientation == .horizontal ? .fillProportionally : .fill
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,15 +150,15 @@ open class Tabs: View {
|
|||||||
public override init(frame: CGRect) {
|
public override init(frame: CGRect) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
public convenience required init() {
|
public convenience required init() {
|
||||||
self.init(frame: .zero)
|
self.init(frame: .zero)
|
||||||
}
|
}
|
||||||
|
|
||||||
public required init?(coder: NSCoder) {
|
public required init?(coder: NSCoder) {
|
||||||
super.init(coder: coder)
|
super.init(coder: coder)
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Overrides
|
// MARK: - Overrides
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -169,7 +169,7 @@ open class Tabs: View {
|
|||||||
scrollView.showsHorizontalScrollIndicator = false
|
scrollView.showsHorizontalScrollIndicator = false
|
||||||
scrollView.showsVerticalScrollIndicator = false
|
scrollView.showsVerticalScrollIndicator = false
|
||||||
addSubview(scrollView)
|
addSubview(scrollView)
|
||||||
|
|
||||||
contentView = View()
|
contentView = View()
|
||||||
contentView.translatesAutoresizingMaskIntoConstraints = false
|
contentView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
scrollView.addSubview(contentView)
|
scrollView.addSubview(contentView)
|
||||||
@ -180,10 +180,11 @@ open class Tabs: View {
|
|||||||
tabStackView.translatesAutoresizingMaskIntoConstraints = false
|
tabStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
contentView.addSubview(borderlineView)
|
contentView.addSubview(borderlineView)
|
||||||
contentView.addSubview(tabStackView)
|
contentView.addSubview(tabStackView)
|
||||||
|
|
||||||
scrollView.pinToSuperView()
|
scrollView.pinToSuperView()
|
||||||
contentView.pinToSuperView()
|
contentView.pinToSuperView()
|
||||||
tabStackView.pinToSuperView()
|
tabStackView.pinToSuperView()
|
||||||
|
|
||||||
contentView.heightAnchor.constraint(equalTo: scrollView.heightAnchor).isActive = true
|
contentView.heightAnchor.constraint(equalTo: scrollView.heightAnchor).isActive = true
|
||||||
|
|
||||||
borderlineViewWidthConstraint = borderlineView.widthAnchor.constraint(equalToConstant: 0)
|
borderlineViewWidthConstraint = borderlineView.widthAnchor.constraint(equalToConstant: 0)
|
||||||
@ -193,21 +194,32 @@ open class Tabs: View {
|
|||||||
borderlineViewTrailingConstraint = borderlineView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
|
borderlineViewTrailingConstraint = borderlineView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
|
||||||
borderlineViewTopConstraint = borderlineView.topAnchor.constraint(equalTo: contentView.topAnchor)
|
borderlineViewTopConstraint = borderlineView.topAnchor.constraint(equalTo: contentView.topAnchor)
|
||||||
borderlineViewBottomConstraint = borderlineView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
|
borderlineViewBottomConstraint = borderlineView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Function used to make changes to the View based off a change events or from local properties.
|
||||||
|
open override func updateView() {
|
||||||
|
super.updateView()
|
||||||
|
|
||||||
|
updateStackView()
|
||||||
|
updateTabs()
|
||||||
|
updateContentView()
|
||||||
|
updateBorderline()
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Private Methods
|
||||||
|
//--------------------------------------------------
|
||||||
|
/// Removes all of the Tab Views and creates new ones from the Tab Models property.
|
||||||
private func updateTabItems() {
|
private func updateTabItems() {
|
||||||
updateTabItems(with: tabModels)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func updateTabItems(with models: [TabModel]) {
|
|
||||||
// Clear existing tab items
|
// Clear existing tab items
|
||||||
for tabItem in tabViews {
|
for tabItem in tabViews {
|
||||||
tabItem.removeFromSuperview()
|
tabItem.removeFromSuperview()
|
||||||
}
|
}
|
||||||
|
|
||||||
tabViews.removeAll()
|
tabViews.removeAll()
|
||||||
// Create new tab items from the models
|
// Create new tab items from the models
|
||||||
for model in models {
|
for model in tabModels {
|
||||||
let tabItem = Tab()
|
let tabItem = Tab()
|
||||||
tabItem.size = size
|
tabItem.size = size
|
||||||
tabItem.text = model.text
|
tabItem.text = model.text
|
||||||
@ -224,25 +236,28 @@ open class Tabs: View {
|
|||||||
setNeedsUpdate()
|
setNeedsUpdate()
|
||||||
scrollToSelectedIndex(animated: false)
|
scrollToSelectedIndex(animated: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Scrolls to the selected Tab by the selectedIndex.
|
||||||
|
/// - Parameter animated: If there is animation of the scrolling to the selectedIndex.
|
||||||
private func scrollToSelectedIndex(animated: Bool) {
|
private func scrollToSelectedIndex(animated: Bool) {
|
||||||
if orientation == .horizontal && self.overflow == .scroll, selectedIndex < tabViews.count {
|
if orientation == .horizontal && self.overflow == .scroll, selectedIndex < tabViews.count {
|
||||||
let selectedTab = tabViews[selectedIndex]
|
let selectedTab = tabViews[selectedIndex]
|
||||||
scrollView.scrollRectToVisible(selectedTab.frame, animated: animated)
|
scrollView.scrollRectToVisible(selectedTab.frame, animated: animated)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Function used to make changes to the View based off a change events or from local properties.
|
/// Updates the StackView from local properties.
|
||||||
open override func updateView() {
|
private func updateStackView() {
|
||||||
super.updateView()
|
|
||||||
|
|
||||||
// Update the stackview properties
|
|
||||||
tabStackView.distribution = stackViewDistribution
|
tabStackView.distribution = stackViewDistribution
|
||||||
tabStackView.axis = stackViewAxis
|
tabStackView.axis = stackViewAxis
|
||||||
tabStackView.alignment = stackViewAlignment
|
tabStackView.alignment = stackViewAlignment
|
||||||
tabStackView.spacing = stackViewSpacing
|
tabStackView.spacing = stackViewSpacing
|
||||||
|
}
|
||||||
// Update tab appearance based on properties
|
|
||||||
|
/// Updates the Tab individual views from local properties.
|
||||||
|
private func updateTabs() {
|
||||||
for (index, tabItem) in tabViews.enumerated() {
|
for (index, tabItem) in tabViews.enumerated() {
|
||||||
tabItem.size = size
|
tabItem.size = size
|
||||||
tabItem.isSelected = selectedIndex == index
|
tabItem.isSelected = selectedIndex == index
|
||||||
@ -254,14 +269,9 @@ open class Tabs: View {
|
|||||||
tabItem.indicatorPosition = indicatorPosition
|
tabItem.indicatorPosition = indicatorPosition
|
||||||
tabItem.accessibilityValue = "\(index+1) of \(tabViews.count) Tabs"
|
tabItem.accessibilityValue = "\(index+1) of \(tabViews.count) Tabs"
|
||||||
}
|
}
|
||||||
|
|
||||||
//update the width based on rules
|
|
||||||
updateContentView()
|
|
||||||
|
|
||||||
setNeedsLayout()
|
|
||||||
layoutIfNeeded()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the ContentView and ScrollView ContentSize from local properties.
|
||||||
private func updateContentView() {
|
private func updateContentView() {
|
||||||
// Deactivate old constraint
|
// Deactivate old constraint
|
||||||
contentViewWidthConstraint?.isActive = false
|
contentViewWidthConstraint?.isActive = false
|
||||||
@ -269,10 +279,10 @@ open class Tabs: View {
|
|||||||
// Apply overflow
|
// Apply overflow
|
||||||
if orientation == .horizontal && overflow == .scroll && !fillContainer {
|
if orientation == .horizontal && overflow == .scroll && !fillContainer {
|
||||||
let contentWidth = tabStackView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).width
|
let contentWidth = tabStackView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).width
|
||||||
contentViewWidthConstraint = contentView.widthAnchor.constraint(equalToConstant: contentWidth)
|
contentViewWidthConstraint = nil
|
||||||
scrollView.contentSize = CGSize(width: contentWidth, height: scrollView.bounds.height)
|
scrollView.contentSize = CGSize(width: contentWidth, height: scrollView.bounds.height)
|
||||||
} else {
|
} else {
|
||||||
contentViewWidthConstraint = contentView.widthAnchor.constraint(equalTo: widthAnchor)
|
contentViewWidthConstraint = contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor)
|
||||||
scrollView.contentSize = bounds.size
|
scrollView.contentSize = bounds.size
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,9 +294,8 @@ open class Tabs: View {
|
|||||||
scrollToSelectedIndex(animated: true)
|
scrollToSelectedIndex(animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func layoutSubviews() {
|
//update layout for borderline
|
||||||
super.layoutSubviews()
|
private func updateBorderline() {
|
||||||
|
|
||||||
//borderLine
|
//borderLine
|
||||||
if borderLine {
|
if borderLine {
|
||||||
var edge: UIRectEdge = .bottom
|
var edge: UIRectEdge = .bottom
|
||||||
@ -302,21 +311,21 @@ open class Tabs: View {
|
|||||||
borderlineViewBottomConstraint?.isActive = false
|
borderlineViewBottomConstraint?.isActive = false
|
||||||
borderlineViewHeightConstraint?.isActive = false
|
borderlineViewHeightConstraint?.isActive = false
|
||||||
borderlineViewWidthConstraint?.isActive = false
|
borderlineViewWidthConstraint?.isActive = false
|
||||||
|
|
||||||
if edge == .left {
|
if edge == .left {
|
||||||
borderlineViewWidthConstraint?.constant = borderlineSize
|
borderlineViewWidthConstraint?.constant = borderlineSize
|
||||||
borderlineViewWidthConstraint?.isActive = true
|
borderlineViewWidthConstraint?.isActive = true
|
||||||
borderlineViewTopConstraint?.isActive = true
|
borderlineViewTopConstraint?.isActive = true
|
||||||
borderlineViewLeadingConstraint?.isActive = true
|
borderlineViewLeadingConstraint?.isActive = true
|
||||||
borderlineViewBottomConstraint?.isActive = true
|
borderlineViewBottomConstraint?.isActive = true
|
||||||
|
|
||||||
} else if edge == .top {
|
} else if edge == .top {
|
||||||
borderlineViewHeightConstraint?.constant = borderlineSize
|
borderlineViewHeightConstraint?.constant = borderlineSize
|
||||||
borderlineViewHeightConstraint?.isActive = true
|
borderlineViewHeightConstraint?.isActive = true
|
||||||
borderlineViewTopConstraint?.isActive = true
|
borderlineViewTopConstraint?.isActive = true
|
||||||
borderlineViewLeadingConstraint?.isActive = true
|
borderlineViewLeadingConstraint?.isActive = true
|
||||||
borderlineViewTrailingConstraint?.isActive = true
|
borderlineViewTrailingConstraint?.isActive = true
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
borderlineViewHeightConstraint?.constant = borderlineSize
|
borderlineViewHeightConstraint?.constant = borderlineSize
|
||||||
borderlineViewHeightConstraint?.isActive = true
|
borderlineViewHeightConstraint?.isActive = true
|
||||||
@ -330,4 +339,6 @@ open class Tabs: View {
|
|||||||
borderlineView.isHidden = true
|
borderlineView.isHidden = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,6 +50,10 @@ open class ToggleView: Control, Changeable {
|
|||||||
$0.isUserInteractionEnabled = false
|
$0.isUserInteractionEnabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private let shadowLayer1 = CALayer()
|
||||||
|
private let shadowLayer2 = CALayer()
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Public Properties
|
// MARK: - Public Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -136,6 +140,25 @@ open class ToggleView: Control, Changeable {
|
|||||||
toggleView.setContentHuggingPriority(.required, for: .vertical)
|
toggleView.setContentHuggingPriority(.required, for: .vertical)
|
||||||
setContentHuggingPriority(.required, for: .horizontal)
|
setContentHuggingPriority(.required, for: .horizontal)
|
||||||
setContentHuggingPriority(.required, for: .vertical)
|
setContentHuggingPriority(.required, for: .vertical)
|
||||||
|
|
||||||
|
//knobview dropshadow
|
||||||
|
// Update shadow layers frames to match the view's bounds
|
||||||
|
knobView.layer.insertSublayer(shadowLayer1, at: 0)
|
||||||
|
knobView.layer.insertSublayer(shadowLayer2, at: 0)
|
||||||
|
|
||||||
|
let shadowColor = VDSColor.paletteBlack.cgColor
|
||||||
|
shadowLayer1.cornerRadius = knobView.layer.cornerRadius
|
||||||
|
shadowLayer1.shadowColor = shadowColor
|
||||||
|
shadowLayer1.shadowOpacity = 0.24
|
||||||
|
shadowLayer1.shadowOffset = .init(width: 0, height: 1)
|
||||||
|
shadowLayer1.shadowRadius = 5.0
|
||||||
|
|
||||||
|
shadowLayer2.cornerRadius = knobView.layer.cornerRadius
|
||||||
|
shadowLayer2.shadowColor = shadowColor
|
||||||
|
shadowLayer2.shadowOpacity = 0.08
|
||||||
|
shadowLayer2.shadowOffset = .init(width: 0, height: 2)
|
||||||
|
shadowLayer2.shadowRadius = 2.0
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resets to default settings.
|
/// Resets to default settings.
|
||||||
@ -180,8 +203,8 @@ open class ToggleView: Control, Changeable {
|
|||||||
// MARK: - Toggle
|
// MARK: - Toggle
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
private func constrainKnob(){
|
private func constrainKnob(){
|
||||||
self.knobLeadingConstraint?.isActive = false
|
knobLeadingConstraint?.isActive = false
|
||||||
self.knobTrailingConstraint?.isActive = false
|
knobTrailingConstraint?.isActive = false
|
||||||
if isOn {
|
if isOn {
|
||||||
knobTrailingConstraint = toggleView.trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 2)
|
knobTrailingConstraint = toggleView.trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 2)
|
||||||
knobLeadingConstraint = knobView.leadingAnchor.constraint(greaterThanOrEqualTo: toggleView.leadingAnchor)
|
knobLeadingConstraint = knobView.leadingAnchor.constraint(greaterThanOrEqualTo: toggleView.leadingAnchor)
|
||||||
@ -191,13 +214,17 @@ open class ToggleView: Control, Changeable {
|
|||||||
}
|
}
|
||||||
knobTrailingConstraint?.isActive = true
|
knobTrailingConstraint?.isActive = true
|
||||||
knobLeadingConstraint?.isActive = true
|
knobLeadingConstraint?.isActive = true
|
||||||
self.layoutIfNeeded()
|
setNeedsLayout()
|
||||||
|
layoutIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateToggle() {
|
private func updateToggle() {
|
||||||
let toggleColor = toggleColorConfiguration.getColor(self)
|
let toggleColor = toggleColorConfiguration.getColor(self)
|
||||||
let knobColor = knobColorConfiguration.getColor(self)
|
let knobColor = knobColorConfiguration.getColor(self)
|
||||||
|
|
||||||
|
shadowLayer1.backgroundColor = knobColor.cgColor
|
||||||
|
shadowLayer2.backgroundColor = knobColor.cgColor
|
||||||
|
|
||||||
if disabled || !isAnimated {
|
if disabled || !isAnimated {
|
||||||
toggleView.backgroundColor = toggleColor
|
toggleView.backgroundColor = toggleColor
|
||||||
knobView.backgroundColor = knobColor
|
knobView.backgroundColor = knobColor
|
||||||
@ -213,6 +240,14 @@ open class ToggleView: Control, Changeable {
|
|||||||
}, completion: nil)
|
}, completion: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open override func layoutSubviews() {
|
||||||
|
super.layoutSubviews()
|
||||||
|
|
||||||
|
shadowLayer1.frame = knobView.bounds
|
||||||
|
shadowLayer2.frame = knobView.bounds
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: AppleGuidlinesTouchable
|
// MARK: AppleGuidlinesTouchable
|
||||||
|
|||||||
@ -1,3 +1,12 @@
|
|||||||
|
1.0.39
|
||||||
|
=======
|
||||||
|
- CXTDT-423141 - Tabs - Selected Tab dark mode text color
|
||||||
|
- CXTDT-426623 - Toggle - Drop Shadow on Knob
|
||||||
|
|
||||||
|
1.0.38
|
||||||
|
=======
|
||||||
|
- Fixed bug in Typography TitleLarge Font update for Mobile
|
||||||
|
|
||||||
1.0.37
|
1.0.37
|
||||||
=======
|
=======
|
||||||
- ONEAPP-4684 - Update Accessibility for Tooltip
|
- ONEAPP-4684 - Update Accessibility for Tooltip
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user