1

I have an iOS app with a MetalView contained in a UIViewController, all setup in a story board.

Now I want to blend over the metal view another SwiftUI view, which is transparent. So only the GUI elements of the SwiftUI view are visible to the user and the background is my MetalView.

I do this using the following code:

  let controller = UIHostingController(rootView: MainView())
  controller.modalPresentationStyle = .fullScreen
  controller.view.backgroundColor = .clear

  self.addChild(controller)
  controller.view.translatesAutoresizingMaskIntoConstraints = false
  self.view.addSubview(controller.view)
  controller.didMove(toParent: self)
  
  NSLayoutConstraint.activate([
    controller.view.topAnchor.constraint(equalTo: self.view.topAnchor),
    controller.view.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
    controller.view.leftAnchor.constraint(equalTo: self.view.leftAnchor),
    controller.view.rightAnchor.constraint(equalTo: self.view.rightAnchor)
  ])

Basically the above code does work. However,the SwiftUI view is no tied to the exact borders of the MetalView although my constraints request this. The problem seems to be that the UIHostingController obeys the safe area insets and especially at the bottom and top the SwiftUI view is always rounded and a little bit smaller.

I have experimented with safe area inset settings and tried several presentation styles but nothing helps.

Does anybody know how I can tie the SwiftUI borders to the UIView borders ?

Update 2021-10-18: enter image description here

On the image you see in orange the device background. On top of that my MetalView is rendering the keyboard image. And on top of that my SwiftUI view is rendering this:

var body: some View {
  Color.black.opacity(0.5)
}

Since my constraints of the SwitUI view are tied to the MetalView I would expect the black.opacity(0.5) to cover the whole MetalView, but as you can see it leaves a small portion at the bottom uncovered. Why is that ?

Chris
  • 1,231
  • 2
  • 10
  • 20
  • Can you share some screenshots of what you're seeing, and what you expect? – brandonscript Oct 15 '21 at 15:29
  • I have updated the question – Chris Oct 18 '21 at 20:09
  • Ah, this is related to the safe area and home indicator bar. You may want to [hide it](https://developer.apple.com/documentation/uikit/uiviewcontroller/2887510-prefershomeindicatorautohidden), or set your constraints to be the screen edge instead of the safe area. – brandonscript Oct 18 '21 at 22:55
  • I have set the constraints to the edges of my MetalView and my MetalView's edges are tied to TopView (not SafeArea) in Interface Builder. So I would assume the SwiftUI View also to ignore SafeArea ? – Chris Oct 19 '21 at 08:17
  • That might be what's going on. What happens if you hide the home indicator? – brandonscript Oct 19 '21 at 20:59

1 Answers1

1

I found it. The problem was not the HostingController. Indeed it was already extended beyond the safe area.

The problem was with my SwiftUIView. You have to add:

.ignoresSafeArea()

to extend the view beyond safe area bounds. Thanks brandonscript to point me into that direction.

Chris
  • 1,231
  • 2
  • 10
  • 20