Custom class that can be applied to every UITextField - Swift - ios

Im very new to programming and am making a project that will have many UITextFields. I want to have the text fields only have a border on the bottom for a cleaner look, and I found some code here that is supposed to make that happen.
let border = CALayer()
let width = CGFloat(2.0)
border.borderColor = UIColor.darkGray.cgColor
border.frame = CGRect(x: 0, y: textField.frame.size.height - width, width: textField.frame.size.width, height: textField.frame.size.height)
border.borderWidth = width
textField.layer.addSublayer(border)
textField.layer.masksToBounds = true
How can I make a class so that every UItext field I place in the storyboard I can simply make it part of said class? I don't want to copy and paste this code for each UITextField. And is there a way to do it where I could individually edit the placeholder text for each UITextfield this class is applied to?

it's very easy just enter this code in under any class only one time
#IBDesignable
open class customUITextField: UITextField {
func setup() {
let border = CALayer()
let width = CGFloat(2.0)
border.borderColor = UIColor.darkGray.cgColor
border.frame = CGRect(x: 0, y: self.frame.size.height - width, width: self.frame.size.width, height: self.frame.size.height)
border.borderWidth = width
self.layer.addSublayer(border)
self.layer.masksToBounds = true
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
}
In "Setup" function put all customizations you want.
After that back to design and choose it in all TextField you have and Run

Here is an example:
class CustomTextField: UITextField {
convenience init() {
self.init(frame: .zero)
let border = CALayer()
let width = CGFloat(2.0)
border.borderColor = UIColor.darkGray.cgColor
border.frame = CGRect(x: 0, y: frame.size.height - width, width: frame.size.width, height: frame.size.height)
border.borderWidth = width
layer.addSublayer(border)
layer.masksToBounds = true
}
}
To simplify your border code you could do this:
layer.borderWidth = 2.0
layer.masksToBounds = true

Related

UITextField Standard Style programmatically

When I create a UITextField using storyboard, it looks like the image below. However, when I create a UITextField programmatically it has absolutely no style. I know that I can apply custom styles to the text field, but is there an easy way to get this standard style when creating the text field programmatically?
Something like this:
let t = UITextField()
t.frame = CGRect(x: 10, y: 20, width: self.view.frame.width - 20, height: 40)
t.layer.cornerRadius = 5
t.layer.borderColor = UIColor.lightGray.cgColor
t.layer.borderWidth = 1
t.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: t.frame.height))
t.leftViewMode = .always
t.rightView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: t.frame.height))
t.rightViewMode = .always
t.clearButtonMode = .whileEditing
self.view.addSubview(t)
EDIT:
Add this class below somewhere such that it is easily / globally accessible.
class StyledTextField: UITextField {
override init(frame: CGRect) {
super.init(frame: frame)
self.layer.cornerRadius = 5
self.layer.borderColor = UIColor.lightGray.cgColor
self.layer.borderWidth = 1
self.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: t.frame.height))
self.leftViewMode = .always
self.rightView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: t.frame.height))
self.rightViewMode = .always
self.clearButtonMode = .whileEditing
}
}
Then you can call this UITextField from where ever you want as follows
let t = StyledTextField()
t.frame = CGRect(x: 10, y: 20, width: self.view.frame.width - 20, height: 40)
self.view.addSubview(t)
EDIT 2:
Use UIEdgeInsets to get padding on all four sides.
class StyledTextField: UITextField {
let insetConstant = UIEdgeInsets(top: 4, left: 10, bottom: 4, right: 10)
override func textRect(forBounds bounds: CGRect) -> CGRect {
return UIEdgeInsetsInsetRect(bounds, insetConstant)
}
override func editingRect(forBounds bounds: CGRect) -> CGRect {
return UIEdgeInsetsInsetRect(bounds, insetConstant)
}
override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
return UIEdgeInsetsInsetRect(bounds, insetConstant)
}
override init(frame: CGRect) {
super.init(frame: frame)
self.layer.cornerRadius = 5
self.layer.borderColor = UIColor(white: 2/3, alpha: 0.5).cgColor
self.layer.borderWidth = 1
self.clearButtonMode = .whileEditing
self.keyboardType = UIKeyboardType.decimalPad
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
You can add borderStyle as .roundedRect and use White background. Something like this:
class MyCustmUITextField: UITextField {
override init(frame: CGRect) {
super.init(frame: frame)
self.borderStyle = .roundedRect
self.backgroundColor = .white
}
}
You can create a subclass from UITextField to serve as your custom text field.
Following this, you need only to instantiate your custom class and then you're good to go.
Something like this:
class MyCustmUITextField: UITextField {
override init(frame: CGRect) {
super.init(frame: frame)
self.layer.cornerRadius = 5
self.layer.borderColor = UIColor.black
self.font = UIFont.systemFont(ofSize: 20)
self.adjustsFontSizeToFitWidth = true
// then add whatever styles you wish
}
}
From there all you need is to create a new instance of MyCustomUITextField

How to add a value within Circle Swift

I have added a imageview which is displayed as a circle by using the code below.
ImageView.layer.cornerRadius = ImageView.frame.size.width/2
ImageView.clipsToBounds = true
how can I implement a label within this which displays a number. I am not sure how to go about doing this. I am quite new to swift therefore I am not if this can be done or if there are better ways about doing this. My goal is to create a custom circle to display within the imageview which displays a number.
Or is it better to embed a view and then use uibeziapath to construct a circle.
You can create a custom view using CAShapeLayer and UIBezierPath if you want a hollow circle and label inside it. This class does that.
class CircleView: UIView {
let shapeLayer = CAShapeLayer()
var circularPath: UIBezierPath?
// This is your label, you can its property here like textColor and Font
let breathingStatusLabel : UILabel = {
let label = UILabel()
label.textColor = UIColor.white
label.text = “1”
label.textAlignment = .center
label.font = UIFont(name: "AvenirNext-UltraLight", size: 31)
label.alpha = 1.0
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.frame = frame
self.setupPaths()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func setupPaths() {
// Add label to your view and set its frame
self.addSubview(breathingStatusLabel)
breathingStatusLabel.frame = CGRect.init(x: 0, y: 0, width: self.bounds.width, height: self.bounds.height)
breathingStatusLabel.center = CGPoint.init(x: self.bounds.width/2, y: self.bounds.height/2)
circularPath = UIBezierPath(arcCenter: .zero, radius: self.bounds.height / 2, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: true)
shapeLayer.path = circularPath?.cgPath
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.lineWidth = 6.0
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.position = CGPoint(x: self.center.x, y: self.bounds.height / 2)
shapeLayer.lineCap = kCALineCapRound
shapeLayer.strokeEnd = 1
self.layer.addSublayer(shapeLayer)
self.shapeLayer.transform = CATransform3DMakeRotation(CGFloat.pi / 2, 0, 0, 1)
}
}
To use it :
let circle = CircleView(frame: someView.frame) // Some frame is where you want to show this.
view.addSubview(circle)
My goal is to create a custom circle to display within the imageview which displays a number.
If you are not using any image in imageView but you just make a circle then its better if you use
mylabel.layer.cornerRadius = mylabel.frame.size.width/2
and set data as mylabel.text = "2" and make sure it is center aligned.

Swift textfields without border

I am new to swift. Your help will be really appreciated.
I have two textfields in my application. How would I create same UI as given in the pic below.
I want to create textfields with only one below border as given in the screenshot.
https://www.dropbox.com/s/wlizis5zybsvnfz/File%202017-04-04%2C%201%2052%2024%20PM.jpeg?dl=0
#IBOutlet var textField: UITextField! {
didSet {
let border = CALayer()
let width: CGFloat = 1 // this manipulates the border's width
border.borderColor = UIColor.darkGray.cgColor
border.frame = CGRect(x: 0, y: textField.frame.size.height - width,
width: textField.frame.size.width, height: textField.frame.size.height)
border.borderWidth = width
textField.layer.addSublayer(border)
textField.layer.masksToBounds = true
}
}
Create a subclass of UITextField so you can reuse this component across multiple views without have to re implement the drawing code. Expose various properties via #IBDesignable and #IBInspectable and you can have control over color and thickness in the story board. Also - implement a "redraw" on by overriding layoutSubviews so the border will adjust if you are using auto layout and there is an orientation or perhaps constraint based animation. That all said - effectively your subclass could look like this:
import UIKit
class Field: UITextField {
private let border = CAShapeLayer()
#IBInspectable var color: UIColor = UIColor.blue {
didSet {
border.strokeColor = color.cgColor
}
}
#IBInspectable var thickness: CGFloat = 1.0 {
didSet {
border.lineWidth = thickness
}
}
override func draw(_ rect: CGRect) {
self.borderStyle = .none
let from = CGPoint(x: 0, y: rect.height)
let here = CGPoint(x: rect.width, y: rect.height)
let path = borderPath(start: from, end: here).cgPath
border.path = path
border.strokeColor = color.cgColor
border.lineWidth = thickness
border.fillColor = nil
layer.addSublayer(border)
}
override func layoutSubviews() {
super.layoutSubviews()
let from = CGPoint(x: 0, y: bounds.height)
let here = CGPoint(x: bounds.width, y: bounds.height)
border.path = borderPath(start: from, end: here).cgPath
}
private func borderPath(start: CGPoint, end: CGPoint) -> UIBezierPath {
let path = UIBezierPath()
path.move(to: start)
path.addLine(to: end)
return path
}
}
Then when you add a text field view to your story board - update the class in the Identity Inspector to use this subclass, Field - and then in the attributes inspector, you can set color and thickness.
Add border at Bottom in UITextField call below function:
func setTextFieldBorder(_ dimension: CGRect) -> CALayer {
let border = CALayer()
let width = CGFloat(2.0)
border.borderColor = UIColor.darkGray.cgColor
border.frame = CGRect(x: 0, y: dimension.size.height - width, width: dimension.size.width, height: dimension.size.height)
border.borderWidth = width
return border
}
How to set UITextField border in textField below sample code for that:
txtDemo.layer.addSublayer(setTextFieldBorder(txtDemo.frame))
txtDemo.layer.masksToBounds = true
Where txtDemo is IBOutlet of UITextField.

Underline UITextField does not work in StackView

I'm having multiple textfields for sign-up page and I have used stack view in it. When I try to assign underline colour to my UITextField it does not work. But if I do the same w/o StackView then it works fine.
extension UITextField {
func underlined() {
let border = CALayer()
let width = CGFloat(1.0)
border.borderColor = themeColor.cgColor
border.frame = CGRect(x: 0, y: self.frame.size.height - width, width: self.frame.size.width, height: self.frame.size.height)
border.borderWidth = width
self.layer.addSublayer(border)
self.layer.masksToBounds = true
}
}
nameTextField.underlined()
ageTextField.underlined()

iOS UITextField Underline Style in swift

I've added this image, I hope you can see it, of a user interface login. Notice the text field is transparent with the exception of the line at the bottom. What code do I put in to get that affect? Can I put the necessary information in the "user defined runtime attributes"?
Create a subclass of UITextField as below, And simply set this class in your storyboard to UITextField
Swift 5 Support With #IBInspectable
import UIKit
class HSUnderLineTextField: UITextField , UITextFieldDelegate {
let border = CALayer()
#IBInspectable open var lineColor : UIColor = UIColor.black {
didSet{
border.borderColor = lineColor.cgColor
}
}
#IBInspectable open var selectedLineColor : UIColor = UIColor.black {
didSet{
}
}
#IBInspectable open var lineHeight : CGFloat = CGFloat(1.0) {
didSet{
border.frame = CGRect(x: 0, y: self.frame.size.height - lineHeight, width: self.frame.size.width, height: self.frame.size.height)
}
}
required init?(coder aDecoder: (NSCoder?)) {
super.init(coder: aDecoder!)
self.delegate=self;
border.borderColor = lineColor.cgColor
self.attributedPlaceholder = NSAttributedString(string: self.placeholder ?? "",
attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])
border.frame = CGRect(x: 0, y: self.frame.size.height - lineHeight, width: self.frame.size.width, height: self.frame.size.height)
border.borderWidth = lineHeight
self.layer.addSublayer(border)
self.layer.masksToBounds = true
}
override func draw(_ rect: CGRect) {
border.frame = CGRect(x: 0, y: self.frame.size.height - lineHeight, width: self.frame.size.width, height: self.frame.size.height)
}
override func awakeFromNib() {
super.awakeFromNib()
border.frame = CGRect(x: 0, y: self.frame.size.height - lineHeight, width: self.frame.size.width, height: self.frame.size.height)
self.delegate = self
}
func textFieldDidBeginEditing(_ textField: UITextField) {
border.borderColor = selectedLineColor.cgColor
}
func textFieldDidEndEditing(_ textField: UITextField) {
border.borderColor = lineColor.cgColor
}
}
Set lineColor and selectedLineColor from the storyboard and run your project.

Resources