We need to add border to UIView. Let's create view and place it in the center of screen with NSLayoutConstraint
var containerView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.containerView = UIView()
self.containerView.backgroundColor = UIColor.red
self.view.addSubview(containerView)
self.containerView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
self.containerView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
self.containerView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
self.containerView.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 0.3),
self.containerView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.3)
])
}
Border using SubView
In viewDidAppear method add top border to view using addSubView method.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let topBorderView = UIView(frame: CGRect(x: 0, y: 0,
width: self.containerView.frame.size.width,
height: 10))
topBorderView.backgroundColor = UIColor.black
self.containerView.addSubview(topBorderView)
}
Great, top border is added. But is it adaptive, what happen when parent view frame is changed. Let's see.
When parent view frame changed top border is not changed it's size.
Border using CALayer
Let's do the same using CALayer. Create new layer and add it as sublayer to parent view.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let topBorderLayer = CALayer()
topBorderLayer.backgroundColor = UIColor.black.cgColor
topBorderLayer.frame = CGRect(x: 0, y: 0,
width: self.containerView.frame.size.width,
height: 10)
self.containerView.layer.addSublayer(topBorderLayer)
}
But it still not adaptive solution.
Adaptive Border
For making really adaptive border we need to use AutoLayout and NSLayoutConstraint. We create view for border, add it as subview and set constraints to it according the side of view where we need to add border.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let topBorderView = UIView(frame: CGRect.zero)
topBorderView.backgroundColor = UIColor.black
self.containerView.addSubview(topBorderView)
topBorderView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
topBorderView.topAnchor.constraint(equalTo: self.containerView.topAnchor),
topBorderView.leadingAnchor.constraint(equalTo: self.containerView.leadingAnchor),
topBorderView.trailingAnchor.constraint(equalTo: self.containerView.trailingAnchor),
topBorderView.heightAnchor.constraint(equalToConstant: 10)
])
}
Adaptive Border Extension
For making this feature available for all other views we can create Extension for UIVIew class.
extension UIView {
func addTopBorder(color: UIColor, width: CGFloat) {
let topBorderView = UIView(frame: CGRect.zero)
topBorderView.backgroundColor = color
self.addSubview(topBorderView)
topBorderView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
topBorderView.topAnchor.constraint(equalTo: self.topAnchor),
topBorderView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
topBorderView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
topBorderView.heightAnchor.constraint(equalToConstant: width)
])
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.containerView.addTopBorder(color: UIColor.blue, width: 15.0)
}
Adaptive Border For Any Side
We can go further and create extension's method for adding borders for any side of view (and for all sides). We can specify which sides of view we need to add borders. For each side we create view and provide for it special constraints.
extension UIView {
func addBorders(edges: UIRectEdge = .all, color: UIColor = .black, width: CGFloat = 1.0) {
func createBorder() -> UIView {
let borderView = UIView(frame: CGRect.zero)
borderView.translatesAutoresizingMaskIntoConstraints = false
borderView.backgroundColor = color
return borderView
}
if (edges.contains(.all) || edges.contains(.top)) {
let topBorder = createBorder()
self.addSubview(topBorder)
NSLayoutConstraint.activate([
topBorder.topAnchor.constraint(equalTo: self.topAnchor),
topBorder.leadingAnchor.constraint(equalTo: self.leadingAnchor),
topBorder.trailingAnchor.constraint(equalTo: self.trailingAnchor),
topBorder.heightAnchor.constraint(equalToConstant: width)
])
}
if (edges.contains(.all) || edges.contains(.left)) {
let leftBorder = createBorder()
self.addSubview(leftBorder)
NSLayoutConstraint.activate([
leftBorder.topAnchor.constraint(equalTo: self.topAnchor),
leftBorder.bottomAnchor.constraint(equalTo: self.bottomAnchor),
leftBorder.leadingAnchor.constraint(equalTo: self.leadingAnchor),
leftBorder.widthAnchor.constraint(equalToConstant: width)
])
}
if (edges.contains(.all) || edges.contains(.right)) {
let rightBorder = createBorder()
self.addSubview(rightBorder)
NSLayoutConstraint.activate([
rightBorder.topAnchor.constraint(equalTo: self.topAnchor),
rightBorder.bottomAnchor.constraint(equalTo: self.bottomAnchor),
rightBorder.trailingAnchor.constraint(equalTo: self.trailingAnchor),
rightBorder.widthAnchor.constraint(equalToConstant: width)
])
}
if (edges.contains(.all) || edges.contains(.bottom)) {
let bottomBorder = createBorder()
self.addSubview(bottomBorder)
NSLayoutConstraint.activate([
bottomBorder.bottomAnchor.constraint(equalTo: self.bottomAnchor),
bottomBorder.leadingAnchor.constraint(equalTo: self.leadingAnchor),
bottomBorder.trailingAnchor.constraint(equalTo: self.trailingAnchor),
bottomBorder.heightAnchor.constraint(equalToConstant: width)
])
}
}
}
Using our Extension for UIView let's add only right and left borders to view.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.containerView.addBorders(edges: [.left, .right], width: 8)
}
Using our Extension for UIView let's add borders to view. Because all parameters are set by default, we can specify only border width.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.containerView.addBorders(width: 8)
}
Source Code
You can find source code of this post on github
GitHub Link
This is great, thank you so much ...
ReplyDeleteThank you. This one should come up in google search instead of other one.
ReplyDeleteHave been looking for this for 2 weeks now. Thanks man
ReplyDeleteHow do we add an adaptive gradient shadow using this model cos I couldn't figure it out
ReplyDeleteGreat post! Thank you so much. I really need these tips. The detailed explanation is really helpful. Seeing how you write was very inspiring.
ReplyDelete-Custom Website Design Company
Your article is one of its kind which explained every bit of Custom Build Website. looking for further valuable articles from you
ReplyDeleteThis is an excellent article! Thank you a lot. I'm in desperate need of these suggestions. The in-depth explanation is quite beneficial. It was incredibly encouraging to see how you write. Best Custom Websites
ReplyDeleteThank you Sir, you made it easy as pie. Now i am able to understand and have enough knowledge about this. It is only because of you.
ReplyDeleteCustom Designed Websites
This is a great article! Thank you very much. I really need these suggestions. An in-depth explanation is of great benefit. Incredibly inspiring to see how you write. Custom Website
ReplyDeleteAmazing write-up! The blog was very informative. Keep it up!
ReplyDeleteSoftware Testing Services