Compare commits

...

14 Commits

Author SHA1 Message Date
Matt Bruce
c0090deac9 Merge branch 'develop' into feature/subject 2023-07-27 11:05:11 -05:00
Matt Bruce
4fd167cfa3 added paused update
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-07-19 16:03:06 -05:00
Matt Bruce
df1e8ee2df fixed issue with updateStrategy
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-07-19 15:38:35 -05:00
Matt Bruce
ce54965edc added wait
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-07-19 15:22:12 -05:00
Matt Bruce
0be0d71f7b removed un-needed
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-07-19 15:22:06 -05:00
Matt Bruce
c2998ee0bf reverted back to develop tab
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-07-19 15:21:56 -05:00
Matt Bruce
ac1e6f692d Merge branch 'develop' of https://gitlab.verizon.com/BPHV_MIPS/vds_ios.git into feature/subject
# Conflicts:
#	VDS/Classes/Control.swift
#	VDS/Components/Toggle/Toggle.swift

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-07-19 14:32:05 -05:00
Matt Bruce
c7e47707c2 updated to make the label and such always update
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-07-14 14:21:46 -05:00
Matt Bruce
3e8c6a12e4 removed intermediate
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-07-14 14:18:00 -05:00
Matt Bruce
d159075f83 added new updateStrategy
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-07-14 11:53:57 -05:00
Matt Bruce
a8e1cf9b48 updated tab
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-07-14 11:53:07 -05:00
Matt Bruce
76c3205921 refmoved shouldUpdateView bools
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-07-14 09:10:22 -05:00
Matt Bruce
abc7f409e7 updated to have 2 subjects for the strategies
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-07-14 09:10:05 -05:00
Matt Bruce
1934da2543 added back subject into the flow
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-07-14 08:17:38 -05:00
23 changed files with 102 additions and 75 deletions

View File

@ -16,6 +16,8 @@ open class Control: UIControl, Handlerable, ViewProtocol, Resettable, UserInfoab
//--------------------------------------------------
// MARK: - Combine Properties
//--------------------------------------------------
public var subject = PassthroughSubject<Void, Never>()
public var updateStrategy: HandlerableUpdateStrategy = .immediate
/// Set of Subscribers for any Publishers for this Control
public var subscribers = Set<AnyCancellable>()
@ -34,9 +36,6 @@ open class Control: UIControl, Handlerable, ViewProtocol, Resettable, UserInfoab
//--------------------------------------------------
private var initialSetupPerformed = false
/// Key of whether or not updateView() is called in setNeedsUpdate()
open var shouldUpdateView: Bool = true
/// Dictionary for keeping information for this Control use only Primitives
open var userInfo = [String: Primitive]()
@ -109,7 +108,8 @@ open class Control: UIControl, Handlerable, ViewProtocol, Resettable, UserInfoab
if !initialSetupPerformed {
initialSetupPerformed = true
setup()
setNeedsUpdate()
setupNeedsUpdateEvent()
updateView()
}
}
@ -125,6 +125,14 @@ open class Control: UIControl, Handlerable, ViewProtocol, Resettable, UserInfoab
//--------------------------------------------------
// MARK: - Overrides
//--------------------------------------------------
open override func didMoveToWindow() {
super.didMoveToWindow()
// Keep the strategy if it's 'alwaysImmediate'
guard updateStrategy != .alwaysImmediate else { return }
// Update the strategy based on whether the view is in a window
updateStrategy = window != nil ? .delayed : .immediate
}
/// Update this view based off of property changes
open func updateView() {

View File

@ -229,7 +229,6 @@ open class SelectorItemBase<Selector: SelectorControlable>: Control, Errorable,
/// Resets back to this objects default settings.
open override func reset() {
super.reset()
shouldUpdateView = false
label.reset()
childLabel.reset()
errorLabel.reset()
@ -250,7 +249,6 @@ open class SelectorItemBase<Selector: SelectorControlable>: Control, Errorable,
value = nil
isSelected = false
shouldUpdateView = true
setNeedsUpdate()
}

View File

@ -17,6 +17,9 @@ open class View: UIView, Handlerable, ViewProtocol, Resettable, UserInfoable {
//--------------------------------------------------
// MARK: - Combine Properties
//--------------------------------------------------
public var subject = PassthroughSubject<Void, Never>()
public var updateStrategy: HandlerableUpdateStrategy = .immediate
public var subscribers = Set<AnyCancellable>()
//--------------------------------------------------
@ -24,9 +27,6 @@ open class View: UIView, Handlerable, ViewProtocol, Resettable, UserInfoable {
//--------------------------------------------------
private var initialSetupPerformed = false
/// Key of whether or not updateView() is called in setNeedsUpdate()
open var shouldUpdateView: Bool = true
/// Dictionary for keeping information for this Control use only Primitives
open var userInfo = [String: Primitive]()
@ -72,13 +72,22 @@ open class View: UIView, Handlerable, ViewProtocol, Resettable, UserInfoable {
if !initialSetupPerformed {
initialSetupPerformed = true
setup()
setNeedsUpdate()
setupNeedsUpdateEvent()
updateView()
}
}
//--------------------------------------------------
// MARK: - Overrides
//--------------------------------------------------
open override func didMoveToWindow() {
super.didMoveToWindow()
// Keep the strategy if it's 'alwaysImmediate'
guard updateStrategy != .alwaysImmediate else { return }
// Update the strategy based on whether the view is in a window
updateStrategy = window != nil ? .delayed : .immediate
}
/// Update this view based off of property changes
open func updateView() {

View File

@ -78,7 +78,6 @@ open class Badge: View {
/// Resets back to this objects default settings.
open override func reset() {
super.reset()
shouldUpdateView = false
label.reset()
label.lineBreakMode = .byTruncatingTail
label.textPosition = .left
@ -87,7 +86,6 @@ open class Badge: View {
text = ""
maxWidth = nil
numberOfLines = 1
shouldUpdateView = true
setNeedsUpdate()
}

View File

@ -281,13 +281,11 @@ open class BadgeIndicator: View {
/// Resets back to this objects default settings.
open override func reset() {
super.reset()
shouldUpdateView = false
label.reset()
label.lineBreakMode = .byTruncatingTail
label.textPosition = .center
fillColor = .red
number = nil
shouldUpdateView = true
setNeedsUpdate()
}

View File

@ -133,11 +133,9 @@ open class Button: ButtonBase, Useable {
/// Resets back to this objects default settings.
open override func reset() {
super.reset()
shouldUpdateView = false
use = .primary
width = nil
size = .large
shouldUpdateView = true
setNeedsUpdate()
}

View File

@ -28,6 +28,8 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab
//--------------------------------------------------
// MARK: - Combine Properties
//--------------------------------------------------
public var subject = PassthroughSubject<Void, Never>()
public var updateStrategy: HandlerableUpdateStrategy = .immediate
public var subscribers = Set<AnyCancellable>()
public var onClickSubscriber: AnyCancellable? {
willSet {
@ -45,8 +47,6 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
open var shouldUpdateView: Bool = true
open var availableSizes: [ButtonSize] { [] }
open var text: String? { didSet { setNeedsUpdate() } }
@ -123,7 +123,8 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab
translatesAutoresizingMaskIntoConstraints = false
accessibilityCustomActions = []
setup()
setNeedsUpdate()
setupNeedsUpdateEvent()
updateView()
}
}
@ -137,18 +138,25 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab
/// Resets back to this objects default settings.
open func reset() {
shouldUpdateView = false
surface = .light
disabled = false
text = nil
accessibilityCustomActions = []
shouldUpdateView = true
setNeedsUpdate()
}
//--------------------------------------------------
// MARK: - Overrides
//--------------------------------------------------
open override func didMoveToWindow() {
super.didMoveToWindow()
// Keep the strategy if it's 'alwaysImmediate'
guard updateStrategy != .alwaysImmediate else { return }
// Update the strategy based on whether the view is in a window
updateStrategy = window != nil ? .delayed : .immediate
}
override open var intrinsicContentSize: CGSize {
let intrinsicContentSize = super.intrinsicContentSize
let adjustedWidth = intrinsicContentSize.width + titleEdgeInsets.left + titleEdgeInsets.right

View File

@ -90,13 +90,11 @@ open class TextLink: ButtonBase {
/// Resets back to this objects default settings.
open override func reset() {
super.reset()
shouldUpdateView = false
text = nil
size = .large
accessibilityCustomActions = []
isAccessibilityElement = true
accessibilityTraits = .link
shouldUpdateView = true
setNeedsUpdate()
}

View File

@ -256,7 +256,6 @@ open class ButtonIcon: Control {
/// Resets back to this objects default settings.
open override func reset() {
super.reset()
shouldUpdateView = false
kind = .ghost
surfaceType = .colorFill
size = .large
@ -264,7 +263,6 @@ open class ButtonIcon: Control {
hideBorder = true
iconOffset = .init(x: 0, y: 0)
iconName = nil
shouldUpdateView = true
setNeedsUpdate()
}

View File

@ -16,15 +16,15 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable {
//--------------------------------------------------
// MARK: - Combine Properties
//--------------------------------------------------
public var subject = PassthroughSubject<Void, Never>()
public var subscribers = Set<AnyCancellable>()
public var updateStrategy: HandlerableUpdateStrategy = .immediate
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
private var initialSetupPerformed = false
open var shouldUpdateView: Bool = true
open var useAttributedText: Bool = false
open var useScaledFont: Bool = false { didSet { setNeedsUpdate() }}
@ -105,7 +105,8 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable {
accessibilityCustomActions = []
accessibilityTraits = .staticText
setup()
setNeedsUpdate()
setupNeedsUpdateEvent()
updateView()
}
}
@ -113,7 +114,6 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable {
/// Resets back to this objects default settings.
open func reset() {
shouldUpdateView = false
surface = .light
disabled = false
attributes = nil
@ -123,7 +123,6 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable {
attributedText = nil
numberOfLines = 0
backgroundColor = .clear
shouldUpdateView = true
setNeedsUpdate()
}
@ -137,6 +136,15 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable {
//--------------------------------------------------
// MARK: - Overrides
//--------------------------------------------------
open override func didMoveToWindow() {
super.didMoveToWindow()
// Keep the strategy if it's 'alwaysImmediate'
guard updateStrategy != .alwaysImmediate else { return }
// Update the strategy based on whether the view is in a window
updateStrategy = window != nil ? .delayed : .immediate
}
open func updateView() {
if !useAttributedText {
if let text = text {

View File

@ -232,8 +232,6 @@ open class Notification: View {
open override func reset() {
super.reset()
shouldUpdateView = false
titleLabel.reset()
titleLabel.text = ""
titleLabel.textStyle = UIDevice.isIPad ? .boldBodyLarge : .boldBodySmall
@ -259,7 +257,6 @@ open class Notification: View {
hideCloseButton = false
fullBleed = false
shouldUpdateView = true
setNeedsUpdate()
}

View File

@ -203,7 +203,6 @@ open class RadioBoxItem: Control, Changeable {
/// Resets back to this objects default settings.
open override func reset() {
super.reset()
shouldUpdateView = false
textLabel.reset()
subTextLabel.reset()
subTextRightLabel.reset()
@ -227,7 +226,6 @@ open class RadioBoxItem: Control, Changeable {
isSelected = false
shouldUpdateView = true
setNeedsUpdate()
}

View File

@ -92,7 +92,6 @@ open class RadioSwatch: Control {
/// Resets back to this objects default settings.
open override func reset() {
super.reset()
shouldUpdateView = false
fillImage = nil
text = ""
primaryColor = nil
@ -100,7 +99,6 @@ open class RadioSwatch: Control {
strikethrough = false
inputId = nil
value = nil
shouldUpdateView = true
setNeedsUpdate()
setNeedsDisplay()
}

View File

@ -123,6 +123,9 @@ extension Tabs {
//--------------------------------------------------
open override func setup() {
super.setup()
updateStrategy = .alwaysImmediate
label.updateStrategy = .alwaysImmediate
addSubview(label)
accessibilityTraits = .button
@ -138,18 +141,6 @@ extension Tabs {
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
NSLayoutConstraint.activate([layoutGuide.topAnchor.constraint(equalTo: topAnchor),
layoutGuide.bottomAnchor.constraint(equalTo: bottomAnchor),
layoutGuide.leadingAnchor.constraint(equalTo: leadingAnchor),
layoutGuide.trailingAnchor.constraint(equalTo: trailingAnchor)])
publisher(for: UITapGestureRecognizer())
.sink { [weak self] _ in
guard let self else { return }

View File

@ -164,6 +164,7 @@ open class Tabs: View {
//--------------------------------------------------
open override func setup() {
super.setup()
updateStrategy = .alwaysImmediate
scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.showsHorizontalScrollIndicator = false

View File

@ -192,7 +192,6 @@ open class TileContainer: Control {
/// Resets back to this objects default settings.
open override func reset() {
super.reset()
shouldUpdateView = false
color = .white
padding = .padding4X
aspectRatio = .ratio1x1
@ -201,7 +200,6 @@ open class TileContainer: Control {
height = nil
showBorder = false
showDropShadows = false
shouldUpdateView = true
setNeedsUpdate()
}

View File

@ -242,7 +242,6 @@ open class Tilelet: TileContainer {
/// Resets back to this objects default settings.
open override func reset() {
shouldUpdateView = false
aspectRatio = .none
color = .black
//models
@ -251,7 +250,6 @@ open class Tilelet: TileContainer {
subTitleModel = nil
descriptiveIconModel = nil
directionalIconModel = nil
shouldUpdateView = true
setNeedsUpdate()
}

View File

@ -199,12 +199,10 @@ open class TitleLockup: View {
/// Resets back to this objects default settings.
open override func reset() {
super.reset()
shouldUpdateView = false
textPosition = .left
eyebrowModel = nil
titleModel = nil
subTitleModel = nil
shouldUpdateView = true
setNeedsUpdate()
}

View File

@ -175,7 +175,6 @@ open class Toggle: Control, Changeable {
/// Resets back to this objects default settings.
open override func reset() {
super.reset()
shouldUpdateView = false
label.reset()
isOn = false
isAnimated = true
@ -187,8 +186,6 @@ open class Toggle: Control, Changeable {
textPosition = .left
inputId = nil
value = nil
shouldUpdateView = true
setNeedsUpdate()
}
/// This will toggle the state of the Toggle

View File

@ -139,15 +139,12 @@ open class ToggleView: Control, Changeable {
/// Resets back to this objects default settings.
open override func reset() {
super.reset()
shouldUpdateView = false
isOn = false
isAnimated = true
inputId = nil
value = nil
toggleView.backgroundColor = toggleColorConfiguration.getColor(self)
knobView.backgroundColor = knobColorConfiguration.getColor(self)
shouldUpdateView = true
setNeedsUpdate()
}
/// This will toggle the state of the Toggle and execute the actionBlock if provided.

View File

@ -142,14 +142,12 @@ open class Tooltip: Control, TooltipLaunchable {
/// Resets back to this objects default settings.
open override func reset() {
super.reset()
shouldUpdateView = false
size = .medium
title = ""
content = ""
fillColor = .primary
closeButtonText = "Close"
imageView.image = nil
shouldUpdateView = true
setNeedsUpdate()
}

View File

@ -80,7 +80,6 @@ open class TrailingTooltipLabel: View, TooltipLaunchable {
/// Resets back to this objects default settings.
open override func reset() {
super.reset()
shouldUpdateView = false
labelText = nil
labelAttributes = nil
labelTextStyle = .defaultStyle
@ -88,7 +87,6 @@ open class TrailingTooltipLabel: View, TooltipLaunchable {
tooltipCloseButtonText = "Close"
tooltipTitle = ""
tooltipContent = ""
shouldUpdateView = true
setNeedsUpdate()
}
}

View File

@ -9,18 +9,43 @@ import Foundation
import Combine
import UIKit
public enum HandlerableUpdateStrategy {
case immediate
case delayed
case alwaysImmediate
case paused
}
public protocol Handlerable: AnyObject, Initable, Disabling, Surfaceable {
var subject: PassthroughSubject<Void, Never> { get set }
var subscribers: Set<AnyCancellable> { get set }
var shouldUpdateView: Bool { get set }
var updateStrategy: HandlerableUpdateStrategy { get set }
func updateView()
}
extension Handlerable {
public func setupNeedsUpdateEvent() {
subject
.debounce(for: .milliseconds(50), scheduler: RunLoop.main)
.sink { [weak self] _ in
self?.updateView()
}.store(in: &subscribers)
}
public func setNeedsUpdate() {
if shouldUpdateView {
shouldUpdateView = false
switch updateStrategy {
case .delayed:
subject.send()
case .immediate, .alwaysImmediate:
updateView()
shouldUpdateView = true
case .paused:
break
}
}
public func updateIfNeeded<T: Equatable>(_ oldValue: T, _ newValue: T) {
if oldValue != newValue {
setNeedsUpdate()
}
}
}
@ -33,3 +58,15 @@ extension Handlerable where Self: UIControl {
}).store(in: &subscribers)
}
}
extension Handlerable {
@discardableResult func pausedUpdate(_ closure: (_ instance: inout Self) -> Void) -> Self {
var copy = self
let oldStrategy = copy.updateStrategy
copy.updateStrategy = .paused
closure(&copy)
copy.updateStrategy = oldStrategy
copy.updateView()
return copy
}
}