Search code examples
iosswiftxcodestoryboardxib

Add UI Gesture Recognizer to UIView instantiated from .xib


I'm working with Xcode 10.0 beta 4 and Swift 4 and I'm trying to add a UIGestureRecognizers specifically a UISwipeGestureRecognizer for both left and right swipes to a UIView that has been added as a subview to my main View Controller via a nib but unfortunately the gesture doesn't seem to be recognized when I actually perform the action in simulator. Here's a snippet of what is in my viewDidLoad():

    //Add gesture recognizer for when the calendar is swiped right.
    let grSwipeRight = UISwipeGestureRecognizer(target: self, action: #selector(swipeRight(sender:)))
    grSwipeRight.direction = UISwipeGestureRecognizer.Direction.right
    calendar.calendarDays.isUserInteractionEnabled = true
    calendar.calendarDays.addGestureRecognizer(grSwipeRight)

The swipeRight action in the selector is to a function that just contains a print() call and calendar is a reference to my UIView which is the class used in my .xib

class Calendar: UIView
{
@IBOutlet var calendarDays: UICollectionView!
let nibName = "Calendar"
var contentView: UIView?

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

    guard let view = self.loadViewFromNib() else { return }
    view.frame = self.bounds
    self.addSubview(view)
    self.bringSubviewToFront(view)
    contentView = view
    contentView?.isUserInteractionEnabled = true
}

private func loadViewFromNib() -> UIView? {
    let bundle = Bundle(for: type(of: self))
    let nib = UINib(nibName: nibName, bundle: bundle)
    return nib.instantiate(withOwner: self, options: nil).first as? UIView
}

I setup the .xib as a UIView using Interface Builder and set the class of the view to my Calendar class and the labels and such within my .xib show up properly its just when I add any Gesture Recognizer to either the calendar(View) or objects within my calendar the gesture isn't recognized. Is this even the proper way to do something like this or should I be taking a completely different approach?

Edit: I've included what my IB .xib and .storyboard look like if its helpful at all. Storyboard, xib


Solution

  • To be able to use gesture recognizers within my .xib, I used an override of awakeFromNib() as follows within my custom UIView Calendar class:

     override func awakeFromNib()
    {
        super.awakeFromNib()
        let touchTest = UITapGestureRecognizer(target: self, action: #selector(self.testTap(sender:)))
        testingLabel.isUserInteractionEnabled = true
        testingLabel.addGestureRecognizer(touchTest)
    }