子类UIEvent嵌入了更多信息?

时间:2017-03-30 16:50:38

标签: uievent

是否可以将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个级别的视图集合。我希望深度嵌套的视图向事件添加一些自定义数据,并将此数据转发到最外面的视图。

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

enter image description here

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

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
        }

    }
}

另一种选择是在绿色视图中本地存储有效载荷数据,然后红色视图唯一需要做的是识别启动事件的绿色视图。这对于命中测试来说相当简单,但是我有超过一百个这样的绿色视图,并且由于有时绿色视图相互重叠,因此可以相当复杂地找出哪一个基于命中测试。

1 个答案:

答案 0 :(得分: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
    }

}