I found through another question on here how to change the height of UINavigationBar using a category:
#import "UINavigationBar+Taller.h"
#implementation UINavigationBar (Taller)
- (CGSize)sizeThatFits:(CGSize)size {
CGSize newSize = CGSizeMake(self.frame.size.width,100); //exaggerated height
return newSize;
}
#end
That works brilliantly.
Is there a way to move the title and navigation buttons up? They are aligning to the bottom of the new size. I want to put something into the bottom of the navigation bar.
Private methods are ok since this isn't going to be an app store candidate.
To change the vertical offset for the title:
CGFloat yourOffset = 5.0; //whatever value you need
[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:yourOffset forBarMetrics:UIBarMetricsDefault];
To make the button a bit higher or lower
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
Another (more flexible) better approach would be to create a subclass of UINavigationBar
and override layoutSubviews, placing your views in the correct place.
Related
I am doing
mapButton *topMapButton = [[mapButton alloc] init];
[topMapButton setSize:CGSizeMake(70, 30)];
topMapButton.frame = CGRectMake(0, STATUS_HEIGHT +7, 70, 30);
UIBarButtonItem *barIcon = [[UIBarButtonItem alloc] initWithCustomView: topMapButton];
[topMapButton addTarget:self action:#selector(openMap:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.rightBarButtonItem = barIcon;
where mapButton is a UIButton subclass, with preset look, nothing else
No matter what frame I set for topMapButton, it keeps being in (0,0) and not in the rightBarButtonItem usual place.
Note that using autolayout programatically to set the place works for placing, but crashes when I push another controller in the stack...
Am I doing anything wrong?
Look at this answer
Shortly, you can set edge inset. override alignmentRectInsets for your uibutton subclass and change top and left insets.
- (UIEdgeInsets)alignmentRectInsets {
UIEdgeInsets insets = UIEdgeInsetsMake(top_value, left_value, bottom_value, right_value);
return insets;
}
OK found the problem..
It seems that UIBarButtonItem doesn't really care what frame the customView has, since it will set it anyway.
however, my custom button MUST have a custom type, otherwise it will mess the frame and keep it (0,0) of the application screen.
self = [UIButton buttonWithType:UIButtonTypeCustom];
I have an issue with my navigation bar, the UIBarButtonItem is not correctly vertically aligned. I don't know why because I'm using a simple UIBarButtonItem and not a custom view. See my code below and thanks for your help!
UIBarButtonItem *newGameItem = [[UIBarButtonItem alloc] initWithTitle:#"New Game" style:UIBarButtonItemStyleDone target:self action:#selector(newGame)];
self.navigationItem.rightBarButtonItem = newGameItem;
Actually there are couple ways to align the bar buttons.
Try to adjust the button title position with this:
[self.navigationItem.rightBarButtonItem setTitlePositionAdjustment:UIOffsetMake(-10, -10)
forBarMetrics:UIBarMetricsDefault];
-10 -10 - just for example
OR
you can initialize your newGameItem with custom UIButton. The custom button is a subclass of UIButton with this method overridden
- (UIEdgeInsets)alignmentRectInsets {
return UIEdgeInsetsMake(0, -10, 0, 15.0f); // here you can play with values to align your button properly
}
then initialize your newGameItem
CustomBarButton *button = [CustomBarButton buttonWithType:UIButtonTypeCustom];
[button setTitle:#"New game" forState:UIControlStateNormal];
button.frame = CGRectMake (0, 0, 60, 40);
[button addTarget:self action:#selector(newGame) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *newGameItem = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.rightBarButtonItem = newGameItem;
I had a similar issue: We use custom fonts via UIAppearance for both navigation titles and bar button items, and in some cases, the right item was vertically misaligned.
I could easily fix the misalignment by using [self.navigationItem setRightBarButtonItem:rightItem animated:YES] instead of the property setter.
I had the same problem with a button on the left, I was able to fix it in Xcode 6.3.1: select the button (bar button item) right column tab "ruler" inset image Top value: -54 instead of 0.
Note that: my device is an iPhone4 with iOS 7, the button was perfectly in place in Xcode and misplaced on the device, now it is in place on the device and misplaced in Xcode
Unfortunately, there is not much you can do about UIBarButtonItem vertical spacing. I believe you'll have to either increase the font size of your title on the UINavigationBar (you can do this with UIAppearance also), or decrease the font size of your UIBarButtonItem.
My logo was looking to small in the default UINavigationBar, so I increased the height to 67 by overriding
- (CGSize)sizeThatFits:(CGSize)size
{
CGSize newSize = CGSizeMake(self.frame.size.width, 67);
return newSize;
}
I added a 2x image of size 266x130 in the - (void)viewDidLoad using
self.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"logo.png"]];
But my title logo is not aligned with the NavigationBar.
I just wanted to know why the title view is behaving weird with custom height. I did not have any issue while adding image as title view to the standard UINavigationBar.
Also is this the right way to override UINavigationBar for custom height? Are there any other methods to do the same?
Have you tried this or something like it?
float positionOffset = ...;
[UINavigationBar appearance] setTitleVerticalPositionAdjustment:positionOffset forBarMetrics:UIBarMetricsDefault];
There's also this, if that doesn't immediately work.
I think this is going to be a stupid question, but I can't seem to find the answer. I have a few simple lines of code to put a button in the navigation bar:
UIBarButtonItem *cancelButton=[[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:#"button-cancel.png"] style:UIBarButtonItemStylePlain target:self action:#selector(cancelPressed:)];
UINavigationItem *item = [[UINavigationItem alloc] init];
item.leftBarButtonItem = cancelButton;
item.hidesBackButton = YES;
[self.navigationBar pushNavigationItem:item animated:NO];
This button works fine, but it looks like this:
Any thoughts?
You probably want to create the bar button item using a custom view, where the custom view is a UIButton:
UIImage *cancelImage = [UIImage imageNamed:#"button-cancel"];
UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
cancelButton.frame = (CGRect){CGPointZero, cancelImage.size);
[cancelButton setImage:cancelImage forState:UIControlStateNormal];
UIBarButtonItem *cancelBarButton = [[UIBarButtonItem alloc] initWithCustomView:cancelButton];
Set your button (cancelButton) size according to the size of the button-cancel.png.
stopButton.frame = CGRectMake ();
Instead, create a custom type UIButton with your image. Set the target and selector of the UIbutton to what you wish the bar button item to do. Then initialize the bar button item as follows:
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
Where button is your UIButton using the desired image.
UIBarButtonItem/initWithImage: is typically used for making iconic buttons - not buttons that have text in them.
If you just want to change how the common textual UIBarButtonItem looks, you just need to set the background image of your bar button item. This way you don't have to have images for each button that contain your button text.
Docs: - (void)setBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics
You can also set this app-wide by calling setBackgroundImage: on the UIBarButtonItem appearance proxy.
Lastly, note that you'll likely need to create a resizeable image to pass to setBackgroundImage. This will let your single image accomodate any button size. See UIImage/resizeableImageWithCapInsets:resizingMode: (iOS6) or UIImage/stretchableImageWithLeftCapWidth:topCapHeight: (pre iOS6)
You can certainly do what #Wain suggests but there are drawbacks. For one, your press-handler will no longer be sending a UIBarButtonItem as the 'sender'. That may not seem like much until you have a common handler that suddenly needs to determine if the sender is a UIBarButtonItem or a UIButton, or if you want to present a UIPopoverController against this BarButtonItem (but you only have the UIButton reference...)
I need to implement something like this:
tableView must bounce, but not navigation bar.
I tried a bunch of different variants.
Something like this:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGRect imageViewFrame = self.imageView.frame;
CGRect tableViewFrame = self.tableView.frame;
//ImageView - is top view(instead of NavBar)
//defaultHeight - is default height of tableView
imageViewFrame.origin.y = MIN(0, MAX(-scrollView.contentOffset.y, -100));
tableViewFrame.origin.y = imageViewFrame.origin.y + 100;
tableViewFrame.size.height = defaultHeight - imageViewFrame.origin.y;
self.imageView.frame = imageViewFrame;
self.tableView.frame = tableViewFrame;
}
Get this:
it is not suitable because in Instagram size of tableView doesn't change(just look at scroll indicators, if size of tableView changed, they also changed)
Also I tried add View as subView into tableView, it works, but not exactly what I need is.
In Instagram navigation bar outside the tableView, so it is not suitable too.
In the facebook app search bar behaves exactly the same
Can anyone help me?
Thanks!
Have the same approach in the sample code but rather than increasing the tableview's height, you have it preloaded with the additional (not-visible height) and just move it upwards by decreasing the frame's y. The additional height will be off-screen. If the content height is not big enough to go off-screen then you don't need to have the off-screen height.
Add a header with height = 0 at start, and as you scroll down it increases the size, up to 100 (the empty header will be off screen now). That way the content will not get cut off as you scroll.
The instagram "navigation bar" isn't a navigation bar. It's a table section header. You'll notice that when you tap on a photo, the entire navigation bar slides away. That's because it's part of the table view controller and not a "real" navigation bar.
You can achieve this by using a UINavigationController but hiding the navigation bar (setNavigationBarHidden:YES). You just call pushViewController:animated: manually when you want to push.
Interestingly it looks like the other tabs of instagram just use a normal navigation bar and don't do anything fancy. I guess they really wanted those 44 points back on the main feed screen.
If you are targeting iOS 5+ than you can easily customize the navigation bar like this:
1- Add Your TableViewController inside a UINavigationController
2- Customize The Navigation Bar:
Set Background Image For Navigation Bar
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"bar_background"]
forBarMetrics:UIBarMetricsDefault];
Add Refresh Button on Right Side
UIImage *img = [UIImage imageNamed:#"refresh.png"];
UIButton *rButton = [UIButton buttonWithType:UIButtonTypeCustom];
[rButton setImage:img forState:UIControlStateNormal];
[rButton addTarget:vc action:#selector(didTapRefreshButton:) forControlEvents:UIControlEventTouchUpInside];
rButton.frame = CGRectMake(0.0f, 0.0f, img.size.width, img.size.height);
UIBarButtonItem *rButtonItem = [[UIBarButtonItem alloc] initWithCustomView:rButton];
self.navigationItem.rightBarButtonItem = rButtonItem;
[rButtonItem release];
Hope that Helps!
You can use the below mentioned method in your class in which you want to add effect on navigation bar as there in Instagram.
- (void)scrollViewDidScroll:(UIScrollView *)sender {
//Initializing the views and the new frame sizes.
UINavigationBar *navbar =self.navigationController.navigationBar;
UIView *tableView = self.view;
CGRect navBarFrame = self.navigationController.navigationBar.frame;
CGRect tableFrame = self.view.frame;
//changing the origin.y based on the current scroll view.
//Adding +20 for the Status Bar since the offset is tied into that.
if (isiOS7) {
navBarFrame.origin.y = MIN(0, MAX(-44, (sender.contentOffset.y * -1))) +20 ;
tableFrame.origin.y = navBarFrame.origin.y + navBarFrame.size.height;
}else{
navBarFrame.origin.y = MIN(0, (sender.contentOffset.y * -1)) +20;
tableFrame.origin.y = MIN(0,MAX(-44,(sender.contentOffset.y * -1))) ;
}
navbar.frame = navBarFrame;
tableView.frame = tableFrame;
}