Hello,
In the simulator (iOS 12.2, multiple phone versions tried), I had some code which presented one view on top of another, using
present(childVC, animated: false, completion: nil)
where childVC is the view controller for the new view. Even though this view had had its windowframe set to the same frame as the window that contained the original view, the new view appeared smaller (in the upper left corner of the screen) with the old view taking up the rest of the space behind it. I couldn't figure out the cause of this, so I worked around it by setting the rootViewController of the window of the application delegate to the new view, which worked fine, except that when going back to the original view (dismissing childVC) and presenting another new view on top of it, I would get the message "Presenting view controllers on detached view controllers is discouraged".
Now working on iOS 13.1, this workaround does not work. It results in a blank screen, after the view pops up briefly; viewWillDisappear is getting called for some reason. If I take out the part setting rootViewController of the window to childVC, then it works fine.
I will note that these errors affect only the first view controller presented (after the original view controller that was originally the rootViewController of the window). If I move on to another view by pressing one of the buttons in my new view (in the case of the black screen, this can be done by setting a break point before the screen goes black and clicking on one of the buttons before continuing), then everything works as expected.
I am looking for some insight into these errors; any help appreciated.
class PresentedBaseClass : UIView{
override init(frame: CGRect){
super.init(frame: frame)
setupSubviews()
}
func setupSubviews(){
self.translatesAutoresizingMaskIntoConstraints = false // This is the problematic line
// ... some code to create subviews
setupConstraints()
}
func setupConstraints(){
NSLayoutConstraint.activate([
// Adding the two lines of code below will correct the problem, although
// it is probably better to remove the problematic line
//self.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width)
//self.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height)
// ... constraints on subviews
])
}
}
class PresentedSubClass1 : PresentedBaseClass{
// ...
}
class PresentedSubClass2 : PresentedBaseClass{
// ...
}
class PresentingClass : UIView{
var windowFrame: CGRect
init(windowframe: CGRect){
windowFrame = windowframe
super.init(nibName: nil, bundle: nil)
}
@objc func originalPresentation(_ sender: UIButton){
childVC = PresentedSubClass1Controller(windowframe: windowFrame)
present(childVC!, animated: false, completion: nil)
// The two lines below are the original workaround
//let appDelegate = UIApplication.shared.delegate
//appDelegate?.window??.rootViewController = childVC
}
@objc func gotoSubClass1(){
childVC?.dismiss(animated: false, completion: nil)
childVC = PresentedSubClass1Controller(windowframe: windowFrame)
present(childVC!, animated: false, completion: nil)
//let appDelegate = UIApplication.shared.delegate
//appDelegate?.window??.rootViewController = childVC
}
@objc func gotoSubClass2(){
childVC?.dismiss(animated: false, completion: nil)
childVC = PresentedSubClass2Controller(windowframe: windowFrame)
present(childVC!, animated: false, completion: nil)
//let appDelegate = UIApplication.shared.delegate
//appDelegate?.window??.rootViewController = childVC
}
}
class AppDelegate: UIResponder, UIApplicationDelegate{
var window: UIWindow?
var PresentingController: PresentingController!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.main.bounds)
PresentingController = PresentingController(windowframe: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
window?.rootViewController = PresentingController
window?.makeKeyAndVisible()
return true
}
}
Apparently, the problem was that the presented view was not properly constrained; its subviews were, but it wasn't. See code above.