use*_*189 5 uigesturerecognizer ios swift
我有视图,我想在其中执行向右滑动手势.不幸的是我收到错误EXC_BAD_ACCESS.有人知道这里有什么问题吗?请看下面的代码.
extension UIView {
func addGestureRecognizerWithAction(nizer: UIGestureRecognizer, action:() -> ()) {
class Invoker {
var action:() -> ()
init(action:() -> ()) {
self.action = action
}
func invokeTarget(nizer: UIGestureRecognizer) {
self.action()
println("Hi from invoker")
}
}
addGestureRecognizer(nizer)
nizer.addTarget(Invoker(action), action: "invokeTarget:")
}
}
class BugView: UIView {
override func awakeFromNib() {
super.awakeFromNib()
var swipeRight = UISwipeGestureRecognizer()
swipeRight.direction = UISwipeGestureRecognizerDirection.Right
self.addGestureRecognizerWithAction(swipeRight) {
println("Hi from the gesture closure")
}
}
}
Run Code Online (Sandbox Code Playgroud)
hei*_*iko 10
恕我直言,这是最简单的解决方案,不需要子类化,因此它非常通用。但它需要关联对象来存储操作:
extension UIGestureRecognizer {
typealias Action = ((UIGestureRecognizer) -> ())
private struct Keys {
static var actionKey = "ActionKey"
}
private var block: Action? {
set {
if let newValue = newValue {
// Computed properties get stored as associated objects
withUnsafePointer(to: &Keys.actionKey) {
objc_setAssociatedObject(self, $0, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
}
}
get {
let action = objc_getAssociatedObject(self, &Keys.actionKey) as? Action
return action
}
}
@objc func handleAction(recognizer: UIGestureRecognizer) {
block?(recognizer)
}
convenience public init(block: @escaping ((UIGestureRecognizer) -> ())) {
self.init()
self.block = block
self.addTarget(self, action: #selector(handleAction(recognizer:)))
}
}
Run Code Online (Sandbox Code Playgroud)
这允许您甚至对您自己的子类使用以下内容。用法:
let tapRecognizer = UITapGestureRecognizer { recognizer in
print("Hallo")
}
myView.addGestureRecognizer(tapRecognizer)
Run Code Online (Sandbox Code Playgroud)
编辑:根据 Andrespch 的说法用“withUnsafePointer”更新了此内容。谢谢你的提示。
最后返回true是对的.在上面的回答中,他通过建议制作InvokerNSObject的子类,指出了我正确的方向.
但这不是我在代码中唯一的错误.我发现当滑动发生时,Invoker用于处理事件的对象已经从记忆中消失了.我认为关闭它的提法并没有像它应该的那样被捕获.现在我想出了另一种实现此功能的方法,我想与您分享:
class UIGestureRecognizerWithClosure: NSObject { // must subclass NSObject otherwise error: "class does not implement methodSignatureForSelector: -- " !!
var closure:() -> ()
init(view:UIView, nizer: UIGestureRecognizer, closure:() -> ()) {
self.closure = closure
super.init()
view.addGestureRecognizer(nizer)
nizer.addTarget(self, action: "invokeTarget:")
}
func invokeTarget(nizer: UIGestureRecognizer) {
self.closure()
}
}
Run Code Online (Sandbox Code Playgroud)
此代码段显示了如何使用代码:
var swipeRight = UISwipeGestureRecognizer()
swipeRight.direction = UISwipeGestureRecognizerDirection.Right
// swipeWrapper has to be defined as a property: var swipeWrapper:UIGestureRecognizerWithClosure?
// -> this is needed in order to keep the object alive till the swipe event occurs
swipeWrapper = UIGestureRecognizerWithClosure(view: self, nizer:swipeRight) {
println("Hi from the gesture closure")
}
Run Code Online (Sandbox Code Playgroud)
对于那些不喜欢关联对象和其他棘手东西的人,我有一个小型手势识别器,不需要任何麻烦。而且它不需要存储在某个地方。像常规GR一样工作。尽管它有一些局限性-它是从继承而来的UITapGestureRecognizer,他只知道如何处理水龙头。但是我们经常需要所有的类型吗?我个人不是。
final class BindableGestureRecognizer: UITapGestureRecognizer {
private var action: () -> Void
init(action: @escaping () -> Void) {
self.action = action
super.init(target: nil, action: nil)
self.addTarget(self, action: #selector(execute))
}
@objc private func execute() {
action()
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
let gestureRecognizer = BindableGestureRecognizer {
print("It's alive!")
}
self.view.addGestureRecognizer(gestureRecognizer)
Run Code Online (Sandbox Code Playgroud)
如果出现了一些更有意义的行,请不要忘记[弱自我]。我们不想创建那些不死伙伴。
let colorGestureRecognizer = BindableGestureRecognizer { [weak self] in
self?.view.backgroundColor = .red
}
self.view.addGestureRecognizer(colorGestureRecognizer)
Run Code Online (Sandbox Code Playgroud)
对我来说似乎很方便,可以从这些@objc衬里中净化我们的视图控制器,并变得更多一点。
| 归档时间: |
|
| 查看次数: |
4208 次 |
| 最近记录: |