【问题标题】:Swift 4: Add View on top of all controllersSwift 4:在所有控制器之上添加视图
【发布时间】:2018-05-09 04:39:20
【问题描述】:

条件:

  • Swift 4,Xcode 9.3
  • 目标:iOS 11.3
  • UI 以编程方式完成
  • 使用约束
  • 我的根视图控制器是一个导航

情况:

我想浮动一个在整个应用程序中可见的音频播放器。 我做了一个包含音频播放器用户界面的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()
    }
}

问题:

如何将它添加到根视图控制器以在我的应用程序中的所有视图控制器中保持领先?无论我在哪里导航,玩家都必须停留在每个控制器的底部。如您所见,我需要对 rootviewcontroller 的引用来设置 AudioPlayer 的约束,但我在很多尝试中都失败了(比如使用 AppDelegate 调用 rootviewcontroller)

【问题讨论】:

标签: ios swift swift4 xcode9


【解决方案1】:

我为你更新了

  1. 添加单例static let shared = AudioPlayer()
  2. 添加public func showAudioPlayer () --> 显示音频播放器
  3. 作为子视图添加到UIApplication.shared.keyWindow?
  4. TODO- 添加 HideAudioPlayer()

这样使用

 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)拉伸到屏幕的侧边? 2)我正在使用 cocoapods 的 SideMenu,每次切换到另一个菜单时,我的音频播放器都会消失。
  • 不要担心这个问题,因为你的代码是在 window.makeKeyAndVisible() 之后执行的
  • 我使用safeAreaLayoutGuide而不是layoutMarginsGuide解决了屏幕边缘问题。
  • 你用过SideMenu吗?每当我切换到另一个视图控制器时,我的音频播放器就会消失。
  • 会检查你可能需要添加更改Zposition
【解决方案2】:

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

AppDelegate.shared.window?.addSubview(AudioPlayer)

【讨论】:

    【解决方案3】:

    您可以将视图添加到 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)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-10
      • 1970-01-01
      • 2017-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多