Bigair Bigair - 1 year ago 119
Swift Question

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

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) )

return v

// Init

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


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)




import UIKit

class ImageViewCheckController: UIViewController {

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

override func viewDidLoad() {

title = "ImageViewCheck"

view.backgroundColor = UIColor.whiteColor()


func setupSubviews() {
view.addSubview( imageView )

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



Answer Source

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
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download