I'm developing (for learning iOS programming) an application for images-sharing.
The wanted layout is this:
It's a tabbar application with three tabs.
When you open the application and you're not logged the tabbar is hidden and you see instead a toolbar with two buttons "SIGNUP" and "LOGIN".
The controller that you see when you open the app it's the same for logged and anonymous users. The anonymous users can see only this because the tabbar (as written above) is hidden and you see instead a toolbar for signing up and log in.
When you tap on login or signup button you see (with pushViewController of navigationController) a new pushed view for do the selected action.
For example you're an anonymous user and you open the app. You see the first controller with all images and a UIToolbar at the bottom with the two buttons. For example you tap on an image and you see a new view with the image details (the view is pushed with navigationcontroller). But also in the new view you can see the UIToolbar for sign up and login. So the UIToolbar it's always visible for the anonymous user.
My problem is always display the UIToolbar for anonymous users and push with a navigationcontroller the login or signup views.
I'm a newbie developer. Have you tips for do that? Thanks.
If I understand your problem correctly, you want to constantly display a UIToolbar for an anonymous user so that they can log in from any of your views? If this is the case, all you would have to do is include your login toolbar in every one of your views you want the user to be able to log in from.
Another option, if I remember correctly, a navigation controller is technically both a top bar and a bottom bar. You could enable and utilize this bottom bar instead of adding your login toolbar to each of your views. To disable it for a know user, you would simply just hide it.
Edit in response to comments:
You should initialize the toolbar in your UINavigationController subclass, it would look something like this:
customNavController.h:
#property(nonatomic,retain) UIToolbar *toolbar
customNavController.m
if (toolbar == nil) {
toolbar = [[UIToolbar alloc] init];
navigationController.toolbar = toolbar;
}
That's the basic idea, though your initialize function for the toolbar will be different in that it will have the necessary UI for the login process. If you want some more information on the Navigation Controller I would highly recommend reading the class reference on it, it is actually very handy.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html
Related
Ultimately, I'd like to know how to store a UIView (globally, if necessary) from one view controller, so that it can be referenced, and called back up to the top, from within another view controller?
I've built an app that has a Home tab and a Guide tab as the two main tabs, but the Guide tab's functionality is a bit unique in that it's a dynamic tab, which will ideally show different content depending on what "guide" has been chosen from the Home tab. Thus, on the Home tab, there are several UIButtons that are meant to load a given guide. Each guide is simply a collection of images that the user can interact with. No problem there.
Now, on the Home tab, when a user selects the guide they want to view, I wanted to transition between the Home tab and the Guide tab with a CurlDown animated transition. This is the only place I'll have a UIView transition animation—meaning normal tab switching by the user will be the standard instant transition without effects.
Here's how I have implemented the Home-to-Guide transition when a user selects a guide from the Home tab. This is done in the HomeViewController, as an IBAction assigned to all the guide-loading UIButtons, each of which has a unique tag that tells the GuideViewController which guide to load:
- (IBAction)loadGuide:(id)sender
{
UIButton *button = (UIButton*) sender;
GuideViewController *guideController = [[GuideViewController alloc] initWithNibName:#"GuideViewController" bundle:nil];
self.guideViewController = guideController;
[self.guideViewController activateGuide:button.tag];
[UIView transitionFromView:self.view
toView:guideController.view
duration:1.0
options:UIViewAnimationOptionTransitionCurlDown
completion:^(BOOL finished){
UITabBarItem *tabBarGuide = [[self.tabBarController.tabBar items] objectAtIndex:1];
[tabBarGuide setEnabled:TRUE];
self.tabBarController.selectedIndex = 1;
}];
[guideController release];
}
// End (IBAction)loadGuide
This works really well, up until the point where I then have to enable the Guide tab and switch to it. What happens at that point seems to be that another instance of the GuideViewController is created and replaces the one that was initially instantiated and transitioned to from the HomeViewController as shown above.
So I thought maybe I could work around it by, instead, moving the guide-loading to a new view, on that isn't used with the UITabBar, then load and transition to this view from the Home tab, just like I did in the above code. Then, after switching tabs, I'd need to somehow recall it into my Guide tab's view controller, as a subview or the like.
I'd think the view would still exist in memory after the tab-switching process, I just don't know how to access it, so I can show it again after the Guide tab's view has hidden it. Should I assign the view to some sort of globally accessible variable from the HomeViewController so that I can then access it from the GuideViewController (Guide tab's view)?
I'm open to any alternate suggestions as well, if you think this approach is bad form! I initially tried to overcome the problem by loading the details of the active guide into the database, then recovering that data when the Guide tab's view controller kicked in. However, the Guide tab's view must be cached or something, because if the user goes back to the home page and chooses a new guide, it'll animate the transition to that guide, but then when the Home-to-Guide-tab-switch kicks in, it flips back to the same state that the Guide tab's view was in before the user went back to the home page to choose a new tab. Also, I noticed the ViewDidLoad method doesn't get called again when manually nor programmatically switching tabs, so I figured that the other view must still be around in memory too! (The "other view" being either the original instance of the GuideViewController's view initiated from the Home tab upon selecting a guide button, or a new view as previously mentioned that would essentially do the same thing, albeit in a separate class.)
So to summarize:
I have two tabs, Home and Guide
Home has several UIButtons that when tapped will load a specific guide
When a UIButton on Home is tapped, it transitions from the Home tab's view to the Guide tab's view view CurlDown, without first switching to the Guide tab because that would lose the CurlDown effect
Then I have to trigger the tab switch programmatically, which seems to load a new instance of the Guide view, which effectively covers up the other instance
I want to know if I can somehow just call back up the first instance by somehow maybe storing the other instance as a global or some such?
Hense the question about how to pass a UIView instance around several UIViewControllers
If I were you I'd ditch the transition and just the tabbar as normal.
Firstly as it's giving you problems, but also and more importantly as it would seem strange to the end user who is used to tab bars just switching when you press the tab (well it would to me).
I'd read and re-read Apple's HIG on tabbars too. I think your users will find it very confusing that something other than the tab bar buttons causes the selected tab to switch.
You would have the data in the model.
The home tab would specify to the model which guide is chosen.
The guide would view load it's data every time it appears.
If you do need to keep the transition, then ditch the guide tab and use a navigationbar inside the home tab. You mention that screen space is the one issue for not doing so, but you can have the navigation bar present but not visible. You could then have a button in the guide tab to close that viewcontroller (pop the guide vc).
Another option might be to present the guide view modally instead - but the partial page curl also restricts screen space a little.
The ideal approach to doing this is to store a retained reference to the UIView object in a persistent object such as the app delegate subclass UIApplicationDelegate. The app delegate can then instantiate the view. Then, each controller needing to show the view would just ask the app delegate for the view. Also, if a root view controller is always available, it could be retained there as well.
I am making code for iPhone. My first screen has only one button with text Menu. When user will click on this button next screen is coming with multiple navigation bar.Each Navigation bar has their own Text information which are being selected after clicking on any Navigation bar.
How i should to design it for iPhone ? Please give me concept. Should i take multiple views ? If i have multiple views how will i hide and show on button click event ?
Thanks in advance.
You will have to adapt your user interface to comply to how Apple wants an app to work, look, and feel - or make your own custom viewcontrollers. Even then, you might not get the exact behavior you want.
My hottest tip is to look at similar apps on appstore and see how they are navigated.
I don't get a picture in my mind from your description, but it seems you want what is called "drill down". This is best done with tableViews.
You can't have multiple navigation controllers on the same "screen"; it doesn't work like that on the iPhone. Instead, what you have is one single Navigation controller, that controls the pushing of views. You decide which sub-view to push depending on which selection the user makes, and the Navigation controller handles the rest of the interaction with the user to let him or her navigate between the views.
Example structure:
Window-based app
+-MainWindow.xib
| +-First view with button
| +-UINavigationController
+-tableview1.xib
+-tableview2.xib
+-any more views you need.
Make the app delegate a <UINavigationControllerDelegate> and declare navCt *UINavigationController, and connect it in Interface Builder. You can then write a pushVC method, which takes as argument a UIViewController *vc. It does a [navCt pushViewController:vc animated:YES];
Connect the button to an IBAction, which then calls the method in the app delegate, [PushVC myVC], where myVC refers to any viewcontroller in your app, in this case table view 1.
In this table, on didSelectRow... event you can use the same method to push the sub-view table view 2.
I think this is minimum code if you are unsure about iPhone app design. Either way, I hope it gives some ideas.
You should read about UINavigationController, UITabBarController, UIViewController.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html
You almost always make one view pr. viewcontroller.
I am using a UITabBarController as well as a UINavigationController on my app.
In my UITabBarController I am using more than 5 items so I automatically get the 'More' item.
I've managed to add a saving procedure so the order of those items will be kept in case somebody changes the order etc.
With 'More' active I get the More navigation controller with the 'Edit' item positioned under my UINavigationController. Both navigation controller are visible. When I click on 'Edit though the More navigation controller disappears and seem to be hiding under my UINavigationController and therefore I can't see/use the 'Done' function to save my new order
What did I miss?
Cheers
It sounds like you have a UINavigationController as the main VC of your app, and a UITabBarController as one of the VC's on its stack.
I believe Apple actively discourages people from doing this in their apps, and so do I. It is never done in the iOS itself, and I have never seen it in any third-party apps either, so users will probably be confused.
I think you should embed the UINavigationController inside the UITabBarController instead of the other way around, or you could just choose to use another way of showing what you want to show.
I believe iOS does use both navigation controller and tab controller at the same time in their iPod app. The navigation controller takes you to the playing song and back and at the same time you have the tab controller when you select songs/albums/playlists etc. However, the navigation controller (or tab bar controller) seems to be custom made as it handles the More->Edit case by hiding the navigation bar underneath the Edit bar, which is not what the default UITabBarController does.
All in all, I see Apple is rather "creative" when it comes to UI design. For example, in the email app, "New" button is in the lower right corner (bottom bar) while in the SMS app the "New" button is in the upper right corner (navigation bar). I think they pretty much make custom UI to fit the individual needs of the app instead or rigidly following some consistent design.
I've built the tab bar application in IB, with three tabs. The third tab happily displays a UIWebview where you can browse. The only thing missing is a back button, as not all web pages supply such a link.
I need a navigation bar hooked up properly to the correct classes. I'm still a bit unsure about exactly how the hierarchy should look in interface builder and how to hook it up properly.
Currently, the third tab is hooked up to a referencing outlet called 'webnews' in the class 'thirdviewcontroller', and the UIWebView (under a normal IUView in the hierarchy, which in turn is under the third tab bar controller) is connected to the webnews outlet.
How do I make the navbar control the webview, and do I add code to the thirdviewcontroller.m that lets the navbar on the view control the webview 'back' function? What do I hook up as the delegate for it? Currently I have an app delegate, but that's hooked up to the tab bar.
I'm not really after specific code as much as a general 'how it works' clue :) (Unless I can just add the navbar dynamically to the functioning app... but I don't think addSubView on viewWillAppear {} in thirdviewcontroller.m will create the proper functionality?)
If I were to guess at the simplest solution, I'd guess create a navbarcontroller.h/.m, slap a navbar on the view in IB, connect the third tab to navbarcontroller, connect the navbar to the webview (?) and move the webnews outlet to navbarcontroller.h, and connect the webview to it. But I don't quite have the nerve to try, better to ask advice first.
Answering this, see similar Detect and handle, or override, clicks on a navigation bar
I posted earlier but am running into similar problems again. Basically the way that my app is setup there is a top bar that is basically just a static image that has UIButtons placed on top of it. That is the Main View Controller and is persistent no matter what view is shown beneath it. I can't use a navigation controller because it is not possible to change the height and I need the bar to be significantly larger than a navbar. However my bar is functioning in much the same way. There is a "Home" Button, a "Back" Button and several destination buttons.
I understand how to switch views from say the home screen. My confusion comes with the back button. In order to press back the app is going to need to know what view is currently being displayed so that it can be removed from view and a new subview can be added. Ideally I would use the UINavigationController so that I can push and pop views which is really what I want to do here, however that is not possible because of the visual problem.
Does anybody know of a method that returns the current displayed view so I could do something like the following
[currentview.view removeFromSuperView];
[self.view insertSubview:experienceViewController.view atIndex:0]
You can use UINavigationController with the nav bar hidden. Put the nav controller inside a view that does have your jumbo toolbar and you'll have access to the push/pop behavior you're looking for.