Search code examples
iosswiftunrecognized-selector

Unrecognized selector error when defining tap gesture in custom view [Swift]


I'm creating a custom view from xib. I want to close the view when touched inside but selector is not recognized. I used it as;

  1. closeView
  2. self.closeView
  3. ToolTipView.closeView

none of them worked. Do you have any idea what am I doing wrong?


class ToolTipView: UIView {

    @IBOutlet private var contentView:UIView?

    override init(frame: CGRect) { // for using CustomView in code
        super.init(frame: frame)
        self.commonInit()
    }

    required init?(coder aDecoder: NSCoder) { // for using CustomView in IB
        super.init(coder: aDecoder)
        self.commonInit()
    }

    private func commonInit() {
        NSBundle.mainBundle().loadNibNamed("ToolTipView", owner: self, options: nil)
        guard let content = contentView else { return }
        content.frame = self.bounds
        content.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
        self.addSubview(content)
    }

    func showTip(viewToAlign: UIView){

        //some unrelated code

        UIApplication.sharedApplication().keyWindow!.addSubview(contentView!)

        contentView!.userInteractionEnabled = true           
        let tapGesture = UITapGestureRecognizer.init(target: contentView, action: #selector(self.closeView))
        contentView!.addGestureRecognizer(tapGesture)

    }

    func closeView() {
        self.removeFromSuperview()
    }
}

Solution

  • It turns out that it was related to part of my code where I said unrelated code.

    I was changing calculating relative position of my custom view. I was changing frame of contentView, which was the wrong part. Instead I manipulated self. Now everything work as I want.

    Working version my function:

    func showTip(viewToAlign: UIView, viewToAdd: UIView){
    
        self.userInteractionEnabled = true
    
        let relativeFrame = viewToAlign.convertRect(viewToAlign.bounds, toView: nil)
        let relativeCenter = viewToAlign.convertPoint(viewToAlign.bounds.origin, toView: nil)
    
        self.frame = CGRectMake(relativeFrame.minX - (self.frame.size.width + 5), relativeCenter.y - self.frame.size.height/2 , self.frame.size.width, self.frame.size.height)
    
        self.layer.masksToBounds = false
        self.layer.shadowOffset = CGSizeMake(0, 0)
        self.layer.shadowRadius = 5
        self.layer.shadowOpacity = 0.5
    
        viewToAdd.addSubview(self)
    
        tapGesture = UITapGestureRecognizer.init(target: self, action: #selector(closeView))
        viewToAdd.addGestureRecognizer(tapGesture!)
    }