Why does the top layout guide move in my iMessage extension

I have the iMessage extension, and I have some problems with the guide to getting the layout started. I have an MSMessagesAppViewController that handles changes between presentation styles. In my extension, I have a button. When it is clicked, I move on to the advanced presentation style, and then present the view controller modulo. Here's the problem: my user interface in the second VC is hiding behind the top navigation bar. I thought it was strange when I set my limits in the top guide. So I broke through my code and started debugging the top layout guide. I noticed that after moving to the advanced presentation style, topLayoutGuide.length = 86. Here's how it should be. But when I present the second view controller modulo, the top layout guide reset is 0. Why is this not the way it should be? Here is my code:

In my main viewController:

 @IBAction func addStickerButtonPressed(_ sender: AnyObject) { shouldPerformCreateSegue = true theSender = sender requestPresentationStyle(.expanded) } override func didTransition(to presentationStyle: MSMessagesAppPresentationStyle) { if presentationStyle == .expanded { if shouldPerformCreateSegue == true { shouldPerformCreateSegue = false performSegue(withIdentifier: "CreateStickerSegue", sender: theSender)//here is where I present the new viewController } else { searchBar.becomeFirstResponder() searchBar.placeholder = nil searchBar.showsCancelButton = true searchBar.tintColor = UIColor.white } } else { searchBar.showsCancelButton = false } print(topLayoutGuide.length) //This prints out 86 } 

In another modular representation of the controller:

 override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.view.addConstraint(navBar.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor)) print(topLayoutGuide.length) //This prints out 0 } 
+8
ios autolayout swift imessage
source share
3 answers

As a workaround, I use the UIPresentationController , which shifts the modal view controller by topLayoutGuide.length :

 class MyViewController: MSMessagesAppViewController { private func presentModalViewController() { let imagePicker = UIImagePickerController() imagePicker.delegate = self imagePicker.sourceType = .savedPhotosAlbum imagePicker.modalPresentationStyle = .custom imagePicker.transitioningDelegate = self present(imagePicker, animated: true, completion: nil) } } // MARK: - UIViewControllerTransitioningDelegate extension MyViewController: UIViewControllerTransitioningDelegate { func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { let vc = PresentationController(presentedViewController: presented, presenting: presenting) // I really don't want to hardcode the value of topLayoutGuideLength here, but when the extension is in compact mode, topLayoutGuide.length returns 172.0. vc.topLayoutGuideLength = topLayoutGuide.length > 100 ? 86.0 : topLayoutGuide.length return vc } } class PresentationController: UIPresentationController { var topLayoutGuideLength: CGFloat = 0.0 override var frameOfPresentedViewInContainerView: CGRect { guard let containerView = containerView else { return super.frameOfPresentedViewInContainerView } return CGRect(x: 0, y: topLayoutGuideLength, width: containerView.bounds.width, height: containerView.bounds.height - topLayoutGuideLength) } } 

The only problem is that you are calling presentModalViewController from compact mode, topLayoutGuide.length - 172.0 for an unknown reason. Therefore, I had to hard-code the value for this case.

+7
source share

I believe this was a known bug in the previous beta version of iOS 10. I had the same problem, and the guide to the top and bottom of the layout works as I expect after I upgraded to the latest version of iOS.

+1
source share

I used a slightly modified version of Andrey

 class MyViewController: MSMessagesAppViewController { private func presentModalViewController() { let imagePicker = UIImagePickerController() imagePicker.delegate = self imagePicker.sourceType = .savedPhotosAlbum imagePicker.modalPresentationStyle = .custom imagePicker.transitioningDelegate = self present( imagePicker, animated: true, completion: nil ) } } extension MyViewController: UIViewControllerTransitioningDelegate { func presentationController( forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController ) -> UIPresentationController? { let vc = PresentationController( presentedViewController: presented, presenting: presenting ) vc.framePresented = modalBoundaries.frame return vc } } class PresentationController: UIPresentationController { var framePresented = CGRect.zero override var frameOfPresentedViewInContainerView: CGRect { return framePresented } } 

modalBoundaries is a dummy UIView limited (via XIB in my case) to respect any length of TopLayoutGuide.

0
source share

All Articles