使用 swift 为自定义控件分配两个不同的 UITapGestureRecognizer
Assign two different UITapGestureRecognizer for a custom control using swift
使用 swift,我正在尝试创建一个动态的通用控件来重用它,基本上,该控件内部应该有一个通用的行为。
更具体地说,我有一个 UIScrollView
,它是使用 UIViews
填充的,当您点击 UIView
时,背景应该会改变。
一切正常。
但是,为了实现,我的 class 通用控件接受一个 Selector
作为参数。
两者单独工作,但一起工作时不工作。
具体部分代码为:
通用 class
let clickAgendaEvent = UITapGestureRecognizer(target: self, action: #selector (self.agendaClicked (_:)))
cellSubView.addGestureRecognizer(clickAgendaEvent)
cell.addSubview(cellSubView)
let itemClickedEvent = UITapGestureRecognizer(target: viewController.self, action: self.agendaItemClicked! )
cell.addGestureRecognizer(itemClickedEvent)
还有一个 ViewController
实现如下:
@objc func eventDailyAgenda(sender:UIView!){
print("Item clicked!")
}
如您所见,第二个事件不在通用class 内部,如果ViewController
,第二个事件是单独的实现。
但是,通用 class 将针对其他 UIViewController
.
实施
有人知道如何处理吗?
研究 UIGestureRecognizerDelegate
以同时处理两种手势。查看回调 gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:)
。 Return true 同时处理。
更简单的方法是实施 UIGestureRecognizerDelegate
。
但是对于我的具体情况并没有奏效,因为我有不同的 classes 实现该行为。
但是,我找到了一种方法。
并且正在实施 NSObject
(如果您在 UIViewController
中,则不必实施它。
对于我的情况,我有 class:
class MyClass:NSObject {
func createAll(){
let clickAgendaEvent = UITapGestureRecognizer(target: self, action: #selector (self.agendaClicked (_:)))
cellSubView.addGestureRecognizer(clickAgendaEvent)
cellSubView.tag = index
cell.addSubview(cellSubView)
}
@objc func agendaClicked(_ sender:AnyObject) {
baseView.setTransparentToSubViews()
print("Here")
let tap = sender as! UITapGestureRecognizer
tap.view?.backgroundColor = UIColor().hexStringToUIColor(hex: "#e0e0e0")
if let v = tap.view {
// use button
print("The tag is \(v.tag)")
}
if let c: NSObject.Type = NSClassFromString(viewController.className) as? NSObject.Type{
let c_tmp = c.init()
c_tmp.perform(Selector(("test")))
c.perform(Selector(("static_test")))
}
}
}
加入你的ViewController
@objc public func test(){
print("This is Test!!!")
}
@objc public class func static_test(){
print("This is Static Test")
}
还有这个扩展:
import Foundation
import UIKit
extension UIViewController {
var className: String {
return NSStringFromClass(self.classForCoder)
}
}
现在,您可以执行所有您想要的方法。
对于这种情况,一旦用户触摸一个元素,下一个事件就会从触摸中触发,并且不需要添加新的委托。
也许这不是更好的方法,但完全可行。
使用 swift,我正在尝试创建一个动态的通用控件来重用它,基本上,该控件内部应该有一个通用的行为。
更具体地说,我有一个 UIScrollView
,它是使用 UIViews
填充的,当您点击 UIView
时,背景应该会改变。
一切正常。
但是,为了实现,我的 class 通用控件接受一个 Selector
作为参数。
两者单独工作,但一起工作时不工作。
具体部分代码为:
通用 class
let clickAgendaEvent = UITapGestureRecognizer(target: self, action: #selector (self.agendaClicked (_:)))
cellSubView.addGestureRecognizer(clickAgendaEvent)
cell.addSubview(cellSubView)
let itemClickedEvent = UITapGestureRecognizer(target: viewController.self, action: self.agendaItemClicked! )
cell.addGestureRecognizer(itemClickedEvent)
还有一个 ViewController
实现如下:
@objc func eventDailyAgenda(sender:UIView!){
print("Item clicked!")
}
如您所见,第二个事件不在通用class 内部,如果ViewController
,第二个事件是单独的实现。
但是,通用 class 将针对其他 UIViewController
.
有人知道如何处理吗?
研究 UIGestureRecognizerDelegate
以同时处理两种手势。查看回调 gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:)
。 Return true 同时处理。
更简单的方法是实施 UIGestureRecognizerDelegate
。
但是对于我的具体情况并没有奏效,因为我有不同的 classes 实现该行为。
但是,我找到了一种方法。
并且正在实施 NSObject
(如果您在 UIViewController
中,则不必实施它。
对于我的情况,我有 class:
class MyClass:NSObject {
func createAll(){
let clickAgendaEvent = UITapGestureRecognizer(target: self, action: #selector (self.agendaClicked (_:)))
cellSubView.addGestureRecognizer(clickAgendaEvent)
cellSubView.tag = index
cell.addSubview(cellSubView)
}
@objc func agendaClicked(_ sender:AnyObject) {
baseView.setTransparentToSubViews()
print("Here")
let tap = sender as! UITapGestureRecognizer
tap.view?.backgroundColor = UIColor().hexStringToUIColor(hex: "#e0e0e0")
if let v = tap.view {
// use button
print("The tag is \(v.tag)")
}
if let c: NSObject.Type = NSClassFromString(viewController.className) as? NSObject.Type{
let c_tmp = c.init()
c_tmp.perform(Selector(("test")))
c.perform(Selector(("static_test")))
}
}
}
加入你的ViewController
@objc public func test(){
print("This is Test!!!")
}
@objc public class func static_test(){
print("This is Static Test")
}
还有这个扩展:
import Foundation
import UIKit
extension UIViewController {
var className: String {
return NSStringFromClass(self.classForCoder)
}
}
现在,您可以执行所有您想要的方法。
对于这种情况,一旦用户触摸一个元素,下一个事件就会从触摸中触发,并且不需要添加新的委托。
也许这不是更好的方法,但完全可行。