如何在我自己的应用程序中实现 Apple Music 中的迷你播放器?

How can I implement the miniplayer in Apple Music in my own app?

Apple 在 iOS 8.4 的 Apple Music 中引入了新的 UI。

当音频曲目开始播放时,标签栏上方会出现一个迷你播放器,通过向上拖动或点击它可以进入全屏模式。

我想这是在使用 UIViewController 遏制 API。我可以从哪里开始我自己的实施?

我该如何实现类似的东西?

有趣的是,我在本周早些时候遇到了一个实现此功能的框架。给 LNPopupController 看看。它实现了您正在寻找的行为(显示迷你栏,然后点击或拖动以显示视图控制器)。如果它不太符合你的需求,也许它至少可以为你实现自己的东西提供一个起点。

在您的根视图控制器中为 Apple Music uiTabBar 控制器添加一个容器视图。

func configureContainer() {
        
        // add container
        containerView = UIView()
        containerView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(containerView)
        
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            containerView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
            containerView.trailingAnchor.constraint(equalTo: g.trailingAnchor),
            containerView.bottomAnchor.constraint(equalTo: tabBar.topAnchor),
            containerView.heightAnchor.constraint(equalToConstant: 64.0)
        ])
        
        // add child view controller view to container
        miniPlayer = MiniPlayerViewController()
        guard let miniPlayer = miniPlayer else { return }
        addChild(miniPlayer)
        miniPlayer.view.translatesAutoresizingMaskIntoConstraints = false
        containerView.addSubview(miniPlayer.view)
        
        
        // Create and activate the constraints for the child’s view.
        guard let miniPlayerView = miniPlayer.view else { return }
        NSLayoutConstraint.activate([
            miniPlayerView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            miniPlayerView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
            miniPlayerView.topAnchor.constraint(equalTo: containerView.topAnchor),
            miniPlayerView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
        ])
        
        miniPlayer.didMove(toParent: self)
    }

在我的例子中,我想将 miniPlayer 隐藏在一个特定的 VC 中,所以我使用 NotificationCenter 来做到这一点。在根 viewController.

中注册一个通知
NotificationCenter.default.addObserver(self, selector: #selector(miniPlayerVisibilityNeedsChange(notify:)), name: NSNotification.Name("miniPlayerVisibilityNeedsToBeUpdate"), object: nil)

Post 在你的特定 VC 中,就是这样!

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        // hide miniPlayer for this vc
        NotificationCenter.default.post(name: NSNotification.Name("miniPlayerVisibilityNeedsToBeUpdate"), object: false)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        // show miniPlayer again when leaving this vc
        NotificationCenter.default.post(name: NSNotification.Name("miniPlayerVisibilityNeedsToBeUpdate"), object: true)
    }