3

私が本当に楽しんでいるライブラリがここにあります ( https://github.com/pixyzehn/MediumMenu )。

基本的に、次のことを行います。

ミディアムメニューのデモ

奥のメニューは実はUIViewControllerです。ソースコードを掘り下げると、次の非常に重要なコードが見つかります。

public init(items: [MediumMenuItem], forViewController: UIViewController) {
    self.init()
    self.items = items
    height = screenHeight - 80 // auto-calculate initial height based on screen size
    frame = CGRect(x: 0, y: 0, width: screenWidth, height: height)
    contentController = forViewController
    menuContentTableView = UITableView(frame: frame)
    menuContentTableView?.delegate = self
    menuContentTableView?.dataSource = self
    menuContentTableView?.showsVerticalScrollIndicator = false
    menuContentTableView?.separatorColor = UIColor.clearColor()
    menuContentTableView?.backgroundColor = menuBackgroundColor
    addSubview(menuContentTableView!)

    if panGestureEnable {
        let pan = UIPanGestureRecognizer(target: self, action: #selector(MediumMenu.didPan(_:)))
        contentController?.view.addGestureRecognizer(pan)
    }

    let menuController = UIViewController()
    menuController.view = self

   UIApplication.sharedApplication().delegate?.window??.rootViewController = contentController
   UIApplication.sharedApplication().delegate?.window??.insertSubview(menuController.view, atIndex: 0)
}

最初の数行はそれほど重要ではありませんが、最後の行 ( を扱う行UIApplication.sharedApplication().delegate?.window??は、このライブラリが機能するための鍵となりますが、ライブラリを制限します。

これらの行によると、メニューを表示する UIViewController を作成しrootViewController、メニュー ビューをウィンドウのインデックス 0 に追加します (これが、メニュー ビューを後ろに配置するものだと思います)。contentController)。

ライブラリの問題:

ライブラリは、最初のView Controllerにメニューが必要な場合にのみ機能します。ある意味では、contentController がすでに rootViewController である場合のみです。私のアプリでは実際に機能しますが、元の UIViewController は階層にないため、元の UIViewController に戻ることはできません。

Login View Controller があるシナリオがあります。ログインに成功すると、メニューが必要な UINavigationController に移動します。問題の最初の明確な兆候は、「警告: ビューがウィンドウ階層にない LoginViewController に UINavigationController を提示しようとしています!」という苦情が表示されることです。明らかに、rootViewController を再割り当てしているため、ウィンドウ階層にはありません。

これを修正する方法がわかりません。メニューを表示したい UIViewController が最初のビュー コントローラーでない場合に、この機能を動作させる方法はありますか?

4

3 に答える 3

3

簡単な答えは:はい.

UIViewControllerTransitioningDelegateこれは、ViewControllerを含む に を割り当て、およびメソッドlist-menuを実装することで実装できます。(直接)に触れる必要はありません。interactionControllerForPresentation()interactionControllerForDismissal()UIWindow

既存の についてこの部分を変更することもできますがlibrary、見た目からはTableView派手な遷移を伴う にすぎません。これは自分で簡単に実装できます。

インタラクティブなトランジションに関するApple のAPI リファレンスと、Ray Wenderlich によるこのチュートリアルを参照して、実践的な例を確認してください。

于 2016-09-17T08:49:58.817 に答える
2

したがって、あなたのシナリオは次のとおりです。

  1. rootViewController= aUINavigationController
  2. rootViewControllerUINavigationControllerLoginController です
  3. 誰かがログインに成功するnavigationControllerと、menuController へのプッシュ (またはセグエ)

また

  1. rootViewControllerLoginController です
  2. 誰かがログインに成功すると、menuController が表示されます

したがって、重要なポイントは、menuController を取得し、それをrootViewControllerアプリの に設定しないことです。

これは、要件に合わせて変更を加えたコードです。 https://github.com/Moonsownner/MediumMenu-master

私は何をしましたか:

  1. MediumMenu実際には でありUIView、トランジションを行うために、それを含むコントローラーを作成する必要があります。という名前の新しいクラスを作成しMediumMenuControllerます。そして、関数showMenuを に移動することがわかりますMediumMenuController。したがって、誰かがメニューを手動で表示したい場合、ターゲットは以前の ではなく MediumMenuController でなければなりませんNavigationController。にMediumMenuControllerは、 の init 関数に送信するビジネス コントローラが含まれますMediumMenuController
class MediumMenuController: UIViewController {

    let menuView: MediumMenu
    let child: UIViewController

    init(items: [MediumMenuItem], childController: UIViewController){
        self.menuView = MediumMenu(items: items, forViewController: childController)
        self.child = childController
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(menuView)
        addChildViewController(child)
        self.view.addSubview(child.view)
        child.view.frame = UIScreen.mainScreen().bounds
        child.didMoveToParentViewController(self)

    }

    func showMenu() {
        menuView.show()
    }

}
  1. のコードを削除しますMediumMenu

let menuController = UIViewController(); menuController.view = self UIApplication.sharedApplication().delegate?.window??.rootViewController = contentController UIApplication.sharedApplication().delegate?.window??.insertSubview(menuController.view, atIndex: 0)

および他のコントローラービューをMediumMenuController追加するという名前の新しいコントローラーを作成します。MediumMenu

上から言ってもわからないかもしれません。コードは詳細を表示できます。幸運を。

于 2016-09-21T04:06:55.660 に答える