Reputation: 37349
I need to calculate the distance between the bottom anchor of the safe area and the bottom of the screen. Is there a way to do that in code given a view?
Upvotes: 15
Views: 11037
Reputation: 1865
Here is a solution that works well on tableviews with adding a bottomView for buttons:
let buttonsView = UIView()
buttonsView.translatesAutoresizingMaskIntoConstraints = false
buttonsView.backgroundColor = .secondarySystemBackground
self.tableView.addSubview(buttonsView)
let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
let bottomPadding = window?.safeAreaInsets.bottom ?? 0
buttonsView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: bottomPadding ).isActive = true
buttonsView.leftAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leftAnchor).isActive = true
buttonsView.rightAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.rightAnchor).isActive = true
buttonsView.heightAnchor.constraint(equalToConstant: 88.0 + bottomPadding ).isActive = true
Upvotes: 0
Reputation: 7350
Try this one
if #available(iOS 11.0, *) {
let window = UIApplication.shared.keyWindow
let bottomPadding = window?.safeAreaInsets.bottom
}
Upvotes: 34
Reputation: 1090
To re-iterate previous answers. Pin a subview to the bottom of the view of a UIViewController
. Then pin a second one to the view.safeAreaLayoutGuide.bottomAnchor
anchor of the view. With both subviews pinning the top
, leading
and trailing
anchors of the parent view. Then, I would assume in viewDidAppear
, you could print out the difference between the two subview's frame.maxY
values. This should give you the difference.
let viewA = UIView()
let viewB = UIView()
override func viewDidLoad() {
view.addSubview(viewA)
view.addSubview(viewB)
viewA.translateAutoResizingMasksIntoConstraints = false
viewB.translateAutoResizingMasksIntoConstraints = false
if #available(iOS 11.0, *) {
NSLayoutConstraint.activate([viewA.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0),
viewA.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 0),
viewA.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: 0),
viewA.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0),
viewB.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0),
viewB.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 0),
viewB.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: 0),
viewB.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0)])
} else {
// Fallback on earlier versions
}
}
override func viewDidAppear() {
super.viewDidAppear()
print("Safe Distance Value is:\(viewA.frame.maxY - viewB.frame.maxY)")
}
As a reference for others, the value appears to be 34
on an iPhone X simulator
Upvotes: 1
Reputation: 2121
You could try pinning a subview (clear , hidden or whatever) to the bottom of the safeAreaLayoutGuide and calculate the difference between the bottom of this view and your view controller's view in viewDidLayoutSubviews
.
class ViewController: UIViewController {
let measuringView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
measuringView.backgroundColor = .magenta
measuringView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(measuringView)
let vConstraint = measuringView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
let heightConstraint = measuringView.heightAnchor.constraint(equalToConstant: 34)
var constraints = NSLayoutConstraint.constraints(withVisualFormat: "|[measuring]|", options: [], metrics: nil, views: ["measuring": measuringView])
constraints.append(vConstraint)
constraints.append(heightConstraint)
NSLayoutConstraint.activate(constraints)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let measuringBottom = measuringView.frame.origin.y + measuringView.frame.height
let viewBottom = view.bounds.height
let distance = abs(measuringBottom - viewBottom)
print("distance is \(distance) points")
}
}
Upvotes: 1