Back button appears on popViewControllerAnimated:YES - ios

I am making an app in which I created custom navigation bar - MyNavigationBar (extends UIView):
MyNavigationBar.xib :
MyNavigationBar.m :
+(id)navigationBar{
MyNavigationBar * bar = (MyNavigationBar *) [[[NSBundle mainBundle] loadNibNamed:#"MyNavigationBar" owner:self options:nil] objectAtIndex:0];
return bar;
}
Then in NavigationViewController implementation I use this code to add view showed above to navigationBar:
NavigationViewController.m:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
_navBar = [MyNavigationBar navigationBar];
[self.navigationBar addSubview:_navBar];
}
return self;
}
When the left button (subview of MyNavigationBar) is pressed
[[self navigationController] popViewControllerAnimated:YES];
is called.
And the problem is that on that pop animation glitch happens, it looks like this:
Back button become visible for all animation duration and then disappears.
I have tried this but nothing happens:
[_navigationBar.backItem setHidesBackButton:YES];

Instead of adding custom subview to navigation bar try setting navigationItem.titleView to your custom UIView or use [UINavigationBar appearance] and [UIBarButtonItem appearance] APIs to customize standard controls.

Related

How do I add a left button item to a UINavigationController on iOS?

I am trying to add a Reload button to the top bar of a navigation controller with no success.
Here is the header:
#interface PropertyViewController : UINavigationController {
}
Here is how I am trying to add it:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
UIBarButtonItem *reload = [[UIBarButtonItem alloc] initWithTitle:#"Show" style:UIBarButtonItemStylePlain
target:self action:#selector(reloadPropertyList:)];
self.navigationItem.leftBarButtonItem = reload;
}
return self;
}
You should use custom navigation bar. hide navigation bar and made your custom. Drag UIView and and add button to it.
If you wantto keep navigation bar than you can use tool bar like,
here
The method initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil is not called automatically so you need to create an instance of PropertyViewController class like below
PropertyViewController *propertyVC = [[PropertyViewController alloc] initWithNibName:#"your_nib_if_exist" bundle:nil];
//pass nib name if nib exist otherwise pass nil

UINavigationBar Back Button show "Back" title on some devices or simulators and the previous view controller title on others

I have an application with a navigation bar that navigates from one view controller to the next.
When navigating to next view controller on some simulators and devices the back button title is "Back" and on some simulator and devices the back button title is the title of the first view controller.
I would really like to understand why?
This is not an issue of changing the text on the back button. The issue is that on some simulators and devices I see the "back" title and on some simulators and devices I see the title of the previous controller.
Tested on over 20 simulators and devices.
Here is the code:
App Delegate
#import "AppDelegate.h"
#import "FirstViewController.h"
#import "SecondViewController.h"
#interface AppDelegate ()
#property (nonatomic, strong) UINavigationController *navigationController;
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
FirstViewController *firstViewController = [[FirstViewController alloc]
initWithNibName:nil
bundle:nil];
self.navigationController = [[UINavigationController alloc]
initWithRootViewController:firstViewController];
self.window = [[UIWindow alloc]
initWithFrame:[[UIScreen mainScreen]bounds]];
self.window.rootViewController = self.navigationController;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
First View Controller
#import "FirstViewController.h"
#import "SecondViewController.h"
#interface FirstViewController ()
#property (nonatomic, strong) UIButton *btnDisplaySecondViewController;
#end
#implementation FirstViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(void)performDisplaySecondViewController:(id)paramSender{
SecondViewController *secondControllrt = [[SecondViewController alloc]
initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:secondControllrt
animated:YES];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"First Controller";
self.btnDisplaySecondViewController = [UIButton
buttonWithType:UIButtonTypeSystem];
[self.btnDisplaySecondViewController
setTitle:#"Display Seconf View Controller"
forState:UIControlStateNormal];
[self.btnDisplaySecondViewController sizeToFit];
self.btnDisplaySecondViewController.center = self.view.center;
[self.btnDisplaySecondViewController addTarget:self
action:#selector(performDisplaySecondViewController:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.btnDisplaySecondViewController];
UIImageView *imageView =
[[UIImageView alloc]
initWithFrame:CGRectMake(0.0, 0.0, 100.0f, 40.0f)];
imageView.contentMode = UIViewContentModeScaleAspectFit;
UIImage *image = [UIImage imageNamed:#"ios7_0135"];
[imageView setImage:image];
self.navigationItem.titleView = imageView;
}
Second View Controller
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Second Controller";
}
When you set the title of the current view controller it will be set automatically in place of Back in the navigation bar when you move to the next view controller. And if you didn't set the title of the current view controller then iOS automatically shows the Back title.
To set the title of the view controller, use the following code:
self.title = #"<title>";
I think you will get this from the explanation.
This is an old question, but I found the same just a second ago. For me, it is a matter of display space. On my iPhone 5, in portrait, I get the short "Back" text, if I rotate the view, it will show the previous' controllers title.
There is a different behavior in iOS6 and iOS7. In iOS7 the title of your first controller will be changed to "Back" (on the left navigationItem in the second VC) if its length exceed 11 characters. In iOS6 the title of the navBar gets truncated and/or the title of the back item.
Hi you can check this one Please upward if your problem has been solve so that the other can be benifited from it.
When my app returns from gallery, it has the navbar's standard colors
Additionally, if you want to change the name of your back button to be different than that of the previous view controller's title, you can do so by creating a custom back button item on the navigation item of the controller being pushed onto the navigation controller stack:
custom UIBarButtonItem for back button
Apple's reference here for backBarButtonItem

UITableView inside popover will not scroll

I am trying to fix someone's code and am running into a problem. Here is the situation:
I have a full screen UIViewController that has a bottom bar button. When I press that button, it shows a popup view controller in the bottom left of the screen. That view controller inside the popup also has a button, and when I press THAT button it pushes a new view controller into my popup window. That new view controller is a UITableView that can have some large number of elements. The problem is that when I try to scroll down to see some offscreen elements, the scroll bounces back to the first position in the table, i.e. it does not really scroll.
More specifically here is some code:
In FullScreenVC.h:
#property (nonatomic, retain) NSMutableArray* stuffInList;
#property (nonatomic, retain) UIPopoverController *namePopover;
#property (nonatomic, retain) UINavigationController *nameNav;
#property (nonatomic, retain) UIBarButtonItem* addButton;
Inside FullScreenVC buttonPressed (called when addButton is pressed):
FirstPopupVC *vc=[FirstPopupVC alloc] initWithNibName#"FirstPopupVC" bundle:nil];
vc.delegate=self;
vc.stuffInList=self.stuffInList; // This is just the NSArray of list items
self.nameNav = [[[UINavigationController alloc] initWithRootViewController:vc] autorelease];
self.namePopover = [[[UIPopoverController alloc]
initWithContentViewController:self.nameNav] autorelease];
[vc release];
[self.namePopover presentPopoverFromBarButtonItem:self.addButton
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
In other words, the FirstPopupVC object vc is the root view controller of a UINavigationViewController nameNav, and nameNav is the navigationcontroller that is the content inside the namePopover UIPopoverController. I think the last line launches FirstPopupVC as a popup from the addButton. Note also that the XIB file FirstPopupVC.xib is a simple NIB file that has a few simple views (label etc) and a little button that a user can press to get the second popup, as we'll see.
Inside FirstPopupVC we have:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// some other irrelevant initialization stuff here ...
self.contentSizeForViewInPopover = CGSizeMake(320, 340);
}
return self;
}
-(void)littleButtonClicked:(id)sender {
SecondPopupVC * secondVC=[[SecondPopupVC alloc]
initWithNibName:"#SimpleTableView" bundle"nil];
secondVC.delegate=self;
secondVC.stuffInList=self.stuffInList;
[self.navigationController pushViewController:secondVC animated:YES];
[secondVC release];
}
This of course presents the second view controller inside the popop.
Inside SecondPopupVC we have:
- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.contentSizeForViewInPopover = CGSizeMake(320, 340);
}
return self;
}
Apparently the contentSizeForViewInPopover call here will set the size of the popover view with the table view. It looks like this is called inside initWithNibName in both the first and second view controllers.
So again, the problem is that if my listOfStuff is large, ie if the set of items in the table is large, then the table will not stay scrolled beyond the first visible set of rows. I can scroll down to see these items but as soon as I release the mouse pointer (on the emulator) or my finger (on the device), it bounces back to the top of the list.
I tried to add autoresizingmak code as discussed in table view in popover is not scrolling but that didn't work for me.
So how can I fix the above code so that my table stays scrolled when I try to scroll it?
Well, it appears that the problem has something to do with the fact that secondVC is created from a NIB file rather than programmatically. I tried doing this instead:
-(void)littleButtonClicked:(id)sender {
SecondPopupVC * secondVC=[[SecondPopupVC alloc] init];
CGSize contentSize = CGSizeMake(320, 320);
UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0,
contentSize.width, contentSize.height)];
popoverView.autoresizingMask = (UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight);
UITableView *tblView = [[UITableView alloc]initWithFrame:popoverView.bounds];
tblView.autoresizingMask = (UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight);
tblView.delegate = secondVC;
tblView.dataSource = secondVC;
tblView.rowHeight = 44;
[popoverView addSubview:tblView];
secondVC.view = popoverView;
secondVC.contentSizeForViewInPopover = contentSize;
secondVC.stuffInList=self.stuffInList;
[self.navigationController pushViewController:secondVC animated:YES];
[secondVC release];
}
and guess what? It works fine. So why would there be such a problem when SecondPopupVC is initialized from a NIB file rather than using code?

Gap when changed of viewcontroller

I'm implementing an application, in which i use several view controllers. But i've found a strange behaviour of my app' when it changes of viewcontroller. Let me explain :
We are in a first viewcontroller, his init method is :
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
Menu = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0)];
self.view.backgroundColor = [UIColor greenColor];
[self.view addSubview:Menu];
[Menu release];
}
return self;
}
After that, to change of viewcontroller and pass from the first to another, i call this method :
-(void)GoPlay
{
if (!parametresviewcontroller)
{
parametresviewcontroller = [[ParametresViewController alloc]init];
}
UIView *menuView = menuviewcontroller.view;
UIView *paramView = parametresviewcontroller.view;
[menuviewcontroller viewWillAppear:NO];
[parametresviewcontroller viewWillDisappear:NO];
[menuView removeFromSuperview];
[self.view addSubview:paramView];
[menuviewcontroller viewDidAppear:NO];
[parametresviewcontroller viewDidDisappear:NO];
}
So the init method of the second viewcontroller is called, i put it next :
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
Parametres = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0)];
Parametres.backgroundColor = [UIColor redColor];
[self.view addSubview:Parametres];
[Parametres release];
}
return self;
}
And the result is :
Why this strange behavior occured ? I really don't understand why the is a gap between the first and the second one...
Thank you ! =)
Ok, The problem is, both the class Is a UIViewController and you have set statusbar for both ViewController's View in XIB file. When you set StatusBar Than the view frame changes its y to 20 pixel below means you have set it to 0 but originally it is 20.
So when you add subView second ViewController's view on the first ViewController's View before doing this set:
secondViewController.view.frame = firstViewController.view.bounds;
. This will solve your problem.
First of all, DO NOT CALL viewWillAppear, viewWillDisappear, viewDidAppear and viewDidDisappear by yourself, this methods are called by the OS in some specific points of a UIViewController life-cycle.
Second, initWithNibName is not the proper method for adding subviews to the controller's view, for that you should use viewWillAppear, viewDidAppear or viewDidLoad.
Third, what you are doing is not changing of view controllers is simply adding a view controller's view to another view controller view, for changing UIViewController you should use addChildViewController: and removeFromParentViewController methods or use UINavigationController
I've found a solution : iPhone hiding StatusBar shifts view down by 20 pix
Use
[self setWantsFullScreenLayout:YES];
in the init method in my case.
Thank you all !

UINavigationController title is not displayed?

I have normal UIViewController ,inwhich I added UINavigationControllerDelegate,i
added as following in willappear?but it did not work?
[self.navigationController setNavigationBarHidden:NO animated:YES];
self.navigationController.navigationItem.title = #"hai";
You should set the title in the view controller you add to your navigation controller.
i.e. in the add view controller
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"My Title";
}
or access the array of your viewcontrollers directly
AddFriendViewController *addFriendsView = [[AddFriendViewController alloc] initWithNibName:#"AddFriendViewController" bundle:nil];
[self.navigationController pushViewController:addFriendsView animated:YES];
[[self.navigationController.viewControllers objectAtIndex:0] setTitle:#"myTitle"];
[addFriendsView release];
Every view controller has a navigation item. You are changing the navigation item of the navigation controller... but that will never be seen unless the navigation controller was inside another navigation controller! Instead of
self.navigationController.navigationItem.title = #"hai";
you want
self.navigationItem.title = #"hai";
or, if your navigation item's title is nil, the navigation controller will use your view controller's title:
self.title = #"hai";
You should simply set the view title, which is used by both navigation bars and tab bars, unless you want to specify a different title for each of those for some reason.
Are you sure that self.navigationController.navigationItem is not nil when you set its title?
If no viewcontroller has been pushed on the stack, ie. you're displaying the viewcontroller at the top of the stack (sometimes called rootViewController) you can do it with
[rootViewController setTitle:#"Title"];
NOTE that you must use setTitle - rootViewController.title=#"Title" will normally not work.
Actually, you can do it with any viewcontroller, even if it's not viewDidLoad'ed yet. If it's created programmatically, just create it with
myViewController *mvc=[[myViewController alloc] initWithNibName:#"nameofnibwithout.xib" bundle:nil];
Or you could declare it as an object in the app delegate, make it an IBOutlet, create a UIViewController and set its class to myViewController, and connect it to the IBOutlet so it's not nil.
You may need to set the Navigation bar to "Black Navigation Bar With Prompt" in the Attributes tab on the controller. That's what worked for me.
In my case the title was not visible on iOS6, when I set it up in the init method:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = LS(#"Favorites");
self.tabBarItem.title = LS(#"Favorites");
self.tabBarItem.image = [UIImage imageNamed:#"star"];
}
return self;
}
So, it should be moved from there to ViewDidLoad.

Resources