Implementing Gesture Recognizer as Segue Between Two View Controllers - ios

I am building an app called Single Photo. It is part of the "Learn to Code" iBook from Apple. I have built the original app, but now would like to expand on it.
I have added a second View Controller to Main.storyboard, as well as a UIImageView. However, I am not sure how to connect the two View Controllers together. I know that I have to add a segue, but I want to use a swipe gesture (like a photo gallery). It was recommended that I use UIPanGestureRecognizer as an alternative to UISwipeGestureRecognizer.
My confusion is that I am not sure how to implement either UIGestureRecognizer. Do I have to implement it as the segue between the two View Controllers? That would make sense.
tl;dr: How do I implement UIGestureRecognizer as a segue between two View Controllers?
EDIT: When I make some changes, I get the errors seen in the screenshot.
{1}: https://i.stack.imgur.com/JpViy.png {1}

I'd be using the Swipe gesture for that; for me it seems the most natural one for changing views with touch?
Whilst I don't know Swift yet sadly, this is how i would do it;
Add a gesture recogniser object onto your view using Interface Builder. You'll find it in the list of objects to add (Label, TextField, etc).
Add an IBAction method in your ViewController.m and declare it in your .h also like:
- (IBAction)handleSwipe:(UISwipeGestureRecognizer *)recognizer
Connect the gesture recogniser in Interface Builder to the IBAction as a 'Sent Action'
Make a new Segue by Control-clicking on the first view controller and dragging the blue line to the second view. Give this segue a unique identifier and set the style of segue.
Handle the gesture in the IBAction based on direction of swipe and call the segue from here;
[self performSegueWithIdentifer:#"theSegue" sender:self];
See if that gets you there

It is possible to use a UIPanGestureRecognizer or UISwipeGestureRecognizer to trigger a segue between view controllers, but it's by no means automatic.
I suggest using a UIPageViewController. That is a type of parent view controller that manages a set of child view controllers and lets you page between them, like a photo gallery or iBooks.
There is a demo application built into Xcode called PhotoScroller that will give you the idea. Search on PhotoScroller in the Xcode help system to find it. As I recall it's written in Objective-C, but it will at least give you the idea of how a page view controller works.

tl;dr: How do I implement UIGestureRecognizer as a segue between two View Controllers?
tl;dr: You would write an interactive custom view controller transition animation.

Create a segue in storyboard from the initial view controller to your new one. Then click on it and set the identifier to something. Place the first three lines of code in your initial controller's viewDidLoad changing 'MyVC' to your controller's class name. Then put the method in and put the name of the segue you created.
let gesture = UISwipeGestureRecognizer(target: self, action: #selector(MyVC.performChange))
gesture.direction = .right
self.view.addGestureRecognizer(gesture)
func performChange() {
self.performSegue(withIdentifier: "MySegue", sender: nil)
}

I think that this is a great question that could be answered best if divided into two different sections.
First thing is to understand how to use UIGestureRecognizer so that you can do different things when a user either taps, long presses, rotates, pinches, etc, a certain view. And then, if you want to make a transition between ViewControllers look different than the usual and add a cool effect to it, you will need to learn more about UIViewControllerAnimatedTransitioning, here is a great tutorial for that: APPCODA's Introduction to Custom View Controller Transitions and Animations.
Let's do an example and try to answer your question:
Let's say you have two ViewControllers, call them MainVC and SecondaryVC and you want to transition from one to the other after the user performs a certain gesture. As you previously mentioned, you can create a segue between them and set an identifier for it (so that you can perform the segue in code later on), you do this by clicking on the segue from your storyboard and going to the Attributes Inspector. For this example let's set the identifier to ToSecondaryVC and do something when the user swipes to the right anywhere in the view.
First thing, you need to initialize a UISwipeGesture object, so let's set the gesture recognizer by adding in the following to ViewDidLoad() of the MainVC class:
let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(MainVC.handleSwipeGesture(_:)))
// Adding detection for a right swipe
swipeGesture.direction = .Right
view.addGestureRecognizer(swipeGesture)
After this you want to create a function in which you will perform the segue (or do anything else really) after the swipeGesture has happened. Like so,
func handleSwipeGesture(gesture: UISwipeGestureRecognizer) {
performSegueWithIdentifier("ToSecondaryVC", sender: self)
}
I think that should do it for understanding how to use UIGestureRecognizer, and you can work on the other supported gestures by doing something very similar to what we did in this example. Hopefully that helps you a little bit! Best of luck!

Related

Unwind segue for interactive popviewcontroller guesture

For starter - I use Swift 3 and Xcode 8.
I am familiar with possibilities, how to do "unwind segue" from StoryBoards or programmatically ( for example, on UIButton click ).
But I'm interested, is there a possibility to use "unwind segue" for "interactive popviewcontroller" guesture?
By the "interactive popviewcontroller" guesture - I meant the option to dismiss / pop currently pushed UIViewController by swiping screen from left side to right.
The solution to your question is quite easy actually because it seems you are familiar with how to hook up buttons and use them to "unwind segues" as you named it or dismiss view controllers etc. What you can do is get a Swipe Gesture Recognizer from the object library.
Or a Screen edge Pan Gesture Recognizer (whichever works for you).
Add that recognizer to your VC in a storyboard and hook it up just like you hook up a UIButton.
Also, note that in the attributes inspector there are properties you can play with and set up the direction of the swipe, the number of touches needed, etc.
Check out the next pictures to see the rest of the implementations to handle:
I hope this helps :-)

To be able to cntrl-drag a segue between a view to a storyboard scene, what are the preconditions

I know I can ctrl-drag a segue from a UIButton to a scene, or from a UITableViewCell; but if I try to ctrl-drag from UIView, the drag destination scene doesn't 'light up,' and so I find I'm unable to create such a segue. I feel like I'm missing something basic here; or, perhaps this isn't possible? So: How do I create a segue between a view and a scene?
(In order to be crystal clear: this question is in the context of my trying to understand, generally, between what kinds of 'things' in a storyboard is it possible to ctrl-drag a segue.)
It needs to be an interactive item, like a button because you can tap it, same for a cell. If you want to be able to tap a plain UIView (or simple subclass) you should add a tap gesture recogniser to it and connect the segue to that.
Note that a segue dragged from the view controller to another view controller isn't triggered by any tap, it's to be triggered from code.
Any UIKit element that inherits from UIControl can be used as ctrl+drag segue origin point.
For your case, as #Wain suggested, you can use a tap gesture recogniser as the origin of the segue.

How to make a switch from one view to the same view?

I'm creating a questionnaire app for iOS in Swift.
I only need one view for all questions. How do I make one generic view and make it look like I'm switching to the new view with swipe when only replacing some of the data on that view?
Alright, so I think I know what you're attempting to do. You could possibly do it like this. This is assuming you have a custom UIViewController subclass with all your textfields and labels on it; I've named this QuestionaireViewController.
let nextVC = QuestionaireViewController()
self.navigationController?.pushViewController(nextVC, animated: true)
Additionally, you'll want to set up unwind segues each time you create a new VC, so that if needed the Navigation Controller can segue back.
You can add an animation to your subviews (UILabels, etc.) on screen. You can add a separate animation to each swipe gesture and have the animation move in the direction of the swipe. I like this because you have some flexibility in what you animate and how you do so.
You'll need to setup swipe gesture recognizers and methods for each to handle the swipe and animate the layers.
If you want a "traditional feeling" swipe left / swipe right type of setup you'll need to setup a push animation with a subtype for each direction.

Add Swipe Gesture to all View controllers in the project

I have set of 50 view controllers with back button. Now I need to add Left to Right swipe gesture for all view controllers in the project. When a swipe is triggered, I need to call back btn clicked event for respective view controller. It is difficult to add swipe gesture to each view controller. Is there any other way to do it with minimal changes to view controllers.
Thanks in advance.
Regards,
Bharath G
Well these other guys have told you why you may not need to do this, but assuming you do (not using UINavigationController || supporting pre iOs7 ..) then surely the easiest way to add to all of them would be to make a new UIViewController subclass, add the swipeRecogniser in viewDidLoad or similar, and then modify each of your 50 other controllers so that they all inherit from this one (i.e. abstract superclass..)
I would always have an abstract superclass above UIViewController in a project with 50 or so, obviously there is plenty of code that can be shared
Create a YourViewController class and implement your SwipeGesture method in viewDidLoad method.
In your 50 viewcontrollers .h file:
#interface ViewController : YourViewController
Let all your 50 viewControllers inherit from your YourViewController.
It should work automatically if the back button is visible. If you are displaying a leftBarButtonItem instead of the back button, the gesture will not be present by default. Also, if you are using a UINavigationBar but not a UINavigationController, you won't see this functionality.
If you are using a UINavigationController and your view controller's navigation item contains a leftBarButtonItem, it's still possible to add functionality for the swipe left to right gesture of the navigation controller, by attaching a delegate to the navigation controller's interactivePopGestureRecognizer.
Note: The Swipe to Back feature is introduced with iOS 7(i Hope you are Developing App fos iOS 7 or later)

How do I add a segue to an UIGestureRecognizer

I am building an app for the first time using Storyboards. I have a scene which I would like to have open another scene when there is a long tap on a particular button. I am able to add the UILongPressGestureRecognizer with no problem, but I can't figure out how to have that gesture be the segue to the other scene. Doesn't seem to matter what I Ctrl-Drag, nothing works.
Am I missing something obvious?
Thanks,
Ken
You can control-drag from your first controller's window to your second controller to create the segue, and then you can call performSegueWithIdentifier in your GestureRecognizer method.
It's now possible to do it all in your Storyboard visually. Every gesture recognizer has Triggered Segues in Connections Inspector.

Resources