하나의 하위보기가있는보기 컨트롤러가 있다고 가정 해 봅시다. 서브 뷰는 모든면에서 100 픽셀의 여백으로 화면 중앙을 차지합니다. 그런 다음 하위 뷰 내부를 클릭하기 위해 작은 것들을 추가합니다. 우리는 새로운 프레임을 이용하기 위해 서브 뷰만을 사용하고 있습니다 (서브 뷰 내에서 x = 0, y = 0은 실제로는 부모 뷰에서 100,100입니다).
그런 다음 메뉴와 같이 하위 뷰 뒤에 무언가가 있다고 상상해보십시오. 사용자가 하위보기에서 “작은 물건”을 선택할 수 있기를 원하지만 아무 것도 없으면 터치가 뒤에 배경으로 전달됩니다 (배경이 분명하기 때문에).
어떻게해야합니까? 터치가 시작된 것처럼 보이지만 버튼이 작동하지 않습니다.
답변
컨테이너에 대한 사용자 지정보기를 만들고 pointInside : 메시지를 재정 의하여 포인트가 다음과 같이 적격 한 자식보기 내에 있지 않은 경우 false를 반환합니다.
빠른:
class PassThroughView: UIView {
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
for subview in subviews {
if !subview.isHidden && subview.isUserInteractionEnabled && subview.point(inside: convert(point, to: subview), with: event) {
return true
}
}
return false
}
}
목표 C :
@interface PassthroughView : UIView
@end
@implementation PassthroughView
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
for (UIView *view in self.subviews) {
if (!view.hidden && view.userInteractionEnabled && [view pointInside:[self convertPoint:point toView:view] withEvent:event])
return YES;
}
return NO;
}
@end
이 뷰를 컨테이너로 사용하면 모든 자식이 터치를받을 수 있지만 뷰 자체는 이벤트에 투명합니다.
답변
나는 또한 사용
myView.userInteractionEnabled = NO;
서브 클래스 할 필요가 없습니다. 잘 작동합니다.
답변
이벤트 전달은 일부 응용 프로그램에서 사용하는 기술입니다. 다른 응답자 오브젝트의 이벤트 처리 메소드를 호출하여 터치 이벤트를 전달합니다. 이것이 효과적인 기술 일 수 있지만주의해서 사용해야합니다. UIKit 프레임 워크의 클래스는 바인딩되지 않은 터치를 수신하도록 설계되지 않았습니다 …. 애플리케이션에서 다른 응답자에게 조건부로 터치를 전달하려면 이러한 응답자는 모두 고유 한 UIView 서브 클래스의 인스턴스 여야합니다.
사과 모범 사례 :
응답자 체인에 이벤트를 명시 적으로 보내지 마십시오 (NextResponder를 통해). 대신, 수퍼 클래스 구현을 호출하고 UIKit이 응답자 체인 탐색을 처리하게하십시오.
대신 다음을 무시할 수 있습니다.
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
터치를 응답자 체인으로 보내려면 (아니면 아무것도없는 뷰 뒤의 뷰에) 원하는 경우 UIView 하위 클래스에서 NO를 반환하십시오.
답변
답변
John이 게시 한 내용을 기반으로 다음은 터치 이벤트가 버튼을 제외한 뷰의 모든 하위 뷰를 통과 할 수있는 예입니다.
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
// Allow buttons to receive press events. All other views will get ignored
for( id foundView in self.subviews )
{
if( [foundView isKindOfClass:[UIButton class]] )
{
UIButton *foundButton = foundView;
if( foundButton.isEnabled && !foundButton.hidden && [foundButton pointInside:[self convertPoint:point toView:foundButton] withEvent:event] )
return YES;
}
}
return NO;
}
답변
최근에 나는 그것을 도와 줄 수업을 썼습니다. UIButton
또는 사용자 정의 클래스로 사용 하거나 UIView
투명 픽셀에서 실행 된 터치 이벤트를 전달합니다.
이 솔루션은 UIButton
반투명 아래에있는 버튼을 클릭 할 수 있지만 투명 UIView
하지 않은 부분은 UIView
터치 이벤트에 계속 반응 하므로 허용 된 답변보다 다소 낫습니다 .
GIF에서 볼 수 있듯이 기린 버튼은 단순한 사각형이지만 투명한 영역의 터치 이벤트는 UIButton
아래 의 노란색으로 전달됩니다 .
답변
최고 투표 솔루션이 저에게 완전히 효과가 없었습니다 .TabBarController를 계층 구조에 넣었 기 때문에 (댓글 중 하나가 지적한 것처럼) 실제로 UI의 일부 부분에 대한 터치를 전달했지만 내 엉망이었습니다. 터치 이벤트를 가로 채는 tableView의 기능, 마지막으로 터치 테스트 를 무시하고 있었지만 터치를 무시하고 해당 뷰의 하위 뷰가 처리하도록했습니다.
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
UIView *view = [super hitTest:point withEvent:event];
if (view == self) {
return nil; //avoid delivering touch events to the container view (self)
}
else{
return view; //the subviews will still receive touch events
}
}