i want to give brder radious like
key path : layer.cormerRadios
value : frame.size.height / 2
in story board there is an one more option type so which type should i give ?
easiest way is to create an #IBInspectable as an extension
extension UIView {
#IBInspectable
var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set {
layer.cornerRadius = newValue
}
}
}
Corner Radius in IB
Related
I'm trying to add shadows to some views via interface builder. I can't seem to get shadows to work on my views. All the resources I look at point to this same code so I'm not sure what I'm doing wrong.
Interface Builder
Interface Builder Extension code
import Foundation
import UIKit
extension UIView {
//cut irrelevant code for SO Question
#IBInspectable
var masksToBounds: Bool {
get {
return layer.masksToBounds
}
set {
layer.masksToBounds = newValue
}
}
// Shadow handling
#IBInspectable
var shadowColor: UIColor? {
get {
if let color = layer.shadowColor {
return UIColor(cgColor: color)
}
return nil
}
set {
if let color = newValue {
layer.shadowColor = color.cgColor
} else {
layer.shadowColor = nil
}
}
}
#IBInspectable
var shadowOpacity: Float {
get {
return layer.opacity
}
set {
layer.opacity = newValue
}
}
#IBInspectable
var shadowRadius: CGFloat {
get {
return layer.shadowRadius
}
set {
layer.shadowRadius = newValue
}
}
#IBInspectable
var shadowOffset: CGSize {
get {
return layer.shadowOffset
}
set {
layer.shadowOffset = newValue
}
}
}
Views layout
This is the result
Your shadowOpacity property is accessing the wrong layer property. It's accessing layer.opacity when it should be layer.shadowOpacity. Also, your shadowRadius is way too large and should probably be around 5 (depending on what you're going for, of course), not 500.
I guess it's your custom search bar to which you're adding shadow. The reason its not visible I guess is because your both view in controller and storyboard of same size. Try to make the storyboard view have a container view in it with some padding along to the storyboard view and add that shadow to that container view. This might show some results.
For making a circular UIView I am using the cornerRadius property.
I have a UIView with dimension 79*158.
redView.layer.cornerRadius = redView.frame.size.height/2
redView.layer.masksToBounds = true
It shows elipse instead of circle:
Any workaround or does it only work with square type (eg. UIView(100*100))?
I am ok if it resizes dynamically.
use this...
func makeCircle (view: UIView) {
view.clipsToBounds = true
let height = view.frame.size.height
let width = view.frame.size.width
let newHeight = min(height, width) // use "max" if you want big circle
var rectFrame = view.frame
rectFrame.size.height = newHeight
rectFrame.size.width = newHeight
view.frame = rectFrame
view.layer.cornerRadius = newHeight/2
}
use like this:
#IBOutlet var rectView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
makeCircle(view: rectView)
}
You have a UIView with dimension 79*158.So that is wrong. You should have exactly same height and width for rounding exact a view to circle shape.
E.g.
redView.frame.size.height = 79.0
redView.frame.size.width = 79.0
or
redView.frame.size.height = 158.0
redView.frame.size.width = 158.0
And apply corner radius like:
redView.clipsToBounds = true
redView.layer.cornerRadius = redView.frame.size.height / 2.0
Result:
Note: Check your constrains also If you are using Auto Layout. Be sure view frame doesn't change.
If you are using constraints then changing the frame/bounds of the view is not a good idea. Instead you should do the following.
If the view is contained in a UIViewController then set the cornerRadius in viewDidLayoutSubviews method
And if the view is itself a subclass of UIView the set the cornerRadius in layoutSubviews method
Only Squire view make a perfect circle. For example, if your view size is (10*10),(50*50),(100*100), etc. then your view becomes perfect squire else not.
Using IBDesignable, you can display without project run in storyboard ox .XIB #simple way
Step 1. Subclass UIView:
#IBDesignable class RoundedCornerView: UIView {
#IBInspectable var borderWidth:CGFloat = 2 {
didSet {
layer.borderWidth = borderWidth
}
}
#IBInspectable var borderColor:UIColor = UIColor.orangeGradientLight {
didSet {
layer.borderColor = borderColor.cgColor
}
}
override func layoutSubviews() {
super.layoutSubviews()
layer.cornerRadius = frame.height/2
layer.masksToBounds = true
layer.borderColor = borderColor.cgColor
layer.borderWidth = borderWidth
}
}
Step 2. Set custom class in identity inspector:
can't.
Try resize UIView to square: 79*79 OR 158*158
And set:
redView.layer.cornerRadius = redView.frame.size.height/2
this is by UI extension method
extension UIView {
func roundCorners(corners:UIRectCorner, radiusWidth: CGFloat,radiusHeight: CGFloat) {
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radiusWidth/2, height: radiusHeight/2))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}}
by this extension method i want to make my buttons with round corners with this code on viewdidload
btnRideNow.roundCorners(corners: [.topRight], radiusWidth: btnRideNow.frame.width,radiusHeight: btnRideNow.frame.height )
btnRideLater.roundCorners(corners: [.topLeft], radiusWidth: btnRideLater.frame.width,radiusHeight: btnRideLater.frame.height )
but on iPhone 5 i am getting this result
ScreenShot
you can see left button wouldn't render properly but in iPhone 6 this work properly Why?
It's all a matter of timing.
If you call roundCorners too soon, e.g. in viewDidLoad, the button's frame and bounds may not yet have been finalized. But your roundCorners depends on the bounds, so if you add the mask and the button is then resized as a result of layout, you will naturally get the wrong result.
If you want round corners you can simple do:
view.layer.cornerRadius
and if you want a border you can do
view.layer.borderWidth
and color
view.layer.borderColor
Here's a simple subclass that works with IB. You should be able to easily adapt it to your needs:
#IBDesignable
public class Button: UIButton {
#IBInspectable public var borderColor:UIColor? {
didSet {
layer.borderColor = borderColor?.cgColor
}
}
#IBInspectable public var borderWidth:CGFloat = 0 {
didSet {
layer.borderWidth = borderWidth
}
}
#IBInspectable public var cornerRadius:CGFloat {
get {
return layer.cornerRadius
}
set {
layer.cornerRadius = newValue
layer.masksToBounds = newValue > 0
}
}
}
Now if you wish to simply code things, you were given most of the answer. For a complete circle:
view.layer.cornerRadius = view.frame.height / 2
You can use width though, if it's square. But like #Matt says (he's very good), be careful to do this after you have the frame/bounds properly set!
I can't get a border onto my buttons in Xcode 5 without setting them directly in the code. Is it possible that there's no way to do this on the storyboard without making a custom background image?
You can use key path.
For example the corner radius (layer.cornerRadius) as describe on the image.
You will not be able to see the effects on storyboard, cause this parameters are evaluated at runtime. Now you can use a swift category in UIView (code bellow the picture) in with #IBInspectable to show the result at the storyboard (If you are using the category, use only cornerRadius and not layer.cornerRadius as a key path.
extension UIView {
#IBInspectable var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set {
layer.cornerRadius = newValue
layer.masksToBounds = newValue > 0
}
}
}
Here is category from Peter DeWeese answer that allow use keypath layer.borderUIColor to set the border color.
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
Swift 3
If you want to see the result in IB when you use IBInspectable, you have to extend UIView and add the properties to that class, i.e.
#IBDesignable class MyView: UIView {}
extension MyView {
#IBInspectable var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set {
layer.cornerRadius = newValue
layer.masksToBounds = newValue > 0
}
}
#IBInspectable var borderWidth: CGFloat {
get {
return layer.borderWidth
}
set {
layer.borderWidth = newValue
layer.masksToBounds = newValue > 0
}
}
#IBInspectable var borderColor: UIColor {
get {
return UIColor.init(cgColor: layer.borderColor!)
}
set {
layer.borderColor = newValue.cgColor
}
}
}
reference: http://nshipster.com/ibinspectable-ibdesignable/
Short answer :
layer.cornerRadius = 10
layer.borderWidth = 1
layer.borderColor = UIColor.blue.cgColor
Long answer :
Rounded Corners UIButton
customUIView.layer.cornerRadius = 10
Border Thickness
pcustomUIView.layer.borderWidth = 1
Border Color
customUIView.layer.borderColor = UIColor.blue.cgColor
you can set your UIButton User Defined Run Time Attributes ie
borderWidth, cornerRadius, borderColor etc. As shown in the image.
Note:- don't use layer. before the attribute name, it will not work.
You can use a piece of code like:
self.addButton.layer.borderColor = [[UIColor greenColor] CGColor];
Please note: addButton is an IBOutlet.
I saw in the inspector that I can change the background color, but I'd like to also change the border color and thickness, is this possible?
You need to use view's layer to set border property. e.g:
#import <QuartzCore/QuartzCore.h>
...
view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth = 3.0f;
You also need to link with QuartzCore.framework to access this functionality.
Xcode 6 update
Since Xcode's newest version there is a better solution to this:
With #IBInspectable you can set Attributes directly from within the Attributes Inspector.
This sets the User Defined Runtime Attributes for you:
There are two approaches to set this up:
Option 1 (with live updating in Storyboard)
Create MyCustomView.
This inherits from UIView.
Set #IBDesignable (this makes the View update live).*
Set your Runtime Attributes (border, etc.) with #IBInspectable
Change your Views Class to MyCustomView
Edit in Attributes Panel and see changes in Storyboard :)
`
#IBDesignable
class MyCustomView: UIView {
#IBInspectable var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
layer.masksToBounds = cornerRadius > 0
}
}
#IBInspectable var borderWidth: CGFloat = 0 {
didSet {
layer.borderWidth = borderWidth
}
}
#IBInspectable var borderColor: UIColor? {
didSet {
layer.borderColor = borderColor?.CGColor
}
}
}
* #IBDesignable only works when set at the start of class MyCustomView
Option 2 (not working since Swift 1.2, see comments)
Extend your UIView Class:
extension UIView {
#IBInspectable var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
layer.masksToBounds = cornerRadius > 0
}
}
#IBInspectable var borderWidth: CGFloat = 0 {
didSet {
layer.borderWidth = borderWidth
}
}
#IBInspectable var borderColor: UIColor? {
didSet {
layer.borderColor = borderColor?.CGColor
}
}
}
This way, your default View always has those extra editable fields in Attributes Inspector. Another advantage is that you don't have to change the class to MycustomView every time.
However, one drawback to this is that you will only see your changes when you run your app.
You can also create border with the color of your wish..
view.layer.borderColor = [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0].CGColor;
*r,g,b are the values between 0 to 255.
Add following #IBInspectables in UIView extension
extension UIView {
#IBInspectable var borderWidth: CGFloat {
get {
return layer.borderWidth
}
set(newValue) {
layer.borderWidth = newValue
}
}
#IBInspectable var borderColor: UIColor? {
get {
if let color = layer.borderColor {
return UIColor(CGColor: color)
}
return nil
}
set(newValue) {
layer.borderColor = newValue?.CGColor
}
}
}
And then you should be able to set borderColor and borderWidth attributes directly from Attribute inspector. See attached image
Attributes Inspector
view.layer.borderWidth = 1.0
view.layer.borderColor = UIColor.lightGray.cgColor
When I use Vladimir's CALayer solution, and on top of the view I have an animation, like a modal UINavigationController dismissing, I see a lot of glitches happening and having drawing performance issues.
So, another way to achieve this, but without the glitches and performance loss, is to make a custom UIView and implement the drawRect message like so:
- (void)drawRect:(CGRect)rect
{
CGContextRef contextRef = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(contextRef, 1);
CGContextSetRGBStrokeColor(contextRef, 255.0, 255.0, 255.0, 1.0);
CGContextStrokeRect(contextRef, rect);
}
Try this code:
view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth= 2.0;
[view setClipsToBounds:YES];
I wouldn't suggest overriding the drawRect due to causing a performance hit.
Instead, I would modify the properties of the class like below (in your custom uiview):
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.layer.borderWidth = 2.f;
self.layer.borderColor = [UIColor redColor].CGColor;
}
return self;
I didn't see any glitches when taking above approach - not sure why putting in the initWithFrame stops these ;-)
I wanted to add this to #marczking's answer (Option 1) as a comment, but my lowly status on StackOverflow is preventing that.
I did a port of #marczking's answer to Objective C. Works like charm, thanks #marczking!
UIView+Border.h:
#import <UIKit/UIKit.h>
IB_DESIGNABLE
#interface UIView (Border)
-(void)setBorderColor:(UIColor *)color;
-(void)setBorderWidth:(CGFloat)width;
-(void)setCornerRadius:(CGFloat)radius;
#end
UIView+Border.m:
#import "UIView+Border.h"
#implementation UIView (Border)
// Note: cannot use synthesize in a Category
-(void)setBorderColor:(UIColor *)color
{
self.layer.borderColor = color.CGColor;
}
-(void)setBorderWidth:(CGFloat)width
{
self.layer.borderWidth = width;
}
-(void)setCornerRadius:(CGFloat)radius
{
self.layer.cornerRadius = radius;
self.layer.masksToBounds = radius > 0;
}
#end
#IBInspectable is working for me on iOS 9 , Swift 2.0
extension UIView {
#IBInspectable var borderWidth: CGFloat {
get {
return layer.borderWidth
}
set(newValue) {
layer.borderWidth = newValue
}
}
#IBInspectable var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set(newValue) {
layer.cornerRadius = newValue
}
}
#IBInspectable var borderColor: UIColor? {
get {
if let color = layer.borderColor {
return UIColor(CGColor: color)
}
return nil
}
set(newValue) {
layer.borderColor = newValue?.CGColor
}
}
If you didn't want to edit the layer of a UIView, you could always embed the view within another view. The parent view would have its background color set to the border color. It would also be slightly larger, depending upon how wide you want the border to be.
Of course, this only works if your view isn't transparent and you only want a single border color. The OP wanted the border in the view itself, but this may be a viable alternative.
item's border color in swift 4.2:
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell_lastOrderId") as! Cell_lastOrder
cell.layer.borderWidth = 1
cell.layer.borderColor = UIColor.white.cgColor
cell.layer.cornerRadius = 10
If you want to add different border on different sides, may be add a subview with the specific style is a way easy to come up with.
[self.view.layer setBorderColor: [UIColor colorWithRed:0.265 green:0.447 blue:0.767 alpha:1.0f].CGColor];