如何在故事板中使UIImageView可点击(Swift)

35

我刚接触Swift(以及Xcode开发), 想知道如何在Storyboard中创建一个可点击的ImageView。我的目标是,当它被点击时,会显示另一个View Controller。


请看这里 http://stackoverflow.com/a/27235390/3810673 - Ian
9个回答

76
你可以添加tapGesture实现此功能。以下是代码:

class ViewController: UIViewController {

@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
    super.viewDidLoad()
    // create tap gesture recognizer
    let tapGesture = UITapGestureRecognizer(target: self, action: "imageTapped:")

    // add it to the image view;
    imageView.addGestureRecognizer(tapGesture)
    // make sure imageView can be interacted with by user
    imageView.userInteractionEnabled = true
}

func imageTapped(gesture: UIGestureRecognizer) {
    // if the tapped view is a UIImageView then set it to imageview
    if let imageView = gesture.view as? UIImageView {
        println("Image Tapped")
        //Here you can initiate your new ViewController

        }
    }
}

Swift 3.0

class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // create tap gesture recognizer
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.imageTapped(gesture:)))

        // add it to the image view;
        imageView.addGestureRecognizer(tapGesture)
        // make sure imageView can be interacted with by user
        imageView.isUserInteractionEnabled = true
    }

    func imageTapped(gesture: UIGestureRecognizer) {
        // if the tapped view is a UIImageView then set it to imageview
        if (gesture.view as? UIImageView) != nil {
            print("Image Tapped")
            //Here you can initiate your new ViewController

        }
    }
}

Swift 5.0

class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // create tap gesture recognizer
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.imageTapped(gesture:)))

        // add it to the image view;
        imageView.addGestureRecognizer(tapGesture)
        // make sure imageView can be interacted with by user
        imageView.isUserInteractionEnabled = true
    }

    @objc func imageTapped(gesture: UIGestureRecognizer) {
        // if the tapped view is a UIImageView then set it to imageview
        if (gesture.view as? UIImageView) != nil {
            print("Image Tapped")
            //Here you can initiate your new ViewController

        }
    }
}

9
虽然这是一种可能性,但是用图片创建 UIButton 比让图片可点击要好得多。当添加无障碍选项时,你会感激我的建议。 - vrwim

34

你甚至可以更加简单地通过Storyboard使图像可点击,而无需任何编码。

  • 首先,在Storyboard中将UITapGestureRecognizer拖到你的UIImageView上。
  • 然后使用@IBAction func imageClicked(_ sender: Any) {}在你的代码中创建你想要运行的操作。
  • 接下来,在文档大纲(Document Outline)中选择手势识别器,切换到连接检查器(Connection Inspector Tab),并将“Sent Actions” -> “Selector”拖到你的UIViewController中,然后选择之前创建的适当操作。
  • 最后,你需要在身份检查器(Identity Inspector)和属性检查器(Properties Inspector)中都勾选图片视图的User Interaction Enabled复选框。

完成了,一个完全可点击的UIImageView,除了明显要调用的函数外,没有任何需要编写的代码。但是,如果你想要推动一个转场(segue),那么你可以使用手势识别器的Triggered Segues而不是Sent Actions,从而完全没有编码。

虽然Storyboard有其局限性,但没有必要为可点击的图像编写代码。 ;)

enter image description here


从你身上学到了很多,非常尊敬! - Wangdu Lin
你得到一个饼干。 - xTwisteDx
2
尽管我在Identity Inspector中勾选了“启用用户交互”,但我仍然需要在viewDidLoad()中显式设置:fooImage.isUserInteractionEnabled = true才能使其正常工作(Xcode的bug?还是其他原因?我不知道)。 - MD TAREQ HASSAN
2
@HassanTareq 请在身份检查器和属性检查器中都设置“用户交互启用”,这对我起作用了。 - Giorgio Barchiesi

5
我建议创建一个没有文本的UIButton,并将其设置为所需的图像。之后,您可以从图像CTRL-drag到要进行segue的视图控制器中。或者您可以在视图控制器的代码中创建一个IBAction手动segue。

这个方法很好用。你也可以配置嵌入在按钮中的UIImageView。它避免了旧技巧——重叠一个带有透明按钮的UIImageView所产生的混合层问题。 - Bob Wakefield

4

如果您使用的是Swift 3.0版本,请尝试以下代码:

override func viewDidLoad() {
super.viewDidLoad()

let tap1 = UITapGestureRecognizer(target: self, action: #selector(tapGesture1))
imageview.addGestureRecognizer(tap1)
imageview.isUserInteractionEnabled = true
}
func tapGesture1() {
    print("Image Tapped")
}

2
在故事板中设置图像视图用户交互已启用,然后使用此方法获取。
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{
    UITouch *touch = [touches anyObject];

    if ([touch view] == yourImageView)
    {
            //add your code for image touch here 
    }
}

2
首先创建一个图片视图。然后编写以下代码:override func viewDidLoad() { super.viewDidLoad() }
let tap = UITapGestureRecognizer(target: self, action:          #selector(tapGesture))
imageview.addGestureRecognizer(tap)
imageview.isUserInteractionEnabled = true
}
func tapGesture() {
    print("Image View Tapped")
}

在您的视图控制器中。

UITapGestureRecognizer方法使所有内容可点击。


1
我通过设置用户交互enable = true来实现这一点。
在TouchesBegan中,下面的代码也很简洁明了...
ImageView也在StackView中。
if let touch = touches.first {
   if touch.view == profilePicture {
      print("image touched")
   }
}

1

好的,虽然你可以像上面提到的那样使用UITapGestureRecognizer,但如果你需要快速完成项目并且只关心应用程序的功能,最简单的方法是使用一个没有文本的透明按钮覆盖你的UIImageView,然后使用它来编写任何你想要的代码。当然,如果你正在制作一个非常重要的项目或其他什么东西,这种方法将不被推荐,但如果你只想制作一个快速应用程序(比如为某个会议制作一个非常简单的MVP),这种方法应该可以正常工作。


0

在我看来,合理的方法是创建UIImage的扩展...

这是我找到的代码...

public typealias SimpleClosure = (() -> ())
private var tappableKey : UInt8 = 0 
private var actionKey : UInt8 = 1 

extension UIImageView {
    
    @objc var callback: SimpleClosure {
        get {
            return objc_getAssociatedObject(self, &actionKey) as! SimpleClosure
        }
        set {
            objc_setAssociatedObject(self, &actionKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    var gesture: UITapGestureRecognizer {
        get {
            return UITapGestureRecognizer(target: self, action: #selector(tapped))
        }
    }
    
    var tappable: Bool! {
        get {
            return objc_getAssociatedObject(self, &tappableKey) as? Bool
        }
        set(newValue) {
            objc_setAssociatedObject(self, &tappableKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
            self.addTapGesture()
        }
    }

    fileprivate func addTapGesture() {
        if (self.tappable) {
            self.gesture.numberOfTapsRequired = 1
            self.isUserInteractionEnabled = true
            self.addGestureRecognizer(gesture)
        }
    }

    @objc private func tapped() {
        callback()
    }
}

使用方式应该如下

    @IBOutlet weak var exampleImageView: UIImageView! {
    didSet {
        self.exampleImageView.tappable = true
    }
}override func viewDidLoad() {
    super.viewDidLoad()
    self.exampleImageView.callback = {
         //TODO: Here you put the On click code.
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接