added Gesture publisher / extension to UIView

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
Matt Bruce 2022-08-31 13:29:44 -05:00
parent 6c67544c71
commit c975f2b06e
7 changed files with 91 additions and 27 deletions

View File

@ -64,6 +64,7 @@
EAB1D2CF28ABEF2B00DAE764 /* Typography.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB1D2CE28ABEF2B00DAE764 /* Typography.swift */; };
EAB1D2E628AE842000DAE764 /* Publisher+Bind.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB1D2E328AE842000DAE764 /* Publisher+Bind.swift */; };
EAB1D2EA28AE84AA00DAE764 /* UIControlPublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB1D2E928AE84AA00DAE764 /* UIControlPublisher.swift */; };
EAD8D2C128BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAD8D2C028BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift */; };
EAF7F0952899861000B287F5 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0932899861000B287F5 /* Checkbox.swift */; };
EAF7F0962899861000B287F5 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0942899861000B287F5 /* CheckboxModel.swift */; };
EAF7F09A2899B17200B287F5 /* CATransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0992899B17200B287F5 /* CATransaction.swift */; };
@ -161,6 +162,7 @@
EAB1D2CE28ABEF2B00DAE764 /* Typography.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Typography.swift; sourceTree = "<group>"; };
EAB1D2E328AE842000DAE764 /* Publisher+Bind.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Publisher+Bind.swift"; sourceTree = "<group>"; };
EAB1D2E928AE84AA00DAE764 /* UIControlPublisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIControlPublisher.swift; sourceTree = "<group>"; };
EAD8D2C028BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIGestureRecognizer+Publisher.swift"; sourceTree = "<group>"; };
EAF7F0932899861000B287F5 /* Checkbox.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Checkbox.swift; sourceTree = "<group>"; };
EAF7F0942899861000B287F5 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = "<group>"; };
EAF7F0992899B17200B287F5 /* CATransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CATransaction.swift; sourceTree = "<group>"; };
@ -436,6 +438,7 @@
EA89200128AECF2A006B9984 /* UIButton+Publisher.swift */,
EAB1D2E928AE84AA00DAE764 /* UIControlPublisher.swift */,
EA89200328AECF4B006B9984 /* UITextField+Publisher.swift */,
EAD8D2C028BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift */,
);
path = Publishers;
sourceTree = "<group>";
@ -621,6 +624,7 @@
EAB1D2EA28AE84AA00DAE764 /* UIControlPublisher.swift in Sources */,
EAF7F13328A2A16500B287F5 /* LabelAttributeAttachment.swift in Sources */,
EA89200628B526D6006B9984 /* CheckboxGroup.swift in Sources */,
EAD8D2C128BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift in Sources */,
EAF7F0B9289C139800B287F5 /* ColorConfiguration.swift in Sources */,
EA3361BD288B2C760071C351 /* TypeAlias.swift in Sources */,
EAB1D2CF28ABEF2B00DAE764 /* Typography.swift in Sources */,

View File

@ -127,7 +127,11 @@ open class CheckboxBase<ModelType: CheckboxModel>: Control<ModelType>, Changable
open override func setup() {
super.setup()
addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(Self.tap)))
//add tapGesture to self
publisher(for: UITapGestureRecognizer()).sink { [weak self] _ in
self?.sendActions(for: .touchUpInside)
}.store(in: &subscribers)
isAccessibilityElement = true
accessibilityTraits = .button
@ -204,10 +208,6 @@ open class CheckboxBase<ModelType: CheckboxModel>: Control<ModelType>, Changable
setAccessibilityLabel()
onChange = nil
}
@objc func tap() {
sendActions(for: .touchUpInside)
}
/// This will checkbox the state of the Selector and execute the actionBlock if provided.
open override func defaultAction() {

View File

@ -128,7 +128,11 @@ open class RadioBoxBase<ModelType: RadioBoxModel>: Control<ModelType>, Changable
open override func setup() {
super.setup()
addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(Self.tap)))
//add tapGesture to self
publisher(for: UITapGestureRecognizer()).sink { [weak self] _ in
self?.sendActions(for: .touchUpInside)
}.store(in: &subscribers)
isAccessibilityElement = true
accessibilityTraits = .button
@ -203,10 +207,6 @@ open class RadioBoxBase<ModelType: RadioBoxModel>: Control<ModelType>, Changable
setAccessibilityLabel()
onChange = nil
}
@objc func tap() {
sendActions(for: .touchUpInside)
}
/// This will radioBox the state of the Selector and execute the actionBlock if provided.
open override func defaultAction() {

View File

@ -126,7 +126,11 @@ open class RadioButtonBase<ModelType: RadioButtonModel>: Control<ModelType>, Cha
open override func setup() {
super.setup()
addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(Self.tap)))
//add tapGesture to self
publisher(for: UITapGestureRecognizer()).sink { [weak self] _ in
self?.sendActions(for: .touchUpInside)
}.store(in: &subscribers)
isAccessibilityElement = true
accessibilityTraits = .button
@ -203,11 +207,7 @@ open class RadioButtonBase<ModelType: RadioButtonModel>: Control<ModelType>, Cha
setAccessibilityLabel()
onChange = nil
}
@objc func tap() {
sendActions(for: .touchUpInside)
}
/// This will checkbox the state of the Selector and execute the actionBlock if provided.
open override func defaultAction() {
guard !isSelected else { return }

View File

@ -88,7 +88,11 @@ open class RadioSwatchBase<ModelType: RadioSwatchModel>: Control<ModelType>, Cha
open override func setup() {
super.setup()
addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(Self.tap)))
//add tapGesture to self
publisher(for: UITapGestureRecognizer()).sink { [weak self] _ in
self?.sendActions(for: .touchUpInside)
}.store(in: &subscribers)
isAccessibilityElement = true
accessibilityTraits = .button
@ -121,11 +125,7 @@ open class RadioSwatchBase<ModelType: RadioSwatchModel>: Control<ModelType>, Cha
setAccessibilityLabel()
onChange = nil
}
@objc func tap() {
sendActions(for: .touchUpInside)
}
open override func defaultAction() {
isSelected.toggle()
sendActions(for: .valueChanged)

View File

@ -254,7 +254,11 @@ open class ToggleBase<ModelType: ToggleModel>: Control<ModelType>, Changable {
//--------------------------------------------------
open override func setup() {
super.setup()
addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(Self.tap)))
//add tapGesture to self
publisher(for: UITapGestureRecognizer()).sink { [weak self] _ in
self?.sendActions(for: .touchUpInside)
}.store(in: &subscribers)
isAccessibilityElement = true
accessibilityTraits = .button
@ -311,10 +315,6 @@ open class ToggleBase<ModelType: ToggleModel>: Control<ModelType>, Changable {
onChange = nil
}
@objc func tap() {
sendActions(for: .touchUpInside)
}
/// This will toggle the state of the Toggle and execute the actionBlock if provided.
open override func defaultAction() {
isOn.toggle()

View File

@ -0,0 +1,60 @@
//
// UIGestureRecognizer.swift
// VDS
//
// Created by Matt Bruce on 8/31/22.
//
import Foundation
import UIKit
import Combine
extension UIView {
public func publisher<G>(for gestureRecognizer: G) -> UIGestureRecognizer.Publisher<G> where G: UIGestureRecognizer {
UIGestureRecognizer.Publisher(gestureRecognizer: gestureRecognizer, view: self)
}
}
extension UIGestureRecognizer {
public struct Publisher<G>: Combine.Publisher where G: UIGestureRecognizer {
public typealias Output = G
public typealias Failure = Never
public let gestureRecognizer: G
public let view: UIView
public func receive<S>(subscriber: S) where S : Subscriber, Failure == S.Failure, Output == S.Input {
subscriber.receive(
subscription: Subscription(subscriber: subscriber, gestureRecognizer: gestureRecognizer, on: view)
)
}
}
public class Subscription<G: UIGestureRecognizer, S: Subscriber>: Combine.Subscription where S.Input == G, S.Failure == Never {
public var subscriber: S?
public let gestureRecognizer: G
public let view: UIView
public init(subscriber: S, gestureRecognizer: G, on view: UIView) {
self.subscriber = subscriber
self.gestureRecognizer = gestureRecognizer
self.view = view
gestureRecognizer.addTarget(self, action: #selector(handle))
view.addGestureRecognizer(gestureRecognizer)
}
@objc private func handle(_ gesture: UIGestureRecognizer) {
_ = subscriber?.receive(gestureRecognizer)
}
public func cancel() {
view.removeGestureRecognizer(gestureRecognizer)
}
public func request(_ demand: Subscribers.Demand) { }
}
}