2

So I've got a UIView that contains a UIScrollview. Inside the scroll view is an array of UIViews, each of which contains a UILabel and a UIButton. I'd like to make it so that touching and then dragging on the button inside the view inside the scrollview will still scroll, since that's not the case by default.

I'm fairly new to iOS programming so this might be a stupid question, forgive me.

Justin
  • 71
  • 7

2 Answers2

2

Turns out this is fairly easy. I got my answer from one of the answers to this question: UIButton touch is delayed when in UIScrollView

What you need to do is subclass your UIScrollview, then paste the following code:

override func touchesShouldCancelInContentView(view: UIView) -> Bool {

    if view is UIButton {
        return  true
    }

    return  super.touchesShouldCancelInContentView(view)
}

Important: you need to have your content touches cancellable, and "delays content touches" needs to be false. You can do this in code by setting scrollview.delaysContentTouches to false, or in Interface Builder in the Scrollview attributes:

enter image description here

Community
  • 1
  • 1
Justin
  • 71
  • 7
0

I had a similar issue with a button and label embedded in a container view, inside a table cell. Touch events were being intercepted by the button.

If you don't need the button to highlight on press, then what I did was to use a UIView with a tap gesture recognizer instead of the button.

let fakeButtonView = UIView()
fakeButtonView.translatesAutoresizingMaskIntoConstraints = false
fakeButtonView.backgroundColor = UIColor.whiteColor()

let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(buttonTapped))
fakeButtonView.addGestureRecognizer(gestureRecognizer)

let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = ...
label.numberOfLines = 1
label.textAlignment = .Center
label.lineBreakMode = .ByTruncatingTail
label.minimumScaleFactor = 0.5
label.font = UIFont.systemFontOfSize(17.0)

fakeButtonView.addSubview(label)
fakeButtonView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-5-[label]-5-|",
options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["label": label]))
fakeButtonView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[label]|",
options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["label": label]))

container.addSubview(fakeButtonView)

// Constraints from button to container
//
// ...
Yasir
  • 2,312
  • 4
  • 23
  • 35
  • thanks, I may end up using this, but I'm trying to figure out how to implement touchesShouldCancelInContentView specifically. I think that learning that may help me with other things down the line. – Justin Aug 16 '16 at 22:16
  • 1
    See the answer I just posted if you're still interested — I figured out how to do this in a drop-dead simple way. Way less code, and I still get to use the button states – Justin Aug 16 '16 at 22:41
  • Thanks, will give it a try when I have a chance. Button states are definitely a bonus! – Yasir Aug 16 '16 at 23:31