This may work for you...
- Add the button as a subview of the scroll view
- set the scroll view's class to
PassTouchScrollView
- constrain the top of the button to the top of the scroll view, with a constant to place it vertically where you want it
- save the original constant, and update it when the scroll view scrolls to keep the button at its original y-position
Here is an example. Setup your scroll view and its content subviews as you normally would. Add your button as a subview, and constrain it to the top of the scroll view (not to its nearest neighbor). Set the scroll view's class to PassTouchScrollView
and connect it via @IBOutlet
. Connect the top-constraint via @IBOutlet
. Finally, connect the button's touchUpInside to the @IBAction
.
class PassTouchScrollView: UIScrollView {
override func touchesShouldCancel(in view: UIView) -> Bool {
if type(of: view) == UIButton.self {
return true
}
return super.touchesShouldCancel(in: view)
}
}
class PassThroughTestViewController: UIViewController, UIScrollViewDelegate {
@IBOutlet var theScrollView: PassTouchScrollView!
// constraint from top of button to top of scroll view
@IBOutlet var theButtonTopConstraint: NSLayoutConstraint!
var origTop: CGFloat = CGFloat(0)
override func viewDidLoad() {
super.viewDidLoad()
theScrollView.delegate = self
// save the original top constraint constant
origTop = theButtonTopConstraint.constant
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// when scrolling, update the top constraint to keep the button in-place
theButtonTopConstraint.constant = origTop + scrollView.contentOffset.y
}
@IBAction func didTap(_ sender: Any) {
print("tapped")
}
}