Is it possible to control UIView border properties (color, thickness, etc...) directly from interface builder or I can only do it programmatically?
-
Check this http://stackoverflow.com/a/28854514/3177007– Mohamed Jaleel NazirMar 4, 2015 at 12:33
-
1Just in case anyone comes from Google like I did. To see those changes reflect in IB you just need to create a subclass of UIView and assign it to whatever View you want to manipulate in IB.– Eloy B.Aug 27, 2017 at 2:38
9 Answers
Actually you can set some properties of a view's layer through interface builder. I know that I can set a layer's borderWidth and cornerRadius through xcode. borderColor doesn't work, probably because the layer wants a CGColor instead of a UIColor.
You might have to use Strings instead of numbers, but it works!
layer.cornerRadius
layer.borderWidth
layer.borderColor
Update: layer.masksToBounds = true
-
4To you and Peter DeWeese: I use Xcode 4.6.3 and I can set keypath type to "Color" without impleting a CALayer interface– user2761503Sep 9, 2013 at 13:06
-
45Unfortunately layer.borderColor can't be set this way. It's a CGColorRef, but that IB Color value type is a UIColor. Feb 10, 2014 at 22:33
-
14So THIS is what the user defined runtime attributes does! Haha, been writing for iOS since 2011 and I never learned what those fields were for. Thanks for this awesome answer. Sep 22, 2014 at 19:31
-
4Nice, but you have to set the correct type for each property. The Type for e. g. "layer.cornerRadius" has to be set to "Number" instead of "String"! Aug 15, 2015 at 18:54
-
6Also, don't forget to check the "clip to bounds" checkbox to have the cornerRadius working. Aug 8, 2018 at 15:08
Rich86Man's answer is correct, but you can use categories to proxy properties such as layer.borderColor. (From the ConventionalC CocoaPod)
CALayer+XibConfiguration.h:
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
@interface CALayer(XibConfiguration)
// This assigns a CGColor to borderColor.
@property(nonatomic, assign) UIColor* borderUIColor;
@end
CALayer+XibConfiguration.m:
#import "CALayer+XibConfiguration.h"
@implementation CALayer(XibConfiguration)
-(void)setBorderUIColor:(UIColor*)color
{
self.borderColor = color.CGColor;
}
-(UIColor*)borderUIColor
{
return [UIColor colorWithCGColor:self.borderColor];
}
@end
layer.borderUIColor
The result will be apparent during runtime, not in Xcode.
Edit: You also need to set layer.borderWidth
to at least 1 to see the border with the chosen color.
In Swift 2.0:
extension CALayer {
@objc var borderUIColor: UIColor {
set {
self.borderColor = newValue.CGColor
}
get {
return UIColor(CGColor: self.borderColor!)
}
}
}
In Swift 3.0:
extension CALayer {
@objc var borderUIColor: UIColor {
set {
self.borderColor = newValue.cgColor
}
get {
return UIColor(cgColor: self.borderColor!)
}
}
}
-
I can't get this to work for me. The .m file moans about borderColor having to be borderUIColor and to fix it, after doing so it still shows warnings and the border color doesnt render at runtime. The bit that is different on mine is I have @ implementation NameOfFile, not @ implementation CALayer(NameOfFile), I dont understand the CALayer part, could you explain that more please Sep 5, 2013 at 8:22
-
1You actually can use Number with borderWidth and accept an NSNumber. It works fine. Oct 19, 2014 at 17:18
-
1This is definitely the best solution in my opinion to solve the issue of BorderColor. Fantastic use of categories! Jul 4, 2015 at 20:15
-
1
-
1In case if swift doesn't work for someone, try this stackoverflow.com/a/46554726/618994– VigneshOct 7, 2020 at 9:36
Similar answer to iHulk's one, but in Swift
Add a file named UIView.swift in your project (or just paste this in any file) :
import UIKit
@IBDesignable extension UIView {
@IBInspectable var borderColor: UIColor? {
set {
layer.borderColor = newValue?.cgColor
}
get {
guard let color = layer.borderColor else {
return nil
}
return UIColor(cgColor: color)
}
}
@IBInspectable var borderWidth: CGFloat {
set {
layer.borderWidth = newValue
}
get {
return layer.borderWidth
}
}
@IBInspectable var cornerRadius: CGFloat {
set {
layer.cornerRadius = newValue
clipsToBounds = newValue > 0
}
get {
return layer.cornerRadius
}
}
}
Then this will be available in Interface Builder for every button, imageView, label, etc. in the Utilities Panel > Attributes Inspector :
Note: the border will only appear at runtime.
-
@Gaurav What error do you see ? On which component (UIButton, UILabel, etc.) are you using it ? Apr 17, 2016 at 16:12
-
-
2I was getting Interface Builder crashes with this approach until I removed
@IBDesignable
from the beginning of the extension. May 19, 2016 at 1:39 -
1
-
1
You can make a category of UIView and add this in .h file of category
@property (nonatomic) IBInspectable UIColor *borderColor;
@property (nonatomic) IBInspectable CGFloat borderWidth;
@property (nonatomic) IBInspectable CGFloat cornerRadius;
Now add this in .m file
@dynamic borderColor,borderWidth,cornerRadius;
and this as well in . m file
-(void)setBorderColor:(UIColor *)borderColor{
[self.layer setBorderColor:borderColor.CGColor];
}
-(void)setBorderWidth:(CGFloat)borderWidth{
[self.layer setBorderWidth:borderWidth];
}
-(void)setCornerRadius:(CGFloat)cornerRadius{
[self.layer setCornerRadius:cornerRadius];
}
now you will see this in your storyboard for all UIView subclasses (UILabel, UITextField, UIImageView etc)
Thats it.. No Need to import category anywhere, just add the category's files in the project and see these properties in the storyboard.
-
2Complement it with IB_DESIGNABLE to make IB redraw your custom view using the drawRect: method developer.apple.com/library/ios/recipes/…– txuluAug 25, 2015 at 15:56
-
3Thats great, If you write IB_DESIGNABLE in the .h file before the interface line, you dont need to add @dynamic line in .m– JasmeetMay 16, 2016 at 21:49
-
@user1618612 it has nothing to do with the resolution, it is just setting normal layer properties.– iHulkDec 9, 2016 at 6:43
For Swift 3 and 4, if you're willing to use IBInspectable
s, there's this:
@IBDesignable extension UIView {
@IBInspectable var borderColor:UIColor? {
set {
layer.borderColor = newValue!.cgColor
}
get {
if let color = layer.borderColor {
return UIColor(cgColor: color)
}
else {
return nil
}
}
}
@IBInspectable var borderWidth:CGFloat {
set {
layer.borderWidth = newValue
}
get {
return layer.borderWidth
}
}
@IBInspectable var cornerRadius:CGFloat {
set {
layer.cornerRadius = newValue
clipsToBounds = newValue > 0
}
get {
return layer.cornerRadius
}
}
}
while this might set the properties, it doesnt actually reflect in IB. So if you're essentially writing code in IB, you might as well then do it in your source code
-
1
-
2
-
1Considering that 95% of the time this code goes in the controller, it is also MVC, of course should you properly subclass or extend your view then its just configuration over coding :-) Sep 30, 2017 at 15:27
Its absolutely possible only when you set layer.masksToBounds = true
and do you rest stuff.
Storyboard doesn't work for me all the time even after trying all the solution here
So it is always perfect answer is using the code, Just create IBOutlet instance of the UIView and add the properties
Short answer :
layer.cornerRadius = 10
layer.borderWidth = 1
layer.borderColor = UIColor.blue.cgColor
Long answer :
Rounded Corners of UIView/UIButton etc
customUIView.layer.cornerRadius = 10
Border Thickness
pcustomUIView.layer.borderWidth = 2
Border Color
customUIView.layer.borderColor = UIColor.blue.cgColor
-
The question is very specific and ask how to do it from the Interface Builder. Your answer is irrelevant.– ShinnyxOct 24, 2019 at 19:03
Please add these 2 simple line of code:
self.YourViewName.layer.cornerRadius = 15
self.YourViewName.layer.masksToBounds = true
It will work fine.