Search code examples
iosswiftuitapgesturerecognizericarousel

How to attach a UIGestureRecognizer to the item view in icarousel swift code


Can somebody help me with adding a double tap recognizer for the center image in icarousel? In the swift code below you can see that the recognizer is programmed but it reacts everywhere on the screen and not only on the center image. I think I have to connect the gesture to newView but I tried several things but nothing solved the problem. There are a lot of examples in Objective-C but is Swift it is hard to find a solution on the forums. Hope somebody can tell me how to code it right.

import UIKit

let image0 = UIImage(named: "Afrojack")
let image1 = UIImage(named: "Calvin Harris")
let image2 = UIImage(named: "Martin Garrix")

var imageArray = [image0, image1, image2]


class ViewController: UIViewController, iCarouselDataSource, iCarouselDelegate
{
var items: [Int] = []

@IBOutlet weak var carousel: iCarousel!

override func awakeFromNib()
{
    super.awakeFromNib()
    for i in 0...2
    {
        items.append(i)
    }
}

override func viewDidLoad()
{
    super.viewDidLoad()
    carousel.type = .CoverFlow2
}


//show message when screen is tapped twice
func message(){
    let alertView = UIAlertView(title: "Oops!", message: "Something happened...", delegate: nil, cancelButtonTitle: "OK")
    alertView.show()
}


func numberOfItemsInCarousel(carousel: iCarousel!) -> Int
{
    return items.count
}


@objc func carousel(carousel: iCarousel!, viewForItemAtIndex index: Int, reusingView view: UIView!) -> UIView! {
    var newView = view
    var label: UILabel! = nil

    if newView == nil {
        //create new view

        //don't do anything specific to the index within
        //this `if (view == nil) {...}` statement because the view will be
        //recycled and used with other index values later
        newView = UIImageView(frame:CGRectMake(0, 0, 200, 200))
        //(newView as! UIImageView).image = UIImage(named: "page")
        newView.contentMode = .Center

        // set label properties
        label = UILabel(frame:newView.bounds)
        label.backgroundColor = UIColor.clearColor()
        label.textAlignment = .Center
        label.font = label.font.fontWithSize(50)
        label.tag = 1
        newView.addSubview(label)
    }
    else
    {
        //get a reference to the label in the recycled view
        label = newView.viewWithTag(1) as! UILabel!
    }

    //set item label
    //remember to always set any properties of your carousel item
    //views outside of the `if (view == nil) {...}` check otherwise
    //you'll get weird issues with carousel item content appearing
    //in the wrong place in the carousel

    //label.text = "\(items[index])"

    (newView as! UIImageView).image = imageArray[items[index]]

    newView.userInteractionEnabled = true

    let tapGesture = UITapGestureRecognizer(target: self , action: "message")
    tapGesture.numberOfTapsRequired = 2
    newView.addGestureRecognizer(tapGesture)

    return newView
}
}


func carousel(carousel: iCarousel!, valueForOption option: iCarouselOption, withDefault value: CGFloat) -> CGFloat
{

    if (option == .Spacing)
    {
        return value * 1.1
    }

    return value

}

Solution

  • Have you tried putting this code below the newView initialization?

    let tapGesture = UITapGestureRecognizer(target: self , action: "message")
    tapGesture.numberOfTapsRequired = 2
    newView.addGestureRecognizer(tapGesture)
    

    You should also delete that gesture in the viewDidLoad().

    EDIT

    You should place the recognizer after newView is 100% not nil, cause where it is now, newView can be nil (you have a if newView == nil) So place below all the if statement. It should work then.