2017-05-24 37 views
2

因此,我在我的应用程序中显示了一个图像,我使用Xcode快速创建了该图像,并且我希望例如在图像被点击时打印“图像点击”。下面是我的了:Swift 3检查用户点击图像

这是假设得到调用的函数,只要用户点按图片:

func imageViewTapped(imageView: UIImageView) { 
    print("Image Clicked") 
} 

我有这个功能,增加了与图像的用户互动:

func tapRecognition(image: UIImageView) { 
    image.isUserInteractionEnabled = true 
    let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector(("imageViewTapped:"))) 
    image.addGestureRecognizer(tapRecognizer) 
} 

最后但并非最不重要的,我创建类型的UIImageView的形象在我的viewDidLoad()函数,我叫:

tapRecognition(image: imageView) 

当我运行它并单击图像时,出现一个错误,指出:“终止于类型为NSException的未捕获异常”。 任何帮助将是伟大的!非常感谢。

+0

凡'imageView'被初始化? –

+1

除非您使用旧的Swift,否则您需要使用正确的选择器语法并在选择器中指定正确的方法名称。 – rmaddy

+1

你有IBOutlet中连接正确,这可能会导致NSException –

回答

5

下面是一些代码,将工作用斯威夫特3:

override func viewDidLoad() { 
    super.viewDidLoad() 

    // #1 
    let myImage = UIImage(named: "myImage") 
    let imageView = UIImageView() 
    imageView.image = myImage 

    // #2 
    imageView.isUserInteractionEnabled = true 
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped)) 
    imageView.addGestureRecognizer(tapRecognizer) 

    // #3 
    imageView.translatesAutoresizingMaskIntoConstraints = false 
    view.addSubview(imageView) 
    // set imageView contraints 

} 

// #4 
func imageTapped(recognizer: UITapGestureRecognizer) { 
    print("Image was tapped") 
    let thePoint = recognizer.location(in: view) 
    let theView = recognizer.view 
} 
  • 1当你的代码是有点不同的,有些缺失,我相信这基本上是一样的。除非您需要在其他地方访问imageimageView,否则请在viewDidLoad的本地声明。 (我建议不要像命名UIImageView那样命名(image),因为这可能会让其他人读到您的代码时感到困惑。)

  • 2这里是我认为@rmaddy正确的地方。如果你使用的是Swift 3,选择器的正确语法是我所拥有的。这可能是我们的代码唯一的问题 - 记住UIImageView的默认值为isUserInteractioEnabled = true

  • 3您没有任何实际布局的代码。但是如果您使用自动布局(而不是帧),则基本语法将关闭自动调整,确保将视图添加到视图层次结构中,并设置约束。很多时候(大部分甚至是)您可以将它们设置为viewDidLoad,但如果您需要需要帧信息,请使用viewWillLayoutSubviewsviewDidLayoutSubviews

  • 4起初我以为你的水龙头功能没问题,但经过进一步的检查,事实并非如此。发件人不是被点击的视图,而是识别器。我在print语句后添加了两行代码。第一个将水龙头的CGPoint放入一个变量中。第二个将UIView附加到识别器(在这种情况下,imageView)到一个变量。此外,如果您需要知道imageView的子视图位于水龙头的区域中,请使用hitTest()方法。

编辑:

有人问我如何使用在水龙头执行功能的观点(在我的例子,imageView)。

首先,你的一件事不能做的就是把它作为参数传递。 iOS和macOS都无法通过他们的操作以这种方式工作。但是你有(至少)三种选择可供选择。 (他们没有使用标签属性,它在某些情况下是另一种选择。)

  • 1还有你的代码说你已经知道图像视图被窃听。这是一种可能的情况,因为您创建的每个手势只能附加到单个视图。如果这是你的场景,考虑在视图控制器级别声明你的图像视图,并在你的函数内编写你需要的代码。

  • 2但是,如果你有两个图像视图查看器,都附有敲击手势,并且希望他们能够根据哪个做一些被窃听?在这种情况下,您可以使用手势的view属性进行投射。骨架代码:

    let imageView1 = UIImageView() 
    let imageView2 = UIImageView() 
    let tapRecognizer1 = UITapGestureRecognizer(target: self, action: #selector(imageTapped)) 
    imageView1.addGestureRecognizer(tapRecognizer1) 
    let tapRecognizer2 = UITapGestureRecognizer(target: self, action: #selector(imageTapped)) 
    imageView2.addGestureRecognizer(tapRecognizer2) 
    
    
    func imageTapped(recognizer: UITapGestureRecognizer) { 
        print("Image was tapped") 
        let imageView = recognizer.view as? UIImageView 
        if imageView != nil { 
         //do something here 
        } 
    } 
    

    请注意,骨架在转换中可能有语法错误。逻辑是坚实的,我在网上写这篇文章,而不是Xcode。基本上将附加的UIView作为图像视图并检查nil。

  • 3,如果你有几个子视图,你想知道哪一个被窃听我通常使用的情况。在你的情况下,假设你有两个像上面那样的UIImageViews,但是你有连接到主视图的轻敲识别器?在这种情况下,您可以使用hitTest()方法。骨架代码:

    let imageView1 = UIImageView() 
    let imageView2 = UIImageView() 
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped)) 
    imageView1.addGestureRecognizer(self.view) 
    
    func imageTapped(recognizer: UITapGestureRecognizer) { 
        print("Image was tapped") 
        let p = recognizer.location(in: view) 
        if imageView1.layer.hitTest(p) != nil { 
         // do something here to imageView1 
        } else if imageView2.layer.hitTest(p) != nil { 
         // do something here to imageView2 
        } 
    } 
    

    我更喜欢使用图层,但观点有hitTest()法也。这个值是一个包含7个子视图的视图,可以用一个手势进行编码,如果你忽略了其中3个子视图的点击(并且点击主视图),你可以。

    关于最后一个,我已经有一段一个小例子项目。它包含一个带有两个彩色标签作为子视图的图像视图。当任一标签被轻敲时,计数器递增。我在我的答案中使用了1-2,我想我会把它放在GitHub存储库中。随意看看它:Image with Labels

+0

如果我想imageTapped,因为它的参数,因为我想要做一些事情,当它被点击的图像拍摄图像的功能......我得到的这个问题,只是说,如果要打印的东西当图像被窃听,但我想要对图像做点什么。 – tee

+1

你不能传递这样的参数。但是,在这里你可以做什么 - (1)如果你需要查看它是否被点击,使用'hitTest()'方法。我会为此添加更多代码。 (2)如果你已经*知道'UIImageView'被挖掘了 - 你可以用你已经显示的代码 - 然后在全局和更多的地方声明'UIImageView'函数做你需要的。 – dfd

+0

花了我30分钟来编辑编辑,对不起。但我有三个选项解释,两个与骨架代码。我还将一个小的Swift 3 Xcode项目添加到GitHub存储库。希望这可以帮助你! – dfd

0

更改参数类型如下:

func imageViewTapped(imageView:UITapGestureRecognizer? = nil) { 
    print("Image Clicked") 
} 
+0

您的签名不容易了解。如果函数被执行,它是**,因为**发件人 - 一个UITapGestureRecognizer - **不是**零!然而你声明“手势”是一个名为'imageView'的变量?再次,不容易理解。 – dfd