self.navigationController.navigationBar.translucent = NO; create an extra gap after navigationBar - ios

Let me explain my situation first. I set the UINavigationBar color in my appDelegate Like:
[[UINavigationBar appearance] setBarTintColor:[UIColor colorWithRed:255.0f/255.0f green:87.0f/255.0f blue:10.0f/255.0f alpha:1]];
Now in my some viewController the translucent of UINavigationBar set as YES.
self.navigationController.navigationBar.translucent = YES;
That's why there is a shade over my UINavigationBar. It wasn't showing the exact color. As a solution, I set translucent from YES to NO. It is showing the exact color now, But I am facing that some of my view completely gone from my interface. Here, let me tell you one thing that, so many of views here, is positioned by programmatically, so I am afraid I can't just move every of my viewControllers view 64 px high. Just wondering is there any solution to solve the thing. I try with opaque, but no luck. If any one understand my problem please share the solution if you have. Thanks a lot in advance.

From iOS7 if you use a translucent bar ( in UINavigationController or UITabbarController) the hosted view controller has as default behavior to extend under them. If you say to set the bar as translucent the color of it it will be a combination of the view under it and bat color. That is normal and the only way is to set translucency to no or apply a background image to navigation bar.
Applying frames manually will lead to unexpected result under auto layout, you must use constraints.
[UPDATE]
To create a background image from a solid color you can use that method, the image is 1px square, but there is no problem because it can be stretched or tiled to cover the entire area:
+ (UIImage *) imageWithColor:(UIColor*) color {
CGRect rect = CGRectMake(0, 0, 1, 1);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, rect);
UIImage *colorImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return colorImage;
}
If you see and extra gap is probably because you have also set automaticallyAdjustScrollViewInset to YES, try setting it NO. This property add and extra inset to your view or your vfirst view subview if it inherits from a UIScrollView

Its late, but i face same issue, and i resolved it by making UINavigationbar none on Viewcontroller in storyboard, and resized the view to start from 0,0

Related

clear color background nav bar, but still float above all the contents

I am a new iOS developer, i found some apps that can have a totally transparent nav bar, but still float above all the content, such as the app has a very nice background picture, and the nav bar is transparent, so you can see the entire background, but there is a scroll view on the navigation view controller. when scroll, it still goes under the nav bar.
when i try it, i set up my nav bar background as transparent like this
[self.navigationController.navigationBar setBackgroundImage:[self imageWithColor:[UIColor clearColor]] forBarMetrics:UIBarMetricsDefault];
but my scroll view will be totally visible when it goes under nav bar. I don't like that, does any one know how to make the nav bar transparent but still kind of floating on everything?
Thank you guys for the reputations, here is a screen shot from Yahoo weather their nav bar does exactly what i want.
But when i set the clear background to it, it becomes like this.
I am not 100% sure how Yahoo did it, but i can kind of fake that effect like this
I am inspired by BTGlassScrollView (https://github.com/BTLibrary/BTGlassScrollView) the approach i am using have several steps:
1.> set up your navigation controller like this:
Put your background image view first
Then add a wrapper view for your scroll view, and set the wrapper view background as Transparent (this wrapper view is very important, we have to fake the effect on this wrapper view)
drag your scroll view into the wrapper view, and set your scroll view background as Transparent as well.
2.> set up all the outlets for scroll view, wrapper view and background image view
3.> You might also want to hide the nav bar shadow image, here is the code, just in case if you need it
self.navigationController.navigationBar.shadowImage = [[UIImage alloc] init];
4.> Then paste this method into your class
- (CALayer *)createViewMaskWithSize:(CGSize)size startGradientAt:(CGFloat)start endGradientAt:(CGFloat)end
{
CAGradientLayer *mask = [CAGradientLayer layer];
mask.anchorPoint = CGPointZero;
mask.startPoint = CGPointMake(0.5f, 0.0f);
mask.endPoint = CGPointMake(0.5f, 1.0f);
mask.colors = #[(id)[UIColor clearColor].CGColor, (id)[UIColor clearColor].CGColor, (id)[UIColor whiteColor].CGColor, (id)[UIColor whiteColor].CGColor];
mask.locations = #[#0.0, #(start/size.height), #(end/size.height), #1.0f];
mask.frame = CGRectMake(0, 0, size.width, size.height);
return mask;
}
The purpose for this method is to create a mask layer with a clear to white gradient on it.
5.> last step, simply add that to your wrapperView.layer.mask like this
// 64 in here is the position where the fade effect should start, and 80 is where the gradien should end
// you can change those 2 numbers and see different effects
self.scrollViewWrapperView.layer.mask = [self createViewMaskWithSize:self.scrollViewWrapperView.frame.size startGradientAt:64 endGradientAt:80];
The wrapper view is the key in this case, the nav bar won't work without it. and remember DO NOT put the background image view into the wrapper view, they should be on the same level, but background image under the wrapper view.
This is a very rough mock ups, but hope this gives you some ideas.

add a transparent view into a translucent view

I want a view like the picture attached, the full view's background is translucent, and the view in green frame is transparent.
I tried addSubview and set subview's alpha but it is not worked.
You can override your drawRect method. Fill it all with translucent, then fill in the transparent part with clear color:
- (void)drawRect:(CGRect)rect {
// fill it all with translucent
[yourTranslucentUIColor setFill];
UIRectFill( rect );
CGRect yourMiddleHoleRect = CGRectMake(* calculate your rect here);
[[UIColor clearColor] setFill];
UIRectFill( yourMiddleHoleRect );
}
I think this will give you a cleaner result than other options.
You could even draw in those green frame indicators here if you wanted.
I believe the only way to achieve that is to instead add 4 translucent views around your transparent view.
first you have to add the translucent view over the background view by CGContextDrawImage.
Then use CGContextSetBlendMode to clear the portion.
Refer the below project to achieve this.
https://github.com/akopanev/iOS-Scratch-n-See

How to remove black background on UITabBar

I want to create the TabBar which align at center no matter what how many tabitem is.
The final result may be look like the image below.
I can set width of TabBar by using
UITabBar *tabBar = self.tabBarController.tabBar;
CGRect rectAdjust = CGRectMake(tabBar.frame.origin.x, tabBar.frame.origin.y, 160.0f, tabBar.frame.size.height);
tabBar.frame = rectAdjust;
But I cannot remove the black background on UITabBar(on the right side in below image) even though I already set the size of TabBar to be half the screen's width.
Is there any way to solve this?
Thanks.
Instead of reinventing the wheel, you could take a look at this control at the CocoaControls website:
ALTabBarController for iOS
It is more customizable than the traditional TabBar
You could set an image for the table bar that has caps on either side and a few pixels in between, then make it a resizeable image like so:
UIImage *background = [[UIImage imageNamed:#"ImageName.png"]resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
Then set it as the background image of the tab bar:
tabBar.backgroundImage = background;
And it should resize to the image you need.
Then set the background color of the tab bar to clear:
tabBar.backgroundColor = [UIColor clearColor];

iOS Change frame of UITabBarButton in UITabBar

In my app I have a UITabBarController in which I give custom selected/unselected images in my AppDelegate as follows:
UIImage *selectedImage = [UIImage imageNamed:#"home-tab-selected"];
UIImage *unselectedImage = [UIImage imageNamed:#"home-tab"];
UITabBar *tabBar = tabController.tabBar;
UITabBarItem *item1 = [tabBar.items objectAtIndex:0];
[item1 setFinishedSelectedImage:selectedImage withFinishedUnselectedImage:unselectedImage];
The images I have are 100x100, much larger than the normal tab bar items. All works well, and my images are placed nicely and look great.
The issue I am having is that the frame of the underlaying UITabBarButton remains 76x48, leaving only a small portion of my tabs 'touchable'. (Image below with a border around the frame)
To attempt to fix this, in my subcalssed UITabBarController viewDidLoad, I go through each UITabBarButton, and set the frame as follows:
for (UIView* subView in self.tabBar.subviews)
{
if ([subView isKindOfClass:NSClassFromString(#"UITabBarButton")])
{
[subView setFrame:CGRectMake(subView.frame.origin.x, subView.frame.origin.y, 100, 100)];
}
}
After I do that, I log the frames and they do change-- BUT the frame never changes in my tab bar-- I still only see and can touch in the smaller red box.
Is this because Apple does not allow you to change these frames or am I doing something wrong here?
Any help apperciated! Thanks!
EDIT:
In the end I just ended up making my tab images smaller. I found a height of 70px still picks up most touches.
The layout of your UITabBarController's view might change after loading: Additional UITabBarItems could be added, of the user could switch to landscape orientation.
Before iOS 6, there wasn't a way to configure complex layouts. Since UITabBar is a very old class, it's most likely doing its work in the layoutSubviews method.
You could subclass UITabBar and override said method, but if you go that far, you might want to think about creating your own tab bar, which in the end is just a UIView with a few UIButtons.
Had a similiar problem with the underlying UITabBarButtons. I solved it by setting the UITabBar's "Item positioning" attribute to "Fill".

How do I get a UINavigationController to NOT change its view size when setting the translucent property?

I have an app where up until now I've been using a UINavigationController with a UINavigationBar that has its property translucent = YES. This means the UINavigationController's content view (i.e. the views from the view controllers you push) to be full-screen (minus status bar).
However, if you set the navigationBar.translucent = NO, this container view becomes 44pt shorter, as I suppose Apple has assumed you don't need any content under an opaque navigationBar.
... except if you're doing what we're doing and are employing a navigationBar that scrolls away (see This Post on how to do that) So I'd like to know if this is possible.
I want to have translucent = NO, but have everything behave as if it were still set to YES. I like the functionality of the translucent = YES, but I don't actually want the bar to be made translucent by UIKit.
What worked for me was to add
extendedLayoutIncludesOpaqueBars = true
in
viewDidLoad
something like this
override func viewDidLoad() {
super.viewDidLoad()
extendedLayoutIncludesOpaqueBars = true
}
Hope it will work for you as well
It's not necessarily a good answer but you could just offset your view that high if you're not translucent.
//This won't take into account orientation and probably other details
if(!self.navigationController.navigationBar.isTranslucent)
{
self.view.frame = CGRectMake(0,0,-44,self.view.bounds.size.height);
}
You could put that in your viewDidLoad or viewWillAppear and if you have a bunch of view controllers you can just subclass them all and put your logic in the subclass.
I found a solution that works, although it is indeed a bit of a hack.
The idea is to give the translucent nav bar an opaque backing. Unfortunately I'm not happy with the solution in that it's dirty and not encapsulated and introduces some potential issues, but i AM happy because it got the job done.
In my Application's base view controller class (i.e. MyViewController : UIViewController), in the viewDidLoad method, I instantiate a new ivar UIView *_navigationBarBG and give it the same frame as self.navigationController.navigationBar. I then set it's backgroundColor property to [UIColor whiteColor] although this is how you achieve some more tint I guess. [EDIT:If you wanted to be a purist (color values remaining exactly as they come from the .psd), you could make the _navigationBarBG a UIImageView and use your custom background there, and the background of the actual UINavigationBar you set to draw clear (or stretch a 1px transparent image if you wanted to use a typical 'change your navigation bar using an image' recipe that's somewhere on the internet)]
if(self.navigationController)
{
_navigationBarBG = [[UIView alloc] initWithFrame: self.navigationController.navigationBar.frame];
_navigationBarBG.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_navigationBarBG];
}
THEN, (and this is the crappy part, but I don't see any other way), I add this view as a subview. BUT, whenever you would normally make a call to [self.view addSubview: anyView], you have to make sure you call [self.view insertSubview: anyView belowSubview: _navigationBarBG];
if (_navigationBarBG)
[self.view insertSubview: anyView belowSubview:_navigationBarBG];
else
[self.view addSubview: anyView];
If you forget that, these added views will slide under your navbar background and look weird. So you need to know that this is a source of error.
WHY AM I DOING THIS? Again you might ask... I want to be able to have a scrolling navigation bar that scrolls out of the way when you scroll down your table view, thereby giving the user more screen space. This is done by using the scrollView delegate (scrollViewDidScroll:) and also viewWillAppear:
// FIRST DEAL WITH SCROLLING NAVIGATION BAR
CALayer *layer = self.navigationController.navigationBar.layer;
CGFloat contentOffsetY = scrollView.contentOffset.y;
CGPoint newPosition;
if (contentOffsetY > _scrollViewContentOffsetYThreshold && self.scrollingNavigationBarEnabled) {
newPosition = CGPointMake(layer.position.x,
22 - MIN((contentOffsetY - _scrollViewContentOffsetYThreshold), 48.0)); // my nav bar BG image is 48.0 tall
layer.position = newPosition;
[_navigationBarBG setCenter: newPosition]; // if it's nil, nothing happens
}
else
{
newPosition = kNavBarDefaultPosition; // i.e. CGPointMake(160, 22) -- portrait only
layer.position = newPosition;
[_navigationBarBG setCenter: newPosition]; // if it's nil, nothing happens
}
I was looking for an answer to this as I wanted my subviews to be at (0,0) and not (0,44)(in reference to the Screen bounds), but I could not find an answer on how to set this in the NavigationController, which I thought would be an included property.
What I ended up doing that was very simple is adding a subview to the navigation controller that was the width and height of the Navigation Bar, but then insert the subview below the Navigation Bar.
Now the setting is Translucent = YES, but it still appears solid and the subviews behave how I want.
EDIT: After re-reading your original post, I suppose if you're going to be rolling the nav bar away, you'll have to take into account hiding and showing the new subview as you do the same with the nav bar

Resources