I have this button and I want when clicked to go to a different view controller. How do I do this?
- (void)buttonPressed:(UIButton *)button {
NSLog(#"Button Pressed");
}
NOTE: I am using theos.
If you are using a Storyboard to set up your views, you can ctrl-click and drag from the UIButton to the new view. This will set up a Segue for you which you can customise further.
In main.storyboard go right click the button, select a segue, drag to the view controller you want it to take you to.
You can present a UIViewController programatically in several ways.
Are you working for iOS8? use showViewController:sender: or showDetailViewController:sender: and presentViewController (if you want it modally)
Are you working for iOS7? use pushViewController, but be aware this method is deprecated
If you want to know more about how to use this methods you should read about UIViewController and UINavigationController at the documentation, hera are the methods I named explained in both Objective-C and Swift
Related
I am trying to write an app using UINavigationViewController. My first screen has several buttons on it, and on the click of each button, I want to segue to a UIViewController. I know that I can add a segue on each button, all pointed to the UIViewController that I want to go to, but I was wondering if it is possible to use only one segue that can be fired from each of the buttons.
If that is not possible, I was wondering if it was possible to open the second UIViewController from the first one, on button click, and provide a Back button like the UINavigationView provides. I did manage to get everything on this idea working, except for the back button. I mean I can put a standard button somewhere on the screen and go back, but I'd like the standard back button on the UINavigationView.
Phew! I'm not sure if that makes any sense.
I know that I could also use a tableview, but I'm trying to set this up with buttons.
Thanks
Edit: Thank you to everyone that answered. I now have this working. I would vote up the answers, but I don't have enough posts to do it. I appreciate the answers!
If you need to have separate action functions for each button, suggest that you segue from the main controller to the other controller and create a segue identifier (see xcode procedure below); then, use performSegueWithIdentifier from each of the button action functions. You can also take advantage of the prepareForSegue. To create the segue, control-drag from the left button in the controller in the storyboard to the controller you want to segue to and pick show.
Check the example code in swift that I did for a very similar problem in the SO reference
Linking View Controllers through button
You can embed the main controller in a navigation controller and that will give you the ability to navigate back. If you have multiple layers you can also use unwind segue.
Link each button to one single action (ex. buttonClick) in that ViewController and then perform the appropriate segue using pushViewController method on self.navigationController
-(IBAction)buttonClick:(id)sender {
if(sender.id == self.button1) {
DestinationViewController *vc = [[UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"VC_IDENTIFIER"];
[self.navigationController pushViewController:vc animated:YES];
}
Or if you already have that 1 segue defined in storyboards you can use
[self performSegueWithIdentifier:#"SegueIdentifier" sender:self];
And use that inside the buttonClick method. Using the 1st example, or the second one as long as the segue you setup in the storyboards is a push then you should already get the back button as that is the default behavior for pushing view controllers onto the navigation stack.
I am creating an app using iOS 5 SDK. I managed to push views using the Storyboard's Segues, but I cannot find the proper way to pop the current view and go back to the previous one.
I am not using any navigationController (the app doesn't have any top or bottom bars).
I don't think using modal or push segue the other way would be the solution as it instantiates a new controller.
Do I have to use a custom Segue with the opposite animation and deletion of the view at the end ? Or is there a better way ?
Storyboards in iOS 5 don't provide a "no-code" way to return from a segue -- that's something you'll need to implement yourself.
If you use "push" segues (which require a navigation controller), use the navigation controller's popViewControllerAnimated: method to undo the last push segue. (Or other methods to undo more; see the UINavigationController documentation.)
If you use "modal" segues, call dismissViewControllerAnimated:completion: on the view controller which presented the current view controller (which you can get from its presentingViewController property).
Update: In iOS 6 and later there's unwind segues for going "back" in a storyboard. It's still not a no-code solution -- and it shouldn't be, because you need to be able to do things like differentiating between "Done" and "Cancel" exits from a modal view controller. But it does let you put more of the semantic flow of your app into the storyboard. Apple has a tech note that describes them in detail, and they're also covered in the video from WWDC 2012 Session 407.
You could try calling [self dismissViewControllerAnimated:YES completion:nil]; from the controller you want to dismiss (whether the controller has been pushed, or shown modally).
Here is the related documentation : UIViewController Class Reference
The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, it automatically forwards the message to the presenting view controller.
Just to clarify.
In the class that was pushed. Simply wire up the following and the controller and view will be popped off.
[self.navigationController popViewControllerAnimated:YES];
Create Segue type "Custom" on your stroyboard. This can be from a button.
Create a new UIStoryboardSegue class named "popSegue"
In the popSegue.m file add the following;
-(void)perform{
UIViewController *sourceViewContreoller = [self sourceViewController];
[sourceViewContreoller.navigationController popViewControllerAnimated:YES];
}
-In the storyboard editor.
-Select the segue and change the Segue Class to "popSegue"
-Set the Identifier to "popSegue"
Done!
You can use the same "popSegue" class throughout your project.
Hope this helps
I'm using Xcode 5 also and here's how it's done. First, in the view code file that pushed the other, create an IBAction method in the .h file such as this:
- (IBAction)exitToHere:(UIStoryboardPopoverSegue *)segue sender:(id)sender;
Then in the .m file add this:
- (IBAction)exitToHere:(UIStoryboardPopoverSegue *)segue sender:(id)sender {
}
You can add any cleanup code you want executed in this method. Next go to your storyboard and select the pushed view. I assume you've got some kind of button on the view that the user taps to signal he's finished. Click on that button, hold down the key and drag to the the green box below the view which is the Exit. Release the mouse button but continue to hold the key. A popup will appear and your method will show in the list. Select that method. Now when the user clicks on the button, the view will pop and you'll be returned to the starting method.
I'm using idev-recipes/RaisedCenterTabBar and I want a modal view called from the center button, not a camera.
Code is here:
https://github.com/boctor/idev-recipes/tree/master/RaisedCenterTabBar
Any ideas on how to get this working?
There is a better approach to follow in order to accomplish that. And much easier.
What I understand by implementing using this methodology: https://github.com/boctor/idev-recipes/tree/master/RaisedCenterTabBar is that strange things are happening when you are trying to hide the tab bar. So the best solution I found for me (the same thing as you do) is here: http://www.lantean.co/display-a-modal-uiviewcontroller-when-a-uitabbaritem-is-pressed/
There is no need to do anything else. Just ignore the view controller that the UITabBarItem is associated with and present your modal view! That's all!
I would create your own subclass of UITabBarController and then add in this method:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
}
You will be able to tell what item was selected and then instantiate a modal VC inside there.
Probably you could just use the UITabBarDelegate, with the - (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item method. The method gets sent to the delegate, when somebody presses a button in the tab bar. In there you could check if it was the right button, and then instantiate the modal view controller.
Either with subclassing or by using the delegate, you can simply check if the item selected is your middle button and if it is, have the tab bar select the item that was previously selected and then present your model view controller. Since you'll be doing this within the same RunLoop source that the original selection happened, the tab selection will effectively be undone without ever switching to the middle VC.
According to the code sample provided by you =>
https://github.com/boctor/idev-recipes/tree/master/RaisedCenterTabBar
The central raised tab button is a UIButton, so just set the action of that button like this in BaseViewController.m class
[button addTarget:self action:#selector(showmodalview) forControlEvents:UIControlEventTouchUpInside];
and then in showmodalview method write this code=>
-(void)showmodalview
{
UIViewController *view1=[[UIViewController alloc] init]; // you can use any view controller instance you want ,this is just the example.
[self presentModalViewController:view1 animated:YES];
}
Using storyboards, what is the proper way to dismiss a modal?
using IBAction and writing code to dismiss after a button click?
using segue and notify the parent view controller after a button click?
See Here Dismissing a Presented View Controller about halfway down
When it comes time to dismiss a presented view controller, the preferred approach is to let the presenting view controller dismiss it.
So you should use an IBAction and writing code to dismiss after a button click
According Alex Cio answer for Swift 3 and XCode 8.3:
Create class:
import UIKit
class DismissSegue: UIStoryboardSegue {
override func perform() {
self.source.presentingViewController?.dismiss(animated: true, completion: nil)
}
}
But in storyboard you should choose:
Action Segue -> Custom -> dismiss
Only after this option appear on Action Segue menu
I've found that usually when I'm attempting to do this in storyboard I'd rather not create extra classes. It still makes sense to perform the dismiss from the presenting view controller, so that requires a class to back it.
If you create an IBAction in the presenting view controller and name it appropriately e.g.
- (IBAction)dismissAnyModel:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
Then from storyboard wherever you want to trigger the dismiss from you create an action to the first responder as shown below. You can extend this to work with multiple presenting view controllers by creating unique names for the IBActions.
More information on first responder and the responder chain
See my answer here. It gives you two ways to dismiss the modal view controller with storyboard. I like method two described because one you add the class in your project your return from modal views can be done with no code using storyboard alone. That said, if you have implemented a delegate and delegate protocol, it is also a good place to put the dismissModalViewController statement.
To do this inside the UIStoryboard you need first to create an Object of the type UIStoryboardSegue in your project
Then insert following method inside the class. Here is my class
#implementation DismissController
- (void)perform{
UIViewController *sourceVC = self.sourceViewController;
[sourceVC.presentingViewController dismissViewControllerAnimated:YES
completion:nil];
}
Now you can use it inside your UIStoryboard. Select the button that should make the UIViewController Disappear and drag it to the UIViewController you want to go to. In my case it shows **dismiss Controller* because of the name of my Class.
Select it and you are done!
There is also a very good explanation on this website.
As the Apple online documentation indicates, the presenting view controller is responsible for dismissing the modal (presented) view.
There's a post and example available
here
I have a table view that pushes to a detail view controller. From the detail view controller, when I press the 'back' button, I'd like an integer value to change. How do I edit the navigation bar back button's action programatically. The back button is automatically placed in my app because I'm using a table view so I didn't actually create the button, so I don't know how to affect it's method.
To be clear, I still want the back button to go back to the original view, but simultaneously change an integer's value. Thanks!
Thanks PengOne to point me to this direction.
Add the UINavigationBarDelegate in the header file and use this in the .m file:
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item
{
//insert your back button handling logic here
// let the pop happen
return YES;
}
I've figured out an easy fix to this. I simply unchecked 'Shows Navigation Bar' in the Interface Builder for the UINavigationController that the Table View was contained in. Then I used a UINavigationBar to replicate the look (but be able to add and delete buttons as I pleased).
After that I just created IBAction's that I connected to the buttons and could control an integer value from there.
(P.S. The only problem with this is that there is no 'Back' button left pointing arrow shape in the XCode interface builder as many of you know. There are solutions around this that are pretty easily found if you search).
If you're using a UINavigationController, then UINavigationBarDelegate is the delegate class and it implements -navigationBar:shouldPopItem. You can put the action you want to trigger in that method, e.g. incrementing or decrementing a counter.
You could try implementing viewDidDisappear, which should be called as the detail view controller's view goes out of view.