Adding MKMapView Causes Status Bar Issue in iOS 7 - ios

I'm solving the status bar issue in iOS 7 using
if(st.version == 7)
{
CGRect screen = [[UIScreen mainScreen] bounds];
CGRect frame = self.navigationController.view.frame;
frame.origin.y = 20;
frame.size.height = screen.size.height - 20;
self.navigationController.view.frame = frame;
}
Since I'm using navigation controller and pushing from one to another using [self.navigationController pushViewController:newone animated:YES];. It works fine in all view controllers. But, if the viewcontroller has mkmapview in xib, status bar issue of ios 7 occurs.
If I delete the mapview form xib and push to that view controller means, it will be like,
If I add the mapview even by code below,
mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 100, 320, 100)];
[self.view addSubview:self.mapView];
It looks like,
How to solve this?

if(st.version == 7){
mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 120, 320, 100)];
}else{
mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 100, 320, 100)];
}

If you add mapView in viewWillAppear replace it in viewDidAppear.
Maybe you have this issue because you're doing manipulations with view's frames before your view is completely set up

I would highly suggest against doing it like that.
If you're using interface builder, then add constraints based on how you want your application to look and the frame will auto adjust itself.
If you're not using interface builder, then still use constraints, but get a good tutorial about making constraints programatically (as I don't know how to do it myself).
Edit: The reason I HIGHLY suggest not doing it with hardcoded numbers is that it'll be a pain to do iOS 6/7 Landscape/Portrait 3.5/4 inch screens. That's 8 cases.

i think you have some adjust your navigation Y position set -20px. that way it goes overlay. use this code your ViewController
CGRect screen = [[UIScreen mainScreen] bounds];
CGRect frame = self.navigationController.view.frame;
frame.origin.y =0;
frame.size.height = screen.size.height;
self.navigationController.view.frame = frame;
or may it you have use wantFullScreenLayout some where in your project
setWantsFullScreenLayout = YES:
statusbar section is located to the (0,0) point to catch.
Statusbar and as large as the size of the current view to increase the value of mainScreen change the size of the bounds.
Statusbar change the style of the translucent style.
this below link you get some clear idea about your issue
How do I get the navigation bar in a UINavigationController to update its position when the status bar is hidden?

Override the -edgesForExtendedLayout method in your view controller
-(UIRectEdge)edgesForExtendedLayout {
return UIRectEdgeNone;
}

If you want to hide status bar from a particular view add this method in that particular view.m file
- (BOOL)prefersStatusBarHidden
{
return YES;
}

What about setting self.automaticallyAdjustsScrollViewInsets = NO; in viewDidLoad of your view controller or in IB?

Try to set MapView(ScrollView) automaticallyAdjustsScrollViewInsets = NO;
Try to set edgesForExtendedLayout to UIRectEdgeNone;
Try to use UIViewController.topLayoutGuide, see the Q&A from apple about this issue:Preventing the Status Bar from Covering Your Views.
Try to use the bar position delegation, see UIBarPositioningDelegate Protocol Reference
According to your description and screenshots, you are trying to move the whole UINavigationController.view.frame 20 pt, and the MapView(ScrollView) did something to prevent it happened (or re-set), put some breakpoint and log to track the frame of UINavigationController.view.frame changed.
Could you please provide a sample project? I'm so curious about what really happened.

try this
- (void)viewWillAppear:(BOOL)animated
{
self.navigationController.navigationBar.translucent = NO;
}
- (void)viewDidAppear:(BOOL)animated
{
self.navigationController.navigationBar.translucent = YES;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
[application setStatusBarHidden:YES];
return YES;}
Please add this line to your code.This will hide the status bar from your app.

If you have a xib. Did you try to enabled Top Bar in simulated Metrics ?

Related

iOS hidesBarsOnSwipe status bar background color

When I swipe and hide the navigation bar with the hidesBarsOnSwipe property the status bar has a clear background. How can I set the background of the status bar to the same color as the navigation bar? Here are a few pictures showing my problem, this is all contained in a UITableViewController.
Separate
Separate picture, looks like one big one.
I've come across the same issue, and was able to solve it. I'm fairly new to iOS dev, and I don't imagine this solution to be foolproof. I couldn't find any good answers elsewhere, so here's how I overcame it:
I converted from a UITableViewController over to UIViewController with a nested UITableView. Note, double check that the delegate to the child tableview is set to the UIViewController.
I Added a view with a height of 20px and a background colour that you want to set as the "background" to the status bar. Set the constraints on that view as follows:
On your table view, set the constrains to be basically full screen. One important note here, the top constraint is to "Top Layout Guide.Top" and not to "Top Layout Guide.Bottom". By default I believe this constraint ties to the bottom. Double clicking on the constraint allows you to adjust it to the top. Without this, any table header cells weren't positioned properly for me
Hope that helps.
Adding to George Huber's answer. I solved this issue programmatically by adding a 20pt height UIView as a subview of the navigationController's view property -- in viewDidLoad method.
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *statusBarBG = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 20)];
statusBarBG.backgroundColor = [UIColor navBar];
[self.navigationController.view addSubview:statusBarBG];
// REST OF CODE
}
Per skg's answer, I add a relative height for status bar according to iOS version.
self.navigationController.hidesBarsOnSwipe = true;
// add a UIView as subView to navigationController
CGFloat statusBarHeight;
if (#available(iOS 13, *)) {
NSArray *windows = UIApplication.sharedApplication.windows;
UIWindow *keyWindow = nil;
for (UIWindow *window in windows) {
if (window.isKeyWindow) {
keyWindow = window;
break;
}
}
statusBarHeight = keyWindow.windowScene.statusBarManager.statusBarFrame.size.height;
NSLog(#"statusBarHeight: %f", statusBarHeight);
} else {
statusBarHeight = UIApplication.sharedApplication.statusBarFrame.size.height;
}
UIView *statusBarBG = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), statusBarHeight)];
statusBarBG.backgroundColor = [UIColor systemBackgroundColor];
[self.navigationController.view addSubview:statusBarBG];

Change color behind app on rotation

When an iOS app rotates it will reveal a black background when the app is between portrait and landscape. Is it possible to change this color from the default black to white? Changing the UIWindow's background color will not help. Here is an example of the black background in Safari during rotation:
I have done something similar but I couldn't find the source now, but here is the idea:
Create and add a significantly larger view as backing view and center it.
Add the UIWebView as subview of this large view whose background is white.
Re-position the center of the UIWebView, too.
You can do this way:
Add a UIViewController and set it as initial VC (in screenshot it is MainVC).
Add two UIViewContainer: first for holding your background view , and second for your other vcs.
Override viewDidLayoutSubviews in implementation file of background VC (in this case the .m file of red VC)
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
//Some hardcode :)
self.view.frame = CGRectMake(-100, -100, 1136, 1136);
}
After doing this you will have something like this:
I know this is not the best solution, but you can do this way until you find the best one.
I got the same issue. As I understand that you want to remove the black background. The easiest solution that I used is set you window clipsToBounds = true instead of your rootViewController.
window?.clipsToBounds = true
You can solve the problem by adding empty general view controller with oversized bounds into your root viewController and make it the lowest in the view hierarchy:
CGFloat length = 2*MAX(rootViewController.view.bounds.size.height, rootViewController.view.bounds.size.width);
UIView *oversizedBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, length, length)];
oversizedBackgroundView.center = vc.view.center;
oversizedBackgroundView.backgroundColor = [UIColor whiteColor];
rootViewController.view.clipsToBounds = NO;
[rootViewController.view addSubview:oversizedBackgroundView];
[rootViewController.view sendSubviewToBack:oversizedBackgroundView];
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
The key point here is to set clipsToBounds to NO

iOS 7 UISearchBar right spacing

Don't know why, my search bar in iOS 7 is leaving a right space. It's ok in iOS 6.
I know it has something to do with the section index, because if I remove it the space disappears, but I don't know how to fix it. Any thoughts?
Embed your UISearchBar in a UIView and then add that as the tableHeaderView. Structuring it that way in a storyboard worked for me. I'm guessing iOS resizes the UISearchBar in the tableHeaderView, but leaves a basic UIView alone (and doesn't bother to look inside it).
You might also want to make the section index transparent, which I did with:
[[UITableView appearance] setSectionIndexBackgroundColor:[UIColor clearColor]];
[[UITableView appearance] setSectionIndexTrackingBackgroundColor:[UIColor clearColor]];
Until a better answer appears, I just manually changed the frame of the search bar like this:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
CGRect barFrame = self.searchBar.frame;
barFrame.size.width = self.view.bounds.size.width;
self.searchBar.frame = barFrame;
}
I had this same issue with the iPhone 6/ 6Plus when using a SearchDisplayController. (Using Swift)
I tried setting the frame of the search bar but with no luck but i noticed that if i tapped on the textField of the UISearchBar and then cancelled it then it would take on the proper size of the view. I therefore managed to fix the issue by calling the code below in ViewDidLoad of the viewController using the search.
self.searchController.setActive(true, animated: false)
self.searchController.setActive(false, animated: false)
self.contactsTableView.sectionIndexBackgroundColor = [UIColor clearColor];
The reason for that white edge is because your index layer has a white background and is on top of the search bar. This should be sufficient.
Add the search bar inside a UIView put as tableView's header view. Set the tableview's sectionIndexBackgroundColor to clear color because it covers the header.
Tested with iOS 7, 7.1;
Because the table view always leaves 15px on the right for section Indexes View, so you should resize the Seach bar after reloading the table view
First:
self.tblData.sectionIndexBackgroundColor = [UIColor clearColor]; //(iOS >= 7 only)
Cheating time:
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
[self performSelector:#selector(resizeSearchBar) withObject:nil afterDelay:0.01];
}
- (void) resizeSearchBar
{
CGRect frame = self.searchBar.frame;
if (frame.size.width < self.tblData.frame.size.width) {
frame.size.width = self.tblData.frame.size.width;
}
self.searchBar.frame = frame;
}
- (void) reloadTableData // call it anytime you want to reload table view
{
[self.tblData reloadData];
[self performSelector:#selector(resizeSearchBar) withObject:nil afterDelay:0.01];
}
Suggest
Dont cheat like me, just do the simpler way:
self.searchBar.searchBarStyle = UISearchBarStyleMinimal; // iOS >= 7 only
I also attached a UISearcBar in my application, and nothing is wrong there even my application supports rotation also.
Could you try removing and re creating UISearchBar in storyboard/xib
I added the search bar as a subview of the top-level view instead of the table view. Used autolayout to pin the searchbar to the top guide, and a vertical space constraint of 0 between the search bar and the table view.
The accepted solution with the method viewDidLayoutSubviews makes the screen flicker.
Instead what I did was create a subclass of UISearchBar that simply does this:
FullWidthSearchBar.h:
#interface FullWidthSearchBar : UISearchBar
#end
FullWidthSearchBar.m:
#import "FullWidthSearchBar.h"
#implementation FullWidthSearchBar
- (void)setFrame:(CGRect)frame {
frame.size.width = self.superview.bounds.size.width;
[super setFrame:frame];
}
#end
And then I assigned that class to the search bar on my xib:
The problem is the right white block, so if we change the block color the same as the search bar background, it looks normal.
just
if (IOS7) {
self.tableview.backgroundColor = [UIColor colorWithPatternImage:self.searchBar.backgroundImage];
}

UIViewController without NavigationBar, UIView overlaps with Status bar

I am working on updating my app to support iOS7, however one of my view is overlapping with the status bar. Please refer my image,
Apple recommends us to use, self.edgesForExtendedLayout = UIRectEdgeNone; to avoid fullscreen layout. however this is working when we have UIViewController within a UINavigationController and the navigationBar is visible. In my app, I didn't use the UINavigationController. can anyone help me to solve this overlapping issue on UIViewController without NavigationBar.
Finally I myself found the answer. We need to offset the frame in
- (void) viewDidLayoutSubviews method as like follow,
- (void) viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
if([self respondsToSelector:#selector(edgesForExtendedLayout)])
{
CGRect frame = self.view.frame;
frame.origin.y = 20;
frame.size.height = frame.size.height - 20;
self.view.frame = frame;
}
}
Since I am ofSetting the frame in - (void) viewDidLayoutSubviews method, user will not see the transition. If we offset the frame in -(void) viewDidload, user will see the transition. Hope this will help someone.
Do you set wantsFullScreenLayout = YES somewhere on ViewController?
Just offset your view in viewDidLoad:
CGRect frame = self.view.frame;
frame.y = 20;
self.view.frame = frame;
I wrote a full explanation here: https://stackoverflow.com/a/18855464/1078579
The short answer is there's no way to prevent the status bar from overlapping your application on iOS 7. edgesForExtendedLayout only affects the child view controllers inside a UINavigationController or UITabBarController.
You'll need to move the contents of your app into a (0,20,320,548) container view if you want to preserve the iOS 6 style layout.
Add following code in ViewDidLoad
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])
{
self.edgesForExtendedLayout = UIRectEdgeNone;
}

UINavigationController's view and 20 points offset

This is an already posted question but I need to understand what is going on with the following scenario. I'm developing an iPad application and I created a UINavigationController like the following (test purposes).
UINavigationController* navigationController = [[UINavigationController alloc] init];
navigationController.view.backgroundColor = [UIColor redColor];
Once created, I added the UINavigationController's view as a subview of a UIViewController.
[self.view addSubview:navigationController.view];
The result is displayed in the following image:
As you can see, there is a gap between the status bar and the navigation bar of the UINavigationController. Since the view of the UINavigationController is red, it seems that the frame of the navigation bar has that gap.
I've found an hack to fix the problem. By setting the frame for the UINavigationController, the navigation bar goes in the right position.
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
CGRect frameRect = CGRectMake(navigationController.view.frame.origin.x, navigationController.view.frame.origin.y - statusBarFrame.size.height, navigationController.view.frame.size.width, navigationController.view.frame.size.height);
navigationController.view.frame = frameRect;
Now, since I don't like very much that hack and I would understand what is going on, do you have any suggestions to find an elegant solution to resolve the problem?
Thank you in advance.
That 20px offset is for status bar, navigation controller is designed to be full-screen, but you are adding it to the subview of the main view.
viewController setWantsFullScreenLayout:YES
It may help you.
This is the fix that really solved all the problem. So thought of posting it as it might really.
How this works
This gonna set my navigation bar origin to 0, and in turn the view of navigation is also set to 0 which takes the reference of Navigation Bar, which solves all the mess :)
And 44 is the heigh of Navigation Bar in the code. :)
Put the code in ViewDidAppear,
CGRect windowFrame = [UIScreen mainScreen].applicationFrame;
//Setting the Origin to 0 of both Navigation Bar and Navigation View for Both Landscape and Portrait
if (UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)){
[self.navigationController.navigationBar setFrame:CGRectMake(0, 0, windowFrame.size.width, 44)];
[self.navigationController.view setFrame:CGRectMake(0, 0, windowFrame.size.width, windowFrame.size.height)];
}
else{
[self.navigationController.navigationBar setFrame:CGRectMake(0, 0, windowFrame.size.height, 44)];
[self.navigationController.view setFrame:CGRectMake(0, 0, windowFrame.size.height, windowFrame.size.width)];
}
[self setWantsFullScreenLayout:<#(BOOL)#>];
is deprecated. If you want to add subviews to your ViewController without worrying about NevigationBar use:
self.edgesForExtendedLayout = UIRectEdgeNone;

Resources