5

I placed a small UIView inside a UITableViewCell.

  • In case of a tapping on such UIView, I would like to open a popup.
  • In case of a tapping outside such UIView, I would like to perform what it's defined in the UITableView "didSelectRowAtIndexPath" function.

What it's happening at the moment is that when I click on the view both things happen: the popup is opened and the "didSelectRowAtIndexPath" function is trigged.

How can I make sure that when I click on that UIView the "didSelectRowAtIndexPath" function is not triggered?

current implementation:

I defined a UITapGestureRecognizer for the UIView inside my custom UITableViewCell class.

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(MyCustomTableViewCell.clickOnHelp(_:))) myClickAreaUIView.addGestureRecognizer(tapGesture)

Daniele B
  • 19,801
  • 29
  • 115
  • 173
  • 2
    may I suggest to change the UIView to a UIButton and handle the touch with a touchUpInside on the button? – ddb Aug 24 '16 at 12:24
  • 1
    Where and how do you handle uitapgesture on the view? – Miknash Aug 24 '16 at 12:26
  • 1
    I think there's a way to set up views to not forward their touch events. I think buttons do that by default, but things like views do not. – nhgrif Aug 24 '16 at 12:26
  • yes, I am actually currently using a `UITapGestureRecognizer` – Daniele B Aug 24 '16 at 12:28
  • You can take button in view. and manage it's click event. – Keyur Hirani Aug 24 '16 at 12:29
  • 1
    add your code that how you adding tapgesture and managing your cell, because default behavior will not result as mentioned by you in question. I mean, for example you have cell and you put uiview in it and add gesture recognizer on it, and then click to that view, it will not called `didselectrowatindexpath`. This is the default behavior. – Ketan Parmar Aug 24 '16 at 12:44
  • Hi Ketan, I added my current implementation code. – Daniele B Aug 24 '16 at 12:55
  • By any chance are you drawing a custom shape in that UIView? – Dravidian Aug 24 '16 at 12:59
  • @Dravidian no, It's just an empty UIView, constrained by the position and width of some other views – Daniele B Aug 24 '16 at 13:02
  • @ddb do you have any idea if a plain `UIView` can achieve the same of a `UIButton` by changing some properties? – Daniele B Aug 24 '16 at 13:07
  • I wrote an answer, please try it, @DanieleB – ddb Aug 24 '16 at 13:18
  • Have you checked this, @Daniele B? http://stackoverflow.com/questions/27429652/detecting-uibutton-pressed-in-tableview-swift-best-practices – pedrouan Aug 24 '16 at 13:45

6 Answers6

1

The best solution I suggest is to change the UIView to a UIButton and handle the touch with a touchUpInside on the button.

This way you will reach your objective, as UIButton automatically prevents touch event forwarding to superview

ddb
  • 2,423
  • 7
  • 28
  • 38
  • This answer suggests that one change their current implementation. Some designs may not work with UIButtons instead of UIViews.. – programmingandroid Apr 18 '18 at 10:15
  • @programmingandroid you may be right, but it's quite uncommon someone tries to make an UIView behave as an UIButton without using an UIButton :))) also I have to say that an UIButton is an UIView – ddb Apr 19 '18 at 14:55
0

Try setting the inner view's exclusiveTouch property to true.

cell.tapView.exclusiveTouch = true
Nirav D
  • 71,513
  • 12
  • 161
  • 183
jlew
  • 10,491
  • 1
  • 35
  • 58
0

I suggest to implement the following method of UIGestureRecognizerDelegate like below

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    print("in shouldReceiveTouch")
    gestureRecognizer.delegate = self
    if ([...]){ // touch location is in the UIView
        print("touching UIView")
        return false // prevent from forwarding touch to superview
    } else {
        println("touching elsewhere")
        return true
    }
}
ddb
  • 2,423
  • 7
  • 28
  • 38
  • Hi ddb! I solved the problem by changing the UIView to a UIButton and handling the touch with a touchUpInside on the button. If you are going to write an answer about that, I am going to accept it as the proper answer to this issue. Many Thanks! – Daniele B Aug 24 '16 at 17:17
  • could you write another answer, where you specify that solution alone? By accepting this answer, I would also accept the first part, which I haven't verified. – Daniele B Aug 24 '16 at 17:46
0

You should use this method from UIGestureRecognizerDelegate

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
   return false
}
0

Create a customClass for your UIView lets say CustomView of type UIView

Connect your UIView's @IBOutlet conforming to tableViewCell of type CustomView

In CustomView class call this function

override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
    super.pointInside(point, withEvent: event)

    return CGRectContainsPoint(self.bounds, point)
}

This will tell you whether or not the location at which user tapped was contained inside that UIView bounds or not, if it returns true do pop up in your UIGestureRecognizer functions and follow https://stackoverflow.com/a/18606840/6297658 , if false do the opposite

Community
  • 1
  • 1
Dravidian
  • 9,945
  • 3
  • 34
  • 74
  • i am looking forward to a solution to your prob, I could'nt check it , that would mean writing a whole new app, but did this work? – Dravidian Aug 24 '16 at 14:31
-1

just write this code inside cellForRowAtIndexPath() for did select prevent::

cell.selectionStyle = UITableViewCellSelectionStyle.None
Chirag Patel
  • 1,453
  • 1
  • 11
  • 21
  • 3
    didSelectRowAtIndexPath must work also, if user tap outside the subview, are you sure it will continue working? – ddb Aug 24 '16 at 12:34