'How to make UIScrollView inside a UIScrollView act simultaneously
I'm using a UIScrollView (UIScrollView_1) with paging enabled to move between 3 pages horizontally.
On the last page there is multiple UIScrollViews (each one in its own cell) (UIScrollView_2), which when scrolling horizontally to the right (forward) displays the last page (loaded accordingly to which cell that was scrolled).
But if scrolling in the left direction (backwards) I want the UIScrollView_1 to take over and scroll back.
This works as intended if I move my finger up and register a new touch-event. But I want it to act simultaneously between both the UIScrollViews, on the same pan.
|-------------UIScrollView_1----------|
| Page_1 | Page_2 |--UIScrollView_2---|
..................|...Page_3|Page_4...|
What I want is to make use of the shouldRecognizeSimultaneouslyWith in the UIGestureRecognizerDelegate.
But when I trying to delegate both the UIScrollViews' to the same ViewController the error 'UIScrollView's built-in pan gesture recognizer must have its scroll view as its delegate.' shows up on the ScrollView_2.
Any ideas on how to solve this?
UPDATE
Here's the cellForRow from page_3's UIViewController that not causing the error with the delegation, but where the UIScrollViews doesn't act simultaneously. (e.g need to move the finger up and down to detect the other UIScrollView.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "random", for: indexPath)
return cell
}
Here's the cellForRow that causing the 'UIScrollView's built-in pan gesture recognizer must have its scroll view as its delegate.'-error
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "random", for: indexPath)
let scrollView_1_VC = self.parent
cell.scrollView_2.panGestureRecognizer.delegate = scrollView_1_VC
return cell
}
Solution 1:[1]
I solved it.
The UIScrollView
's built-in UIPanGestureRecognizer
must be delegated to its own UIScrollView
as the error 'UIScrollView's built-in pan gesture recognizer must have its scroll view as its delegate.' said.
Instead subclass the UIScrollView
and create a second UIPanGestureRecognizer
which then acts simultaneously with the built-in UIPanGestureRecognizer
.
Step 1 - 4:
Subclass the cell's
UIScrollView
and create a secondUIPanGestureRecognizer
.Add the
UIGestureRecognizerDelegate
to theCellScrollView
and make theshouldRecognizeSimultaneouslyWith
returntrue
.
The secondUIPanGestureRecognizer
will now act simultaneously with the built-inUIPanGestureRecognizer
.
class CellScrollView : UIScrollView, UIGestureRecognizerDelegate {
var panGesture : UIPanGestureRecognizer!
override func awakeFromNib() {
panGesture = UIPanGestureRecognizer.init(target: self, action: nil)
addGestureRecognizer(panGesture)
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
- In the cellForRow, make the newly created UIPanGestureRecognizer delegate to the UIScrollView_1's UIViewController.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if medicines.isEmpty {
return tableView.dequeueReusableCell(withIdentifier: "emptyMedCell", for: indexPath)
}
let cell = tableView.dequeueReusableCell(withIdentifier: "random", for: indexPath)
let scrollView_1_VC = self.parent
cell.cellScrollView.panGesture.delegate = scrollView_1_VC
return cell
}
- Lastly, in the ScrollView_1's UIViewController let the shouldRecognizeSimultaneouslyWith return true.
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
Solution 2:[2]
I think you want to use something like
func gestureRecognizer(UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer:UIGestureRecognizer) -> Bool {
if page3 {
return true
}
}
On the UIViewController of ScrollView_2 and have the ScrollView_2's(not the gesture's) delegate as the ViewController,
ScrollView_2.delegate = self
UIPanGesture.delegate = ScrollView_2
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | shim |
Solution 2 |