Strange Bug in iOS 6 UINavigationController - objective-c

I have found a strange bug in ios. When I use UINavigationController and push other controllers, the titleView shifted to the right so much as how many controllers was pushed
It's looks like this:
My code is simple:
self.navigationItem.title = #"Test Title";
In the second case, controller has 5th in viewControllers stack. The controller in the all cases is same.
I was using the appearance for UIBarButtonItem, in my AppDelegate.
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(-1000, 0) forBarMetrics:UIBarMetricsDefault];

I was fix it with some trick =)
[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTitleTextAttributes:#{UITextAttributeFont: [UIFont systemFontOfSize:0.1]}
forState:UIControlStateNormal];

Related

Storyboard: How to set a UIToolbar at the bottom of a UITableViewController controlled by a UINavigationViewController

I'm new to the Cocoa topic. I build with the Storyboard a small application which runs just fine.
I'm pushing UITableViewController to another one, controlled by the UINavigationViewController. Now I need a UIToolbar with a UIBarButtonItem fixed at the bottom of the screen.
Here can you see my Storyboard So I added via drag and drop a Toolbar and in the toolbar an button into the Period TableViewController, thus it is on the same hierarchic level like the UITableView.
Unfortunately neither the "PayOff" Button nor a bottom Toolbar does appear in the app.
Can you help me, what is wrong with my Storyboard?
In your ViewController try adding this
[self.navigationController setToolbarHidden:NO animated:YES];
and use this to add BarItems to it
[self setToolbarItems:#[item1, item2, item3] animated:YES];
I'm using this method to add a scan button to a UITableViewController:
UIBarButtonItem *leftSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *rightSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
...
...
UIBarButtonItem *scanItem = [[UIBarButtonItem alloc] initWithCustomView:scanButton];
[self setToolbarItems:#[leftSpace, scanItem, rightSpace] animated:YES];
You should be careful because the ToolBar visibility is set for the entire NavigationController you are using and you should show/hide it when needed.
Also the items on it need to be set on each controller (I have this issue, maybe there is a better way to do it)
Hope this helps.

Modal status bar and navigation bar text colors from UIActivityViewControllers in iOS 7

When I'm using a UIActivityViewController, after the user chooses an activity (such as Mail or Message), I can not change the text color for the status bar nor the text/tint color of the Cancel and Send navigation bar buttons. For the bar buttons, in the AppDelegate I've tried using:
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
And nothing happens. However I am able to set the navigation bar title with this:
[[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor], UITextAttributeTextColor, nil]];
I set the UIViewControllerBasedStatusBarAppearance to NO in the Info.plist. And put the line:
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
in the AppDelegate, and have had no luck changing the status bar color at all. Any ideas?
As the UIActivityViewController presents the underlying model view controllers, we use this workaround to fix the status bar color issue:
#interface StatusBarColorApplyingActivityViewController : UIActivityViewController
#end
#implementation StatusBarColorApplyingActivityViewController
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
[super presentViewController:viewControllerToPresent animated:flag completion:^{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
if (completion) {
completion();
}
}];
}
#end
As you can see, this is just a class extending the UIActivityViewController overriding the presentViewController:animated:completion:. When the view controller has been presented we set the status bar style via UIApplication in the completion block. Then we call the original completion block given to the method, if any.
Rather than sub-classing from UIActivityViewController, we can change the tintColor of the navigation bar upon presenting it and revert it upon completion in the completionHandler. For example:
UIColor *normalColor = [[UINavigationBar appearance] tintColor];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:dataToShare applicationActivities:nil];
[activityViewController setCompletionHandler:^(NSString *activityType, BOOL completed) {
// back to normal color
[[UINavigationBar appearance] setTintColor:normalColor];
}];
[self presentViewController:activityViewController animated:YES completion:^{
// change color to suit your need
[[UINavigationBar appearance] setTintColor:[UIColor colorWithRed:25.0f/255.0f green:125.0f/255.0f blue:255.0f/255.0f alpha:1.0f]]; // ActionSheet options' Blue color
}];
In iOS 8 the UIActivityViewController presents its individual compose controllers on the root view controller of your application.
You need to subclass your root view controller (whether it be a UIViewController or UINavigationController) and add the following code.
#interface UINavigationControllerBarColor : UINavigationController
#end
#implementation UINavigationControllerBarColor
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
[super presentViewController:viewControllerToPresent animated:flag completion:^{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
if (completion) {
completion();
}
}];
}
#end
and then instead of initializing a UINavigationController in the AppDelegate or storyboard, initialize your newly subclassed controller.
Some other recommendations subclass the UIActivityViewController but this does not work.
If you want to change the bar button and title colors as well use the following in your application:didFinishLaunching:
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
[[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
[UIColor whiteColor], UITextAttributeTextColor,
[UIFont systemFontOfSize:18.0f], UITextAttributeFont,
nil]];
[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTintColor:[UIColor whiteColor]];
I believe the code to change the navigation bar color is this:
[[UINavigationBar appearance] setBarTintColor:[UIColor whiteColor]];
This is for changing the colours of the navigation bar buttons in iOS 7, if you might need it:
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
And this is the code if you want to change the colours of the buttons in iOS 6:
[[UIBarButtonItem appearance] setTintColor:[UIColor redColor]];
This code is also for iOS 8+ to change the bar button text color for UIActivityViewController activities (like sharing via Messages or Mail Composer).
I found a solution to change the text color of the Send and Cancel buttons.
Check my answer from here.
Regarding changing the status bar style from black to white, I've tried pretty much everything that is on Stackoverflow and nothing worked. There seems to be no workaround it.
One thing that might work, but I don't really know how to use it, could be changing the status bar style in the child view controller. There's a Stackoverflow post about it here.
This might work only if the assumption that the MFMailComposerViewController and MFMessageComposeViewController are child view controllers of UIActivityViewController and therefore if we specify the status bar style for the UIActivityViewController then the child view controllers should have the same status bar style as the parent.
There's a method in the UIViewController called childViewControllerForStatusBarStyle. Here is the Apple documentation for it .
But I don't really know how to use that. Did anyone figure this out?
You have to set the tintColor of the entire app.
self.window.tintColor = [UIColor redColor];
or
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
bar buttons
self.navigationController.navigationBar.tintColor = [UIColor redColor];

Recipients field of MFMessageComposeViewController doesn't show in iOS 7

The code below works fine in iOS 5/6. In iOS 7, it looks like this (red oval for emphasis).
Code:
if ([MFMessageComposeViewController canSendText]) {
self.messageComposer = [MFMessageComposeViewController new];
self.messageComposer.recipients = #[number];
self.messageComposer.messageComposeDelegate = self;
[self presentViewController:self.messageComposer
animated:YES
completion:nil];
}
Question: This is simple code. Is there some other external property, perhaps of the presenting view controller, that is affecting this? Anyone have a fix or workaround?
thanks.
I've found that the MFMessageComposeViewController's recipient field seems to take some of it's appearance from the UINavigationBar appearance proxy in iOS7. To work around this, I've done the following in my apps:
Create an empty custom UINavigationController subclass, which doesn't override any of UINavigationController's methods.
Use this custom UINavigationController subclass as a marker for any navigation controllers that I want to have custom appearance, by setting the custom class on the identity inspector in IB:
In my app delegate, set up the appearance of navigation bars like this:
[[UINavigationBar appearanceWhenContainedIn:[MyCustomNavigationController class], nil] ...];
This ensures that I get the navigation bar appearance I want in the controllers I want to customize, but preserves the standard navigation bar (and related) appearance in other controllers (like MFMessageComposeViewController). Here's a screenshot; note the standard appearance of MFMessageComposeViewController, with the custom navigation bar appearance on the popover in the background:
I faced same problem and here is my solution-
Before presenting your message composer( [self presentViewController:messageComposer animated:YES completion:nil]; )
set
[[UINavigationBar appearance] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
and in delegate method
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller
didFinishWithResult:(MessageComposeResult)result {
UIImage *backgroundImage = [UIImage imageNamed:#"Navigation Bar"];
[[UINavigationBar appearance] setBackgroundImage:backgroundImage forBarMetrics:UIBarMetricsDefault];
[self dismissViewControllerAnimated:YES completion:nil];
}
Thats all!!

Set default rightBarButtonItem for UINavigationController

Sup guys,
I have a tabBarController with a navigationController on each tab.
I wanted to set de default right bar button of navigation bar so I wouldn't have to write the same code on 3 different view controllers.
I tried [[UINavigationBar appearance] setRightBarButtonItem:myButton];
but had no success, is says:
-[_UIAppearance setRightBarButtonItem:]: unrecognized selector sent to instance
Then I tried to create my own UINavigationController subclass so I could set the button like:
self.navigationItem.rightBarButtonItem = myButton but again no success, nothing seems to happen probably because I dont have a navigationItem at this time.
Anyone have another solution?
If you inherit from the UIViewController you can set the right button like this
UIBarButtonItem * rightButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"foobar.png"] style:UIBarButtonItemStylePlain target:self action:#selector(myAction)];
self.navigationItem.rightBarButtonItem = rightButton;
[rightButton release];

UIToolbar in a popover

Is it possible to show toolbar items in a UIViewController inside a popover? I'm doing this in the viewDidLoad method of my view controller:
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil];
[self setToolbarItems:[NSArray arrayWithObject:addButton]];
[addButton release];
Then I'm wrapping this view controller in a UINavigationController (which has a toolbar property, and according to the docs, I'm supposed to use the setToolbarItems method of UIViewController to add items to the toolbar), then presenting it in a popover.
I do not see the toolbar. Are toolbars unsupported when using a popover?
Thanks
Figured it out, apparently the toolbar is hidden by default so you have to do this:
[self.navigationController setToolbarHidden:NO animated:NO];
To make it appear.