Button with border (most optimized) - ios

In my app I need to create a button with a 1px colored border with a corner radius. Width may be different.
Naturally I will create a UIButton setting its layer.cornerRadius and layer.borderWidth.
Is it optimal?
Is there a betterway to achieve this?
Another developer told me that doing this way is expensive.
What do you think?
Thanks.

Subclass UIButton. May be named ViewWithThinBorder .
In its implementation in awakeFromNib method add border corner and width properties.
Now you can go to interface builder select button and set its class to ViewWithThinBorder from identity inspector.
This is not only optimized its more reusable anywhere around the interface builder. Also you can change buttons around all view hierarchy from central location.
#import "ViewWithThinBorder.h"
#implementation ViewWithThinBorder
-(void)awakeFromNib
{
self.layer.borderColor = [UIColor groupTableViewBackgroundColor].CGColor;
self.layer.borderWidth = 1.0f;
self.layer.cornerRadius = 1.0f;
}
#end

Related

Getting UIButton width before viewDidAppear, with AutoLayout

I have a UIButton (created in interface builder), that I'm turning into a circle by setting button.layer.borderRadius = button.frame.size.width / 2.0; (programatically, in viewDidAppear:). However, the viewController it belongs to is presented modally with an animation. Since viewDidAppear isn't called until after the transition animation has finished, the button is square until then, which makes the sudden change quite jarring.
I can't set the radius in viewDidLoad, since the button properties are incorrect then (the width is too large), which I think is because autolayout constraints haven't been properly resolved yet. I tried to rectify this by calling [self.view setNeedsLayout] in viewDidLoad, and then setting the cornerRadius, but the button width was still wrong. What I don't understand is, during the animation, everything otherwise renders correctly, suggesting that the autolayout constraints /have/ been resolved, or that iOS does something else in the name of quick animations (like storing a snapshot preview to use for the animation).
Any suggestions?
The result of trying to set the corner radius in viewDidLoad:
You can get the width in the function
- viewDidLayoutSubviews.
Apple Documentation here.
Override the UIButton and make its layoutSubviews method like this:
- (void)layoutSubviews {
[super layoutSubviews];
self.layer.cornerRadius = self.bounds.size.width/2.f;
}
Then whenever the button's size changes it will adjusts its value.
Also add it in buttonWithType: and initWithFrame: as I'm not sure if the layoutSubviews is called after init.
Your controls get the constraints and frame set after viewDidLoad amd after viewDidLoad you can get your requirements in viewwilllayoutsubviews or in viewdidlayoutsubviews before viewDidAppear
what about
-(void) viewWillAppear:(BOOL)animated
Sorry I didn't get you well. As your screenshot explains that your image isn't being circular.For that you can try:(1) layer.cornerRadius = btn.frame.size.width/2; or layer.CornerRadius = 50(if width is 100)
layer.masksToBounds = YES;
layer.borderWidth = 1.5; or whatever you want
layer.borderColor = [UIColor whiteColor];
If still you get problem, then share your constraints that you added on button and also the code where you are doing this.

iOS Buttons - add border

I am making my app ready for iOS7. I did conversion and was working with a user. The button in the app does not look like button. Looks very flat. Is there someway to put border or make it stand like a button?
Try this for adding border, It will work
#import <QuartzCore/QuartzCore.h>
then in viewDidLoad
_btn.layer.borderWidth=1.0f;
_btn.layer.borderColor=[[UIColor blackColor] CGColor];
_btn.layer.cornerRadius = 10;
also you can fill the color for making appearance somewhat like button, or best way is to use image there
Apart from BorderColor, you can do it by using Runtime attributes too.
try this , this will set border to button
#import <QuartzCore/QuartzCore.h>
btn.layer.borderColor = [UIColor blackColor].CGColor;
btn.layer.borderWidth = 1.0;
btn.layer.cornerRadius = 10;
With Swift and XCode 6 you can do this.
Click the UIButton element in Storyboard, and go to identity inspector. In the user defined runtime attributes, enter:
layer.borderWidth number 1
If you want nice looking corners
layer.cornerRadius number 5
layer.maskToBounds boolean true
Now this will give you a border but to set the colour you need to do it with code. Go to your view controller, and add an IBOutlet from your button. Note that in this case it's an IBOutlet, not an IBAction. Say you do,
#IBOutlet weak var xButton: UIButton!
Call this in the viewDidLoad function like below to set the colour.
xButton.layer.borderColor = UIColor.whiteColor().CGColor
Thanks!
The design principles in iOS7 have changed. However, if you want to go flatter, but still want a custom button that "stands like a button", you can try out this open source component collection:
FlatUIKit on GitHub
There are two way to simplify button in ios 7
1>Set image : Just like Button using setImage Property for button
2>Set bordercolor borderWidth :
button.layer.borderWidth=1.0f;
button.layer.borderColor=[[UIColor blackColor] CGColor];
I suggest you try one of the iOS BootstrapButton libraries (or clones). Just change UIButton in the storyboard to BButton. There is just no preview in the storyboard.
http://github.com/katzlbt/iOSBootstrapButton
http://github.com/katzlbt/iOSBootstrapButtonDemo
http://github.com/mattlawer/BButton
If you use a background image, move button backward.
Editor>Arrange>send backward
In ios7 buttons are supposed to look borderless. Please see apple's View Transition Guidelines for help.
If you REALLY want the buttons to have a border, do: [button setImage:forState:] to set a customized button image with border.

UIView border cover sub-view?

I have a UIView which includes a UIButton which is partially on UIView. I have a problem when I draw a border on my UIView. Please have a look at my screenshot:
You can see the border is above the UIButton, why? Can anybody suggest? Thanks
Thanks for aăâ, I found a solution.
Basically the border is always drawn on top of everything
What I did is:
Create a UIView with color of border
Create another UIView as the child the main UIView which is a little bit smaller than the first one. The color of this newly create UIView is the main color
Here is the code:
self.layer.cornerRadius = 15;
self.layer.masksToBounds = YES;
self.backView.layer.cornerRadius = 15;
self.backView.layer.masksToBounds = YES;
The result is:
It's more or less what I need although it's not perfect.
It could have to do with the order that the objects are drawn. In your storyboard's "Document Outline", views that are lower down in a view controller's outline are drawn later. Perhaps the button is not the last drawn view, like you want?

How can I inherit from a rounded rect UIButton in Interface Builder?

I've created a class that inherits from UIButton. If I add rounded-rect buttons to my XIB and set their class property to UIButton, they appear as rounded-rect buttons (but then none of my custom code is ever called, so the buttons behave like ordinary buttons which isn't what I want). If I set these buttons' class property in IB to my custom class UIButtonCustom, they still appear to be rounded rect buttons in the IB designer, but when I run the app the buttons are of the custom type (meaning they appear mostly blank with the button text, since I'm not setting any background image for the button).
Is there any way to get these buttons to look like rounded rect buttons when the app actually runs?
The rounded button that you see on xib is sub class of UIButton i.e. UIRoundedRectButton.
And I don't think you can subclass it as it's not documented (a private API).
As others here have noted, you cannot subclass a UIRoundedRectButton. But you can get your buttons to look like rounded rect buttons by setting some CALayer properties in your init method.
#import "MyCustomButton.h"
#import <QuartzCore/QuartzCore.h>
#implementation MyCustomButton
- (id)initWithFrame:(CGRect)frame
//button created in code
{
self = [super initWithFrame:frame];
if (self) {
[self initialise];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder;
//button created in Interface Builder
{
self = [super initWithCoder:aDecoder];
if (self) {
[self initialise];
}
return self;
}
- (void)initialise;
{
self.layer.cornerRadius = 10.0f;
self.layer.borderWidth = 1.0f;
self.layer.borderColor = [[UIColor lightGrayColor] CGColor];
}
#end
If you have autolayout disabled you can continue to use 'Rounded Rect' button style in IB to give you the correct appearance in layout, although the style will be ignored when your custom button loads. If autolayout is enabled, you will have to change your IB style to 'custom', or you will find the button frame does not behave the way you expect.

How to remove the "fuzzy" drop shadow in the UIPopoverController

I don't want the drop shadow when the UIPopoverController's view appears. Is there a way to remove this drop shadow look?
Not straight forward, but since iOS 5, you can make your own custom popover background using UIPopoverBackgroundView.
See the answer for this question: Using UIPopoverBackgroundView class. It's pointing to a good tuto.
Then, in the initWithFrame of your UIPopoverBackgroundView implementation, you can use a clearColor for the drop shadow. Using offset and radius did not work for me.
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.layer.shadowColor = [[UIColor clearColor] CGColor];
}
return self;
}
The shadow is an attribute of the popover view's layer. If you could get access to the layer, you could set it's shadow radius to 0.0 and shadow offset to {0.0, 0.0}. However, it looks like the view must be a private ivar of the popover controller, so there's not an easy way to get to it. Moreover, if you're looking to distribute this app through the app store, using a private ivar and changing the look of standard UI elements both are likely to get your app rejected.
You just have to use your custom UIPopoverBackgroundView and there implement this function:
+ (BOOL)wantsDefaultContentAppearance {
return NO;
}

Resources