UITextField rounded corner - swift - ios

Is there anyway to fix this problem and how to put icon inside UITextField?
This is my code.
func roundCorners(corners:UIRectCorner, radius:CGFloat) {
let bounds = self.bounds
let maskPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let maskLayer = CAShapeLayer()
maskLayer.frame = bounds
maskLayer.path = maskPath.cgPath
self.layer.mask = maskLayer
let frameLayer = CAShapeLayer()
frameLayer.frame = bounds
frameLayer.path = maskPath.cgPath
frameLayer.strokeColor = UIColor.darkGray.cgColor
frameLayer.fillColor = UIColor.init(red: 247, green: 247, blue: 247, alpha: 0).cgColor
self.layer.addSublayer(frameLayer)
}
func roundTopCornersRadius(radius:CGFloat) {
self.roundCorners(corners: [UIRectCorner.topLeft, UIRectCorner.topRight], radius:radius)
}
func roundBottomCornersRadius(radius:CGFloat) {
self.roundCorners(corners: [UIRectCorner.bottomLeft, UIRectCorner.bottomRight], radius:radius)
}
in viewDidLoad()
username.roundTopCornersRadius(radius: 8)
password.roundBottomCornersRadius(radius: 8)
This is what i've got
i want my textField look like this

To add an image, use the leftView property of the UITextField.
Your code for the borders seems fine, but remember to ensure that the layout of the textfield has completed before adding the cornerRadius. You can call view.layoutIfNeeded() to ensure that it has been called. Alternatively (the better solution), you can override layoutSubviews() in your custom textfield and ensure the bounds of the layer is changed when the layout of the textfield changes.
Set the textField's borderStyle to .none.
Swift 3 Code Example
#IBDesignable
class CustomTextField: UITextField {
#IBInspectable
var image: UIImage? {
didSet {
imageView.image = image
}
}
var imageView: UIImageView = UIImageView()
override func awakeFromNib() {
super.awakeFromNib()
self.borderStyle = .none
setupImageView()
}
func roundCorners(corners:UIRectCorner, radius:CGFloat) {
let bounds = self.bounds
let maskPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let maskLayer = CAShapeLayer()
maskLayer.frame = bounds
maskLayer.path = maskPath.cgPath
self.layer.mask = maskLayer
let frameLayer = CAShapeLayer()
frameLayer.frame = bounds
frameLayer.path = maskPath.cgPath
frameLayer.strokeColor = UIColor.darkGray.cgColor
frameLayer.fillColor = UIColor.init(red: 247, green: 247, blue: 247, alpha: 0).cgColor
self.layer.addSublayer(frameLayer)
}
func setupImageView() {
imageView = UIImageView(frame: CGRect(x:5,y:0,width:35,height:25))
imageView.image = image
imageView.contentMode = .scaleAspectFit
self.leftView = imageView
self.leftViewMode = .always
}
func roundTopCornersRadius(radius:CGFloat) {
roundCorners(corners: [UIRectCorner.topLeft, UIRectCorner.topRight], radius:radius)
}
func roundBottomCornersRadius(radius:CGFloat) {
roundCorners(corners: [UIRectCorner.bottomLeft, UIRectCorner.bottomRight], radius:radius)
}
}

You will need to implement IBDesignable View

Hmm this is really custom, not sure if you can do that with native textfield without some work.
Why not doing this instead:
An UIView that will contain your two icons and two textfields next to them :
Just make sure to set no border style to your textfield :
Then set the corner radius of the UIView that contain everything to whatever you want ;) easy mate!

Related

Swift - Shadow for a irregular shape of a View

i am struggling to add shadow to a custom shape.
Here is a picture of what i want to construct:
(Dont mind the text and the symbol)
You can see the custom shape with the curved corner on the right and the rectangular shape on the left with shadow.
I am using UIView, and added corner to the left.
This is the code i have so far that shape the view correct:
View1.backgroundColor = .green //green color is just to see the shape well
let path = UIBezierPath(roundedRect:View1.bounds,
byRoundingCorners:[.topRight, .bottomRight],
cornerRadii: CGSize(width: self.frame.height/2, height: self.frame.height/2))
let maskLayer = CAShapeLayer()
I Have tried to add shadow to it, but the shadow does not apear.
Here is the code i have tried to add shadow:
View1.layer.masksToBounds = false
View1.layer.layer.shadowPath = maskLayer.path
View1.layer.shadowColor = UIColor.black.cgColor
View1.layer.shadowOffset = CGSize(width: 0.0, height: 3.0)
View1.layer.shadowOpacity = 0.5
View1.layer.shadowRadius = 1.0
How can you add shadow to this shape?
You can achieve this by using a single UIView (shadowView), adding a shapeLayer sublayer and setting the shadow of the shadowView's layer.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
#IBOutlet var shadowView: UIView!
func setup() {
// setup irregular shape
let path = UIBezierPath.init(roundedRect: shadowView.bounds, byRoundingCorners: [.topRight, .bottomRight], cornerRadii: CGSize.init(width: 20, height: 20))
let layer = CAShapeLayer.init()
layer.frame = shadowView.bounds
layer.path = path.cgPath
layer.fillColor = UIColor.white.cgColor
layer.masksToBounds = true
shadowView.layer.insertSublayer(layer, at: 0)
// setup shadow
shadowView.layer.shadowRadius = 8
shadowView.layer.shadowOpacity = 0.2
shadowView.layer.shadowOffset = CGSize.init(width: 0, height: 2.5)
shadowView.layer.shadowColor = UIColor.black.cgColor
shadowView.layer.shadowPath = path.cgPath
}
}
Note:
The shadowView.clipToBounds must be false for the shadows to take effect.
To see the layer.fillColor, set the shadowView.backgroundColor to .clear.
You can easily achieve the above via Interface Builder by setting the 'Background' property and unchecking the 'Clip to Bounds' checkbox.

UIView Custom Class trigger either shadow or roundCorners/addCornerRadius but not both in swift 3 [duplicate]

This question already has answers here:
UIView with rounded corners and drop shadow?
(35 answers)
Closed 4 years ago.
UIView Custom Class trigger only shadow. I want to display both shadow and rounded corner for specific edges.Here is my code. Any suggestions would be appreciated.
extension UIView {
func roundCorners(_ corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
}
class CustomView: UIView {
override func layoutSubviews() {
self.shadowColor = UIColor.darkGray
self.shadowOffset = CGSize(width: 4, height: 4)
self.shadowOpacity = 0.5
self.shadowRadius = 6.0
//only rounded corners triggered in UI
self.backgroundColor = UIColor.white
self.roundCorners(corners: [.topRight, .bottomRight], radius: 15.0)
}
}
Thanks in advance
Use separate views for the shadow and the border. The base view is transparent and has the shadow. The border view clips any other subcontent that it has to its borders. See the code below.
// add the shadow to the base view
baseView.backgroundColor = UIColor.clear
baseView.layer.shadowColor = UIColor.black.cgColor
baseView.layer.shadowOffset = CGSize(width: 3, height: 3)
baseView.layer.shadowOpacity = 0.7
baseView.layer.shadowRadius = 4.0
// add the border to subview
let borderView = UIView()
borderView.frame = baseView.bounds
borderView.layer.cornerRadius = 10
borderView.layer.borderColor = UIColor.black.cgColor
borderView.layer.borderWidth = 1.0
borderView.layer.masksToBounds = true
baseView.addSubview(borderView)
// add any other subcontent that you want clipped
let otherSubContent = UIImageView()
otherSubContent.image = UIImage(named: "lion")
otherSubContent.frame = borderView.bounds
borderView.addSubview(otherSubContent)
Use this function:-
func addShadow(view: UIView, corner: CGFloat) {
view.layer.shadowColor = UIColor.gray.cgColor
view.layer.shadowOpacity = 0.5
view.layer.shadowRadius = 2
view.layer.shadowOffset = CGSize(width: 1, height: 1)
view.layer.masksToBounds = false
view.layer.cornerRadius = corner
}

rounding corners of UIbutton disturbing its width

I have three buttons in which I want to round:
Top corners of first button
Bottom corners of second button
All four corners of third button
I achieved this by the following code:
button1.roundedButton1()
button2.roundedButton2()
button3.layer.cornerRadius = 5
extension UIButton {
func roundedButton1(){
let maskPAth1 = UIBezierPath(roundedRect: self.bounds,
byRoundingCorners: [.topLeft , .topRight],
cornerRadii:CGSize(width:5.0, height:5.0))
let maskLayer1 = CAShapeLayer()
// maskLayer1.frame = self.bounds
maskLayer1.path = maskPAth1.cgPath
self.layer.mask = maskLayer1
}
func roundedButton2(){
let maskPAth1 = UIBezierPath(roundedRect: self.bounds,
byRoundingCorners: [.bottomLeft , .bottomRight],
cornerRadii:CGSize(width:5.0, height:5.0))
let maskLayer1 = CAShapeLayer()
maskLayer1.frame = self.bounds
maskLayer1.path = maskPAth1.cgPath
self.layer.mask = maskLayer1
}
}
But the width of my 1st and 2nd button is getting disturbed.
If I use button2.layer.cornerRadius = 5 then the width becomes alright. I have searched which code it altering its width but didn't find anything appropriate. And this is the only working solution i found for UIButton.Can anyone tell me why the width of button is changing and how to fix it?
The constraints of button are as follows:
Instead of using UIButton you can achieve this result by using UIView & UITapGestureRecognizer
add this extension
extension UIView {
func roundCorners(_ corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
}
then create a custom view class
class CustomView: UIView {
override func layoutSubviews() {
super.layoutSubviews()
self.roundCorners([.topRight, .topLeft], radius: 5) // you can use .topRight , .topLeft , .bottomRight, .bottomLeft
}
}
then use the class on your view
Hope this will help you

How To Add Border To a UIView With Mask?

Here's what I need to do to my two buttons.
and here's what I got right now.
What I'm doing:
- Set these up in IB inside a stackView.
- Add masks
- Add borders with width and color
- Add shadow.
The borders are being added but being cut-off as well by the masks.
Codes:
public func addCornerRadiusToCorners(
_ corners: UIRectCorner,
cornerRadius: CGFloat,
borderColor: UIColor,
borderWidth: CGFloat) {
// self.layer.masksToBounds = true
// self.clipsToBounds = true
self.layer.borderWidth = borderWidth
self.layer.borderColor = borderColor.cgColor
let size = CGSize(width: cornerRadius, height: cornerRadius)
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: size)
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
public func addDefaultShadow() {
let shadowPath = UIBezierPath(rect: self.bounds)
self.layer.masksToBounds = false
self.layer.shadowOffset = CGSize(width: 1, height: 1)
self.layer.shadowOpacity = 0.5
self.layer.shadowPath = shadowPath.cgPath
}
Any idea how to achieve the result in the first photo?
EDIT: the border is being cut, the result was just got from the UI Debugger of Xcode. Sorry.
Add corner radius to you view on viewDidAppear
#IBOutlet weak var segmentView: UIView!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
segmentView.layer.cornerRadius = segmentView.frame.size.height/2;
segmentView.layer.borderWidth = 1.0;
segmentView.clipsToBounds = true
segmentView.layer.borderColor = UIColor.lightGray.cgColor
segmentView.layer.shadowColor = UIColor.black.cgColor
segmentView.layer.shadowOpacity = 0.2
segmentView.layer.shadowRadius = 10.0
segmentView.layer.shadowOffset = CGSize(width: 1, height: 1)
segmentView.layer.masksToBounds = false
}
Sample Output:
you forgot to clip ur view.
self.clipsToBounds = true
you need to set maskstobounds to the view layer
segmentView.layer.masksToBounds = true

Chopped edge around border of image

I have an image with a border
let smallicon: UIImageView = {
let smallicon = UIImageView()
smallicon.layer.borderWidth = 2
smallicon.layer.borderColor = UIColor.whiteColor().CGColor
smallicon.hidden = true
return smallicon
}()
The problem is that is has tiny chopped edge around border (small image with yellow and black lines)
How to get rid of it ?
Solution
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Create a view with red background for demonstration
let v = UIView(frame: CGRectMake(0, 0, 100, 100))
v.center = view.center
v.backgroundColor = UIColor.redColor()
view.addSubview(v)
// Add rounded corners
let maskLayer = CAShapeLayer()
maskLayer.frame = v.bounds
maskLayer.path = UIBezierPath(roundedRect: v.bounds, byRoundingCorners: .TopRight | .TopLeft, cornerRadii: CGSize(width: 25, height: 25)).CGPath
v.layer.mask = maskLayer
// Add border
let borderLayer = CAShapeLayer()
borderLayer.path = maskLayer.path // Reuse the Bezier path
borderLayer.fillColor = UIColor.clearColor().CGColor
borderLayer.strokeColor = UIColor.greenColor().CGColor
borderLayer.lineWidth = 5
borderLayer.frame = v.bounds
v.layer.addSublayer(borderLayer)
}
}
NOTE! in order this to work target view must have frame property setup with size. without size your view will not be seen at all

Resources