This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I'm having trouble figuring out how to add a navigationcontroller to my iOS app. I need all of the views except the "home" screen to have a back button but I'm not sure how to add it.
Here is a link to my project:
https://www.dropbox.com/s/sv0y3oh1aftxl95/KFBNewsroom%204.zip
Remove the navigation bars from all of your NIBs and use a navigation controller (such as in the app delegate like NeverBe outlined), and then transition to the child controllers via a pushViewController rather than presentViewController as you're currently doing, and you should get your "back" button automatically. You'll also want to remove any references to dismissViewControllerAnimated, if you have any, as your back button will now do popViewControllerAnimated for you. If you need to programmatically pop anywhere, though, you can just used popViewControllerAnimated.
In your NIBs, you might also want to tweak the simulated metrics so you can design your NIBs with the navigation bar graphically represented, e.g.:
See the navigation controller section of the View Controller Catalog and refer to the UINavigationController Class Reference.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[[KFBViewController alloc] initWithNibName:#"KFBViewController" bundle:nil]];
self.window.rootViewController = nav;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
Call new view controller
KFBYouTubeView *youtubeView = [[KFBYouTubeView alloc] initWithNibName:#"KFBYouTubeView" bundle:nil];
[self.navigationController pushViewController:youtubeView animated:YES];
Update:
Method for add custom nav bar buttons
- (void)customizeNavigationButtonWithType:(NavigationBarButtonType)type
normalImageName:(NSString *)normalImageName
selectedImageName:(NSString *)selectedImageName
selector:(SEL)selector {
UIImage *img = [UIImage imageNamed:normalImageName];
UIImage *imgPressed = [UIImage imageNamed:selectedImageName];
UIButton *customButton = [UIButton buttonWithType:UIButtonTypeCustom];
[customButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[customButton setImage:img forState:UIControlStateNormal];
[customButton setImage:imgPressed forState:UIControlStateHighlighted];
customButton.frame = CGRectMake(0, 0, img.size.width, img.size.height);
[customButton addTarget:self action:selector forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithCustomView:customButton];
switch (type) {
case NavigationBarButtonTypeLeft:
[self.navigationItem setLeftBarButtonItem:btn animated:YES];
break;
case NavigationBarButtonTypeRight:
[self.navigationItem setRightBarButtonItem:btn animated:YES];
break;
}
}
Usage:
[self customizeNavigationButtonWithType:NavigationBarButtonTypeRight
normalImageName:#"create.png"
selectedImageName:#"create_highlight.png"
selector:#selector(pressButton:)];
Related
When I push a viewcontroller on my navigation stack, the back button appears to be against the left side of the screen. How can I get the regular padding of the back button?
Here is how I present the view controller:
- (void)goToCollection:(UIButton *)btn {
Card *colCard = (Card *)btn.userData;
WViewController *vc = [WViewController new];
NSString *colID = [[colCard.href componentsSeparatedByString:#"/"] lastObject];
vc.collectionID = colID;
[self.navigationController pushViewController:vc animated:YES];
}
Here's my view setup in didFinishLaunchingWithOptions :
//Profile View
ProfileViewController *pv = [ProfileViewController new];
UINavigationController *profNav = [[UINavigationController alloc] initWithRootViewController:pv];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setRootViewController:profNav];
[self.window setTintColor:[UIColor Primary]];
[self.window makeKeyAndVisible];
As per apple documentation, you can not edit or modify back button in any case. Only allowed operation for back button is show and hide .
So if you want something to do with back button, you need to hide it and create a customise left bar button item as back button.
self.navigationItem.hidesBackButton = YES; //hides back button
UIButton *myButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 40, 40)]; // creates a new button
[myButton setImage:[UIImage backButtonImage]; // sets image for new button
[myButton setContentEdgeInsets:UIEdgeInsetsMake(0, -15, 0, 0)];//content edgeInset to provide required padding
[myButton addTarget:self action:#selector(backToHOmePage) forControlEvents:UIControlEventTouchUpInside];//adding target for new button
UIBarButtonItem *customBackBtn = [[UIBarButtonItem alloc] initWithCustomView:myButton]; //custom bar button item
self.navigationItem.leftBarButtonItem = customBackBtn; //assigning to left bar button item
-(void)backToHOmePage
{
[self.navigationController popViewControllerAnimated:YES];
} // method to be triggered on tapping above button
Put this in your AppDelegate
[[UIBarButtonItem appearance] setBackButtonBackgroundVerticalPositionAdjustment:-3 forBarMetrics:UIBarMetricsDefault];
I am using RESideMenu in my application. But I need to add login and registration viewcontrollers before the RESideMenu.
Is it possible, if yes then how can I do that ?
Thanks in advance.
There are many ways to do this. The most common is you have a loginView controller and then in the app delegate you can write something like this in the app delegate:
if([[NSUserDefaults standardUserDefaults] valueForKey:#"AlreadyLogin"])
{
// So, here user already login then set your root view controller, let's say `SecondViewController``
SecondViewController *secondViewController = [storyBoard instantiateViewControllerWithIdentifier:#"SecondViewController"];
// then set your root view controller
self.window.rootViewController = secondViewController;
}
else
{
// It means you need to your root view controller is your login view controller, so let's create it
LoginViewController *loginViewController= [storyBoard instantiateViewControllerWithIdentifier:#"LoginViewController"];
self.window.rootViewController = loginViewController;
}
Credit: Skip view if user already logged
Yes it is very possible.
Solution A:
After successful login/sign up, do:
[UIApplication sharedApplication].window.rootViewController = [[RESideMenu alloc] init...];
Solution B:
Place your login/signup view controllers in the main content portion of the RESideMenu, and disable the two side menus until the user is signed in.
Solution C:
Embed the RESideMenu in a UINavigationController and optionally hide the navigation bar.
For more info I recommend researching "view controller containment" as that is the pattern used by RESideMenu, UINavigationController, and other types of "container" view controllers.
I hacked together a quick example of Solution C and it seems to work fine:
#implementation LoginViewController
- (void)viewDidLoad {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(50, 50, 100, 100);
[button setTitle:#"Login" forState:UIControlStateNormal];
[button addTarget:self action:#selector(goToRESideMenu) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
self.navigationController.navigationBarHidden = YES;
}
- (void)goToRESideMenu {
UIViewController *redViewController = [[UIViewController alloc] init];
redViewController.view.backgroundColor = [UIColor redColor];
UIViewController *greenViewController = [[UIViewController alloc] init];
greenViewController.view.backgroundColor = [UIColor greenColor];
UIViewController *blueViewController = [[UIViewController alloc] init];
blueViewController.view.backgroundColor = [UIColor blueColor];
RESideMenu *sideMenu = [[RESideMenu alloc] initWithContentViewController:redViewController
leftMenuViewController:greenViewController
rightMenuViewController:blueViewController];
[self.navigationController pushViewController:sideMenu animated:YES];
}
#end
The result looks like this:
I encountered a strange problem on the rightBarButtonItem of UINavigationController. The margin of the button disappears on iOS7, so it looks like this:
At first, I thought it was some mistakes in my UINavigationController related categories, but I removed all my customisation code and all the header files of categories, and simply use a UINavigationController and an empty view controller.
In - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
VCTestViewController *vc = [[[VCTestViewController alloc]init]autorelease];
UINavigationController *nc = [[[UINavigationController alloc]initWithRootViewController:vc]autorelease];
self.window.rootViewController = nc;
[self.window makeKeyAndVisible];
In VCTestViewController.m -> viewDidLoad
self.view.backgroundColor = [UIColor whiteColor];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:#"hello" style:UIBarButtonItemStyleBordered target:nil action:nil];
The problem still exists(as shown above). I can't figure out what is wrong. Do you have any idea about this problem?
you can share your line of code if it's not working:
- (UIBarButtonItem *)rightNavBarButton
{
UIButton *filterBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[filterBtn setTitle:#"hello" forState:UIControlStateNormal];
filterBtn.frame = CGRectMake(0, 0,40,27);
[filterBtn addTarget:self action:#selector(getFriendsList) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *filterNavBarItem = [[UIBarButtonItem alloc] initWithCustomView:filterBtn];
return filterNavBarItem;
}
I finally figure out what happened.
The link given by βhargavḯ is not the solution of my problem, but it's the cause of my problem. One of my colleagues wrote a category of UINavigationItem to narrow the empty space in iOS7. He then used method swizzling to exchanged the system method setRightBarButtonItem: with his own method. I didn't realise this.
So I think method swizzling would be extremely dangerous if you exchange the system methods with your own methods.
I have a customised UITabBar and use the following code in the AppDelegate:
- (void)tabBarController:(MainUITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
[self customizeTabBar];
}
- (void)customizeTabBar {
NSLog(#"*******customizeTabBar*******");
UIImage *tabBackground = [[UIImage imageNamed:#"unselectedtab"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
// Set background for all UITabBars
[[UITabBar appearance] setBackgroundImage:tabBackground];
// Set tint color for the images for all tabbars
[[UITabBar appearance] setSelectedImageTintColor:[UIColor whiteColor]];
// Set selectionIndicatorImage for all tabbars
[[UITabBar appearance] setSelectionIndicatorImage:[UIImage imageNamed:#"selectedtab"]];
}
- (void)tabBarController:(MainUITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed
{
NSLog(#"*******didEndCustomizingViewControllers*******");
}
This is all fine in iOS5+ but in 7 on first load the first TabBarItem the item indicator is white and the button seems to have been selected but the "selectedTab" image is not loaded.
When I press another tab the new tab is red and appears correctly - as does the first or any tab bar item selected after this - it only doesn't work on first launch.
customizeTabBar get called but the selected image does not appear on first launch.
didEndCustomizingViewControllers does not seem to get called at all.
This doesn't work in emulator or device on iOS7 - but does on iOS5, 6.
Any ideas?
Thanks in advance.
Setting the selection indicator image for the tab bar directly once again, apart from doing it via appearance, worked for me!
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
....
UITabBarController *tabBarContr = (UITabBarController *)self.window.rootViewController;
...
[[UITabBar appearance] setSelectionIndicatorImage:[UIImage imageNamed:#"tab_bar_selection_indicator.png"]];
// iOS7 hack: to make selectionIndicatorImage appear on the selected tab on the first app run
[[tabBarContr tabBar] setSelectionIndicatorImage:[UIImage imageNamed:#"tab_bar_selection_indicator.png"]];
return YES;
}
I am seeing this exact same issue. Here is my didFinishLaunching
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self applyStyleSheet];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
self.window.backgroundColor = [UIColor redColor];
self.window.tintColor = [UIColor whiteColor];
UITabBarController *tabBarController = [self setupTabBarController];
self.window.rootViewController = tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
Here is how I setup the tab bar:
- (UITabBarController *)setupTabBarController
{
UITabBarController *tabBarController = [[UITabBarController alloc] init];
UINavigationController *nav1 = [[UINavigationController alloc] initWithRootViewController:[[FirstViewController alloc] init]];
UINavigationController *nav2 = [[UINavigationController alloc] initWithRootViewController:[[SecondViewController alloc] init]];
UINavigationController *nav3 = [[UINavigationController alloc] initWithRootViewController:[[ThirdViewController alloc] init]];
UINavigationController *nav4 = [[UINavigationController alloc] initWithRootViewController:[[FourthViewController alloc] init]];
UINavigationController *nav5 = [[UINavigationController alloc] initWithRootViewController:[[FifthViewController alloc] init]];
[tabBarController setViewControllers:#[nav1, nav2, nav3, nav4, nav5]];
return tabBarController;
}
And finally, this is the tab bar customization block:
- (void)applyStyleSheet
{
UITabBar *tabBar = [UITabBar appearance];
[tabBar setBackgroundImage:[UIImage imageWithColor:[UIColor redColor]]];
[tabBar setTintColor:[UIColor whiteColor]];
[tabBar setSelectionIndicatorImage:[UIImage imageNamed:#"tab-selected"]];
[tabBar setSelectedImageTintColor:[UIColor whiteColor]];
}
As stated, the "tab-selected" image is not loaded on the first tab. However, I added the following line after [self.window makeKeyAndVisible] so that my tab starts up with a different tab opened, and the "tab-selected" image does show up on this tab:
[tabBarController setSelectedIndex:1];
So here's my finalized didFinishLaunching with the subtle hack that makes it work :)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self applyStyleSheet];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
self.window.backgroundColor = [UIColor redColor];
self.window.tintColor = [UIColor whiteColor];
UITabBarController *tabBarController = [self setupTabBarController];
self.window.rootViewController = tabBarController;
[self.window makeKeyAndVisible];
[tabBarController setSelectedIndex:1];
[tabBarController setSelectedIndex:0];
return YES;
}
ok.
not the best of fixes but hey have to submit.
Remove the customisation code in the appdelegate and in the projects xib file (is an old project) on the TabBars attributes inspector (using xcode 5) - add the tab bars background and selection images.
This works for ios7 without the need for any of the customisation code in the appdelegate.
For pre iOS5 + 6 (this app only supports 5+) however we still need the code so I added a simple check for version and kept the code as is:
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
if(SYSTEM_VERSION_LESS_THAN(#"7.0"))
{
UIImage *tabBackground = [[UIImage imageNamed:#"unselectedtab"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
// Set background for all UITabBars
[[UITabBar appearance] setBackgroundImage:tabBackground];
[[UINavigationBar appearance] setTintColor:[UIColor blackColor]];
// Set tint colour for the images for all tabbars
[[UITabBar appearance] setSelectedImageTintColor:[UIColor whiteColor]];
// Set selectionIndicatorImage for all tabbars
[[UITabBar appearance] setSelectionIndicatorImage:nil];
[[UITabBar appearance] setSelectionIndicatorImage:[UIImage imageNamed:#"selectedtab.png"]];
}
I think I also have had the same problem when doing my design for the new App in iOS 7!!
iOS 7 has been built more of the stuff different as we all were used to things different.
Here as I have understood we all were using StoryBoards, and were unable to integrate that Segues in our Code! :)
So I choose not to mess with the code, after I tried most of all the StackOverFlow Answers regarding this! :) Because, why you wanna do so, when you have given a Goody Good Interface Builder (IB) and Story Boarding Tool?
Question:
When we have set our Selected Tab Image, background image specially for the tab bar, it doesn't shows which tab is selected with the image we have set in our code...???
Solution
Following are the screenshots of my StoryBoard Settings I did to solve this problem!
Select your TabBarController from your via document outline panel:
Set your settings for the Tab Bar from the Utilities Panel:
Then your Program is set up to run! It now knows that first tab is selected when the App first shows the First Tab View and also which image should be shown for all the Tab Bar indicators when each of them are selected! :)
hope you all got a clue!!!
If I helped you I'm Happy!!!
But if I have wasted your Time I'm So Sorry!!! :(
But trust me, This worked me like a charm!!!
- (void)customizeTabBar {
UIImageView *customizeTabBar = [[UIImageView alloc]initWithFrame:CGRectMake(0,0,320.0,50)];
customizeTabBar.image=[UIImage imageNamed:#"Tab_bar.png"];
firstTab = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tab1.png"] highlightedImage:[UIImage imageNamed:#"tab11.png"]];
[firstTab setFrame:CGRectMake(8.0,01.0,90.0,49.0)];
[customizeTabBar addSubview: firstTab];
secondTab = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tab2"] highlightedImage:[UIImage imageNamed:#"tab22"]];
[secondTab setFrame:CGRectMake(115.0,01.0,90.0,49.0)];
[customizeTabBar addSubview: secondTab];
thirdTab = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tab3"] highlightedImage:[UIImage imageNamed:#"tab33"]];
[thirdTab setFrame:CGRectMake(223.0,01.0,90.0,49.0)];
[customizeTabBar addSubview: thirdTab];
self.tabBar.tag=10;
[self.tabBar addSubview:customizeTabBar];
}
So this is how I make the navbar:
- (void)viewDidLoad
{
[super viewDidLoad];
UINavigationController *navBar = [[UINavigationController alloc] init];
[navBar willMoveToParentViewController:self];
navBar.view.frame = CGRectMake(0, 0, 320, 44);
[self.view addSubview:navBar.view];
[self addChildViewController:navBar];
[navBar didMoveToParentViewController:self];
...
And everywhere I have read says that this is how you add buttons:
UIBarButtonItem *button = [[UIBarButtonItem alloc]initWithTitle:#"test" style:UIBarButtonItemStyleBordered target:self action:#selector(print_message:)];
self.navigationItem.rightBarButtonItem = button;
[button release];
But the button does not show on the navbar. What is wrong with this code?
Unless you're building a custom container view controller (which is a relatively rare thing to do), you should not be building a UINavigationController inside your content controller's -viewDidLoad. While it will provide you a navigation bar, your view controller parent-child relationship will be backwards: your content controller will contain the navigation controller, rather than the other way around.
Instead, you need to create the navigation controller earlier in your app's startup process - maybe in your application delegate, or in your main storyboard if you're using one. Make sure that the new navigation controller has your content controller as its root controller (usually by way of -initWithRootViewController:). Then your self.navigationItem configuration will work properly.
You should create your navigationbar probably differently:
In your xxxAppDelegate.m edit this method:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
//This is the ViewController of the view you want to be the root
xxxViewController *tvc = [[xxxViewController alloc]init];
//Now you have to initialize a UINavigationController and set its RootViewController
UINavigationController *nvc = [[UINavigationController alloc]initWithRootViewController:tvc];
//Now set the RootViewController to the NavigationViewController
[[self window]setRootViewController:nvc];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
So now you have a proper NavigationController. If you do this in the viewDidLoad method, the NavigationController will be made each time you reload your view.
Now in your xxxViewController.m edit your init method:
- (id)init
{
...
if (self) {
//Create a UINavigationItem
UINavigationItem *n = [self navigationItem];
//Create a new bar button item
UIBarButtonItem *button = [[UIBarButtonItem alloc]initWithTitle:#"test" style:UIBarButtonItemStyleBordered target:self action:#selector(print_message:)];
[[self navigationItem]setRightBarButtonItem:button];
}
return self;
}
This should now display a proper NavigationBar with a UIBarButtonItem.