【问题标题】:How to check if tap happened in a specific place如何检查点击是否发生在特定位置
【发布时间】:2015-03-06 16:18:54
【问题描述】:

我正在尝试检查是否在屏幕上的特定区域发生了点击。我已经设置了 TapGestureRecognizer 这是我现在拥有的代码:

func handleTap(tap: UITapGestureRecognizer) {
    var point = tap.locationInView(self.view)
    println("tapped")

    if (tap.state == UIGestureRecognizerState.Ended)
    {
        if (CGRectContainsPoint(self.Region.frame, point)) {
            println("touch")
            var y = kbHeight - textYoutube.center.y
            youTextConst.constant += y
        }
    }
}

应用识别到了tap,但没有识别到​​特定区域的tap,代码有什么问题?

更新

我不知道这是否重要,但 Region 是 TextView

【问题讨论】:

标签: ios swift xcode6 uitapgesturerecognizer


【解决方案1】:

(注意:我假设self.Region 是一个UIView。你没有在你的问题中解释它是什么,所以我必须猜测它可能是什么。顺便说一句,请不要在属性名称中使用大写字母。我这样做只是为了让您轻松匹配自己的代码。)

考虑坐标系。你在说

var point = tap.locationInView(self.view)

这意味着pointself.view 的坐标系中。但如果你要调用 CGRectContainsPoint,那是错误的坐标系。在你弄清楚pointself.Region之间的关系之前,你需要把pointself.Region放到同一个坐标系中:

point = self.Region.convertPoint(point, fromView:self.view)

现在你可以使用self.Region.bounds,它与point的新值在同一个坐标系中:

if CGRectContainsPoint(self.Region.bounds, point)

【讨论】:

    【解决方案2】:

    我的第一个答案,即使是草图,也很混乱。我已经删除了。

    因此,这里有多种方法可以实现您的目标。我们假设您的区域是一个 UIView。

    解决方案 1

    您正在从 主视图 检索点,因此您需要检查您的 regionView 的 frame 是否包含您的点。

    import UIKit
    
    class ViewController: UIViewController {
    
        @IBOutlet var regionView: UIView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
    
            let tap = UITapGestureRecognizer()
            tap.addTarget(self, action: "handleTap:")
    
            self.view.addGestureRecognizer(tap)
        }
    
        func handleTap(tap: UITapGestureRecognizer) {
            if (tap.state == UIGestureRecognizerState.Ended) {
                println("[handleTap] Tap ended")
    
                var point = tap.locationInView(self.view)
    
                println("[handleTap] Tap point : x\(point.x) ; y\(point.y) (in self.view)")
    
                if (CGRectContainsPoint(self.regionView.frame, point)) {
                    println("[handleTap] Tap is inside regionView")
                }
    
                println()
            }
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
    }
    

    解决方案 2

    您正在检索该点并将其转换到内部 regionView 坐标系。因此,您需要检查该点是否在您的 regionView 的 bounds 内。

    import UIKit
    
    class ViewController: UIViewController {
    
        @IBOutlet var regionView: UIView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
    
            let tap = UITapGestureRecognizer()
            tap.addTarget(self, action: "handleTap:")
    
            self.view.addGestureRecognizer(tap)
        }
    
        func handleTap(tap: UITapGestureRecognizer) {
            if (tap.state == UIGestureRecognizerState.Ended) {
                println("[handleTap] Tap ended")
    
                var point = tap.locationInView(self.view)
    
                println("[handleTap] Tap point : x\(point.x) ; y\(point.y) (in self.view)")
    
                point = self.regionView.convertPoint(point, fromView: self.view)
    
                println("[handleTap] Tap point converted : x\(point.x) ; y\(point.y) (in self.regionView)")
    
                if (CGRectContainsPoint(self.regionView.bounds, point)) {
                    println("[handleTap] Tap is inside regionView")
                }
    
                println()
            }
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
    }
    

    解决方案 3

    您可以直接从您的 regionView 中获得要点。所以你不需要转换它,但是你仍然需要检查它是否在它的 bounds 之内,就像解决方案 2 一样。

    import UIKit
    
    class ViewController: UIViewController {
    
        @IBOutlet var regionView: UIView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
    
            let tap = UITapGestureRecognizer()
            tap.addTarget(self, action: "handleTap:")
    
            self.view.addGestureRecognizer(tap)
        }
    
        func handleTap(tap: UITapGestureRecognizer) {
            if (tap.state == UIGestureRecognizerState.Ended) {
                println("[handleTap] Tap ended")
    
                var point = tap.locationInView(self.regionView)
    
                println("[handleTap] Tap point : x\(point.x) ; y\(point.y) (in self.view)")
    
                if (CGRectContainsPoint(self.regionView.bounds, point)) {
                    println("[handleTap] Tap is inside regionView")
                }
    
                println()
            }
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
    }
    

    或者,您只能在 regionView 上设置手势识别器:self.regionView.addGestureRecognizer(tap)

    如果有帮助请告诉我!

    【讨论】:

    • 该区域是一个文本字段,我认为这就是为什么你的代码对我不起作用的原因,当我在图像上检查它时它工作正常。
    • 完美解决方案!我正在寻找一种方法来通过在图像视图之外点击来关闭控制器,并且由于任何原因 touchesBegan 没有在视图上工作,但这个解决方案有效!
    【解决方案3】:

    斯威夫特 5:

    func handleTap(recognizer: UITapGestureRecognizer) {
        if (recognizer.state == .ended) {
            let point = recognizer.location(in: self.view)
            
            if (self.headerView.frame.contains(point)) {
                // Do something
            }
            
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多