self.view (view of UIViewCotroller
)를 두 번 탭하면 일부 코드를 호출하는 기능을 구현해야합니다 . 그러나이 뷰에 다른 UI 개체가 있고 모든 인식기 개체를 첨부하고 싶지 않은 문제입니다. 나는이 방법을 내 관점에서 제스처를 만드는 방법을 발견했으며 어떻게 작동하는지 알고 있습니다. 지금 나는 하위보기를 무시 하고이 인식기를 만들기 위해 선택할 방법을 선택하는 핸디캡 앞에 있습니다. 어떤 아이디어? 감사.
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
[doubleTap setNumberOfTapsRequired:2];
[self.view addGestureRecognizer:doubleTap];
답변
객체 UIGestureRecognizerDelegate
내부 에 프로토콜을 채택 self
하고 뷰를 확인하기 위해 아래 메소드를 호출해야합니다. 이 메서드 내에서보기를 확인 touch.view
하고 적절한 부울 (예 / 아니요)을 반환합니다. 이 같은:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isDescendantOfView:yourSubView]) {
return NO;
}
return YES;
}
편집 : @Ian의 대답도 확인하십시오!
스위프트 5
// MARK: UIGestureRecognizerDelegate methods, You need to set the delegate of the recognizer
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
if touch.view?.isDescendant(of: tableView) == true {
return false
}
return true
}
답변
또 다른 접근 방식은 후손이 조건을 통과하지 않기 때문에 터치의보기가 제스처보기인지 비교하는 것입니다. 멋지고 간단한 한 줄짜리 :
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return touch.view == gestureRecognizer.view
}
답변
그리고 Swift 변형의 경우 :
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
if touch.view.isDescendantOfView(yourSubView){
return false
}
return true
}
알아두면 좋은 점 은 수신자가 지정된 뷰의 하위 뷰인지 또는 해당 뷰와 동일한 지 나타내는 값을 isDescendantOfView
반환합니다 Boolean
.
답변
Swift 5 및 iOS 12 UIGestureRecognizerDelegate
에는 gestureRecognizer(_:shouldReceive:)
. gestureRecognizer(_:shouldReceive:)
다음과 같은 선언이 있습니다.
제스처 인식기가 터치를 나타내는 개체를 받아야하는지 대리인에게 문의하십시오.
optional func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool
아래의 전체 코드는 gestureRecognizer(_:shouldReceive:)
. 이 코드를 사용하면 ViewController
의 뷰 (포함 imageView
) 의 하위 뷰를 탭 해도 printHello(_:)
메서드가 트리거되지 않습니다 .
import UIKit
class ViewController: UIViewController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(printHello))
tapGestureRecognizer.delegate = self
view.addGestureRecognizer(tapGestureRecognizer)
let imageView = UIImageView(image: UIImage(named: "icon")!)
imageView.frame = CGRect(x: 50, y: 50, width: 100, height: 100)
view.addSubview(imageView)
// ⚠️ Enable user interaction for imageView so that it can participate to touch events.
// Otherwise, taps on imageView will be forwarded to its superview and managed by it.
imageView.isUserInteractionEnabled = true
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
// Prevent subviews of a specific view to send touch events to the view's gesture recognizers.
if let touchedView = touch.view, let gestureView = gestureRecognizer.view, touchedView.isDescendant(of: gestureView), touchedView !== gestureView {
return false
}
return true
}
@objc func printHello(_ sender: UITapGestureRecognizer) {
print("Hello")
}
}
의 대체 구현은 gestureRecognizer(_:shouldReceive:)
다음과 같습니다.
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return gestureRecognizer.view === touch.view
}
그러나이 대체 코드 touch.view
는의 하위보기 인지 확인하지 않습니다 gestureRecognizer.view
.
답변
완전한 신속한 솔루션 (대리인이 구현되고 인식기에 대해 설정되어야 함) :
class MyViewController: UIViewController UIGestureRecognizerDelegate {
override func viewDidLoad() {
let doubleTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(onBaseTapOnly))
doubleTapRecognizer.numberOfTapsRequired = 2
doubleTapRecognizer.delegate = self
self.view.addGestureRecognizer(doubleTapRecognizer)
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
if touch.view.isDescendantOfView(self.view){
return false
}
return true
}
func onBaseTapOnly(sender: UITapGestureRecognizer) {
if sender.state == .Ended {
//react to tap
}
}
}
답변
터치하는 CGPoint를 사용하는 변형 (SWIFT 4.0)
class MyViewController: UIViewController, UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
// Get the location in CGPoint
let location = touch.location(in: nil)
// Check if location is inside the view to avoid
if viewToAvoid.frame.contains(location) {
return false
}
return true
}
}
답변
명확한 신속한 방법
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return touch.view == self.view
}