After I toggle in-call status bar, the navigation bar drops. And the content behind falls a height of 20 .
I can not figure out why.
The picture shows the scene.
Looks like the navigation bar drops. And the blue bar falls.
Seen from the view hierarchy debugger, I do not know why the blue bar has a distance from the navigation bar.
Here is the relevant code.
- (void)viewWillLayoutSubviews{
self.blueBar.translatesAutoresizingMaskIntoConstraints = NO;
[super viewWillLayoutSubviews];
[self.blueBar.topAnchor constraintEqualToAnchor: self.view.topAnchor].active = YES;
[self.blueBar.leadingAnchor constraintEqualToAnchor: self.view.leadingAnchor].active = YES;
[self.blueBar.trailingAnchor constraintEqualToAnchor: self.view.trailingAnchor].active = YES;
[self.blueBar.heightAnchor constraintEqualToConstant: 75].active = YES;
......
}
-(UIView *)blueBar{
if(!_blueBar){
_blueBar = [[UIView alloc] init];
_blueBar.backgroundColor = [UIColor blueColor];
}
return _blueBar;
}
The status bar height change from 20 to 40 when in-call.And I found you use tableView,so try this:
if (#available(iOS 11.0, *)) {
self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
self.automaticallyAdjustsScrollViewInsets = NO;
}
What's more,why not use mainstream frameworkMasonry?
Related
I am creating a UI component that should display a UILabel and a UISearchBar below.
However, I am not able to align them, the UISearchBar always has extra space on both left and right side (highlighted RED).
I was trying to set the dimensions of searchBarTextField by layout anchors directly, but it didn't work.
I would prefer to do it using layout anchors when possible.
SearchBar.m:
-(id) init {
self.titleLabel = [UILabel new];
self.searchBar = self.searchController.searchBar;
UIView *searchBarWrapper = [UIView new];
[self.view addSubview:self.titleLabel];
[self.view addSubview:searchBarWrapper];
[searchBarWrapper addSubview:self.searchBar];
[self.titleLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[searchBarWrapper setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.searchBar setTranslatesAutoresizingMaskIntoConstraints:NO];
//[self.titleLabel.widthAnchor constraintEqualToAnchor:self.view.widthAnchor multiplier:1.0].active = YES;
[self.titleLabel.heightAnchor constraintEqualToConstant:14.0].active = YES;
[self.titleLabel.topAnchor constraintEqualToAnchor:self.view.topAnchor].active = YES;
[self.titleLabel.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES;
[self.titleLabel.rightAnchor constraintEqualToAnchor:self.view.rightAnchor].active = YES;
//[self.titleLabel.bottomAnchor constraintEqualToAnchor:searchBarTextField.topAnchor].active = YES;
[searchBarWrapper.widthAnchor constraintEqualToAnchor:self.view.widthAnchor multiplier:1.0].active = YES;
//[self.searchBar.heightAnchor constraintEqualToConstant:36.0].active = YES;
[searchBarWrapper.topAnchor constraintEqualToAnchor:self.titleLabel.bottomAnchor].active = YES;
[searchBarWrapper.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES;
[searchBarWrapper.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES;
[searchBarWrapper.rightAnchor constraintEqualToAnchor:self.view.rightAnchor].active = YES;
[self.searchBar.topAnchor constraintEqualToAnchor:searchBarWrapper.topAnchor].active = YES;
[self.searchBar.bottomAnchor constraintEqualToAnchor:searchBarWrapper.bottomAnchor].active = YES;
[self.searchBar.leftAnchor constraintEqualToAnchor:searchBarWrapper.leftAnchor].active = YES;
[self.searchBar.rightAnchor constraintEqualToAnchor:searchBarWrapper.rightAnchor constant:16.0].active = YES;
return self;
}
The UISearchBarTextField is embedded in a UIView to which I don't have access to.
The constraints:
The approach by #BenOng - works fine, but breaks after tapping for the first time:
UISearchBar have this property searchFieldBackgroundPositionAdjustment:UIOffset which you can set to UIOffsetMake(-8,0) to make the left side of the text field align with the left edge of the search bar.
Create a UIView right where the full search bar should be and make the search bar it's subview. Set the right edge of the search bar beyond it's super view till the right edge aligns with the superview, it should be about 16 points extra. Make sure the superview's property clipsToBoundsis set to true, the extra 16 points of search bar background will be clipped.
This is my question
CONTEXT
I have a ViewController which I have an effect where the Navigation Bar gets transparent when the user go down in the scroll, and the Navigation Bar gets normal when the user go up in scroll view. This effect I did with the UIScrollViewDelegate's methods. This is the code:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat offset = scrollView.contentOffset.y;
if (scrollView.contentOffset.y < 0){
scrollView.bounces = false;
}else{
scrollView.bounces = true;
}
CGFloat currentAlpha = (offset / 310);
if (currentAlpha < 0) {
self.navigationController.navigationBar.translucent = YES;
self.navigationController.navigationBar.alpha = 1;
self.navigationController.titleNavBar.alpha = 0; //This property I made in an UINavigationController extension
} else {
self.navigationController.navigationBar.translucent = YES;
self.navigationController.navigationBar.alpha = 1;
self.navigationController.titleNavBar.alpha = currentAlpha; //This property I made in an UINavigationController extension
[self.navigationController.navigationBar setBackgroundColor:[UIColor colorWithRed:0.0f/0.0f green:136.0f/255.0 blue:206.00f/255.0f alpha:currentAlpha]];
}
}
With the previous code I got the effect, but I have a problem: I can't add it to the status bar because self.navigationController.navigationBar.translucent is set on YES. So, in the iPhones, the status bar shows transparent and in the iPhone X shows bigger this transparence than another iPhones (see the image).
Anyone know how can I do this transparent effect with Navigation Bar and the Statsus Bar?
You need to change statusBar UIView color with NavigationBar color.
Create AppDelegate SharedInastance :
+ (AppDelegate *)sharedAppDelegate {
return (AppDelegate *)[UIApplication sharedApplication].delegate;
}
Add below code in AppDelegate to get status bar view:
- (UIView *)statusBarView {
return [[[UIApplication sharedApplication] valueForKey:#"statusBarWindow"] valueForKey:#"statusBar"];
}
Add below code when you want to change status bar color:
[[AppDelegate sharedAppDelegate] statusBarView].backgroundColor = [UIColor redColor];
With iOS 11 navigation bar's title view and bar button item is not centered.
Also the background image's height does not change and is not shown in full.The bar height is 74.
See the white space.
I have tried this
if(#available(iOS 11,*)){
_homeNavigationBar.prefersLargeTitles = NO;
_homeNavigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeNever;
[_homeNavigationBar setBarTintColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"navbarBg.png"]]];
}
else{
[_homeNavigationBar setBackgroundImage:[UIImage imageNamed:#"navbarBg.png"] forBarMetrics:UIBarMetricsDefault];
}
But still i am unable to center the title and bar button item.
Any idea how can i fix this?Please do let me know.Thanks
Subclassing the navigation bar did the trick for me.
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *view in self.subviews) {
if([NSStringFromClass([view class]) containsString:#"Background"]) {
view.frame = self.bounds;
}
else if ([NSStringFromClass([view class]) containsString:#"ContentView"]) {
CGRect frame = view.frame;
frame.origin.y = 25;
view.frame = frame;
}
}
}
So I've got a UITableView with a UISearchController. It loads up fine, then I do my search and select a result, pushing a new view controller to my UINavigationController.
If, while the new VC is onscreen, I rotate my phone, then rotate back, and go back...when I get back to the UITableView, the UISearchBar is nowhere to be seen. If, to troubleshoot, I hide the UINavigationBar, or if I look at the view hierarchy, I find that it has moved up behind the navigation bar and is being covered.
I've tried all kinds of hackey solutions, like moving the frame of the bar after it finishes loading, with no success. I really need help on this one, I'm stumped. None of the stuff I've found on google has helped.
Here are screenshots of before, after, and the view heirarchy:
Screenshots
Here is all the View-related code:
- (void)viewDidLoad {
[super viewDidLoad];
if (!self.title)
self.title = #"GLOBAL SEARCH";
self.tableView.backgroundColor = [UIColor whiteColor];
//TESTING
//if I don't have this, the bar detaches from the navigation bar
self.edgesForExtendedLayout = UIRectEdgeAll;
self.extendedLayoutIncludesOpaqueBars = YES;
//test
self.definesPresentationContext = YES;
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.searchResultsUpdater = self;
self.searchController.delegate = self;
self.searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x,
self.searchController.searchBar.frame.origin.y,
self.searchController.searchBar.frame.size.width,
44.0);
self.searchController.searchBar.backgroundImage = [[UIImage alloc] init];
self.searchController.searchBar.backgroundColor = kConstantBaseColor;
self.searchController.searchBar.barTintColor = kConstantBaseColor;
self.searchController.searchBar.tintColor = kConstantLabelColor;
//set color
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:#{NSForegroundColorAttributeName:kConstantLabelColor}];
self.searchController.hidesNavigationBarDuringPresentation = NO;
[self.searchController.searchBar setSearchBarStyle:UISearchBarStyleMinimal];
self.tableView.tableHeaderView = self.searchController.searchBar;
self.tableView.clipsToBounds = NO;
self.tableView.tableHeaderView.clipsToBounds = NO;
self.tableView.tableHeaderView.backgroundColor = kConstantBaseColor;
//put purple block above, in case user scrolls up
CGRect bufferFrame = CGRectMake(self.searchController.searchBar.frame.origin.x,
self.searchController.searchBar.frame.origin.y-300,
self.searchController.searchBar.frame.size.width*2,
300);
UIView *purpleBuffer = [[UIView alloc] initWithFrame:bufferFrame];
purpleBuffer.backgroundColor = kConstantBaseColor;
[self.tableView addSubview:purpleBuffer];
}
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
[coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
}];
}
Does anyone have any solutions? I'm stumped and have been beating my head against it for days. Thank you so much.
I have a UINavigationController to which I need to add a second UINavigationBar. Neither of those bars is translucent. Problem is, view controllers that I put inside this navigation controller are partially covered by my second navigation bar. Where do I adjust the frames of those view controllers' views so that I don't get a "blinking" effect of them changing frames while being visible?
EDIT:
This is in viewDidLoad:
UINavigationBar *secondaryNavBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, 50)];
secondaryNavBar.translucent = NO;
if ([secondaryNavBar respondsToSelector:#selector(setBarTintColor:)]) { //it has to work on iOS 6 as well
secondaryNavBar.barTintColor = [UIColor darkGrayColor];
secondaryNavBar.tintColor = [UIColor whiteColor];
}
else {
secondaryNavBar.tintColor = [UIColor darkGrayColor];
}
[self.view addSubview:secondaryNavBar];
self.secondaryNavBar = secondaryNavBar;
Here's a working solution. Certainly not the best, and I did not make it to support iOS 6, you'll have to work on it and test it.
CustomNavigationController.m :
#implementation CustomNavigationController {
UINavigationBar *bottomNavBar;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self showNavBar];
}
- (void)showNavBar {
UINavigationBar *secondaryNavBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, 50)];
secondaryNavBar.translucent = NO;
if ([secondaryNavBar respondsToSelector:#selector(setBarTintColor:)]) { //it has to work on iOS 6 as well
secondaryNavBar.barTintColor = [UIColor darkGrayColor];
secondaryNavBar.tintColor = [UIColor whiteColor];
}
else {
secondaryNavBar.tintColor = [UIColor darkGrayColor];
}
[self.view addSubview:secondaryNavBar];
bottomNavBar = secondaryNavBar;
[self layoutNavBar];
}
- (void)layoutNavBar {
// Get the currently displayed view
UIView *contentView = self.topViewController.view;
// Get its frame and height
CGRect contentFrame = contentView.frame;
float height = contentFrame.size.height;
// Adapt height and y origin with the new nav bar
contentFrame.size.height = height - bottomNavBar.frame.size.height;
contentFrame.origin.y = bottomNavBar.frame.origin.y + bottomNavBar.frame.size.height;
// Set the view's frame
contentView.frame = contentFrame;
}
#end
ViewController.m :
#implementation ViewController
-(void)viewDidAppear:(BOOL)animated {
CustomNavigationController *navigation = (CustomNavigationController*)self.navigationController;
[navigation layoutNavBar];
}
#end
Note that you have to call layoutNavBar on viewDidAppear, or the view's frame will be reset by your app. This is not a perfectly clean solution, but a pretty good fix.