Building an interface, but I need a button, let's say its a round HOME button, that sits in the lower-right of the screen, that is always there, and will always return you back to the main screen.
It makes senses in the context of what I'm trying to accomplish.
Is there a clever/elegant way to do this, or am I restricted to just making a version of the Navigation Controller?
I think here you need to play somehow with navigation controller. In the bottom of application stack there is always RootViewController, over which all other controller pushed in the application stack with respect to application window.
So just follow these steps to fulfill your question requirments.
Assign RootViewController to your HomeViewController (On which you want to come again and again via a right bottom most of screen).
HomeViewController *homeViewController = self.window.rootViewController;
And Every time When click on that "Right most bottom button " call this.
[self popToRootViewController];
Hope this helps you !!
To do so make an interface for the home button
#interface stickyHomeButton :UIViewController
#end
#implementation stickyHomeButton
- (void)viewDidLoad
{
[super viewDidLoad];
BDSAppDelegate *mainDelegate=[[UIApplication sharedApplication] delegate];
UIButton *homeButton=[UIButton buttonWithType:UIButtonTypeCustom];
[homeButton setFrame:homeButtonRect];
//desing you home button as you want
[homeButton addTarget:self action:#selector(popToHomeViewController) forControlEvents:UIControlEventTouchUpInside];
[[mainDelegate window] addSubview:homeButton];
[[mainDelegate window] bringSubviewToFront:homeButton];
}
-(void)popToHomeViewController
{
[[self navigationController] popToRootViewControllerAnimated:YES];
}
#end
You are ready with you home button, now you need to do just a simple thing. all the viewController need to inherit stickyHomeButton
Or you could add a container view, full screen size, and present your modals inside that as childrenViewControllers, with the static button above this container view in the hierarchy...
Related
So I was create three UITableViewControllers with UINavigationController. I want a back button on 3rd UITableViewController, what returns my view to first UITableViewController instead of second.
How can I do that? That must be a real backButton, not a image or something else. Will be perfect to do this only with storyboard.
UPDATE
Perhaps I poorly explained what I want.
I don't want use any button with action on it. I just want something like as setting "address" of 1st TableViewController on my default back button. There is any way to do it?
add a button and connect it to following action
- (IBAction)backToFirstView:(UIButton *)sender
{
[self.navigationController popToRootViewControllerAnimated:YES];
(or)
[self.navigationController popToViewController:yourFirstViewControllerObject animated:YES];
}
There are different ways to navigate from DetailViewController to other view controllers.
We will go through the cases one by one.
First of all I would like to clear that if its your default
navigation bar's back button, then it must return to the last most
view controller only which is actually a default behavior of a
navigation controller.
Second, If you would like to go back to the
last most view controller on the tap of a button placed by you, you
should write the following code
[self.navigationController popToViewController:NAME_OF_A_VIEWCONTROLLER animated:YES];
Third, If you would like to go to the first view controller from where you
started, you should write the following code
[self.navigationController popToRootViewControllerAnimated:YES];
Ok, I found a way to resolve my problem. Thanks for your answers guys, they was very helpful.
So for resolve this problem you just need use link what give me Kumar KL upper, and wrote next method in your UITableVIewController
-(void) viewWillDisappear:(BOOL)animated {
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
// Navigation button was pressed. Do some stuff
[self.navigationController popViewControllerAnimated:NO];
}
[super viewWillDisappear:animated];
}
Now you got a backButton what redirect you to your viewController, BUT title of this button is wrong. Let's resolve that unfair.
Create new class CustomSegueцрфе inherited from UIStoryboardSegue with next code in CustomSegue.m :
- (void)perform
{
UIViewController *sourceView = (UIViewController *) self.sourceViewController;
UIViewController *destinationView = (UIViewController *) self.destinationViewController;
[[destinationView navigationItem] setTitle:#"TitleOfYourViewController" ] ;
[sourceView.navigationItem setTitle:#"TitleOfButton"] ;
[sourceView.navigationController pushViewController:destinationView animated:YES];
}
Now you can go to storyboard and connect 2nd ViewController with 3rd with custom segue.
Like you see UINavigationController uses Title of previous ViewController for button title, so you just need change it.
I am pushing a viewController onto the UINavigationController with animation, and the controller being pushed on is basically doing something like:
--- app delegate:
[((UINavigationController *)window.rootViewController) pushViewController:initialController animated:YES];
--- initial controller:
- (void)viewDidLoad {
[super viewDidLoad];
if (self.shouldSkipThisController) {
SomeOtherViewController *someOther = [[SomeOtherViewController alloc] init];
[self.navigationController pushViewController:someOther animated:NO];
}
}
This is causing some CRAZY behavior which I don't understand at all. Basically, it seems like the navigation items set on SomeOtherViewController are being covered up by some strange other button that has the name of the title in a back button. It looks like although SomeOtherViewController is setting it's own left and right navigation items, they are covered up by the "default" back button--- and then if I tap on that back button, then just the navigation bar at the top animates-- and THEN SomeOtherViewController's navigation items are then there.
The only thing I could find that sort of worked was to either 1) not animate the push of the initial view controller in the app delegate, or 2) move the shouldSkipThisController condition into viewDidAppear: method.
However, neither of those options are ideal... Any help could be greatly appreciated.
I am creating an iPhone client for one of my apps that has an API. I am using the GTMOAuth2 library for authentication. The library takes care of opening a web view for me with the correct url. However I have to push the view controller myself. Let me show you some code to make things more clear:
- (void)signInWithCatapult
{
[self signOut];
GTMOAuth2ViewControllerTouch *viewController;
viewController = [[GTMOAuth2ViewControllerTouch alloc] initWithAuthentication:[_account catapultAuthenticaiton]
authorizationURL:[NSURL URLWithString:kCatapultAuthURL]
keychainItemName:kCatapultKeychainItemName
delegate:self
finishedSelector:#selector(viewController:finishedWithAuth:error:)];
[self.navigationController pushViewController:viewController animated:YES];
}
I have a "plus"/"add" button that I add to the view dynamically and that points to that method:
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(signInWithCatapult)];
When I press the "add" button, what is supposed to happen is to open the web view with an animation, and then add an account to the accounts instance variable which populates the table view. This works fine if I add one account, but as soon as I try to add a second account, the screen goes black and two errors appear in the console:
nested pop animation can result in corrupted navigation bar
Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
The only way that I found to avoid this problem was to disable animations when pushing the view controller.
What am I doing wrong please?
Typical situations
You push or pop controllers inside viewWillAppear: or similar methods.
You override viewWillAppear: (or similar methods) but you are not calling [super viewWillAppear:].
You are starting two animations at the same time, e.g. running an animated pop and then immediately running an animated push. The animations then collide. In this case, using [UINavigationController setViewControllers:animated:] must be used.
Have you tried the following for dismissing once you're in?
[self dismissViewControllerAnimated:YES completion:nil];
I got the nested pop animation can result in corrupted navigation bar message when I was trying to pop a view controller before it had appeared. Override viewDidAppear to set a flag in your UIViewController subclass indicating that the view has appeared (remember to call [super viewDidAppear] as well). Test that flag before you pop the controller. If the view hasn't appeared yet, you may want to set another flag indicating that you need to immediately pop the view controller, from within viewDidAppear, as soon as it has appeared. Like so:
#interface MyViewController : UIViewController {
bool didAppear, needToPop;
}
...and in the #implementation...
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
didAppear = YES;
if (needToPop)
[self.navigationController popViewControllerAnimated:YES];
}
- (void)myCrucialBackgroundTask {
// this task was presumably initiated when view was created or loaded....
...
if (myTaskFailed) { // o noes!
if (didAppear)
[self.navigationController popViewControllerAnimated:YES];
else
needToPop = YES;
}
}
The duplicated popViewControllerAnimated call is a bit ugly, but the only way I could get this to work in my currently-tired state.
I am making my first iOS application, it is for the iPad. It is a memorization game. It has cover page with a couple of options and depending on the option you choose it sends you different page/view. Throughout the application, the user will be traveling through different pages/views. The entire interface for the application will be custom made, so i want have the navigation bars or anything. I am using xCode 3.2.5. I have created the views in the interface builder. And I have attached the cover page to the app, so after the splash page it appears.
How do I go about switching between views?
Thanks for any help you can give me.
Edit 1:
Here is some code that I think is pertinent
This is the AppDelegate.m file, I left out the methods I did not edit
#synthesize coverController=_coverController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
cover *aCoverController = [[cover alloc] initWithNibName:#"cover" bundle:nil];
self.coverController = aCoverController;
// Or, instead of the line above:
// [self setcover:aCoverController];
[aCoverController release];
self.window.rootViewController = self.coverController;
[self.window makeKeyAndVisible];
return YES;
}
- (void)dealloc {
[managedObjectContext_ release];
[managedObjectModel_ release];
[persistentStoreCoordinator_ release];
[_coverController release];
[window release];
[super dealloc];
}
Ok. 1stly can you be a little more clearer about what you want.
From what I got was, you are not looking to navigate in/out of controllers, you just have few views prepared for your RootViewController, and then you want to switch between them.
Navigation controller is used when you have a sequential flow of views, as in moving from view1 'leads to' view2, and so on. eg- a contactsBook-->contactDetails-->editContact--> so on ..
But it feels, in your case, the views/pages are separate and have no connection whatsoever, so there wont be any sequential flow, but a random flow of say view1-->view5-->view2--> ..
If that is the case, if you have already build the views, you just need to connect each of them with their parentController(coverController in your case).
Simplest way would be - lets say you have 3 views, view1 view2 view3, each having 1 or more buttons to switch b/w views.
1 way would be to have a reference of the coverController, in each of the views. There are more elegant methods possible, but this 1 will be the easiest to understand and implement.
So, in view1.h(add these) :
import "cover.h"
#class cover;
#interface view1 : UIView {
cover *coverController;
}
#property(nonatomic, assign)cover *coverController;
#end
And in cover.h, add
import "view1.h"
#class view1;
#interface cover : UIViewController{
IBOutlet view1 *firstView;
}
#property(nonatomic, retain) IBOutlet view1 *firstView;
#end
Finally in cover.m, add
#implementation cover
#synthesize view1;
and in 'viewDidLoad' method in cover.m, add 2 lines
self.view1.frame = CGRectMake(0,0,768,1024); //set whatever frame you want
self.view1.coverController = self; //concept of reference-paring
And done.
in the view1ButtonPressed method of view1 -
-(IBAction)view1ButtonPressed{
// remove the current view from the superview
[self removeFromSuperView];
//go to superView, to load anotherview
[coverController view1ButtonWasPressed];
}
in cover.m :
-(void)view1ButtonWasPressed{
//after doing the same process for view2
[self.view addSubview:view2];
}
If you have made the correct connections, in you nib files, you ll achieve what you set out to do.
Concept is simple, what we are doing is - on click on the button, we remove the current view from superview, go to the super view itself(which is the controller's view only), and add as a subview some other view of our choice.
There is only 1 controller, and many views, and we are switching in b/w those views.
You should use a navigation controller, it's the simplest way of structuring an app with multiple views. There's nothing that says you have to show the navigation bar and you can create custom buttons which push and pop views on and off of the stack.
I've been playing with different ways of doing this and it's just not worth the effort. I strongly recommend the navigation controller.
This tutorial helped me get my head round it, but try googling to find what works best for you.
I am making an application that has a UITabBar and it works just fine, however I want to add a first screen which contains some instructions and a logo, then a button and when said button is pressed to show the UITabBar I've tried for a couple of days to do this on my own with no luck, I'm not even sure if it can be done, could anyone help me out? or give me a lead?
Try setting up the tab bar application, and then showing the first screen over it as a modalViewController. Inside your main app's viewController:
FirstViewController *firstViewController = [FirstViewController alloc] initWithNibName:#"FirstView" bundle:nil];
[self presentModalViewController:firstViewController animated:NO];
[firstViewController release];
When the button is pressed inside the modal view, call:
[[self parentViewController] dismissModalViewControllerAnimated:YES];
to get rid of it. You can adjust the animation style for the dismissal, or use NO instead to have it just disappear.