vds_ios/VDS/Protocols/ViewProtocol.swift
Matt Bruce d013f07db3 first cut with just inline replace
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-06-20 10:11:41 -05:00

156 lines
5.2 KiB
Swift

//
// ViewProtocol.swift
// VDS
//
// Created by Matt Bruce on 7/22/22.
//
import Foundation
import UIKit
import Combine
public protocol ViewProtocol: AnyObject, Initable, Resettable, Enabling, Surfaceable {
/// Set of Subscribers for any Publishers for this Control.
var subscribers: Set<AnyCancellable> { get set }
/// Key of whether or not updateView() is called in setNeedsUpdate()
var shouldUpdateView: Bool { get set }
/// Key of whether or not updateAccessibility() is called in setNeedsUpdate()
var shouldUpdateAccessibility: Bool { get set }
/// Used for setting an implementation for the default Accessible Action
var accessibilityAction: ((Self) -> Void)? { get set }
/// Executed on initialization for this View.
func initialSetup()
/// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations.
func setup()
/// Used to make changes to the View based off a change events or from local properties.
func updateView()
/// Used to update any Accessibility properties.
func updateAccessibility()
}
extension ViewProtocol {
/// Called when there are changes in a View based off a change events or from local properties.
public func setNeedsUpdate() {
if shouldUpdateView {
shouldUpdateView = false
updateView()
if shouldUpdateAccessibility {
updateAccessibility()
}
shouldUpdateView = true
}
}
}
extension ViewProtocol where Self: UIView {
/// Helper method for removing a superview and updating Self.
public func removeFromSuperview(_ view: UIView){
if view.superview != nil {
view.removeFromSuperview()
setNeedsDisplay()
}
}
}
extension ViewProtocol where Self: UIControl {
/// Helper method to assign a completion block to a specific UIControl Event using Combine and stored in the subscribers.
public func addEvent(event: UIControl.Event, block: @escaping (Self)->()) {
publisher(for: event)
.sink(receiveValue: { c in
block(c)
}).store(in: &subscribers)
}
}
public protocol AccessibilityUpdatable {
// Basic accessibility
var bridge_isAccessibilityElementBlock: AXBoolReturnBlock? { get set }
var bridge_accessibilityLabelBlock: AXStringReturnBlock? { get set }
var bridge_accessibilityValueBlock: AXStringReturnBlock? { get set }
var bridge_accessibilityHintBlock: AXStringReturnBlock? { get set }
var bridge_accessibilityActivateBlock: AXBoolReturnBlock? { get set }
}
extension NSObject: AccessibilityUpdatable {
static var isAccessibilityElementBlockKey: UInt8 = 0
static var activateBlockKey: UInt8 = 1
static var valueBlockKey: UInt8 = 2
static var hintBlockKey: UInt8 = 3
static var labelBlockKey: UInt8 = 4
public var bridge_isAccessibilityElementBlock: AXBoolReturnBlock? {
get {
return objc_getAssociatedObject(self, &NSObject.isAccessibilityElementBlockKey) as? AXBoolReturnBlock
}
set {
objc_setAssociatedObject(self, &NSObject.isAccessibilityElementBlockKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
// if #available(iOS 17, *) {
// self.isAccessibilityElementBlock = newValue
// }
}
}
public var bridge_accessibilityActivateBlock: AXBoolReturnBlock? {
get {
return objc_getAssociatedObject(self, &NSObject.activateBlockKey) as? AXBoolReturnBlock
}
set {
objc_setAssociatedObject(self, &NSObject.activateBlockKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
// if #available(iOS 17, *) {
// self.accessibilityActivateBlock = newValue
// }
}
}
public var bridge_accessibilityValueBlock: AXStringReturnBlock? {
get {
return objc_getAssociatedObject(self, &NSObject.valueBlockKey) as? AXStringReturnBlock
}
set {
objc_setAssociatedObject(self, &NSObject.valueBlockKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
// if #available(iOS 17, *) {
// self.accessibilityValueBlock = newValue
// }
}
}
public var bridge_accessibilityHintBlock: AXStringReturnBlock? {
get {
return objc_getAssociatedObject(self, &NSObject.hintBlockKey) as? AXStringReturnBlock
}
set {
objc_setAssociatedObject(self, &NSObject.hintBlockKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
// if #available(iOS 17, *) {
// self.accessibilityHintBlock = newValue
// }
}
}
public var bridge_accessibilityLabelBlock: AXStringReturnBlock? {
get {
return objc_getAssociatedObject(self, &NSObject.labelBlockKey) as? AXStringReturnBlock
}
set {
objc_setAssociatedObject(self, &NSObject.labelBlockKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
// if #available(iOS 17, *) {
// self.accessibilityLabelBlock = newValue
// }
}
}
}