I am new to swift and I am trying to set a black border around my UIImageView but I am unable to do so. This is my code
#IBOutlet weak var flagImage: UIImageView!
var image = UIImage(named: "estonia")
override func viewDidLoad() {
super.viewDidLoad()
flagImage.layer.borderColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 1.0).CGColor
flagImage.layer.cornerRadius = 5.0
flagImage.contentMode = .scaleAspectFit
flagImage.image = image
}
Could I get some help on this?
You gave the border color to the imageView but how could you expect to see the color with out any area to fill in. So, the
flagImage.layer.borderWidth = 2 /** as you wish **/
Gives the Area around the imageView of thickness 2 to fill in the color you gave.
Try to add this
Objective-C
flagImage.layer.masksToBounds = YES;
Swift
flagImage.layer.masksToBounds = true
you only MISS borderWidth = 1 (x)
Made an ImageView that was say 65w x 65h. I then dragged another image view over it in interface builder and made it 67wx67h. I then changed its background to black and moved it behind the other. This will give the first imageView a black border. Just adjust the black image view as needed to adjust the border thickness.
Related
Following is my code to create CardView and add shadow effect
override func awakeFromNib() {
super.awakeFromNib()
self.layoutIfNeeded()
cellBgview.layer.cornerRadius = 15.0
cellBgview.layer.borderWidth = 1.0
cellBgview.layer.borderColor = UIColor.clear.cgColor
cellBgview.layer.shadowColor = UIColor.gray.cgColor
cellBgview.layer.shadowRadius = 14.0
cellBgview.layer.shadowOpacity = 0.5
cellBgview.layer.shadowPath = UIBezierPath(roundedRect: cellBgview.bounds, cornerRadius: cellBgview.layer.cornerRadius).cgPath
// In
}
This looks like this
Corner radius not working in this case to make corner radius work I have added following code
cellBgview.clipsToBounds = true
After adding above code it looks this
Note that after adding cellBgview.clipsToBounds = true card elevation and shadow is missing but corner radius appears
How to make card view with corner radius and shadow without image getting clip.
Also tried
cellBgview.layer.masksToBounds = true
but it is not working.
Add another UIView in your cell and add imageView in that UIView...Apply corner radius to imageView. Apply shadow to that UIView holding imageView. add clipsToBounds to imageView not to that UIView because clipsToBounds clip anything outside bounds that can be shadow as well. will solve your issue
add a uiview in your cell, lets call it content view. in this view add another uiview in which you'll add the image view and your bottom labels. So actual hierarchy would look like this
--Cell
---UIView //add shadow on this view, also make its backgroundColor to clear color
---UIView //add corner radius to this view and clipsToBounds = true for this view
---UIImageView
---Bottom Labels / Another UIView / Stack View
this hierarchy will help you to achieve the image round corner only on top and view round corners on bottom content
Try this to achieve Shadow, Corner Radius, Border in one view.
cellBgview.backgroundColor = UIColor.white
let cellBgViewLayer = cellBgview.layer()
cellBgViewLayer?.masksToBounds = false
cellBgViewLayer?.shadowColor = UIColor.lightGray.cgColor
cellBgViewLayer?.shadowOpacity = 1.0
cellBgViewLayer?.shadowRadius = 6.0
cellBgViewLayer?.shadowOffset = CGSize(width: 0, height: 0)
cellBgViewLayer?.shouldRasterize = true
cellBgViewLayer?.cornerRadius = 5.0
cellBgViewLayer?.borderColor = UIColor.lightGray.cgColor
cellBgViewLayer?.borderWidth = 1.0
cellBgViewLayer?.shadowPath = UIBezierPath(rect: cellBgview.bounds).cgPath
I'm calling a function that sets up a UIImageView:
func setupImageView(_ imageView: UIImageView) {}
I want to give that UIImageView an image, round its corners, and give it two different borders.
Here is what I am currently doing:
imageView.image = imageConstants.imageThatIsWanted
imageView.clipsToBounds = true
imageView.layer.cornerRadius = imageView.frame.height / 2
imageView.layer.borderWidth = 3.0
imageView.layer.borderColor = UIColor.white.cgColor
What is the best way to apply a second borderColor of color blue around the white border?
I tried creating a sublayer as a CALayer and giving it a blue border, but this goes behind the image, and also inside of the white border. I also tried drawing a UIBezierPath, but that stays inside of the white border as well.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var secondView: UIView!
#IBOutlet weak var imgView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
imgView.layer.cornerRadius = imgView.frame.size.height/2
secondView.layer.cornerRadius = secondView.frame.size.height/2
imgView.layer.borderWidth = 5.0
imgView.layer.borderColor = UIColor.red.cgColor
imgView.clipsToBounds = true
secondView.clipsToBounds = true
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You can add UIlabel or UIImageview at back of your image view having size little bit larger than your image view and applying corner radius, if you want to reduce line of your code (Please check below code)
imgview.layer.masksToBounds = true
imgview.layer.cornerRadius = imgview.frame.size.width/2
imgview.layer.borderWidth = 5
imgview.layer.borderColor = UIColor.white.cgColor
Add new image view programatically at back side of image view already taken
let img = UIImageView(frame: CGRect(x: imgview.frame.origin.x - 2, y: imgview.frame.origin.y - 2, width: imgview.frame.size.width + 4, height: imgview.frame.size.height + 4))
img.layer.masksToBounds = true
img.layer.cornerRadius = img.frame.size.width/2
//img.backgroundColor = UIColor.blue // You can also use background color instead of border
img.layer.borderWidth = 5
img.layer.borderColor = UIColor.blue.cgColor
self.view.addSubview(img)
self.view.sendSubview(toBack: img)
I know its not proper solution but we can use this to reduce lines of code
Hope it will helps you
From my understanding, the only way to change the color of the top border is to set the background image (320x49, with pixel line at top). It seems to me that this is the only way (please correct me if I'm wrong).
Is there a way to do this without using an image file? For example, someone helped me change the NavigationBar bottom border by creating a UIImage from code:
UINavigationBar.appearance().shadowImage = UIImage.colorForNavBar(UIColor.redColor())
extension UIImage {
class func colorForNavBar(color: UIColor) -> UIImage {
let rect = CGRectMake(0.0, 0.0, 1.0, 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
CGContextSetFillColorWithColor(context, color.CGColor)
CGContextFillRect(context, rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
This solution actually works well; it changes the color of my bottom border.
I tried to apply this to the TabBar, but nothing changes at all.
UITabBar.appearance().shadowImage = UIImage.colorForNavBar(.redColor())
You've pretty much answered your own question. You can do the same thing with your UITabBar as you did with your UINavigationBar. If you want to change the shadow image (i.e. the "top border"), then you have to change the background image. Straight from Apple:
The custom shadow image for the tab bar. This attribute is ignored if the tab bar does not also have a custom background image. To set this attribute programmatically, use the shadowImage property.
In your own question you seem to be aware of this:
the only way to change the color of the top border is to set the background image (320x49, with pixel line at top)
Except that it's not the background image that has a line at the top. You just have to set the background image to anything, then you can set the shadow image to your preference.
If you open up the simple "tabbed application" template within Xcode, you'll find that adding these two lines of code (and your UIImage extension code) indeed work:
// White background with red border on top
UITabBar.appearance().backgroundImage = UIImage.colorForNavBar(.whiteColor())
UITabBar.appearance().shadowImage = UIImage.colorForNavBar(.redColor())
Here is the Swift 3 solution:
extension UIImage {
class func colorForNavBar(color: UIColor) -> UIImage {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
// Or if you need a thinner border :
// let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 0.5)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor)
context!.fill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
used with the code above in the viewDidLoad of the UITabBarController
UITabBar.appearance().backgroundImage = UIImage.colorForNavBar(color: .white)
UITabBar.appearance().shadowImage = UIImage.colorForNavBar(color: .red)
You need to provide an different image for UINavigationBar.appearance().backgroundImage.
For example:
UINavigationBar.appearance().backgroundImage = UIImage.colorForNavBar(.blackColor())
UINavigationBar.appearance().shadowImage = UIImage.colorForNavBar(.redColor())
Normally, the other answers got it right - you have to set both a background image and a shadow image. However, doing so will cause the bar to drop its translucency (blur); even if you set a transparent image, the bar will be transparent, not translucent.
We also had a similar need, but we wanted to preserve the translucency of the bar. Instead of setting a shadow image, we subclassed the bar, and put a hairline subview with a color we want. When the bar lays out its subviews, we set the frame of the hairline to be the width of the bar, and a pixel exactly.
See my GitHub demo project.
Here is a screenshot of the result:
After you include my subview in your project, just use the following line to set the color:
if let tabBar = tabBarController?.tabBar as? ColoredHairlineTabBar {
tabBar.hairlineColor = ... //Your color
}
What about simply subclassing UITabBar and adding a new sublayer to the view in layoutSubviews.
Swift example:
override func layoutSubviews() {
super.layoutSubviews()
let topBorder = CALayer()
let borderHeight: CGFloat = 2
topBorder.borderWidth = borderHeight
topBorder.borderColor = UIColor.redColor().CGColor
topBorder.frame = CGRect(x: 0, y: -1, width: self.frame.width, height: borderHeight)
self.layer.addSublayer(topBorder)
}
You don't need an extension to create an image of a certain size, UIImage has a perfectly good constructor for that.
To prevent losing the translucent blur, you can set the bar tint color instead of a background image. You can also use the screen scale to make sure the border is one pixel, like the original border was:
let hairlineHeight = CGFloat(1) / UIScreen.main.scale
tabBar.barTintColor = .white
tabBar.shadowImage = UIImage(color: .black, size: CGSize(width: 1, height: hairlineHeight))
I have a PNG image of pedal in my view with transparency. I have implemented shadow according to that question, using Swift. Here I have custom UIViewWithShadow:
import UIKit
class UIViewWithShadow: UIView {
let image: UIImage!
var shadowOffset = CGSize.init(width: 5, height: 5)
var shadowBlur: CGFloat = 5
override func drawRect(rect: CGRect) {
let c = UIGraphicsGetCurrentContext();
CGContextSetShadow(c, shadowOffset, shadowBlur);
CGContextSetShadowWithColor(c, shadowOffset, shadowBlur, UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.8).CGColor)
self.image.drawAtPoint(CGPointMake(rect.minX, rect.minY)
}
}
Example of shadow change
It draws correctly, and now I need to animate that shadow - specificly, to decrease shadow's blur and offset when my image is pressed. I wonder if there is a way to do that like it is usually done with layer's shadow animation?
UPD
The goal is to make an illusion of pressing the pedal. I have done 3D transformation of it, the only thing I need is decreasing shadow under it, to make it look like the pedal became closer to the floor. If there are other ways to achieve that (like making shadow dependent on the Z-coordinate of pedal's view), I'll appreciate that
Is there a built in way to create round-cornered UILabels? If the answer is no, how would one go about creating such an object?
iOS 3.0 and later
iPhone OS 3.0 and later supports the cornerRadius property on the CALayer class. Every view has a CALayer instance that you can manipulate. This means you can get rounded corners in one line:
view.layer.cornerRadius = 8;
You will need to #import <QuartzCore/QuartzCore.h> and link to the QuartzCore framework to get access to CALayer's headers and properties.
Before iOS 3.0
One way to do it, which I used recently, is to create a UIView subclass which simply draws a rounded rectangle, and then make the UILabel or, in my case, UITextView, a subview inside of it. Specifically:
Create a UIView subclass and name it something like RoundRectView.
In RoundRectView's drawRect: method, draw a path around the bounds of the view using Core Graphics calls like CGContextAddLineToPoint() for the edges and and CGContextAddArcToPoint() for the rounded corners.
Create a UILabel instance and make it a subview of the RoundRectView.
Set the frame of the label to be a few pixels inset of the RoundRectView's bounds. (For example, label.frame = CGRectInset(roundRectView.bounds, 8, 8);)
You can place the RoundRectView on a view using Interface Builder if you create a generic UIView and then change its class using the inspector. You won't see the rectangle until you compile and run your app, but at least you'll be able to place the subview and connect it to outlets or actions if needed.
For devices with iOS 7.1 or later, you need to add:
yourUILabel.layer.masksToBounds = YES;
yourUILabel.layer.cornerRadius = 8.0;
For Swift IOS8 onwards based on OScarsWyck answer:
yourUILabel.layer.masksToBounds = true
yourUILabel.layer.cornerRadius = 8.0
you have an UILabel called: myLabel.
in your "m" or "h" file import: #import <QuartzCore/QuartzCore.h>
in your viewDidLoad write this line: self.myLabel.layer.cornerRadius = 8;
depends on how you want you can change cornerRadius value from 8 to other number :)
Good luck
You can make rounded border with width of border of any control in this way:-
CALayer * l1 = [lblName layer];
[l1 setMasksToBounds:YES];
[l1 setCornerRadius:5.0];
// You can even add a border
[l1 setBorderWidth:5.0];
[l1 setBorderColor:[[UIColor darkGrayColor] CGColor]];
Just replace lblName with your UILabel.
Note:- Don't forget to import <QuartzCore/QuartzCore.h>
Swift 3
If you want rounded label with background color, in addition to most of the other answers, you need to set layer's background color as well. It does not work when setting view background color.
label.layer.cornerRadius = 8
label.layer.masksToBounds = true
label.layer.backgroundColor = UIColor.lightGray.cgColor
If you are using auto layout, want some padding around the label and do not want to set the size of the label manually, you can create UILabel subclass and override intrinsincContentSize property:
class LabelWithPadding: UILabel {
override var intrinsicContentSize: CGSize {
let defaultSize = super.intrinsicContentSize
return CGSize(width: defaultSize.width + 12, height: defaultSize.height + 8)
}
}
To combine the two you will also need to set label.textAlignment = center, otherwise the text would be left aligned.
I made a swift UILabel subclass to achieve this effect. In addition I automatically set the text color to either black or white for maximal contrast.
Result
Used SO-Posts:
How to draw border around a UILabel?
Add a border outside of a UIView
Check if UIColor is dark or bright?
Playground
Just paste this into an iOS Playground:
//: Playground - noun: a place where people can play
import UIKit
class PillLabel : UILabel{
#IBInspectable var color = UIColor.lightGrayColor()
#IBInspectable var cornerRadius: CGFloat = 8
#IBInspectable var labelText: String = "None"
#IBInspectable var fontSize: CGFloat = 10.5
// This has to be balanced with the number of spaces prefixed to the text
let borderWidth: CGFloat = 3
init(text: String, color: UIColor = UIColor.lightGrayColor()) {
super.init(frame: CGRectMake(0, 0, 1, 1))
labelText = text
self.color = color
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
func setup(){
// This has to be balanced with the borderWidth property
text = " \(labelText)".uppercaseString
// Credits to https://stackoverflow.com/a/33015915/784318
layer.borderWidth = borderWidth
layer.cornerRadius = cornerRadius
backgroundColor = color
layer.borderColor = color.CGColor
layer.masksToBounds = true
font = UIFont.boldSystemFontOfSize(fontSize)
textColor = color.contrastColor
sizeToFit()
// Credits to https://stackoverflow.com/a/15184257/784318
frame = CGRectInset(self.frame, -borderWidth, -borderWidth)
}
}
extension UIColor {
// Credits to https://stackoverflow.com/a/29044899/784318
func isLight() -> Bool{
var green: CGFloat = 0.0, red: CGFloat = 0.0, blue: CGFloat = 0.0, alpha: CGFloat = 0.0
self.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
let brightness = ((red * 299) + (green * 587) + (blue * 114) ) / 1000
return brightness < 0.5 ? false : true
}
var contrastColor: UIColor{
return self.isLight() ? UIColor.blackColor() : UIColor.whiteColor()
}
}
var label = PillLabel(text: "yellow", color: .yellowColor())
label = PillLabel(text: "green", color: .greenColor())
label = PillLabel(text: "white", color: .whiteColor())
label = PillLabel(text: "black", color: .blackColor())
If you want rounded corner of UI objects like (UILabel, UIView, UIButton, UIImageView) by storyboard then set clip to bounds true and set User Defined Runtime Attributes Key path as
layer.cornerRadius, type = Number and value = 9 (as your requirement)
xCode 7.3.1 iOS 9.3.2
_siteLabel.layer.masksToBounds = true;
_siteLabel.layer.cornerRadius = 8;
Another method is to place a png behind the UILabel. I have views with several labels that overlay a single background png that has all the artwork for the individual labels.
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
label.text = #"Your String.";
label.layer.cornerRadius = 8.0;
[self.view addSubview:label];
Works fine in Xcode 8.1.2 with Swift 3
.cornerRadius is the key property to set rounded edges. If you are using the same style for all labels in your application, I would recommend for an extension method.
Code:
// extension Class
extension UILabel {
// extension user defined Method
func setRoundEdge() {
let myGreenColor = (UIColor(red: -0.108958, green: 0.714926, blue: 0.758113, alpha: 1.0))
//Width of border
self.layer.borderWidth = 1.0
//How much the edge to be rounded
self.layer.cornerRadius = 5.0
// following properties are optional
//color for border
self.layer.borderColor = myGreenColor.cgColor
//color for text
self.textColor = UIColor.red
// Mask the bound
self.layer.masksToBounds = true
//clip the pixel contents
self.clipsToBounds = true
}
}
Output:
Why Extension method?
Create a Swift file and add the following code, which has the Extention method to the "UILabel" class, where this method is user defined but will work for all the label in your application and will help to maintain consistency and clean code, if you change any style in future require only in the extension method.
In Monotouch / Xamarin.iOS I solved the same problem like this:
UILabel exampleLabel = new UILabel(new CGRect(0, 0, 100, 50))
{
Text = "Hello Monotouch red label"
};
exampleLabel.Layer.MasksToBounds = true;
exampleLabel.Layer.CornerRadius = 8;
exampleLabel.Layer.BorderColor = UIColor.Red.CGColor;
exampleLabel.Layer.BorderWidth = 2;
Works perfect in Swift 2.0
#IBOutlet var theImage: UIImageView! //you can replace this with any UIObject eg: label etc
override func viewDidLoad() {
super.viewDidLoad()
//Make sure the width and height are same
self.theImage.layer.cornerRadius = self.theImage.frame.size.width / 2
self.theImage.layer.borderWidth = 2.0
self.theImage.layer.borderColor = UIColor.whiteColor().CGColor
self.theImage.clipsToBounds = true
}
Did you try using the UIButton from the Interface builder (that has rounded corners) and experimenting with the settings to make it look like a label. if all you want is to display static text within.
Depending on what exactly you are doing you could make an image and set it as the background programatically.