How to Apply Borders and Corner Radius to Uibarbuttonitem

How to apply borders and corner radius to UIBarButtonItem?

If you can find the UIView associated with the UIBarButtonItem, you can modify the UIView.layer. But, finding the UIView is not made easy. I used the technique from Figure out UIBarButtonItem frame in window? . Starting with the navigationController.navigationBar, which itself is a UIView, I recursed through the subviews, one of which will be the button I wanted. Which one? Pick your own criteria! Here's my code:

func recurseViews(view:UIView) {
print("recurseViews: \(view)") // helpful for sorting out which view is which
if view.frame.origin.x > 700 { // find _my_ button
view.layer.cornerRadius = 5
view.layer.borderColor = UIColor.redColor().CGColor
view.layer.borderWidth = 2
}
for v in view.subviews { recurseViews(v) }
}

then in viewDidAppear (or similar)

recurseViews((navigationController?.navigationBar)!)

which is a bit of a hack but does the job:

button with border

UIBarButtonItem with rounded corners and shadow

Try this Updated code :

UIButton *useButton = [UIButton buttonWithType:UIButtonTypeCustom];
useButton.frame = CGRectMake(100, 430, 100, 40);
useButton.layer.masksToBounds = NO;
useButton.layer.cornerRadius = 10;
useButton.layer.shadowOffset = CGSizeMake(1.5, 1.5);
useButton.layer.shadowRadius = 0.5;
useButton.layer.shadowOpacity = 1.0;
useButton.layer.shadowColor = [UIColor blackColor].CGColor;
useButton.backgroundColor = [UIColor redColor];

UIBarButtonItem *useItem = [[UIBarButtonItem alloc] initWithCustomView:useButton];
[self.navigationItem setRightBarButtonItems:@[useItem]];

How to add the borders to the UIBarButtonItem

One more solution is that create UIButton object and play with it's layer property.

I have done some basic setup which looks like blue image as shown in question:

Sample Image

Add below code in viewDidLoad() method, also include <QuartzCore/QuartzCore.h> framework.

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(0, 0, 50, 40)];
[button setImage:[UIImage imageNamed:@"settings.png"] forState:UIControlStateNormal];
button.layer.borderWidth = 1.0f;
button.layer.borderColor = [UIColor lightGrayColor].CGColor;
button.layer.cornerRadius = 5.0f;

button.layer.shadowColor = [UIColor lightGrayColor].CGColor;
button.layer.shadowRadius = 4.0f;
button.layer.shadowOpacity = .9;
button.layer.shadowOffset = CGSizeZero;
button.layer.masksToBounds = NO;


UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithCustomView:button];

self.navigationItem.leftBarButtonItem = leftItem;

Add more gradient effects

I did found one git help YIInnerShadowView have a look, it's very useful.

I have use these classes to make gradient and shadow looks like blue image. Able to get much similarity with that image. You can have do more customisation on these classes to get desire accuracy.

Sample Image

Add this library to project, import #import "YIInnerShadowView.h" and add code to viewDidLoad()

YIInnerShadowView *innerView = [[YIInnerShadowView alloc] initWithFrame:CGRectMake(0, 0, 50, 40)];
innerView.shadowRadius = 1.5;
innerView.cornerRadius = 5;
innerView.shadowMask = YIInnerShadowMaskAll;

innerView.layer.borderColor = [UIColor colorWithRed:0.3843 green:0.6235 blue:0.8156 alpha:1.0].CGColor;
innerView.layer.borderWidth = 1.0;

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(0, 0, 50, 40)];
[button setImage:[UIImage imageNamed:@"settings.png"] forState:UIControlStateNormal];
[innerView addSubview:button];

UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithCustomView:innerView];
self.navigationItem.leftBarButtonItem = leftItem;

Also have done little modification in YIInnerShadowLayer.m class:

- (id)init
{
self = [super init];
if (self) {

self.masksToBounds = YES;
self.needsDisplayOnBoundsChange = YES;
self.shouldRasterize = YES;

// Standard shadow stuff
[self setShadowColor:[[UIColor colorWithWhite:0 alpha:1] CGColor]];
[self setShadowOffset:CGSizeMake(0.0f, 1.0f)];
[self setShadowOpacity:1.0f];
[self setShadowRadius:5];

// Causes the inner region in this example to NOT be filled.
[self setFillRule:kCAFillRuleEvenOdd];

self.shadowMask = YIInnerShadowMaskAll;

}
return self;
}

How to place profile image on uibarbuttonitem with rounded corners in objective c?

It works for me:

- (void)viewDidLoad
{
[super viewDidLoad];
NSString* url = @"http://i.stack.imgur.com/EbYBY.jpg";
NSData * data = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString:url]];
UIImage* img = [UIImage imageWithData:data];

UIImageView* v = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
v.image = img;
v.layer.masksToBounds = YES;
v.layer.cornerRadius = 20;

UIBarButtonItem* rightBtn = [[UIBarButtonItem alloc] initWithCustomView:v];
self.navigationItem.rightBarButtonItem = rightBtn;
}

Sample Image

Set UIBarButtonItem's background color working with Storyboard swift

First, drag and drop a UIButton to UINavigationBar. Then from Document Outline select the UIButton which is a child of UIBarButtonItem.

Sample Image

Now go to Identity Inspector from the right panel. Here in User Defined Runtime Attributes section you can set backgroundColor, cornerRadius etc. of UIButton.

Sample Image

But the modification does not reflect in Storyboard. Run your project and you can see the changes.

Sample Image

Figure out UIBarButtonItem frame in window?

Do you like to use private APIs? If yes,

UIView* view = thatItem.view;
return [view convertRect:view.bounds toView:nil];

Of course no one wants this when targeting the AppStore. A more unreliable method, and also uses undocumented features, but will pass Apple's test, is to loop through the subviews to look for the corresponding button item.

NSMutableArray* buttons = [[NSMutableArray alloc] init];
for (UIControl* btn in theToolbarOrNavbar.subviews)
if ([btn isKindOfClass:[UIControl class]])
[buttons addObject:btn];
UIView* view = [buttons objectAtIndex:index];
[buttons release];
return [view convertRect:view.bounds toView:nil];

The index is the index to your bar item in the array of .items, after removing all blank items. This assumes the buttons are arranged in increasing order, which may not be. A more reliable method is to sort the buttons array in increasing .origin.x value. Of course this still assumes the bar button item must inherit the UIControl class, and are direct subviews of the toolbar/nav-bar, which again may not be.


As you can see, there are a lot of uncertainty when dealing with undocumented features. However, you just want to pop up something under the finger right? The UIBarButtonItem's .action can be a selector of the form:

-(void)buttonClicked:(UIBarButtonItem*)sender event:(UIEvent*)event;

note the event argument — you can obtain the position of touch with

[[event.allTouches anyObject] locationInView:theWindow]

or the button view with

[[event.allTouches anyObject] view]

Therefore, there's no need to iterate the subviews or use undocumented features for what you want to do.

Setting corner radius through viewDidAppear() or viewWillLayoutSubviews()?

Use viewDidLayoutSubviews instead, because you'll have the updated bounds at that point, but not yet in viewWillLayoutSubviews.

Or I might suggesting have a button subclass that does the rounding within its own layoutSubviews, freeing your view controller from having to iterate through buttons and rounding them.

For example:

@IBDesignable
class RoundedButton: UIButton {

override func layoutSubviews() {
super.layoutSubviews()

let radius = min(bounds.width, bounds.height) / 2
layer.cornerRadius = radius
}

}

And then just use this class instead of UIButton. That yields:

Sample Image



Related Topics



Leave a reply



Submit