0

Put simply, I want to get the bounds of this blue rectangle using Swift code:

enter image description here

The coordinates of this rectangle are visible in the Size inspector:

enter image description here

In an empty App project in Xcode, I've tried using view.safeAreaLayoutGuide.layoutFrame to get the CGRect, but this property seems to contain the bounds of the entire view, not the safe area. Specifically, it returns 0.0, 0.0, 896.0 and 414.0 for minX, minY, width and height respectively.

I've also tried to get the top, bottom, left and right properties of view.safeAreaInsets, but this returns 0 for each of them.

I've also tried to get the view.superview in case there was another view on top, but it returned nil.

All these values come from the iPhone 11. I'm using Xcode 12.

matt
  • 515,959
  • 87
  • 875
  • 1,141
Makoren
  • 321
  • 1
  • 3
  • 12
  • Have you come across this post. This could some help https://stackoverflow.com/a/53850392/390102 – Shankar Shinde Sep 27 '20 at 01:28
  • "I've also tried to get the top, bottom, left and right properties of `view.safeAreaInsets`, but this returns 0 for each of them." Well, I assure they are not zero. You probably tried to get them _at the wrong time_. But you know what? _You didn't show any code._ So it's impossible to say. – matt Sep 27 '20 at 01:59

1 Answers1

4

First, get the safe area insets. (Wait until they are known before you get them.) Okay, what are they inset from? The view controller's view. So simply apply those insets to the view controller's view's bounds and you have the rect of your rectangle (in view coordinates).

So, I believe this is the rectangle you were looking for?

enter image description here

How I did that:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    for v in self.view.subviews {
        v.removeFromSuperview()
    }
    let v = UIView()
    v.backgroundColor = .blue
    self.view.addSubview(v)
    // okay, ready? here we go ...
    let r = self.view.bounds.inset(by:self.view.safeAreaInsets) // *
    v.frame = r
}

Remember, that rect, r, is in view coordinates. If you need the rect in some other coordinate system, there are coordinate conversion methods you can call.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • That solved it, thanks. The two mistakes I made were using `viewDidLoad` instead of `viewDidLayoutSubviews`, and trying to use `view.safeAreaInsets` directly instead of using that `inset(by:)` function. – Makoren Sep 27 '20 at 02:57
  • You can use the insets directly but you have to know how. In fact that’s what I did in the first version of my code. So it can be done! – matt Sep 27 '20 at 03:12