Swift 4:在所有控制器

时间:2018-05-09 04:39:20

标签: ios swift swift4 xcode9

条件:

  • Swift 4,Xcode 9.3
  • 目标:iOS 11.3
  • 以编程方式完成UI
  • 使用约束
  • 我的Root View Controller是一个导航

情况:

我想浮动一个在整个应用程序中可见的音频播放器。 我做了一个AudioPlayer.swift类,其中包含音频播放器的用户界面。

AudioPlayer.swift

import Foundation
import UIKit
import FRadioPlayer

class AudioPlayer: UIView {

    let screenSize: CGRect = UIScreen.main.bounds

    let playerImage: UIImageView = {
        let iv = UIImageView()
        iv.translatesAutoresizingMaskIntoConstraints = false
        iv.contentMode = .scaleAspectFill
        iv.layer.masksToBounds = true

        return iv
    }()

    let playerTitle: UILabel = {
        let l = UILabel()
        l.textColor = .darkGray
        l.font = UIFont.boldSystemFont(ofSize: 13)
        l.translatesAutoresizingMaskIntoConstraints = false

        return l
    }()

    let playerSeriesTitle: UILabel = {
        let l = UILabel()
        l.textColor = .darkGray
        l.font = UIFont.boldSystemFont(ofSize: 12)
        l.translatesAutoresizingMaskIntoConstraints = false

        return l
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        translatesAutoresizingMaskIntoConstraints = false
        setupAudioControls()
    }

    private func setupAudioControls(){

        let appDelegate = AppDelegate.sharedInstance
        self.backgroundColor = UIColor.init(hex: "#EBE4D3")

        self.addSubview(playerImage)
        self.addSubview(playerTitle)
        self.addSubview(playerSeriesTitle)

        self.heightAnchor.constraint(equalToConstant: 150).isActive = true
        self.bottomAnchor.constraint(equalTo: appDelegate().rootView ).isActive = true
        self.leadingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leadingAnchor).isActive = true
        self.trailingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.trailingAnchor).isActive = true

        playerImage.topAnchor.constraint(equalTo: self.topAnchor, constant: 10).isActive = true
        playerImage.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 10).isActive = true
        playerImage.widthAnchor.constraint(equalToConstant: 55).isActive = true
        playerImage.heightAnchor.constraint(equalToConstant: 55).isActive = true

        playerTitle.topAnchor.constraint(equalTo: self.topAnchor, constant: 5).isActive = true
        playerTitle.leadingAnchor.constraint(equalTo: playerImage.trailingAnchor, constant: 10).isActive = true
        playerTitle.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 10).isActive = true
        playerTitle.heightAnchor.constraint(equalToConstant: 25).isActive = true

        playerSeriesTitle.topAnchor.constraint(equalTo: playerTitle.topAnchor, constant: 20).isActive = true
        playerSeriesTitle.leadingAnchor.constraint(equalTo: playerImage.trailingAnchor, constant: 10).isActive = true
        playerSeriesTitle.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 10).isActive = true
        playerSeriesTitle.heightAnchor.constraint(equalToConstant: 20).isActive = true

        UIView.animate(withDuration: 0.5, animations: {
            self.frame.origin.y -= 150
            self.playerImage.frame.origin.y -= 150
            self.playerTitle.frame.origin.y -= 150
            self.playerSeriesTitle.frame.origin.y -= 150
        }, completion: nil)


        self.setNeedsLayout()
        self.reloadInputViews()
    }
}

问题:

如何将其添加到Root View Controller以在我的应用程序中拥有的所有视图控制器中保持最佳状态?无论我在哪里导航,玩家都必须留在每个控制器的底部。正如您所看到的,我需要对rootviewcontroller的引用来设置AudioPlayer的约束,但是我在很多尝试中失败了(比如使用AppDelegate调用rootviewcontroller)

3 个答案:

答案 0 :(得分:1)

我为您更新

  1. 添加单身static let shared = AudioPlayer()
  2. 添加public func showAudioPlayer () - >显示音频播放器
  3. 将子视图添加到UIApplication.shared.keyWindow?
  4. TODO-添加HideAudioPlayer()
  5. 像这样使用

     AudioPlayer.shared.showAudioPlayer()
    

    这是更新的代码

    import Foundation
    import UIKit
    
    class AudioPlayer: UIView {
    
    
        static let shared = AudioPlayer()
    
        let screenSize: CGRect = UIScreen.main.bounds
    
        let playerImage: UIImageView = {
            let iv = UIImageView()
            iv.translatesAutoresizingMaskIntoConstraints = false
            iv.contentMode = .scaleAspectFill
            iv.layer.masksToBounds = true
    
            return iv
        }()
    
        let playerTitle: UILabel = {
            let l = UILabel()
            l.textColor = .darkGray
            l.font = UIFont.boldSystemFont(ofSize: 13)
            l.translatesAutoresizingMaskIntoConstraints = false
    
            return l
        }()
    
        let playerSeriesTitle: UILabel = {
            let l = UILabel()
            l.textColor = .darkGray
            l.font = UIFont.boldSystemFont(ofSize: 12)
            l.translatesAutoresizingMaskIntoConstraints = false
    
            return l
        }()
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            translatesAutoresizingMaskIntoConstraints = false
           // setupAudioControls()
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
         public func showAudioPlayer (){
            self.setupAudioControls()
        }
    
        private func setupAudioControls(){
    
            self.backgroundColor = .red
    
            self.addSubview(playerImage)
            self.addSubview(playerTitle)
            self.addSubview(playerSeriesTitle)
            UIApplication.shared.keyWindow?.addSubview(self)
    
            if let  layoutGuide  = UIApplication.shared.keyWindow?.layoutMarginsGuide {
                self.heightAnchor.constraint(equalToConstant: 150).isActive = true
                self.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor ).isActive = true
                self.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).isActive = true
                self.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).isActive = true
            }
    
    
            playerImage.topAnchor.constraint(equalTo: self.topAnchor, constant: 10).isActive = true
            playerImage.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 10).isActive = true
            playerImage.widthAnchor.constraint(equalToConstant: 55).isActive = true
            playerImage.heightAnchor.constraint(equalToConstant: 55).isActive = true
    
            playerTitle.topAnchor.constraint(equalTo: self.topAnchor, constant: 5).isActive = true
            playerTitle.leadingAnchor.constraint(equalTo: playerImage.trailingAnchor, constant: 10).isActive = true
            playerTitle.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 10).isActive = true
            playerTitle.heightAnchor.constraint(equalToConstant: 25).isActive = true
    
            playerSeriesTitle.topAnchor.constraint(equalTo: playerTitle.topAnchor, constant: 20).isActive = true
            playerSeriesTitle.leadingAnchor.constraint(equalTo: playerImage.trailingAnchor, constant: 10).isActive = true
            playerSeriesTitle.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 10).isActive = true
            playerSeriesTitle.heightAnchor.constraint(equalToConstant: 20).isActive = true
    
            UIView.animate(withDuration: 0.5, animations: {
                self.frame.origin.y -= 150
                self.playerImage.frame.origin.y -= 150
                self.playerTitle.frame.origin.y -= 150
                self.playerSeriesTitle.frame.origin.y -= 150
            }, completion: nil)
    
    
            self.setNeedsLayout()
            self.reloadInputViews()
        }
    }
    

答案 1 :(得分:0)

如果要在每个视图控制器中显示视图,那么根据视图层次结构,您必须添加UIWindowUIWindow是所有屏幕的基础。

AppDelegate.shared.window?.addSubview(AudioPlayer)

答案 2 :(得分:0)

您可以将视图添加到UIWindow。 我在AppDelegate中使用下面的方法做同样的事情。

var window: UIWindow?

func addPlayerViewAtBottom()  {
  var bottomView : PlayerBottomView!
  bottomView = PlayerBottomView(frame: CGRect(x: 0, y: UIScreen.main.bounds.size.height - 60, width: UIScreen.main.bounds.width, height: 60))
  self.window?.addSubview(bottomView)
  self.window?.bringSubview(toFront: bottomView)
}