iOS 10 Messages Extension - Wrong Layout when using Storyboard Segue

こ雲淡風輕ζ 提交于 2019-12-21 04:20:51

问题


When using Segues in Messages Extension Application the layout gets messed up.
Is there any way to solve this issue while still using storrybord segues?

Screenshots:
(Note: The first and second View / ViewController are identical. The segue-type doesn't matter)

Expanded Presentation Style:


Compact Presentation Style:

Update 1:

The top and bottom layout guides reset after a segue

  • compact:
    • top: should be: 0 but is: 20
    • bottom: should be: 44 but is: 0
  • expanded:
    • top: should be: 86 but is: 20
    • bottom: should be: 44 but is: 0


P.S. Can someone create a new "messages-extension" tag?


回答1:


I hope this won't always be necessary, but I ended up using a combination of a constraint outlet, presentationStyle variable, and viewDidLayoutSubviews() to overcome this bug/oversight.

In my DetailViewController:

@IBOutlet weak var myViewTopConstraint: NSLayoutConstraint!
var presentationStyle: MSMessagesAppPresentationStyle?

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if presentationStyle == .expanded {
        myViewTopConstraint.constant = 86
    } else {
        myViewTopConstraint.constant = 0
    }
}

And in my MainViewController:

override func willTransition(to presentationStyle: MSMessagesAppPresentationStyle) {
    if let detailController = presentedViewController as? DetailViewController {
        detailController.presentationStyle = presentationStyle
    }
}

And in case it makes a difference, my segue presents modally as a Page Sheet.




回答2:


in my app, viewcontroller in .expand mode set :

view.topAnchor.constraint(equalTo: self.topLayoutGuide.bottomAnchor).isActive = true

in .compact mode set it to false

view.topAnchor.constraint(equalTo: self.topLayoutGuide.bottomAnchor).isActive = false

it should work.




回答3:


One possible solution I arrived at with the help of http://sandmoose.com/post/35714028270/storyboards-with-custom-container-view-controllers

In your entry point view controller, place a container view that has auto layout constraints aligning the top and bottom of the container view to the top and bottom layout guides.

The container view itself then needs to embed any view controller that you segue to. This way destination view controllers will always live in the confines of the container view. The container view will also be constrained correctly by the top and bottom layout guides of the initial view controller.

One way to achieve this: Implement a protocol that will receive notifications for segues - something like:

protocol SegueDelegate {
  func willSegue(to: UIViewController)

  func didSegue(to: UIViewController)
}

Implement a subclass of UIViewController that has a reference to SegueDelegate e.g.

class ContainedViewController: UIViewController {
  weak var segueDelegate: SegueDelegate?

  ...

  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    segueDelegate?.willSegue(to: segue.destination)
  }
}

Have your initial messages view controller implement the protocol.

extension MSMessagesAppViewController: SegueDelegate {

  func didSegue(to destination: UIViewController) {
    guard let destination = destination as? ContainedViewController else {
      return
    }
    // Reference through IBOutlet or something
    containerViewController.embed(destination)
  }
}

The containerViewController here must implement an embed method that swaps the displaying view controller with the new one e.g.

class ContainerViewController: UIViewController {
  ...

  func embed(_ viewController: UIViewController) {
    let source = childViewControllers.first
    if source == viewController {
        return
    }

    source?.willMove(toParentViewController: nil)
    addChildViewController(viewController)
    if let source = source {
        // Do transition here if you want
        viewController.view.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height)
        view.addSubview(viewController.view)
        viewController.didMove(toParentViewController: self)

        source.willMove(toParentViewController: nil)
        source.removeFromParentViewController()
    } else {
        viewController.view.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height)
        view.addSubview(viewController.view)
        viewController.didMove(toParentViewController: self)
    }

    // Assigned in viewDidLoad of MSMessagesAppViewController or similar
    segueDelegate?.didSegue(to: viewController)
  }

}


来源:https://stackoverflow.com/questions/38593054/ios-10-messages-extension-wrong-layout-when-using-storyboard-segue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!