2

I moved all my UIElements in a scrollView to avoid a loaded UIViewcontroller. But now the GestureRecognizers on the view does not work anymore.

My View hierarchy looks like this:

  • UIViewController (SingleEventController)
    • UIScrollView (EventScrollView)
      • UIView (contentView)
        • UILabel, UIView, UITableView, etc.

This looks like a common problem because I found quite much on Stackoverflow like: Example 1 Example 2. Still, I was not able to solve my case..

Simplified code in my EventScrollView looks like this:

let locationLabel: UILabel = {
    let label           = UILabel()
    label.text          = "Standort"
    label.isUserInteractionEnabled = true //Important!
    return label
}()

override init(frame: CGRect) {
    super.init(frame: frame)
    self.isUserInteractionEnabled = true //not needed!
    contentView.isUserInteractionEnabled = true //Important!
}

func setupViews() {
    guard let parent = parentVC else { return }
    let locationTap = UITapGestureRecognizer(target: parent, action: #selector(parent.openInGoogleMaps))
    locationTap.cancelsTouchesInView = false //Important!

    addSubview(contentView)
    contentView.addSubview(locationLabel)
    locationLabel.addGestureRecognizer(locationTap)
}

What step am I missing? Btw, clicks on a row of a UITableView inside the contentView don't get registered either.

Noodledew
  • 509
  • 4
  • 19
  • Your view hierarchy example doesn't mention a UITableView or its cells? – Scriptable Sep 24 '18 at 12:55
  • I meant that with "etc." Shouldn't really matter because the label-clicks aren't registered either. – Noodledew Sep 24 '18 at 12:56
  • okay, I just wanted to understand where the tableView sat in the hierarchy. It sounds like you have alot of conflicting gesture recognisers, you may need to specify which can work together and which cant. I imagine a long tap on your tableView would possibly work, but a normal tap wouldn't. See http://developer.apple.com/library/ios/documentation/uikit/reference/UIGestureRecognizerDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UIGestureRecognizerDelegate/gestureRecognizer%3ashouldRecognizeSimultaneouslyWithGestureRecognizer%3a – Scriptable Sep 24 '18 at 12:57
  • Aactually I only have this one gesture recognizer. Long taps don't work either. – Noodledew Sep 24 '18 at 12:59
  • Yes, but the ScrollView has pan and pinch recognisers, the tableView has tap and pan recognisors. – Scriptable Sep 24 '18 at 13:01
  • And how do I avoid this conflict? – Noodledew Sep 24 '18 at 13:04
  • Look at the link I provided above, you can specify which gestures can work at the same time. working with a tableView inside a scrollView can be a little tricky because they both scroll to fit content – Scriptable Sep 24 '18 at 13:15
  • Well I don't really understand how I should adapt it but thanks I guess – Noodledew Sep 24 '18 at 13:18
  • I'm not 100% sure myself, which is why I haven't posted an answer. It's a while since I have implemented a tableView inside a scrollView. So I am just trying to point you in the right direction as noone else has yet answered. If I remember rightly, you need to use that method to define which gestures can be triggered at the same time. I'll try and find an example – Scriptable Sep 24 '18 at 13:20
  • See this question, there are some suggestions on how to workaround it: https://stackoverflow.com/questions/21677268/uitableview-inside-uiscrollview-not-receiving-first-tap-after-scrollling – Scriptable Sep 24 '18 at 13:24
  • Okay, I appreciate that but I don't think it has something to do with the tableviews because the problem is still there If I remove them. – Noodledew Sep 24 '18 at 13:26
  • @Noodledew - you say *"the GestureRecognizers on the view does not work anymore"* ... from the little bit of code you posted, it's tough to tell what's actually "not working". Does the tap gesture trigger, but the function doesn't get called? Your approach of `target: self, action: #selector(parent.openInGoogleMaps)` looks like it could be problematic. – DonMag Sep 24 '18 at 15:41
  • This means it worked before I put all the views in the scrollView (or actually the contentView). I am pretty sure it also worked after that & before I updated to swift 4.2 but this could also be wrong.. I tried to set up the gestureRecog. in the parentVC (SingleEventVC) aswell but this does not work either. The method does not get called, but if I detect the the hits with :hitTest: it actually does work. But then the scrolling is disabled so I can't really build a workaround (or at least I dont know how) – Noodledew Sep 25 '18 at 08:11

2 Answers2

6

I found my issue in the comments of this Answer. The contentView inside my scrollView which got all the other views in it, had 0 height and so-on it could not be clicked. By giving the view a height, it worked:

contentView.heightAnchor.constraint(equalTo: self.frameLayoutGuide.heightAnchor, multiplier: 1).isActive = true
Noodledew
  • 509
  • 4
  • 19
0

In my case, I had a UIView (Content view) into a UIScrollView, this UIView had an UIStackView into itself and then differents UIView's (like buttons) embedded into UIStackView, every one component had a height property except content view (UIView), so setting height property based on child component (UIStackView) worked for me!

splitItAllMainView.heightAnchor.constraint(equalTo: self.splitItAllStackView.heightAnchor, multiplier: 1).isActive = true