Bigair
Bigair

Reputation: 1592

UIGestureRecognizer not detected on subview

I made a UIView subclass and added a circle view on top right corner of the view. Then I added UIPanGestureRecognizer to the circle view.

The problem is that gesture is only recognized on left bottom part of circle where the circle is located over the super view.

How can I make entire circle to property detected gesture?

enter image description here

Following is entire class code of UIView subclass I made.

import UIKit

class ResizableImageView: UIView {


private let circleWidth: CGFloat = 40

var themeColor: UIColor = UIColor.magentaColor()

lazy var cornerCircle: UIView = {
    let v = UIView()

    v.layer.cornerRadius = self.circleWidth / 2
    v.layer.borderWidth  = 1
    v.layer.borderColor  = self.themeColor.CGColor

    let panGesture = UIPanGestureRecognizer(target: self, action: #selector(buttonTouchMoved) )
    v.addGestureRecognizer(panGesture)

    return v
}()





// Init

override init(frame: CGRect) {
    super.init(frame: frame)

    setupSubviews()
    configureSelf()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}



func setupSubviews() {

    // Add cornerButton to self and set auto layout
    addSubview( cornerCircle )
    addConstraintsWithFormat("H:[v0(\(circleWidth))]", views: cornerCircle) // Extension code for setting auto layout
    addConstraintsWithFormat("V:[v0(\(circleWidth))]", views: cornerCircle)
    addConstraint(NSLayoutConstraint(item: cornerCircle, attribute: .CenterX, relatedBy: .Equal, toItem: self, attribute: .Right, multiplier: 1, constant: 0))
    addConstraint(NSLayoutConstraint(item: cornerCircle, attribute: .CenterY, relatedBy: .Equal, toItem: self, attribute: .Top,   multiplier: 1, constant: 0))


}

func configureSelf() {

    // Set border
    layer.borderWidth = 1
    layer.borderColor = themeColor.CGColor
}




// Gesture Event

func buttonTouchMoved(gestureRecognizer: UIPanGestureRecognizer) {

    let point = gestureRecognizer.locationInView(self)
    print(point)

}


}

ViewController

import UIKit

class ImageViewCheckController: UIViewController {

let imageView: ResizableImageView = {
    let iv = ResizableImageView()
    return iv
}()


override func viewDidLoad() {
    super.viewDidLoad()

    title = "ImageViewCheck"

    view.backgroundColor = UIColor.whiteColor()

    setupSubviews()
}

func setupSubviews() {
    view.addSubview( imageView )

    view.addConstraintsWithFormat("V:|-100-[v0(200)]", views: imageView)
    view.addConstraintsWithFormat("H:|-50-[v0(100)]", views: imageView)

}

}

Upvotes: 0

Views: 543

Answers (1)

matt
matt

Reputation: 534895

Normally, there is no touch on a subview outside the bounds of its superview.

To change this, you will have to override hitTest(point:withEvent:) on the superview to alter the way hit-testing works:

override func hitTest(point: CGPoint, withEvent e: UIEvent?) -> UIView? {
    if let result = super.hitTest(point, withEvent:e) {
        return result
    }
    for sub in self.subviews.reverse() {
        let pt = self.convertPoint(point, toView:sub)
        if let result = sub.hitTest(pt, withEvent:e) {
            return result
        }
    }
    return nil
}

Upvotes: 3

Related Questions