在 Swift/Xcode 中使用图像作为手势识别器,出现的图像为零

Using image as gesture recognizer in Swift/Xcode, image coming up nil

我刚刚看完了大书呆子牧场 iOS 编程书,开始了我的第一本 'project'。我正在尝试将 UIImageView 用作按钮,但我的图像显示为 nil,我无法弄清楚原因。我是这方面的新手,所以任何帮助,甚至只是识别这段代码中没有意义的任何部分都是值得赞赏的。

import UIKit

class ImageScreenViewController: UIViewController {
    @ IBOutlet var imageView: UIImageView!

    // set up images 
    let picture1 = UIImage(named: "picture1")

    override func viewDidLoad() {
        super.viewDidLoad()

        // set image on screen
        imageView.image = picture1
    }

    // set up gesture recognizer
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(count(_:)))
        self.imageView.addGestureRecognizer(tapRecognizer)
        self.imageView.isUserInteractionEnabled = true
    }

    @objc func count(_ gestureRecognizer: UIGestureRecognizer) {
        print("tapped the picture")
    }
}

注意,图片 1 在 Assets.xcassets 中。

你可以在 viewDidload 中添加 tapRecongnize 因为在 init 方法中 imageview 没有初始化并且 return nil 这样你就可以像这样使用

    override func viewDidLoad() {
            super.viewDidLoad()
            imageView.image = picture1

            let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(count(_:)))
            self.imageView.addGestureRecognizer(tapRecognizer)
            self.imageView.isUserInteractionEnabled = true
}

对你的问题的一些解释

encodeWithCoder(_ aCoder: NSCoder) {
    // Serialize 
}

init(coder aDecoder: NSCoder) {
    // Deserialize 
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    //You used
}

要添加手势,您实际上不需要在此处实现编码器,因为它们用于存储状态

检查以下示例

1- ImageView 正在从 storyBoard 获取 2- 正在使用代码

添加 myImage

现在,Storyboard初步植入了序列化和反序列化机制 因此 imageView 是从情节提要中添加的 属性,因此那里不需要编码器

import UIKit

class ImageVC: UIViewController {


    @ IBOutlet var imageView: UIImageView!

    // set up images
    let picture1 = UIImage(named: "cc")

    //ImageView programmaticlly
    var myImage = UIImageView()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        // set image on screen
        imageView.image = picture1

        //setting properties and frame
        myImage.image = picture1
        myImage.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        self.view.addSubview(myImage)

        let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(count(_:)))
        self.imageView.addGestureRecognizer(tapRecognizer)
        self.imageView.isUserInteractionEnabled = true
    }

    // set up gesture recognizer
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        //adding gesture
        let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(count(_:)))
        self.myImage.addGestureRecognizer(tapRecognizer)
        self.myImage.isUserInteractionEnabled = true

    }

    @objc func count(_ gestureRecognizer: UIGestureRecognizer) {
        print("tapped the picture")
    }

}

就像你在上面实现 Algo 它不会崩溃,因为从情节提要中添加的属性可以直接在 didload 或 willAppear 中访问,因为我们永远不会从 superview 中删除它们,所以间接地序列化

第二种情况 - myImage - 以编程方式添加也可以从 superView 中删除并再次添加因此可以序列化意味着需要

var image: UIImage?

@IBOutlet weak var imageChoisie: UIImageView!

override func viewDidLoad() {
    super.viewDidLoad()
    
    imageChoisie.image = image // from Segue
    
    // Click on Image
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(count(_:)))
    self.imageChoisie.addGestureRecognizer(tapRecognizer)
    self.imageChoisie.isUserInteractionEnabled = true
}

@objc func count(_ gestureRecognizer: UIGestureRecognizer) {
    //print("tapped the picture")
    dismiss(animated: true, completion: nil) // back previous screen
}