如何使UIImageView可以兼容并使它做某事? (迅速)

时间:2015-02-15 01:18:06

标签: xcode swift uiimage touch

(我刚刚开始使用Swift,并且对编程比较新,所以请耐心等待。)我试图在屏幕上显示随机块,用户必须点击它们才能使它们消失。我已经能够创建块,但我不知道如何实际使它们可以应用。有人可以帮帮我吗?到目前为止,这是我的代码:

func createBlock(){

    let imageName = "block.png"
    let image = UIImage(named: imageName)
    let imageView = UIImageView(image: image!)

    imageView.frame = CGRect(x: xPosition, y: -50, width: size, height: size)
    self.view.addSubview(imageView)



    UIView.animateWithDuration(duration, delay: delay, options: options, animations: {

        imageView.backgroundColor = UIColor.redColor()

        imageView.frame = CGRect(x: self.xPosition, y: 590, width: self.size, height: self.size)

        }, completion: { animationFinished in


            imageView.removeFromSuperview()


    })



}

这是新代码:

func createBlock(){


    let imageName = "block.png"
    let image = UIImage(named: imageName)
    let imageView = UIImageView(image: image!)

    imageView.frame = CGRect(x: xPosition, y: -50, width: size, height: size)
    self.view.addSubview(imageView)

    imageView.userInteractionEnabled = true
    let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector("imageTapped"))
    imageView.addGestureRecognizer(tapRecognizer)

    func imageTapped(gestureRecognizer: UITapGestureRecognizer) {
        let tappedImageView = gestureRecognizer.view!
        tappedImageView.removeFromSuperview()
        score += 10
    }



    UIView.animateWithDuration(duration, delay: delay, options: options, animations: {

        imageView.backgroundColor = UIColor.redColor()
        imageView.frame = CGRect(x: self.xPosition, y: 590, width: self.size, height: self.size)

        }, completion: { animationFinished in


            imageView.removeFromSuperview()


    })



}

5 个答案:

答案 0 :(得分:32)

创建视图后,您需要将其userInteractionEnabled属性设置为true。然后你需要附加一个手势。

imageView.userInteractionEnabled = true
//now you need a tap gesture recognizer
//note that target and action point to what happens when the action is recognized.
let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector("imageTapped:"))
//Add the recognizer to your view.
imageView.addGestureRecognizer(tapRecognizer)

现在你仍然需要这个函数,在这种情况下是imageTapped:,这是识别手势时动作发生的地方。已识别的手势将作为参数发送,您可以找到从手势视图属性中点击的图像。

func imageTapped(gestureRecognizer: UITapGestureRecognizer) {
    //tappedImageView will be the image view that was tapped.
    //dismiss it, animate it off screen, whatever.
    let tappedImageView = gestureRecognizer.view!
}

答案 1 :(得分:4)

在swift 3.0中:

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

目标方法:

func imageTapped(sender: UIImageView) {
    print("image tapped")
}

答案 2 :(得分:2)

我之前的回答对于向UIImageView添加点击识别器仍然是准确的,但是对于动画视图来说,这还不够。如果您实际上正在创建一个游戏,那么您可能想要查看SpriteKit,因为它实际上是为此量身定制的。但是,这可以通过普通的UIKit来完成。我测试了两种方法,它们都有效。

这两种方法在实际设备上的效果要好于模拟器

方法1,更简单但稍微不那么精确 在我的测试中慢了十分之一。

不是向UIImageView添加点按手势,而是将手势添加到超级视图。在数组属性中保留对块的引用,并检查是否有任何块被窃听拦截。

class ViewController: UIViewController {
    let size = CGFloat(40)
    let xPosition = CGFloat(14)
    let options = UIViewAnimationOptions.Autoreverse
    var blocks = [UIImageView]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Adding recognizer to the whole view.
        let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector("screenTapped:"))
        view.addGestureRecognizer(tapRecognizer)
        blocks.append(createBlock())
    }

    //changed to return the created block so it can be stored in an array.
    func createBlock() -> UIImageView {
        let imageName = "block.png"
        let image = UIImage(named: imageName)
        let imageView = UIImageView(image: image!)
        imageView.frame = CGRect(x: xPosition, y: -40, width: size, height: size)
        self.view.addSubview(imageView)
        UIView.animateWithDuration(2, delay: 0.0, options: options, animations: {
            imageView.backgroundColor = UIColor.redColor()
            imageView.frame = CGRect(x: self.xPosition, y: 590, width: self.size, height: self.size)
            }, completion: { animationFinished in
                imageView.removeFromSuperview()
                self.blocks.append(self.createBlock())
        })
        return imageView
    }

    func screenTapped(gestureRecognizer: UITapGestureRecognizer) {
        let tapLocation = gestureRecognizer.locationInView(view)
        //This is to keep track of the blocks to remove from the array.
        //If you remove them as you iterate the array, and you have more than 
        //one block to remove, you may end up removing the wrong block
        //or with an index out of bounds.
        var removeBlocks = [Int]()
        for (index, block) in enumerate(blocks) {
            //this is the frame of the view as we see it on screen.
            //unfortunately block.frame is not where we see it making a recognizer
            //on the block itself not work.
            if block.layer.presentationLayer().frame.contains(tapLocation) {
                //Then this block was clicked.
                block.removeFromSuperview()
                removeBlocks.append(index)
            }
        }
        //get the indexes ro remove backwards so we are removing from
        //back to front.
        for index in removeBlocks.reverse() {
            blocks.removeAtIndex(index)
        }
    }

}

SpriteKit之外的方法2,最佳性能

在方法二中,您将UIView子类化,并将主视图设置为它而不是UIView。您只需要覆盖单个方法。为方便起见,我将块数组存储在视图中。

首先是TouchView。

import UIKit

class TouchView: UIView {
    var blocks = [UIImageView]()
    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        // ignoring multiple touches for now
        if touches.count == 1 {
            if let touch = touches.first as? UITouch {
                let touchLocation = touch.locationInView(self)
                //This is to keep track of the blocks to remove from the array.
                //If you remove them as you iterate the array, and you have more than
                //one block to remove, you may end up removing the wrong block
                //or with an index out of bounds.
                var removeBlocks = [Int]()
                for (index, block) in enumerate(blocks) {
                    //this is the frame of the view as we see it on screen.
                    //unfortunately block.frame is not where we see it making a recognizer
                    //on the block itself not work.
                    if block.layer.presentationLayer().frame.contains(touchLocation) {
                        //Then this block was clicked.
                        block.removeFromSuperview()
                        removeBlocks.append(index)
                    }
                }
                //get the indexes ro remove backwards so we are removing from
                //back to front.
                for index in removeBlocks.reverse() {
                    blocks.removeAtIndex(index)
                }
            }
        }
    }
}

现在ViewController看起来像:

import UIKit

class ViewController: UIViewController {
    let size = CGFloat(40)
    let xPosition = CGFloat(14)
    let options = UIViewAnimationOptions.Autoreverse
    var blocks = [UIImageView]()
    // computed get only property for conveniece of accessing block array
    var touchView:TouchView {
        get {
            return self.view as! TouchView
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        touchView.blocks.append(createBlock())
        // Do any additional setup after loading the view, typically from a nib.
    }

    func createBlock() -> UIImageView {
        let imageName = "block.png"
        let image = UIImage(named: imageName)
        let imageView = UIImageView(image: image!)
        imageView.frame = CGRect(x: xPosition, y: -40, width: size, height: size)
        self.view.addSubview(imageView)
        UIView.animateWithDuration(2, delay: 0.0, options: options, animations: {
            imageView.backgroundColor = UIColor.redColor()
            imageView.frame = CGRect(x: self.xPosition, y: 590, width: self.size, height: self.size)
            }, completion: { animationFinished in
                imageView.removeFromSuperview()
                self.touchView.blocks.append(self.createBlock())
        })
        return imageView
    }
}

在我的测试中,这似乎工作得很好,即使是快速动画的&#34;块&#34;。再说一遍,如果你打算制作一款完整的游戏,你应该真正看看SpriteKit。有一个非常简单的教程here可以帮助您入门。如果您可以从我之前的答案中删除接受的答案,这将有助于其他人不要走错路径,除非他们只是想要向不移动的UIImageView添加手势。

答案 3 :(得分:1)

而是使用UIImageView,您可以尝试使用Custome UIButton并用您的默认按钮图像替换。因此,您不需要为每个UIImageView添加UITapGestureRecognizer。与这种方法相比,@ JeremyPope的方法实际上更有效。

处理UIButton非常简单,它是UIControl的子类,因此有hideenabled等属性,您可以按照自己的方式操作它们。

您需要做的是以编程方式创建UIButton,就像您创建UIImageView一样。创建它们的方式类似于UIImageView,请在create UIButton programmaticly in Swift上阅读更多内容。

下图是自定义UIButton的外观。

enter image description here

如果您需要更多信息,请留言。

答案 4 :(得分:1)

默认情况下,未启用图像视图用户交互,因此请务必将其关闭。

let myImageView = UIImageView()
myImageView.isUserInteractionEnabled = true