Custom UIBarButtonItem keep Aspect Ratio for Image but Space out Buttons - ios

I am adding some custom image UIBarButtonItems to my navigation bar. If I do not mess with the item.width property, then my buttons are too close together, but if I space them out with the width property, then the button image is distorted. How can I maintain the aspect ratio of the button image but space out my custom items?
// Create custom map button
UIButton *mapButton = [UIButton buttonWithType:UIButtonTypeCustom];
[mapButton setImage:[UIImage imageNamed:#"map.png"] forState:UIControlStateNormal];
[mapButton addTarget:self action:#selector(dismissMapView:) forControlEvents:UIControlEventTouchUpInside];
[mapButton setFrame:CGRectMake(280, 25, 30, 30)];
UIBarButtonItem *button1 = [[UIBarButtonItem alloc] initWithCustomView:mapButton];
button1.width = (self.drawer.frame.size.width / 5.0f); // Space it out a bit
// Create custom list button
UIButton *listButton = [UIButton buttonWithType:UIButtonTypeCustom];
[listButton setImage:[UIImage imageNamed:#"list.png"] forState:UIControlStateNormal];
[listButton addTarget:self action:#selector(scrollToRow:) forControlEvents:UIControlEventTouchUpInside];
[listButton setFrame:CGRectMake(280, 25, 30, 30)];
UIBarButtonItem *button2 = [[UIBarButtonItem alloc] initWithCustomView:listButton];
button2.width = (self.drawer.frame.size.width / 5.0f); // Space it out a bit
// Add buttons to drawer
self.drawer.items = #[button1,button2];

Try this code for adding custom bar button in navigationbar.
UIImage* image3 = [UIImage imageNamed:#"compose_message_button.png"];
CGRect frameimg = CGRectMake(250, 9, 43,32);
UIButton *SettingButton = [[UIButton alloc] initWithFrame:frameimg];
[SettingButton setBackgroundImage:image3 forState:UIControlStateNormal];
[SettingButton addTarget:self action:#selector(BtnWriteMessage:)
forControlEvents:UIControlEventTouchUpInside];
[SettingButton setShowsTouchWhenHighlighted:YES];
UIBarButtonItem *mailbutton =[[UIBarButtonItem alloc] initWithCustomView:SettingButton];
self.navigationItem.rightBarButtonItem=mailbutton;
[SettingButton release];
i hope this code is useful for you.

You can create some explicit spacer items using UIBarButtonSystemItemFixedSpace.
Or you could create your bar buttons with custom views (initWithCustomView:) and then you can lay the content views out as you like.

Related

UINavigationItems Stretching in iOS11

I'm updating an app to ensure that it works as expected in iOS11. The only issue I've run into is that the navigation bar looks quite different in iOS11. The position of the elements and size is not the same between versions. I've looked at my code and i'm explicitly setting frame sizes and edge insets, why are these values are not respected in iOS11?
//-- Create Right Navigation Item Buttons
// create kabob btn
UIButton *kabobBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[kabobBtn addTarget:self action:#selector(viewUsersClicked:)forControlEvents:UIControlEventTouchUpInside];
kabobBtn.clipsToBounds = YES;
[kabobBtn setImage:[UIImage imageNamed:#"KabobMenu2_0071bc_Right.png"]
forState:UIControlStateNormal];
[kabobBtn.imageView setContentMode:UIViewContentModeScaleAspectFit];
[kabobBtn setFrame:CGRectMake(0, 0, 32, 32)];
// create user profile button
UIButton *userBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[userBtn setImage:[UIImage imageNamed:#"people.png"]
forState:UIControlStateNormal];
[userBtn addTarget:self action:#selector(viewUserProfileClicked:)forControlEvents:UIControlEventTouchUpInside];
[userBtn setFrame:CGRectMake(0, 0, 38, 38)];
userBtn.clipsToBounds = YES;
[userBtn.layer setCornerRadius:(38/2)];
[userBtn.layer setMasksToBounds:YES];
[userBtn.layer setBorderColor:[[UIColor blackColor]CGColor]];
[userBtn.layer setBorderWidth:1];
self.userPictureURL = [defaults objectForKey:#"userPicture"];
[userBtn setImage:[UIImage imageNamed:#"defaultUserImage.png"] forState:UIControlStateNormal];
[userBtn setContentMode:UIViewContentModeScaleAspectFill];
[userBtn setBackgroundColor:[UIColor clearColor]];
// add buttons to bar button items
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:kabobBtn];
UIBarButtonItem *barButton2 = [[UIBarButtonItem alloc] initWithCustomView:userBtn];
// add bar button items to right bar button item array
self.navigationItem.rightBarButtonItems = #[barButton,barButton2];
//-- Create Left Hamburger Button
UIButton *customOpen = [UIButton buttonWithType:UIButtonTypeCustom];
[customOpen setFrame:CGRectMake(0, 0, 30, 44)];
[customOpen setImage:[UIImage imageNamed:#"hamburger.png"] forState:UIControlStateNormal];
[customOpen setImageEdgeInsets:UIEdgeInsetsMake(10, -5, 16, 10)];
UIBarButtonItem *openItem = [[UIBarButtonItem alloc] initWithCustomView:customOpen];
if(self.showHamburger){
self.navigationItem.leftBarButtonItem = openItem;
}else{
self.navigationItem.leftBarButtonItem = nil;
}
Apparently iOS 11 uses autolayout for nav bar buttons. Use auto layout constraints to set button width and height.
[userBtn.widthAnchor constraintEqualToConstant:38.f].active = YES;
[userBtn.heightAnchor constraintEqualToConstant:38.f].active = YES;
This should fix the stretching issue.
Thanks to this answer

How to cancel UIBarbuttonItem setTitle shining effect

Like image shows, I used UIBarbuttonItem as rightBarButtonItem, what I want to do is just change rightBarButton's title when I select a picture or deselect a picture, so I used code like this:
[self.rightBarButton setTitle:[NSString stringWithFormat:#"完成(%#/%#)",#(_selectedAssets.count),#(self.maxPicturesNum)]];
but the barbutton will show shin when its text changed, I try to use UIButton instead of UIBarButtonItem, and shin effect disappear indeed, but UIButton will be close to right bounds far, can you help me?
You can create UIButton and assign it to your rightBarButton
UIButton *rightButton = [[UIButton alloc] initWithFrame:someFrame];
[rightButton setBackgroundImage:someImage forState:UIControlStateNormal];
[rightButton addTarget:self action:#selector(back:) forControlEvents:UIControlEventTouchUpInside];
rightButton.titleLabel.text = [NSString stringWithFormat:#"完成(%#/%#)",#(_selectedAssets.count),#(self.maxPicturesNum)];
rightButton.titleLabel.font = someFont;
UIBarButtonItem *rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:rightButton];
self.rightBarButton = rightBarButtonItem;
And while updating label use rightButton.titleLabel.text
For Adjusting label use this:
- (void)setTitlePositionAdjustment:(UIOffset)adjustment
forBarMetrics:(UIBarMetrics)barMetrics
Finally,I do like this:
- (void)loadRightButtonItem{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(30, 0, 120, 40);
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
[button setTitle:#"完成(0/9)" forState:UIControlStateNormal];
button.tintColor = [UIColor whiteColor];
[button setTitleShadowColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
// [button setTitleColor:[self.buttonFolder titleColorForState:UIControlStateHighlighted] forState:UIControlStateHighlighted];
[button addTarget:self action:#selector(onFinishClicked:) forControlEvents:UIControlEventTouchUpInside];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 135, 40)];
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:view];
[view addSubview:button];
self.navigationItem.rightBarButtonItem = item;
_rightBarButton = button;
}
It cancel the shin effect.
thanks to #RoHaN,your idea did great inspired me.

UINavigatiobar right barbutton item image not visible

I am creating a custom right bar button item for UINavigation bar. Here is the code I am using,
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 40)];
UIButton *backPageButton = [UIButton buttonWithType:UIButtonTypeCustom];
[backPageButton setFrame:CGRectMake(0, 0, 50, 30)];
[ backPageButton setImage:[UIImage imageNamed:#"left_arrow.png"] forState:UIControlStateNormal];
backPageButton.imageView.contentMode = UIViewContentModeScaleAspectFill;
[backPageButton addTarget:self action:#selector(backButtonAction) forControlEvents:UIControlEventTouchUpInside];
[backPageButton setUserInteractionEnabled:YES];
[container addSubview:backPageButton];
UIButton *forwardPageButton = [UIButton buttonWithType:UIButtonTypeCustom];
[forwardPageButton setFrame:CGRectMake(30, 0, 50, 30)];
[ forwardPageButton setImage:[UIImage imageNamed:#"right_arrow.png"] forState:UIControlStateNormal];
[forwardPageButton addTarget:self action:#selector(forwardButtonAction) forControlEvents:UIControlEventTouchUpInside];
forwardPageButton.imageView.contentMode = UIViewContentModeScaleAspectFill;
[forwardPageButton setUserInteractionEnabled:YES];
[container addSubview:forwardPageButton];
UIBarButtonItem* item = [[UIBarButtonItem alloc] initWithCustomView:container];
// set the nav bar's right button item
self.navigationItem.rightBarButtonItem = item;
For some reason the button images are not visible. I added a background color to each button and can see that the buttons are actually added to navigation bar and also the click events are working fine. But button images are not visible.
How to fix it?
Thanks
Of course you've made a double check that images belong to your target?
To debug your views in runtime you could use small but very useful button in Xcode
more about this: https://developer.apple.com/library/ios/recipes/xcode_help-debugger/using_view_debugger/using_view_debugger.html

How to get this UIBarButtonItem in the picture?

I want to get a button with short lines on UINavigationBar.
Please, see that on this image:
What is it? How to get it?
You'll want to instantiate a UIBarButtonItem with a custom view.
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, 24, 24);
[button setImage:[UIImage imageNamed:#"your_image_filename"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonTappedMethod) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
[self.navigationItem setLeftBarButtonItem:barButtonItem];
This creates a UIButton with a supplied image. That UIButton is then set as a custom view for a UIBarButtonItem. Then, just set the barButtonItem on your navigation item.

How to have iOS set a gradient on UIBarButtonItem image?

just wondering, I customised the UIBarButtonItems the following way
+ (UIBarButtonItem *)createBarButtonItemWithTitle:(NSString *)t target:(id)tgt action:(SEL)a
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *buttonImage = [[UIImage imageNamed:#"blabla.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 10, 0, 10)];
CGRect buttonFrame = [button frame];
buttonFrame.size.width = 35;
buttonFrame.size.height = buttonImage.size.height;
[button setFrame:buttonFrame];
[button setBackgroundImage:buttonImage forState:UIControlStateNormal];
[button addTarget:tgt action:a forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
return buttonItem ;
}
But now, I don't have the shading/glossy effect on the button background image....
Is there a way to have it done automatically, or I have to do it programatically ?
EDIT:
To totally customize the bar button in such a way you'd need to provide something other than the flat green image in "blabla.png".
A different way to handle this would be to create a bordered style button with your image. Something like:
UIBarButtonItem* barButton = [UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"blabla.png"] style:UIBarButtonItemStyleBordered target:tgt selector:a];
The UIBarButtonItemStyleBordered style gives it the 3D raised button-y look. You can tint its appearance to match your bar if desired.

Resources