We have a "bottom bar" in our app which at the moment is just a UIView and defined all over the place which leads to inconsistency etc...
I'm trying to replace the use of the this with a UIToolBar and UIBarButtonItems so I can customise the appearance with the UIAppearance protocol.
The buttons we use in the tool bar have a background image made of a resizable image (defined in asset catalog).
What we want it to look like is something like this...
The buttons are nicely centred between the top and bottom of the tool bar.
However, what happens when I set the background image using the UIAppearance protocol is this...
The buttons are vertically aligned off centre.
It seems like the text is in the same place and the background is being applied around the text but the text is actually lower than centre. With no BG this makes sense but with a BG it doesn't work.
I could change the frame in code of every button but this is not ideal as we get back to the inconsistency problem that I'm trying to solve.
Is there any way to change this for all instances of UIBarButtonItem in one place?
I even tried adding transparency to the bottom of the image to "push it upwards" but it didn't have an effect.
Update to show the problem in place
In a enw project I embed a view controller in a navigation controlle rand use this code...
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setToolbarHidden:NO animated:animated];
}
- (NSArray *)toolbarItems
{
return #[
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil],
[[UIBarButtonItem alloc] initWithTitle:#"Hello" style:UIBarButtonItemStyleDone target:nil action:nil],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil],
[[UIBarButtonItem alloc] initWithTitle:#"World!" style:UIBarButtonItemStyleDone target:nil action:nil],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc] initWithTitle:#"Goodbye!" style:UIBarButtonItemStyleDone target:nil action:nil],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]
];
}
The result is...
Then I use the UIAppearance code...
[[UIToolbar appearance] setTintColor:[UIColor whiteColor]];
[[UIToolbar appearance] setBarTintColor:[UIColor colorWithRed:0.15 green:0.2 blue:0.85 alpha:1.0]];
And the result is...
This looks fine but when I add the background image...
With the code...
[[UIBarButtonItem appearance] setBackgroundImage:[UIImage imageNamed:#"ToolBarButtonBackgroundEnabled"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
I see this...
I tried changing the title position adjustment...
[[UIBarButtonItem appearance] setTitlePositionAdjustment:UIOffsetMake(0, -5) forBarMetrics:UIBarMetricsDefault];
But that just moves the text inside the button...
It doesn't move the button background.
I can't find anything relating to the offset of the buttons in the toolbar appearance.
Moving Text
I was wrong about the text staying int he same place. The text moves when you add a background to the bar button items...
I merged screenshots of the toolbar with and without the button backgrounds. You can see that the text is moved downwards.
Have you tried [xyzbtn setImageEdgeInsets:UIEdgeInsetsMake(10, 10, 10, 10)];
or your image size is greater than your button's size, so it might be affecting the layout.
I have noticed the same thing: if you set a background image, the UIBarButtonItem moves down by 3pt. It also moves right by 1pt.
This doesn't seem to happen in iOS 11, which is good news.
My conjecture is that Apple made the assumption that if you have a background image set you're trying to indicate a 'selected' button state, and they deliberately move he button down and right a bit to give a 3-D movement appearance.
Related
I want to create a UI tool bar with effect like this
[DONE]-------[MINUS]--------
button DONE locate at left and button MINUS locate at middle
this is my code but I didn't get the button MINUS set to middle
UIToolbar* mtbKeyboardAccessoryView = [[UIToolbar alloc] init];
[mtbKeyboardAccessoryView sizeToFit];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(doneKeyboard)];
UIBarButtonItem *minusBtn = [[UIBarButtonItem alloc] initWithTitle:#"MINUS" style:UIBarButtonItemStyleBordered target:self action:#selector(minusSign)];
UIBarButtonItem *flexibleItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFlexibleSpace target: nil action: nil];
[mtbKeyboardAccessoryView setItems:[NSArray arrayWithObjects:doneBtn, flexibleItem, minusBtn, flexibleItem, flexibleItem, nil]];
I don't want to create button with frame and customary set (w, h, x, y) and add sub-view to UI tool bar
Is that any way to set the UI bar button at left and middle and without affect the button coordinate when change orientation in landscape and portrait
I get a result like this
[DONE]-------[MINUS]-------------------
which minus button not set to middle
Add UIBarButton for Done than add FlexibleItem than another UIBarButton for Minus and again add FlexibleItem.
Try to add this above..!! May this will help you..!!
When I deleted the title text of my back button, the text of my navigation title is not centred.
I used
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#" " style:UIBarButtonItemStylePlain target:nil action:nil];
and
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) forBarMetrics:UIBarMetricsDefault];
in both my viewDidLoad and viewWillAppear
this is a screenshot of the result
Any idea how I can fix this?
The UINavigationBar displays the backBarButtonItem of the previous view controller, so you'll need to make sure you are setting that and not the backBarButtonItem of the displayed view controller. The call to setBackButtonTitlePositionAdjustment(_:forBarMetrics:) is not necessary.
I want to put two UIBarButtonItem instances to UIToolbar in my iOS universal app, on which the first item is on the left-edge of the toolbar and the second is on the center. However, it looks like this cannot be done in Interface Builder, because the auto layout doesn't support forcing constraints on UIBarButtonItem class due to the fact that it is not a subclass from UIView.
Notice that I don't want to put the first on the left-edge and the second is on the right-edge - I have to put the second button at the center. Also, I don't have a plan to use the third button in order to align them as left, center, and right at equal interval.
Is it still possible to add such constraint in this situation in storyboard? I use Xcode 6 beta 5.
You can do it all in your Storyboard.
Select a Bar Button Item in the Object library and drag it into your Toolbar. Add a Flexible Space Bar Button Item at its right. Add your second Bar Button Item at its right. Then, add a second Flexible Space Bar Button Item at its right.
The result will look like this in Interface Builder:
If necessary, you can add an extra Fixed Space Bar Button Item at the right edge of your Toolbar to be sure that your second Bar Button Item is really centered.
User lxt gives another example of this in answer for a similar question here.
Edit: Be sure that your UIToolbar has good constraints before proceeding!
you can do this programmatically
UIBarButtonItem *flexible = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithTitle:#"item1" style:UIBarButtonItemStylePlain target:self action:nil];
UIBarButtonItem *item2 = [[UIBarButtonItem alloc] initWithTitle:#"item2" style:UIBarButtonItemStylePlain target:self action:nil];
UIBarButtonItem *item3 = [[UIBarButtonItem alloc] initWithTitle:#"item3" style:UIBarButtonItemStylePlain target:self action:nil];
self.toolbarItems = [NSArray arrayWithObjects: item1, flexible, item2, flexible, item3, nil];
check this link if you want more details
How to place UIBarButtonItem on the right side of a UIToolbar?
I think you should try Flexible bar button space item and for more understating i am sharing a link, so have look of it might this help you out
UIToolbar and Flexable/Fixed bar button items
Code to add toolbar :
Here fixed width can be variable. Accordingly you can keep it as far as you want so as to keep the second button in centre.
UIBarButtonItem *fixedItemSpaceWidth = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
fixedItemSpaceWidth.width = 200.0f; // or whatever you want
UIBarButtonItem *doneBarButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneButtonAction:)];
UIBarButtonItem *cancelBarButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(cancelButtonAction:)];
// Initialise toolabr
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height-44, 320, 44)];
//toolbar.barStyle = UIBarStyleBlack;
toolbar.items = [NSArray arrayWithObjects:cancelBarButton,fixedItemSpaceWidth,doneBarButton, nil];
[self.view addSubview:toolbar];
I am trying to create a custom back button on a navigation bar. I start from the following:
// Nav bar - back button
[[UINavigationBar appearance] setTintColor:COLOR_WHITE];
[[UINavigationBar appearance] setBackIndicatorImage:[[UIImage imageNamed:#"navMenuBackButton"]
imageWithAlignmentRectInsets:UIEdgeInsetsMake(6.0, -6.0, 6.0, -6.0)]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:#"navMenuBackButton"]];
The image is 34x34 points so does not centre properly without the image alignment. The current problem is trying to get rid of the "Back" label without setting a blank title for each screen or making any changes on the ViewController itself.
Any idea's? Thank you
Disable leftBarButtonItem and rightBarButtonItem. Try the following.
[navigationItem.backItem.leftBarButtonItem setEnabled:NO];
[navigationItem.backItem.rightBarButtonItem setEnabled:NO];
[navigationItem.backItem setHidesBackButton:YES];
Did you try this :
NSString *backString = #"";
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:backString
style:UIBarButtonItemStyleDone
target:nil
action:nil];
[[self navigationItem] setBackBarButtonItem:backButton];
I added code to the viewDidLoad method of ViewController. I have two UIBarButtonItem, one of them is on the left called Left and the other one is at the right called Right. I can get the left button to work but I cannot even see the right button. What am I doing wrong?
UINavigationBar *navbar = [[UINavigationBar alloc]initWithFrame:CGRectMake(0, 0, 420, 44)];
[navbar setBackgroundImage:[UIImage imageNamed:#"bg_fade.png"] forBarMetrics:UIBarMetricsDefault];
UINavigationItem *item = [[UINavigationItem alloc]initWithTitle:#"Tray Tracker"];
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc]initWithTitle:#"Left" style:UIBarButtonItemStylePlain target:self action:
#selector(leftAction:)];
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc]initWithTitle:#"Right" style:UIBarButtonItemStylePlain target:self action:
#selector(saveAction:)];
item.leftBarButtonItem = leftButton;
item.rightBarButtonItem = rightButton;
navbar.items = #[item];
[self.view addSubview:navbar];
I do have the IBActions for leftAction and saveAction
If you simply want a bar with two buttons, you should use a UIToolbar instead. It's much easier to handle for this simple case. The only change you would need is to create a UIBarButtonItem flexibleSpace (it's a system item), and call [toolbar setItems:#[leftButton, flexibleSpace, rightButton]];
If you need actual navigation functionality such as a back button, take a look at this answer. You need to use UINavigationBar pushNavigationItem.
using UINavigationBar without UINavigationController
In your example, you are misusing the items property. The documentation for UINavigationBar states,
The bottom item is at index 0, the back item is at index n-2,
and the top item is at index n-1, where n is the number of items in the array.
In order to do accomplish what you're trying to do with a UINavigationBar, I think you need multiple navigationItems.
It would be MUCH easier to either use a UIToolbar or use the UINavigationBar in conjunction with a UINavigationController.
Edit
Now that you posted the image, I think the reason you can't see the right bar button is because your frame width is too large. The iphone screen is 320 px wide, so your frame for the navigationBar should be CGRectMake(0, 0, 320, 44)