0

是否可以将 UIEvent 子类化以嵌入一些附加信息?我试过但不断收到异常,找不到任何关于子类化 UIEvent 的信息。

class CustomEvent: UIEvent {
      let payload: CustomData
      override init(payload: CustomData) {
            super.init()
            self.payload = payload
      }
}


017-03-30 08:51:17.504497 StealingTouches[1041:778674] -[StealingTouches.TouchEvent _firstTouchForView:]: unrecognized selector sent to instance 0x170053950
2017-03-30 08:51:17.505470 StealingTouches[1041:778674] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[StealingTouches.TouchEvent _firstTouchForView:]: unrecognized selector sent to instance 0x170053950'
*** First throw call stack:
(0x18bf991b8 0x18a9d055c 0x18bfa0268 0x18bf9d270 0x18be9680c 0x191e8494c 0x100026278 0x100026550 0x100026fc4 0x100027214 0x191e7be98 0x191e77328 0x191e47da0 0x19263175c 0x19262b130 0x18bf46b5c 0x18bf464a4 0x18bf440a4 0x18be722b8 0x18d926198 0x191eb27fc 0x191ead534 0x100029418 0x18ae555b8)
libc++abi.dylib: terminating with uncaught exception of type NSException

我有一组嵌套在超级视图深处的 3 层视图。我希望深度嵌套视图向事件添加一些自定义数据,并将这些数据转发到最外层视图。

见图片。绿色视图应该处理事件,进行适当的计算,将数据保存到事件中,并将数据转发到红色视图。只有绿色视图响应事件,但只有红色视图知道如何处理该事件。

在此处输入图像描述

绿色视图处理触摸......

class GreenView: UIControl {
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)

        //do some complicated calculation then save in custom event
        let customEvent = CustomEvent.init(payload: calculations)

        if let nextRespoonder = self.next {
            nextRespoonder.touchesBegan(touches, with: customEvent)
        } 
    }
}

然后将其转发到黄色视图...

 class YellowView: UIControl {
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        if let nextRespoonder = self.next {
            nextRespoonder.touchesBegan(touches, with: event)
        } 
    }
}

最后红色视图可以提取事件有效负载并做它需要做的事情......

 class RedView: UIControl {
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        if let customEvent = event as? CustomEvent {
               let payload = customEvent.payload
               //do something with the payload
        }

    }
}

另一种选择是将有效负载数据本地存储在绿色视图中,然后红色视图唯一需要做的就是识别哪个绿色视图发起了事件。这对于命中测试来说相当简单,但是我有超过一百个这样的绿色视图,并且仅根据命中测试来确定哪个是相当复杂的,因为有时绿色视图会相互重叠。

4

1 回答 1

0

我了解到这种模式是处理此问题的错误方法。更好的做法是使用委托。将 redView 指定为 greenView 的代表,然后将信息向上传递。

protocol GreenViewDelegate {
     func onTouchesBegan(greenView: GreenView)
}

class GreenView: UIControl {

    var delegate: GreenViewDelegate?

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        self.delegate?.onTouchesBegan(greenView: self)
    }


}

class RedView: UIControl, GreenViewDelegate {

    init() {
        greenView.delegate = self
    } 

    func onTochesBegan(greenView: GreenView) {
         //extract whatever data you want
    }

}
于 2017-03-30T17:36:03.863 回答