Compare commits

...

1 Commits

Author SHA1 Message Date
a7d99fd523 Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2025-02-06 21:31:09 -06:00
7 changed files with 105 additions and 23 deletions

View File

@ -35,6 +35,7 @@ open class Control: UIControl, ViewProtocol, UserInfoable, Clickable {
// MARK: - Combine Properties // MARK: - Combine Properties
//-------------------------------------------------- //--------------------------------------------------
open var subscribers = Set<AnyCancellable>() open var subscribers = Set<AnyCancellable>()
open var subject = PassthroughSubject<Void, Never>()
open var onClickSubscriber: AnyCancellable? open var onClickSubscriber: AnyCancellable?
@ -78,10 +79,19 @@ open class Control: UIControl, ViewProtocol, UserInfoable, Clickable {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Lifecycle // MARK: - Lifecycle
//-------------------------------------------------- //--------------------------------------------------
/// When the view moves to a window, force any pending update immediately.
open override func didMoveToWindow() {
super.didMoveToWindow()
if window != nil {
updateView()
}
}
private func initialSetup() { private func initialSetup() {
if !initialSetupPerformed { if !initialSetupPerformed {
initialSetupPerformed = true initialSetupPerformed = true
shouldUpdateView = false shouldUpdateView = false
setupDidChangeEvent(true)
setup() setup()
setDefaults() setDefaults()
shouldUpdateView = true shouldUpdateView = true

View File

@ -36,6 +36,7 @@ open class View: UIView, ViewProtocol, UserInfoable, Clickable {
// MARK: - Combine Properties // MARK: - Combine Properties
//-------------------------------------------------- //--------------------------------------------------
open var subscribers = Set<AnyCancellable>() open var subscribers = Set<AnyCancellable>()
open var subject = PassthroughSubject<Void, Never>()
open var onClickSubscriber: AnyCancellable? open var onClickSubscriber: AnyCancellable?
//-------------------------------------------------- //--------------------------------------------------
@ -58,10 +59,19 @@ open class View: UIView, ViewProtocol, UserInfoable, Clickable {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Lifecycle // MARK: - Lifecycle
//-------------------------------------------------- //--------------------------------------------------
/// When the view moves to a window, force any pending update immediately.
open override func didMoveToWindow() {
super.didMoveToWindow()
if window != nil {
updateView()
}
}
private func initialSetup() { private func initialSetup() {
if !initialSetupPerformed { if !initialSetupPerformed {
initialSetupPerformed = true initialSetupPerformed = true
shouldUpdateView = false shouldUpdateView = false
setupDidChangeEvent(true)
setup() setup()
setDefaults() setDefaults()
shouldUpdateView = true shouldUpdateView = true

View File

@ -38,6 +38,7 @@ open class ButtonBase: UIButton, ViewProtocol, UserInfoable, Clickable {
//-------------------------------------------------- //--------------------------------------------------
/// Set of Subscribers for any Publishers for this Control. /// Set of Subscribers for any Publishers for this Control.
open var subscribers = Set<AnyCancellable>() open var subscribers = Set<AnyCancellable>()
open var subject = PassthroughSubject<Void, Never>()
open var onClickSubscriber: AnyCancellable? open var onClickSubscriber: AnyCancellable?
@ -97,10 +98,19 @@ open class ButtonBase: UIButton, ViewProtocol, UserInfoable, Clickable {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Lifecycle // MARK: - Lifecycle
//-------------------------------------------------- //--------------------------------------------------
/// When the view moves to a window, force any pending update immediately.
open override func didMoveToWindow() {
super.didMoveToWindow()
if window != nil {
updateView()
}
}
private func initialSetup() { private func initialSetup() {
if !initialSetupPerformed { if !initialSetupPerformed {
initialSetupPerformed = true initialSetupPerformed = true
shouldUpdateView = false shouldUpdateView = false
setupDidChangeEvent(true)
setup() setup()
setDefaults() setDefaults()
shouldUpdateView = true shouldUpdateView = true

View File

@ -39,6 +39,7 @@ open class Label: UILabel, ViewProtocol, UserInfoable {
//-------------------------------------------------- //--------------------------------------------------
/// Set of Subscribers for any Publishers for this Control. /// Set of Subscribers for any Publishers for this Control.
open var subscribers = Set<AnyCancellable>() open var subscribers = Set<AnyCancellable>()
open var subject = PassthroughSubject<Void, Never>()
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Private Properties // MARK: - Private Properties
@ -192,10 +193,19 @@ open class Label: UILabel, ViewProtocol, UserInfoable {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Lifecycle // MARK: - Lifecycle
//-------------------------------------------------- //--------------------------------------------------
/// When the view moves to a window, force any pending update immediately.
open override func didMoveToWindow() {
super.didMoveToWindow()
if window != nil {
updateView()
}
}
private func initialSetup() { private func initialSetup() {
if !initialSetupPerformed { if !initialSetupPerformed {
initialSetupPerformed = true initialSetupPerformed = true
shouldUpdateView = false shouldUpdateView = false
setupDidChangeEvent(true)
setup() setup()
setDefaults() setDefaults()
shouldUpdateView = true shouldUpdateView = true

View File

@ -37,6 +37,7 @@ open class TextField: UITextField, ViewProtocol, Errorable {
//-------------------------------------------------- //--------------------------------------------------
/// Set of Subscribers for any Publishers for this Control. /// Set of Subscribers for any Publishers for this Control.
open var subscribers = Set<AnyCancellable>() open var subscribers = Set<AnyCancellable>()
open var subject = PassthroughSubject<Void, Never>()
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Private Properties // MARK: - Private Properties
@ -98,10 +99,19 @@ open class TextField: UITextField, ViewProtocol, Errorable {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Lifecycle // MARK: - Lifecycle
//-------------------------------------------------- //--------------------------------------------------
/// When the view moves to a window, force any pending update immediately.
open override func didMoveToWindow() {
super.didMoveToWindow()
if window != nil {
updateView()
}
}
private func initialSetup() { private func initialSetup() {
if !initialSetupPerformed { if !initialSetupPerformed {
initialSetupPerformed = true initialSetupPerformed = true
shouldUpdateView = false shouldUpdateView = false
setupDidChangeEvent(true)
setup() setup()
setDefaults() setDefaults()
shouldUpdateView = true shouldUpdateView = true

View File

@ -37,6 +37,7 @@ open class TextView: UITextView, ViewProtocol, Errorable {
//-------------------------------------------------- //--------------------------------------------------
/// Set of Subscribers for any Publishers for this Control. /// Set of Subscribers for any Publishers for this Control.
open var subscribers = Set<AnyCancellable>() open var subscribers = Set<AnyCancellable>()
open var subject = PassthroughSubject<Void, Never>()
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Private Properties // MARK: - Private Properties
@ -107,10 +108,19 @@ open class TextView: UITextView, ViewProtocol, Errorable {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Lifecycle // MARK: - Lifecycle
//-------------------------------------------------- //--------------------------------------------------
/// When the view moves to a window, force any pending update immediately.
open override func didMoveToWindow() {
super.didMoveToWindow()
if window != nil {
updateView()
}
}
private func initialSetup() { private func initialSetup() {
if !initialSetupPerformed { if !initialSetupPerformed {
initialSetupPerformed = true initialSetupPerformed = true
shouldUpdateView = false shouldUpdateView = false
setupDidChangeEvent(true)
setup() setup()
setDefaults() setDefaults()
shouldUpdateView = true shouldUpdateView = true

View File

@ -10,6 +10,8 @@ import UIKit
import Combine import Combine
public protocol ViewProtocol: AnyObject, Initable, Resettable, Enabling, Surfaceable, AccessibilityUpdatable { public protocol ViewProtocol: AnyObject, Initable, Resettable, Enabling, Surfaceable, AccessibilityUpdatable {
var subject: PassthroughSubject<Void, Never> { get set }
/// Set of Subscribers for any Publishers for this Control. /// Set of Subscribers for any Publishers for this Control.
var subscribers: Set<AnyCancellable> { get set } var subscribers: Set<AnyCancellable> { get set }
@ -36,28 +38,48 @@ extension ViewProtocol {
/// Called when there are changes in a View based off a change events or from local properties. /// Called when there are changes in a View based off a change events or from local properties.
public func setNeedsUpdate() { public func setNeedsUpdate() {
if shouldUpdateView { // if shouldUpdateView {
shouldUpdateView = false // shouldUpdateView = false
//
// //see if this is a view that has children
// let parent = self as? any ParentViewProtocol
// let children = parent?.getAllChildren()
// //if so turn off the shouldUpdate to keep UI
// //from blocking
// children?.forEach{ $0.shouldUpdateView = false }
//
// updateView()
// updateAccessibility()
//
// //if so turn on
// children?.forEach{
// $0.updateView()
// $0.updateAccessibility()
// $0.shouldUpdateView = true
// }
// shouldUpdateView = true
// }
subject.send()
}
//see if this is a view that has children public func setupDidChangeEvent(_ debounce: Bool = false) {
let parent = self as? any ParentViewProtocol handlerPublisher(debounce)
let children = parent?.getAllChildren() .sink { [weak self] _ in
//if so turn off the shouldUpdate to keep UI self?.updateView()
//from blocking }.store(in: &subscribers)
children?.forEach{ $0.shouldUpdateView = false } }
updateView() public func handlerPublisher(_ debounce: Bool = false) -> AnyPublisher<Void, Never> {
updateAccessibility() if debounce {
return subject
//if so turn on .debounce(for: .seconds(0.05), scheduler: RunLoop.main)
children?.forEach{ .eraseToAnyPublisher()
$0.updateView() } else {
$0.updateAccessibility() return subject
$0.shouldUpdateView = true .eraseToAnyPublisher()
}
shouldUpdateView = true
} }
} }
} }
extension ViewProtocol where Self: UIView { extension ViewProtocol where Self: UIView {