터치 이벤트를 무시하고 다른 하위보기의 UIControl 개체에 전달하는 방법은 무엇입니까?
UIView가 화면의 모서리를 차지하는 사용자 지정 UIViewController가 있지만 일부 버튼과 항목이있는 부분을 제외하고는 대부분 투명합니다. 해당보기의 개체 레이아웃으로 인해보기의 프레임이 그 아래에있는 일부 버튼을 가릴 수 있습니다. 나는 그들이 그것에 중요한 것을 건드리지 않는다면 그 뷰에 대한 어떤 터치도 무시할 수 있기를 원하지만 실제 터치 이벤트 (touchesEnded / nextResponder 물건) 만 전달할 수있는 것 같습니다. touchesEnded를 사용하지 않는 UIButton 또는 이와 유사한 것이있는 경우 터치 이벤트를 어떻게 전달합니까?
이 사용자 정의 ViewController는 다양한 뷰에서 사용할 수 있기 때문에 호출 할 버튼 선택기를 수동으로 알아낼 수는 없습니다. 기본적으로 이것을 호출하는 방법이 필요합니다.
[self.nextResponder touchesEnded:touches withEvent:event];
UIControl 유형에도 적용됩니다.
아마도이 작업을 수행하는 가장 좋은 방법은 hitTest:withEvent:
터치를 무시하려는 뷰에서 재정의 하는 것입니다. 보기 계층 구조의 복잡성에 따라이를 수행하는 몇 가지 쉬운 방법이 있습니다.
무시할보기 아래에보기에 대한 참조가있는 경우 :
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *hitView = [super hitTest:point withEvent:event];
// If the hitView is THIS view, return the view that you want to receive the touch instead:
if (hitView == self) {
return otherView;
}
// Else return the hitView (as it could be one of this view's buttons):
return hitView;
}
뷰에 대한 참조가없는 경우 :
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *hitView = [super hitTest:point withEvent:event];
// If the hitView is THIS view, return nil and allow hitTest:withEvent: to
// continue traversing the hierarchy to find the underlying view.
if (hitView == self) {
return nil;
}
// Else return the hitView (as it could be one of this view's buttons):
return hitView;
}
첫 번째 접근 방식이 가장 강력한 것으로 권장합니다 (기본 뷰에 대한 참조를 얻을 수있는 경우).
터치 이벤트가 무시되고 부모에게 전달되도록 사용자 상호 작용을 비활성화 할 수도 있습니다.
Swift에서 :
yourView.isUserInteractionEnabled = false
신속한 답변 :
UIView 하위 클래스 인 IgnoreTouchView를 만들 수 있습니다. 스토리 보드에서 터치를 통과하려는 VC의 뷰에 설정합니다.
class IgnoreTouchView : UIView {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let hitView = super.hitTest(point, with: event)
if hitView == self {
return nil
}
return hitView
}
}
해당 UIView에 대해 UserInteractionEnabled를 true로 설정해야합니다.
I haven't found a good way to pass UITouch events between objects. What usually works better is to implement hitTest and return nil if the point isn't in the view that you want to handle it:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
This is an old question, and it comes up at the top of searches. So, I thought I'd post another possible solution that might work better for your situation. In my case I wanted to drag a label on top of another label and I wanted to get the label below in the hitTest. The simplest thing to do is to set the userInteractionEnabled
to NO
or false
, then do your hitTest, and then set it back again if you need to move it again. Here's a code sample in Swift:
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch = touches.first
let location = touch?.locationInView(self.view)
self.label1.userInteractionEnabled = false
let view = self.view.hitTest(location!, withEvent: nil) as? UILabel
print(view?.text)
self.label1.userInteractionEnabled = true
}
My problem was similar: I had a UIControl with complex touch responders, but it acted funny when embedded in a scroll view...
This prevents parent scrolling (or can be modified to prevent other interactions) when sub view has an active touch gesture.
My solution:
Create a delegate protocol for didBeginInteraction and didEndInteraction in sub view.
Call delegate.didBeginInteraction from touchesBegan
Call delegate.didEndInteraction from touchesEnded and touchesCancelled
In parent controller, implement didBegin and didEnd protocol, set delegate
Then set scrollView.scrollEnabled = NO in didBegin, scrollEnabled = YES in didEnd.
Hope this helps someone with a slightly different use case than the question posed!
'IT Share you' 카테고리의 다른 글
git diff가 권한 변경을 무시하도록 할 수 있습니까? (0) | 2020.11.19 |
---|---|
IDE 내부에서 .bat를 실행하는 방법 (0) | 2020.11.19 |
Java에서 nullable int를 작성하는 방법은 무엇입니까? (0) | 2020.11.19 |
필드가있는 경우 NoSuchFieldException (0) | 2020.11.19 |
MySQL에서 열의 마지막 두 문자 제거 (0) | 2020.11.19 |