Changing appearance of UIBarButtonItem also changes position of navigationbar and toolbar? - ios

once again I have a problem with my custom navigation- and toolbar:
I've customised their tintColor and the font by using the appearance proxy in didFinishLaunchingWithOptions. Initially the bars should be hidden by setting their center outside the visible area in viewDidLoad. By single-tapping I use my own animation to slide the bars in/out. Everything was working just fine until the next step:
I wanted the UIBarButtonItems to have the same font like i used in the bars, so I went back to didFinishLaunchingWithOptions and added the following code:
[[UIBarButtonItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:FONT_HEADER size:0.0],UITextAttributeFont,nil] forState:UIControlStateNormal];
It works just fine for the font part, but somehow it also sets the bars back into the visible position before viewWillAppear so the bars are not initially hidden anymore. I tried to find out what causes this unmeant repositioning and couldn't find any connection. I also tried to reset the position at some later point like viewWillAppear but this somehow doesn't work for the toolbar.
EDIT: The described behaviour does only occur on devices with iOS 5 though. On the iOS6 simulator everything still seems fine.
Does anyone have a hint for me what is going wrong here or how I could smoothly solve this problem?
Thanks in advance

[[UIBarButtonItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:FONT_HEADER size:0.0],UITextAttributeFont,nil] forState:UIControlStateNormal];
what's the FONT_HEADER here? Did you check if the ios 5 support this font?

Related

iOS Navigation Bar Height

novice iOS developer and I am trying to figure out why my Navigation bar height wont change after I programmatically change it. I have done the following things:
I added this piece of code to the AppDelegate.m in the didFinishLaunchingWithOptions method
[[UINavigationBar appearance] setFrame:CGRectMake(0, 0, 320, 200)];
I was told that this would create a much larger navigation bar but it doesn't seem to be doing so.
I have also added the following code in a specific view controller (FirstViewController.m) to change the font family, text color, etc.
-(void)awakeFromNib {
[[UINavigationBar appearance] setBarTintColor:[UIColor colorWithRed:(72/255.0) green:(167/255.0) blue:(192/255.0) alpha:1]];
[self.navigationController.navigationBar setTitleTextAttributes:
[NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:#"CaviarDreams" size:28], NSFontAttributeName,
[UIColor whiteColor], NSForegroundColorAttributeName, nil]];}
Am I doing something wrong here?
Any help would be great!!
You can change the height of a navigation bar if it is your navigation bar - if it's just a free-standing interface object.
But if you're using a UINavigationController, the height of the navigation bar is really not up to you. The UINavigationController does the layout of views, and you can't really change what it does. That is part of the price of using this built-in structure, if you see what I mean.
As for your other attempts, you are probably doing them at the wrong time. For example, in awakeFromNib it makes no sense to talk about self.navigationController.navigationBar as it is probably nil anyway at that time (you can easily check with logging). That is why it is better to use the appearance proxy. But then you are doing that too late; you have to use the appearance proxy in application:didFinishLaunching...:, because it affects only future instances of that type.
Basically as a newbie you need to learn what Cocoa lets you do and what it doesn't, and when are the right moments in the process to do those things. It's a big framework. You're in bed with a gorilla; you need to know when the gorilla wants to turn over and let it turn over, or you'll just get squashed. You'll get better at this as you become more accustomed to it.

applicationDidEnterBackground changes navigationColor

I am trying to set navigationBar color with the code below added on applicationDidFinishLaunching:
//Set tint color
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
//Set title attributes
[[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:#"Pacifico" size:21],
NSFontAttributeName, [UIColor whiteColor], NSForegroundColorAttributeName, nil]];
//Set navigationBar color
[[UINavigationBar appearance] setBarTintColor:[UIColor redColor];
everything works good, application starts and colors are correct like the image below
Issue happens when I follow these steps:
I press home button application enters background.
I double press home button to see my application, and there is shown but not in navigationColor RED but BLACK in gradient with RED.
I click to open it, it loads again with the color RED. (Screenshot below)
Maybe the issue is related to the tabBarController.tabBarColor because I set it to black!
I don't know why is this happening, I don't if there is an issue with global tint or so! Has this problem happened to anyone? Any idea how to fix it?
The methods you are looking for are not applicationDidEnterBackground: and applicationWillEnterForeground:. You should use applicationWillResignActive: and applicationDidBecomeActive:.
Here is how they work. If you minimize the app by pressing the home button once, both applicationWillResignActive: and applicationDidEnterBackground: are called, in this order. When you maximize your app applicationWillEnterForeground: and applicationDidBecomeActive: are called, again in the same order. However when you double press the home button to see the recently used apps, only applicationWillResignActive: is called, and selecting your app from this view will call applicationDidBecomeActive: only. So these are the methods you should use.
A warning though, these methods are also called if your app is active and you open the Control Center, or the Notification Center by dragging the bottom / top edge of screen.
Hope you can use this info to your advantage.
For those who are having the same issue, this has nothing to do with background or foreground. It is just no content under the TopViews.
Finally I found the solution
Extend Edges Under Top Bars was unchecked, I did a check on it, and it works.
For those who don't know how to show this, go to you viewController on storyboard, click on it.
Show the attributes inspector (the fourth button) on the right dock
There is a part where is written Extend Edges
Check under the top bars, run the application and everything should be fine
I don't know what causes this issue to let the navBar change to black (I mean the part which has no content, it is just part of the view)

Prevent UiNavigationBar Title from getting Cut off?

I am trying to customize the appearance of the navigationBar title in my ios application. This is the code I currently have:
NSMutableDictionary *navigationTitleAttributes = [NSMutableDictionary dictionary];
[navigationTitleAttributes setValue:[UIColor whiteColor] forKey:UITextAttributeTextColor];
[navigationTitleAttributes setValue:[UIColor clearColor] forKey:UITextAttributeTextShadowColor];
[navigationTitleAttributes setValue:[NSValue valueWithUIOffset:UIOffsetMake(0.0, 0.0)] forKey:UITextAttributeTextShadowOffset];
[navigationTitleAttributes setValue:[UIFont fontWithName:#"Calibri" size:30] forKey:UITextAttributeFont];
[[UINavigationBar appearance] setTitleTextAttributes:navigationTitleAttributes];
[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:-8 forBarMetrics:UIBarMetricsDefault];
The code yields the following effect:
It works great but my title gets cut off from the bottom.
I've seen solutions to this problem that use a custom UIView (such as this one: UINavigationbar title is cut off when using titleTextAttributes). However, that particular solution requires that the titleView property of the navigation bar be updated for each screen.
I was wondering if there was a simple solution that would cascade through my entire application.
Thanks
Th simple solution is to not use such a large font size. If you set the size to zero then the text should be auto-sized as appropriate.
Otherwise, using a custom view is the correct solution. You can subclass the navigation controller or navigation bar in order to ensure that all of the views have the label styled in the same way.
If you're using a custom font, you may be having the same problem I was. I found a few answers on this post to be quite helpful. I changed my descender values in my .otf font file to prevent my font from being cut off on the bottom. It was especially prevalent in iOS 7.
Custom installed font not displayed correctly in UILabel

uiappearance for UIButton also changes UIBarButton image?

I am using this piece of code
[[UIButton appearance] setBackgroundImage:[UIImage imageNamed:#"button.png"] forState:UIControlStateNormal];
To change the appearance of UIButtons. This works nicely and does not affect UIBarButtonItems except for one of them (The only one that is not an auto generated "back" button) and only initially. When you touch the barbutton, it reverts back to not having a background image.
The problematic button is a UIBarButton and not an UIButton (Unless it is both, in which case the other UIBarButtons should be affected too).
A clue can be that the other UIBarButton that are not affected are all generated and not created by me in the storyboard.
This must be a bug in the api?
Solved using setTintColor. Was an api bug that since then probably has been fixed

Customize UINavigationBar font

I'm trying to customize my UINavigationBar font, using the following code for iOS 5 in my app delegate's application:didFinishLaunchingWithOptions:
if ([[UINavigationBar class] respondsToSelector:#selector(appearance)])
{
[[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
[UIColor whiteColor], UITextAttributeTextColor,
[UIColor blackColor], UITextAttributeTextShadowColor,
[NSValue valueWithUIOffset:UIOffsetMake(1, 0)], UITextAttributeTextShadowOffset,
[UIFont fontWithName:kDefaultFont size:0.0], UITextAttributeFont,
nil]];
}
It works fine and the navigation bar is rendered using my font. Great.
The references I've found suggest that you can use the font size of zero and it will resize the font to fit your navigation bar (using a slightly smaller font for the shorter navigation bar for the landscape layout). And it does choose a font size that fits nicely to the height of the navigation bar. But it looks like if you go from portrait to landscape and back, the width of the navigation bar's title label gets screwed up, so what shows up as a title of, for example, "Long Titlebar", looks fine when you first view it in portrait orientation, looks fine when you view it in landscape (with the appropriately smaller font), but when I come back to portrait, the font correctly reverts to the larger font, but the title text itself is truncated, becoming "Long..." even though there's plenty of space for the full title. Has anyone else seen this behavior when using a font size of 0.0?
Clearly, I can just specify an actual font size (in which case I don't see this truncating behavior), but then I'm manually figuring out what size to use. And worse, the font size is the same for landscape and portrait, so right now I'm using a font size that fits in the shorter landscape navigation bar title and the title is smaller than it needs to be in the taller portrait navigation bar.
Has anyone out there had experience with using setTitleTextAttributes to change the font of the [UINavigationBar appearance] in such a way that the font size changes between portrait and landscape, but not having this truncation of the title when you return back to portrait after going to landscape? I'm about to pursue various kludgy workarounds, but if you have any experience in this issue, let me know.
Update:
In the process of submitting this bug to Apple, I decided to demonstrate how to reproduce the problem:
Create new iOS Master-Detail Application in Xcode 4.3.2.
Put the above setTitleTextAttributes code in the app delegate's application:didFinishLaunchingWithOptions (I used the font #"GillSans").
Go to MasterViewController and add line that says self.title = #"Long Title";
Comment out the UIBarButtonItem *addButton code.
Run the program. Note the title correctly says "Long Title". Rotate to landscape. Still looks good. Rotate back to portrait and the title now says "Long..." even though there's plenty of space.
Curiously, if you restore the UIBarButtonItem *addButton code, the title works as it should. But if you either eliminate the UIBarButton item, or replace it with a button that uses initWithTitle rather than initWithBarButtonSystemItem, you get the problem with the navigation bar title after rotating from portrait to landscape and then back to portrait.
By the way, I neglected to point out that Apple replied to my bug report, acknowledging that this was a known issue. Hopefully it will be resolved soon!
the following is my workaround for this problem, and here's the comment that appears next to my workaround implementation in each case as a reminder to myself as to why i implemented this bit of code:
// when using an appearance proxy to set a custom font for the navigation bar (generally in
// application:didFinishLaunchingWithOptions: in the appDelegate code) for both iOS 5 & 6,
// there's a glitch that incorrectly auto-truncates the title in the following cirumstances:
//
// 1) when a 0.0 value is used for UITextAttributeFont in the titleTextAttributes dictionary
// and a device/simulator running pre-iOS 5 rotates back to portrait from landscape
// solution: perform [self.navigationController.navigationBar setNeedsLayout] in
// didRotateFromInterfaceOrientation: the view controller in which the
// auto-truncation is incorrectly occurring for systemVersion < 6.0
//
// 2) when a view initially loads running iOS 6 for a non-0.0 value for the UITextAttributeFont
// in the titleTextAttributes dictionary
// solution: perform [self.navigationController.navigationBar setNeedsLayout]
// in viewDidLoad in the view controller in which the auto truncation is
// incorrectly occurring for systemVersion >= 6.0
so, for the cases where i'm ok with using the 0.0 value for UITextAttributeFont but have to continue supporting iOS5, i use solution (1):
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)
&& UIDevice.currentDevice.systemVersion.floatValue < 6.0)
[self.navigationController.navigationBar setNeedsLayout];
}
#endif
and in the couple of cases of legacy code where i wanted to support iOS 6 and fix the glitch when the view first appears without having to re-write the MyAppAppearance class methods i have that set non-0.0 values for my [UINavigationBar appearance] titleTextAttributes, i found it easier to implement the solution (2) thus:
- (void)viewDidLoad
{
[super viewDidLoad];
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
if (UIDevice.currentDevice.systemVersion.floatValue >= 6.0)
#endif
[self.navigationController.navigationBar setNeedsLayout];
// … other viewDidLoadCode
(and the __IPHONE_OS_VERSION_MIN_REQUIRED bracket just helps remind me which code can eventually go away if desired in the future, and which may have to stay.)
to see a little more exactly what happens here, particularly in the case of the rotation, run the simulator with slow animations toggled.
I think a good solution is to refresh the title of your Navbar after a device rotation. Something like
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
self.navigationItem.title = #"Your title";
}
Hope this helps!
Based on the response from #Abramodj (which doesn't work), I tried this. Presumably nothing was happening in that solution as the system notices that the text hasn't actually changed. Switching to nothing and back again sorts it out.
Tested as definitely working on iOS5.0.
// iOS5 has a bug where if you switch orientation the title bar text gets cut off...
-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
self.navigationItem.title = #"";
self.navigationItem.title = #"Your Title";
}
The bug where a UINavigationBar title text is cut off after applying changes via appearance can happen even if you're not doing orientation switching like Ben Clayton describes. I've seen this problem occur on an app that only supports portrait orientation.
[self.navigationItem setTitle:#""];
[self.navigationItem setTitle:#"The real title"];
Will work just fine even in such a case.
By the way, I've had this issue since iOS 5. Just tested it right now in iOS 6 and IT'S STILL THERE. What the heck, Apple?

Resources