Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

UITapGestureRecognizer

I'm trying to change the color of a square when the user taps on it. However, I seem to be missing something.

//
//  ViewController.swift
//  PlayingAround
//
//  Created by Mav3r1ck on 12/6/14.
//  Copyright (c) 2014 Mav3r1ck. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var fireButton: UIButton!

var coloredSquare = UIView()

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

        let singleTap = UITapGestureRecognizer(target: self, action: Selector("tapped"))
        singleTap.numberOfTapsRequired = 1
        //self.view.addGestureRecognizer(singleTap)
       self.coloredSquare.addGestureRecognizer(singleTap)
}

    func tapped() {
        println("it was tapped")
        self.coloredSquare.backgroundColor = UIColor .blackColor()
    }

    @IBAction func fireButtonPressed(sender: AnyObject) {



        let duration = 9.0
        let delay = 0.0
        let options = UIViewAnimationOptions.CurveLinear
        let damping = 0.5 // set damping ration
        let velocity = 1.0 // set initial velocity

        let size : CGFloat = CGFloat( Int(rand()) % 40 + 20)
        let yPosition : CGFloat = CGFloat( Int(rand()) % 500 + 8)

        coloredSquare = UIView()
        //coloredSquare.backgroundColor = UIColor.blueColor()
        coloredSquare.frame = CGRectMake(0, yPosition, size, size)
        self.view.addSubview(coloredSquare)

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

            // any changes entered in this block will be animated
            self.coloredSquare.backgroundColor = UIColor.redColor()
            self.coloredSquare.frame = CGRect(x: 320-size, y: yPosition, width: size, height: size)

            }, completion: { finished in
           self.coloredSquare.removeFromSuperview()
        })


    }




    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

2 Answers

I almost solved this, so I'd appreciate your feedback.

I added a Tap Gesture Recognizer in Main.Storyboard. The IBAction function is the same as your "tapped" function.

@IBAction func tapIt(sender: UITapGestureRecognizer) {
        println("it was tapped")
        self.coloredSquare.backgroundColor = UIColor .blackColor()
    }

In the "fireButtonPressed" function, I added .AllowUserInteraction to the animate options. This allows tapping the sqaures.

let options = UIViewAnimationOptions.CurveLinear | UIViewAnimationOptions.AllowUserInteraction

The problem is, the Tap Gesture Recognizer is not limited to coloredSquare. Tapping anywhere causes the squares to change.

I'm going to continue working on this. I'll update when I figure out how to restrict the taps to just coloredSquare.

Hi Eric,

Thanks for giving this a shot. I'm still hacking away at it as well. I've been thinking about moving it to Sprite Kit. But I'm not quite ready to give up on it yet.

Eric Wood

figured it out.. Try this

//
//  ViewController.swift
//  BlockGame4
//
//  Created by Mav3r1ck on 12/13/14.
//  Copyright (c) 2014 Mav3r1ck. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    let coloredSquare = UIView()
    var isSquareDead = false

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

        //Setting up the Square

        coloredSquare.backgroundColor = UIColor.blueColor()
        coloredSquare.frame = CGRect(x: 0, y: 120, width: 50, height: 50)
        self.view.addSubview(coloredSquare)

        let duration = 1.0
        let delay = 0.0
        let options = UIViewAnimationOptions.Autoreverse | UIViewAnimationOptions.Repeat | UIViewAnimationOptions.AllowUserInteraction
        let damping = 0.5
        let velocity = 1.0

        UIView.animateWithDuration(1.0, delay: 0.0, options: options, animations: {

            // any changes entered in this block will be animated
            self.coloredSquare.backgroundColor = UIColor.redColor()
            self.coloredSquare.frame = CGRect(x: 320-50, y: 120, width: 50, height: 50)
            self.coloredSquare.transform = CGAffineTransformMakeScale(1.5, 1.5)


            }, completion: nil)

        let tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
        view.addGestureRecognizer(tap)


    }



    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    func handleTap(gesture: UITapGestureRecognizer) {
        let tapLocation = gesture.locationInView(coloredSquare.superview)
        if coloredSquare.layer.presentationLayer().frame.contains(tapLocation) {
            println("Sqaure tapped!")

            if isSquareDead { return }
            isSquareDead = true

            UIView.animateWithDuration(0.7, delay: 0.0, options: .CurveEaseOut, animations: {
                self.coloredSquare.transform = CGAffineTransformMakeScale(1.25, 0.75)
                }, completion: { finished in
                    UIView.animateWithDuration(2.0, delay: 2.0, options: nil, animations: {
                        self.coloredSquare.alpha = 0.0
                        }, completion: { finished in
                            self.coloredSquare.removeFromSuperview()
                    })
            })
        } else {
            println("Square not tapped!")
        }
    }


}