I want to make a textfield that has inset shadows.
I found an answer here but i do not get the expected result so because i don't have enough karma and cannot post a comment.
This is the result i get :
This is the code :
func applyDesign() {
let innerShadow = CALayer()
innerShadow.frame = bounds
// Shadow path (1pt ring around bounds)
let radius = self.frame.size.height/2
let path = UIBezierPath(roundedRect: innerShadow.bounds.insetBy(dx: -1, dy:-1), cornerRadius:radius)
let cutout = UIBezierPath(roundedRect: innerShadow.bounds, cornerRadius:radius).reversing()
path.append(cutout)
innerShadow.shadowPath = path.cgPath
innerShadow.masksToBounds = true
// Shadow properties
innerShadow.shadowColor = UIColor.darkGray.cgColor
innerShadow.shadowOffset = CGSize(width: 0, height: 2)
innerShadow.shadowOpacity = 0.5
innerShadow.shadowRadius = 2
innerShadow.cornerRadius = self.frame.size.height/2
layer.addSublayer(innerShadow)
}
How do i edit the code so that the textfield scales over the screen correctly again ?
The key thing is where do you call applyDesign. When view is loaded, it usually has size derived from nib / init method. So if you apply design then, it might not match what's on the screen later.
In your case, you should reapply these custom design every time text field is layouted by auto-layout engine.
Short example how could it look:
class CustomField: UITextField {
lazy var innerShadow: CALayer = {
let innerShadow = CALayer()
layer.addSublayer(innerShadow)
return innerShadow
}()
override func layoutSubviews() {
super.layoutSubviews()
applyDesign()
}
func applyDesign() {
innerShadow.frame = bounds
// Shadow path (1pt ring around bounds)
let radius = self.frame.size.height/2
let path = UIBezierPath(roundedRect: innerShadow.bounds.insetBy(dx: -1, dy:-1), cornerRadius:radius)
let cutout = UIBezierPath(roundedRect: innerShadow.bounds, cornerRadius:radius).reversing()
path.append(cutout)
innerShadow.shadowPath = path.cgPath
innerShadow.masksToBounds = true
// Shadow properties
innerShadow.shadowColor = UIColor.darkGray.cgColor
innerShadow.shadowOffset = CGSize(width: 0, height: 2)
innerShadow.shadowOpacity = 0.5
innerShadow.shadowRadius = 2
innerShadow.cornerRadius = self.frame.size.height/2
}
}
You can improve it a bit by moving some redundant setup from applyDeisgn
to some kind of one-time initializer (even in this lazy var definition).