iOS8: How do I make statusBar opaque after navigationBar is hidden using hidesBarsOnSwipe? - objective-c

I am building iOS8 app. On my tableview controller, I am using self.navigationController.hidesBarsOnSwipe = YES, to hide the navigationBar on swipe up gesture. It is working nicely, but my statusBar becomes transparent and shows the table content underneath.
On storyboard, Status Bar are Top Bar are set to "Inferred"
I want to:
1. Keep my status bar opaque
2. Maintain the same color as the navigationBar
3. Table content scrolls underneath the statusBar
Thank you.

Here is a Swift solution:
First, change UITableViewController to UIViewController and add a tableView field.
Then, implement your viewDidLoad method as follows:
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.frame = view.frame
view.addSubview(tableView)
let topBar = UIView(frame: UIApplication.sharedApplication().statusBarFrame)
topBar.backgroundColor = myDesiredColor
view.addSubview(topBar)
}

You can add a constraint to the top layout, by this scrolling content will not appear below the status bar.

Make a custom View.
UIView * statusBarView =[[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 20)];
statusBarView.backgroundColor=[UIColor whiteColor];
[self.view addSubview:statusBarView];

Related

UISearchDisplayController with ViewController issues

I have a ViewController with a Navigation Controller before it, that has a TableView and other elements inside. The tableView has also a Search Bar, and in the scene, besides the main ViewController I have a Search Display Controller.
The functionality is working, but I have the following UI issues:
Although my main view has black background colour(and most of the elements have black background colour), when I drag the tableView downwards there appears some white space.
I also have the following initial setup for UI
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.view.backgroundColor = [UIColor blackColor];
self.tableView.backgroundColor = [UIColor blackColor];
self.searchDisplayController.searchResultsTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
self.searchDisplayController.searchResultsTableView.separatorColor = [UIColor blackColor];
self.searchDisplayController.searchResultsTableView.separatorInset = UIEdgeInsetsMake(0, 12, 0, 12);
[self.searchDisplayController.searchResultsTableView setBackgroundColor:[UIColor blackColor]];
[self.searchDisplayController.searchContentsController.view setBackgroundColor:[UIColor blackColor]];
self.searchDisplayController.searchBar.barStyle = UIBarStyleBlack;
self.searchDisplayController.displaysSearchBarInNavigationBar = NO;
}
When I search for a result, and drag the table upwards after the Search Bar, there is a small place where the table view is visible.
Any ideas how can I fix this :(?
Edit update:
Both were solved removing the Search Bar from the TableView. After this another issue came that the animation of Search Display Controller wasn't updating the Search Bar. this was solved with the following post:
UISearchBar animation issue
You have to set UIView background color to black (not just UITableView color).
You have to position your table view below UISearchBar, you can do this either programmatically or via IB. I recommend second option. Pretty easy.

Adjust SearchBar size in Navigation Bar when Orientation changes to Landscape iOS7

I'm using a Storyboard where I have a UIViewController embedded in a Navigation Controller. I have placed a SearchBar into the Navigation Controller "replacing" the TextView item with it. It works as expected in portrait.
The problem is when I rotate it to Landscape, where the Searchbar remains in the center and its height seems to be bigger than the Nav Bar.
I have tried configuring the constraints, but it hasn't been successful.
Could you help me please?
Set Constraints to your Search bar.. It will shows the magic.
I fixed it adding the search bar in the title view, this way:
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectZero];
[self.searchBar setPlaceholder:#"Buscar Recetas"];
[self.searchBar sizeToFit];
[self.searchBar setDelegate:self];
[self.navigationItem setTitleView:self.searchBar];
Note that I'm not using a search display controller in this case. Search Display Controller already has a property where you can set the search bar in the navigation bar, like this:
self.searchdisplaycontroller.displaysSearchBarInNavigationBar = YES;

Visible buttons with transparent navigation bar

I've seen several apps that have completely transparent navigation bars but with visible buttons, I cant seem to find anything that wont make the button invisible as well. I'm sure they were using UINavigationController for the navbar because it had the same animations with fade and what not.
Im currently using this code in ViewDidLoad and ViewDidAppear to either hide or show the nav bar because it's not supposed to be on the first page-
[self.navigationController setNavigationBarHidden:NO animated:YES];
and this code for its transparency:
[self.navigationController.navigationBar setAlpha:0.0];
Create a subclass of UINavigationBar containing no methods except drawRect:. Put custom drawing code there if you need to, otherwise leave it empty (but implement it).
Next, set the UINavigationController's navigation bar to this subclass. Use initWithNavigationBarClass:toolBarClass: in code, or just change it in the Interface Builder if you're using storyboards/nibs (it's a subclass of your UINavigationController in the hierarchy at the side).
Finally, get a reference to your navigation bar so we can configure it using self.navigationController.navigationBar in the loadView of the contained view controller. Set the navigation bar's translucent to YES and backgroundColor to [UIColor clearColor]. Example below.
//CustomNavigationBar.h
#import <UIKit/UIKit.h>
#interface CustomNavigationBar : UINavigationBar
#end
//CustomNavigationBar.m
#import "CustomNavigationBar.h"
#implementation CustomNavigationBar
- (void)drawRect:(CGRect)rect {}
#end
//Put this in the implementation of the view controller displayed by the navigation controller
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBar.translucent = YES;
[self navigationController].navigationBar.backgroundColor = [UIColor clearColor];
}
Here's a screen shot of the result, mimicking Plague.
The blue border was drawn in drawRect: to show you that a UINavigationBar is there and not just a button and a label. I implemented sizeThatFits: in the subclass to make the bar taller. Both the button and label are UIView's containing the correct UI element that were placed in the bar as UIBarButtonItems. I embedded them in views first so that I could change their vertical alignment (otherwise they "stuck" to the bottom when I implemented sizeThatFits:).
self.navigationController.navigationBar.translucent = YES; // Setting this slides the view up, underneath the nav bar (otherwise it'll appear black)
const float colorMask[6] = {222, 255, 222, 255, 222, 255};
UIImage *img = [[UIImage alloc] init];
UIImage *maskedImage = [UIImage imageWithCGImage: CGImageCreateWithMaskingColors(img.CGImage, colorMask)];
[self.navigationController.navigationBar setBackgroundImage:maskedImage forBarMetrics:UIBarMetricsDefault];
//remove shadow
[[UINavigationBar appearance] setShadowImage: [[UIImage alloc] init]];
To make the Navigation Bar transparent, use the below code:
self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];
self.navigationController.navigationBar.tintColor = [UIColor clearColor];
self.navigationController.navigationBar.translucent = YES;
After this set the background image of the Navigation Bar the same as the view behind it using the below property:
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"SAMPLE.jpg"] forBarMetrics:UIBarMetricsDefault];

How to change the Title View of the navigation bar into some Custom View and fill the original size

I want to change the titleView of navigationBar with a regular text field. Then I want to set the textField size to fill the old "normal" titleView.
I can't seem to be able to do this in storyBoard. Dragging a text Field to the place where the navigation title View is doesn't work.
So I added stuff at
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
PO(self.navigationItem.titleView);
CGRect theFrame= self.navigationItem.titleView.frame;
self.navigationItem.titleView=self.searchBar;
//self.searchBar.frame = theFrame;
while (false);
...
It's working with one cached. That PO is a macro that print the content of the object. Turns out at viewDidAppear, self.navigationItem.titleView is null.
So while I can display the searchBar, I cannot make the searchBar "fill" it's space because I do not know the space is.
I prefer not to hard code it because you know, things may change in the future.
So what should I do?
I once saw codes where rather than setting the self.navigationItem.titleView, you would simply add subview to it. The problem with this approach even on viewDidAppear, self.navigationItem.titleView is 0.
I added these codes:
CGRect theFrame= self.navigationItem.titleView.frame;
CGRect theFrame2 = self.searchBar.frame;
CGRect theFrame3 = self.navigationController.navigationItem.titleView.frame;
And, I do not know how to nslog structure value, however, theFrame and theFrame3 are all 0
You can try this inside viewWillAppear:
UIView *customTitleView = [[UIView alloc]initWithFrame:CGRectMake((320-210)/2, 0, 210, 50)];
customTitleView.backgroundColor = [UIColor clearColor];
//create your UITextField or UILabel or other view and add as subview of customTitleView
self.navigationItem.titleView = customTitleView;

UINavigationBar editable title?

I have a UINavigationController based app. I can programatically set the title of the UINavigationBar from within my view controller's viewDidLoad method:
self.navigationItem.title = m_name;
Can I make it so that the title in the navigation bar is editable? IE. I want the user to be able to tap the title in the navigation bar, and to be able to edit it.
Is this possible? And if it is possible, does is it likely to meet Apple's Human Interface Guidelines? (This post suggests it will, but does not tell me how to implement it - Make UINavigationBar title editable)
Many thanks
Nathan
You are able to set a custom view for your title.
titleView
A custom view displayed in the center of the navigation bar when the
receiver is the top item.
#property(nonatomic, retain) UIView *titleView
Discussion
If this property value is nil, the navigation item’s title is
displayed in the center of the navigation bar when the receiver is the
top item. If you set this property to a custom title, it is displayed
instead of the title. This property is ignored if leftBarButtonItem is
not nil.
Custom views can contain buttons. Use the buttonWithType: method in
UIButton class to add buttons to your custom view in the style of the
navigation bar. Custom title views are centered on the navigation bar
and may be resized to fit.
If you were to place a UITextField in your titleView you could give it a clearColor background and set it to have no border. Wala you have a UINavigationBar Title you can tap and edit.
Ryan's solution is exactly right. In case anyone is having trouble implementing it, here is some sample code that should get you going. Just paste it into ViewDidLoad on any class with a navigationController.
UITextField *textField = [[UITextField alloc]initWithFrame:CGRectMake(0, 0, 200, 22)];
textField.text = #"Insert Title Here";
textField.font = [UIFont boldSystemFontOfSize:19];
textField.textColor = [UIColor whiteColor];
textField.textAlignment = NSTextAlignmentCenter;
self.navigationItem.titleView = textField;
And if your project doesn't use ARC, make sure to release the textField like so:
UITextField *textField = [[[UITextField alloc]initWithFrame:CGRectMake(0, 0, 200, 22)]autorelease];
or like so:
[textField release];
Hope that helps.
Ryan's solution for swift
let textField = UITextField(frame: CGRect(x: 0, y: 0, width: 200, height: 22))
textField.text = "Title"
textField.font = UIFont.systemFontOfSize(19)
textField.textColor = UIColor.whiteColor()
textField.textAlignment = .Center
self.navigationItem.titleView = textField
Here is Ciprian's code in Swift 4 and corrected for iOS 12:
let textField = UITextField(frame: CGRect(x: 0, y: 0, width: 200, height: 21))
textField.text = "Your Title"
textField.font = UIFont.systemFont(ofSize: 17, weight: .semibold)
textField.textAlignment = .center
self.navigationItem.titleView = textField
You can put a text field right ON TOP the navigation bar, and set it hidden/not enabled., the use a gesture recognizer to detect a tap on the navigation bar and set the text field to enabled/ not hidden. Then in the textfield's did end editing method, set it to hidden again and set navigation bar's title to that of the textfield.
Add a hidden textfield over navigation bar, so on tapping, it will popup a keyboard and user can enter text into that.
Get the return button event, over there you can change your navigation bar text with newly added text. And hide the textfield again.
Enjoy Coding :)
Put a textField on the NavigationBar and set the textField background color with opacity to zero.