2016-08-22 57 views
8

我有一個iMessage擴展,並且在頂部佈局指南中遇到了一些問題。我有一個MSMessagesAppViewController處理演示文稿樣式之間的變化。在我的擴展中,我有一個按鈕。當它被點擊時,我轉換到展開的演示樣式,然後以模態方式呈現視圖控制器。問題在於:第二個VC中的用戶界面隱藏在頂部導航欄後面。我認爲這很奇怪,因爲我將約束條件設置爲頂層佈局指南。所以我通過我的代碼挖掘並開始調試頂層佈局指南。我注意到,在我轉換到擴展的演示文稿樣式後,topLayoutGuide.length = 86。這就是它應該如此。但是,當我以模態形式呈現第二個視圖控制器時,頂部佈局指南將重置爲0.爲什麼它不是86應該是?這裏是我的代碼:爲什麼頂部佈局指南在我的iMessage擴展中移動

在我的主要的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 
} 

在其他模態呈現視圖控制器:

override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(animated) 
    self.view.addConstraint(navBar.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor)) 
    print(topLayoutGuide.length) //This prints out 0 
} 
+0

同樣的問題[here](http://stackoverflow.com/questions/38593054/ios-10-messages-extension-wrong-layout-when-using-storyboard-segue) – 123FLO321

+0

在這裏也是同樣的問題,我認爲你應該真的向蘋果提出錯誤報告;)我認爲他們感到厭倦了我的^^ – RomOne

+1

我目前的解決方法是將頂部佈局約束更改爲66在展開 –

回答

1

我相信這被稱爲以前的iOS版10測試版的bug。在我將iOS版本升級到最新版本後,我遇到了相同的問題以及頂部和底部佈局指南。

+0

我正在使用模擬器。將嘗試最新的Xcode測試版雖然 –

7

作爲一種變通方法我用UIPresentationController,它通過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) 
    } 
} 

唯一的問題是,當你從緊湊模式調用presentModalViewControllertopLayoutGuide.length172.0由於未知原因。所以我必須爲這種情況硬編碼一個值。

+1

這真是太棒了!我必須做的另一件事是通過在重寫的viewWillTransition方法中關閉並重新打開此視圖控制器來考慮方向更改。 – Swindler

0

我使用的安德烈的

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一個稍微改變版本是(在我的情況下經由XIB)約束的虛設的UIView尊重任何TopLayoutGuide長度。