AppleMusic과 같은 TabBar에 Dock된 툴바를 구축

12527 단어 Swift우이

AppleMusic과 같은 TabBar에 Dock된 툴바 구축



AppleMusic의 iOS 앱에는 TabBar 위에 재생 중인 음악을 보여주는 툴바가 표시됩니다.
이번에는 탭을 전환하거나 UINavigationController에서 push 전이를 해도 단일 인스턴스를 사용하여 표시할 수 있는 구현을 해보겠습니다.

완성 이미지





구현 개요



UITabBarController를 상속한 TabBarController측에 Player용의 UIView를 레이아웃 해, 공개시켜 둡니다.

UITabBarController에 내장된 UIViewController에서 UITabBarController를 가져올 수 있으므로 이를 통해 Player 인스턴스에 액세스하고,
레이아웃에 사용할 수 있습니다.

구현을 단순화하기 위해 TabBarVisible protocol을 만들고 protocol extension에서 플레이어를 검색할 수 있습니다.

주의점으로서는 tabBarController는 viewDidLoad 시점에서는 취득할 수 없기 때문에, updateViewConstraints등으로 레이아웃을 할 필요가 있습니다.

구현


import UIKit

final class TabBarController: UITabBarController {
    enum Const {
        static let playerHeight: CGFloat = 64
    }

    let player: UILabel = {
        let label = UILabel()
        label.text = "This is Music Player"
        label.font = .boldSystemFont(ofSize: 18)
        label.backgroundColor = UIColor.purple
        return label
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        player.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(player)
        NSLayoutConstraint.activate([
            player.heightAnchor.constraint(equalToConstant: Const.playerHeight),
            player.leftAnchor.constraint(equalTo: view.leftAnchor),
            player.rightAnchor.constraint(equalTo: view.rightAnchor),
            player.bottomAnchor.constraint(equalTo: tabBar.topAnchor)
        ])

        viewControllers = [
            TopViewController(title: "Page1", color: .green),
            TopViewController(title: "Page2", color: .yellow)
        ]
    }
}

import UIKit

protocol TabBarVisible {}

extension TabBarVisible where Self: UIViewController {
    var player: UIView {
        guard let tabBarController = tabBarController as? TabBarController else {
            fatalError("Must to be embbeded in UITabBarController")
        }
        return tabBarController.player
    }
}
import UIKit

final class TopViewController: UIViewController, TabBarVisible {
    private let label: UILabel = {
        let label = UILabel()
        label.numberOfLines = 0
        label.minimumScaleFactor = 0.1
        label.adjustsFontSizeToFitWidth = true
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    init(title: String, color: UIColor) {
        super.init(nibName: nil, bundle: nil)
        self.title = title
        label.text = Array(repeating: title, count: 100).joined()
        view.backgroundColor = color
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(label)
    }

    override func updateViewConstraints() {
        NSLayoutConstraint.activate([
            label.topAnchor.constraint(equalTo: view.topAnchor),
            label.rightAnchor.constraint(equalTo: view.rightAnchor),
            label.leftAnchor.constraint(equalTo: view.leftAnchor),
            label.bottomAnchor.constraint(equalTo: player.topAnchor)
        ])

        super.updateViewConstraints()
    }
}

좋은 웹페이지 즐겨찾기