My question is similar to a bunch of questions on stackoverflow (eg. swipe to delete in a UITableView which is embeded in a UIScrollView)
I need to implement a swipe action on a table view cell for a tableview controller which is a custom view embedded in a scrollview. However, the swipe events are not working properly and I understand the problem is that the UIScrollView is eating up the events for the UITableView so I tried out a bunch of options.
1) I subclassed the UIScrollView with the touchesBegan, touchesEnd etc methods but they never seem to get hit.
2) I could get hits on scrollViewWillBeginDragging but I am not sure how to call the responder for the UITableViewController from this.
3) I implemented a gesture recognizer in the tableviewcontroller class but that also didn't help.
I am confused as to how to go about so some code in Swift 3 syntax would be really helpful.
Related
I'm hurt to an edge case I guess?
Here is my current view hierarchy of the my problematic top most view controller.
UIView-> UIScrollView-> UIView-> UIStackView-> UICollectionView
My stack view contain multiple arranged views.
What happen is that for some reason my (non scrollable) UICollectionView is not responding to its delegate didSelectRow method.
It receive touch event, I can even see shoudlHighightCell being called. But impossible to get the didSelect method called.
It's a reusable component I'm using maybe more than 10 times all across my apps, but in this specific hierarchy, it's not working.
I've tried to remove some gesture, to fiddle with delay touch of the parent UIScrollView, but it's still not working.
Any clues?
Thanks!
I have the following scenario and need help in resolving a tricky situation in the scenario
There is an Xcode project and am using EzSwipeController for swipe (pagination effect) between three View Controllers at the moment.
In my first ViewController (this viewController is fetched from my custom dynamic framework as part of my requirement) -
Code to fetch ViewController:
userProfile.createProfileUI(userSession!) { result in
switch result {
case let .Success(profileViewController):
myDetailsVC = profileViewController //myDetailsVc is passed to EZSwipControllerDataSource array
default:
break
}
}
The other two ViewControllers are within my project storyboard
The Problem -
In the first ViewController, there is a tableView with canEditRowAtIndexPath enabled for few cells (phone numbers).
So when I try to swipe the row, the EZSwipeController responds first and
hence, I am not able to edit the row.
Here is what is happening - http://recordit.co/SOJgdeYchP
Here is what should happen - http://recordit.co/EBPSbjH31q
How do I handle this problem? Is there a way where I can override the default swipe controller action when I try to edit the row?
Please help!
Attach the swipe gesture recognizer to a parent in the hierarchy.
If you're using a UITableViewController, replace it with a UIViewController with a UITableView inside it. Then just drag the gesture recognizer onto the view controller in Storyboard, and it'll attach to the UIViewController's Content View instead of the UITableView.
Though at the end of the day, this is inherently a flawed approach, since swiping to flip pages in an app is only ever viable if you don't have any elements on the pages that also have swipe gestures in them. If you do, even if you code a workaround to make the gesture recognizer for the element in the view controller (in this case, a table view cell) fire instead of the page flipping swipe gesture, that creates an inconsistent user experience.
My suggestion: don't use a table view for such a form altogether. On top of the aforementioned mechanical UX issue, from a user perception perspective, there's nothing indicating visually that this is a table view and not just a scroll view, so there's nothing indicating to the user that swipe actions (Delete) are available. Use a scroll view instead, and take a different approach to deleting (Delete buttons that are always visible, Delete buttons that are only visible after the user hits Edit somewhere, etc.).
I have a UIPageViewController that displays images with Transition style scroll. I want to handle tap and pan gestures so in order to do that, I did a little hack of putting another view on top of the uipageviewcontroller and assign tap and pan gesture recognizers. In this case, i use -setViewControllers:direction:animated:completion: to perform swipes when i detect pan gestures to the left or right.
My problem is that when using -setViewControllers:direction:animated:completion: the datasource methods viewControllerBeforeViewController and viewControllerAfterViewController doesn't get called. Also the Delegate method -pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted: doesnt get callled.
what do i have to do for these methods to be called using setViewControllers?
I think you can get UIPageController's gesture recognisers, and use them for disable or enable UIPageController interaction by using method of UIGestureRecogniser:
- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer
If you use setViewControllers... methods of dataSource will not called, because you've provided viewControllers. Also you can handle completion of appearing animation in the completion block of this method. (you can call methods of the dataSource and delegate by self)
UPD
When I had same task, I implemented custom page view (based on UIScrollView in pages state), and used gesture recognisers of the scrollView to avoid scrolling, while pan gesture is recognised inside some page. I can't remember why I've implemented custom control, maybe because I can't find solution for same problem. I remember that my page view used dataSource to get views for the pages. I think you can implement custom control with your special logic.
Looks like UIPageViewController prevent UITableView to get touch events. My table view is placed in rightest page, so there is no potential problem to recognize gesture.
Is there any solutions of this problem?
Put this in your UIPageViewController's viewDidLoad function.
if let myView = view?.subviews.first as? UIScrollView {
myView.canCancelContentTouches = false
}
You can use this third party library which will allow the swipe gesture of the menu to have president over the uipageviewcontroller swipe
https://github.com/WinterKirk/MKSlidingTableViewCell
the important thing is that your whole view shouldnt only have these kind of cells cause then the uipageviewcontroller wont be able to swipe
but it works great in situations where you lets say have an image and comments under it and people should be able to delete the comments but swipe to the next pic on all other cells
I've added a swipe gesture recognizer to a UICollectionView on storyboard, with a Navigation Controller set up. I'm following this tutorial, except I'm using an UICollectionView for the first view.
The actual problem is that when I run the program, and I try to swipe, nothing happens. Everything else happens.
I have tried following the directions over and over and in different ways, but nothing seems to work. I've created another project and just using regular view, it worked fine, which makes me think that the UICollectionView is part of the problem. Am I putting the gesture recognizer in the wrong view? I've tried putting it in the UIView of the first View Controller and in the UICollectionView, but it doesn't work.
What am I doing wrong?
Clearly, if I left any information out or you need any information at all, please don't hesitate to ask in the comments for it.
EDIT: The connections of the swipe:
Did you have define in storyboard, the segue from swipe gesture to next viewController ?
did you swipe in the correct direction (this can be set in storybord, select your swipe, attributes inspector, Right / Left / UP / Down
The UICollectionView Is probably taking the gesture over and telling the controller that It cannot handle the collection view gesture and your swipe gesture at the same time. Implement the UIGestureRecognizerDelegate protocol and return YES in this delegate method - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer. Make sure that the delegate of the swipe gesture is set on the controller from the storyboard.