8

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:

1Exp 2Exp


Compact Presentation Style:

1Comp 2Comp

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?

4

3 回答 3

1

我希望这并不总是必要的,但我最终使用了约束出口、presentationStyle 变量和 viewDidLayoutSubviews() 的组合来克服这个错误/疏忽。

在我的 DetailViewController 中:

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

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

在我的 MainViewController 中:

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

如果它有所作为,我的 segue 以模态方式呈现为页面表。

于 2016-11-09T17:25:52.733 回答
0

在我的应用程序中,视图控制器在 .expand 模式下设置:

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

在 .compact 模式下将其设置为 false

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

它应该工作。

于 2016-12-10T02:19:53.053 回答
0

我在http://sandmoose.com/post/35714028270/storyboards-with-custom-container-view-controllers的帮助下找到了一种可能的解决方案

在入口点视图控制器中,放置一个具有自动布局约束的容器视图,将容器视图的顶部和底部与顶部和底部布局指南对齐。

然后,容器视图本身需要嵌入您选择的任何视图控制器。这样,目标视图控制器将始终存在于容器视图的范围内。容器视图也将受到初始视图控制器的顶部和底部布局指南的正确约束。

实现此目的的一种方法:实现一个将接收 segue 通知的协议 - 例如:

protocol SegueDelegate {
  func willSegue(to: UIViewController)

  func didSegue(to: UIViewController)
}

实现一个 UIViewController 的子类,它具有对 SegueDelegate 的引用,例如

class ContainedViewController: UIViewController {
  weak var segueDelegate: SegueDelegate?

  ...

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

让您的初始消息视图控制器实现协议。

extension MSMessagesAppViewController: SegueDelegate {

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

这里的 containerViewController 必须实现一个嵌入方法,将显示的视图控制器与新的交换,例如

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)
  }

}
于 2017-03-14T17:27:15.553 回答