如何检查点击是不是发生在特定位置

Posted

技术标签:

【中文标题】如何检查点击是不是发生在特定位置【英文标题】: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

【问题讨论】:

想想你在这里使用的不同坐标系... 在调用 CGRectContainsPoint 之前,您需要一个矩形和一个点在同一坐标系中。我要做的是将point 转换为self.Region 本身的坐标系,然后将pointself.Region.bounds 进行比较。看我的书:apeth.com/iosBook/ch14.html#_frame 和 apeth.com/iOSBook/ch14.html#_bounds_and_center 【参考方案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
        
        
    

【讨论】:

以上是关于如何检查点击是不是发生在特定位置的主要内容,如果未能解决你的问题,请参考以下文章

如何检查图像是不是存在于特定位置?

如何检查指南针航向是不是指向特定位置?

Actionscript 2 - 如何检查电影剪辑是不是存在于舞台的特定位置?

Selenium Webdriver:如何检查特定屏幕上是不是存在 ui 元素,无论它当前是不是可见/可点击

如何检查 Json 是不是匹配特定的 C# 类型?

批处理文件以检查文件中是不是存在特定单词“test”,如果存在则将整个文件夹复制到另一个位置