所有控制器上的快速播放器小部件

时间:2018-02-15 17:18:56

标签: ios swift widget instance

我正在我的应用中做广播播放器。并希望拥有带有信息+控制按钮的小部件,这些按钮将在播放时保留在应用程序中的所有控制器上。就像在itunes或像谷歌chromecast容器一样,将从底部推送其他viewcontroller的所有元素(不是覆盖元素)

enter image description here

我知道可以在appdelegate中将重叠视图添加到keywindow,因为GoogleCast Container添加了:

let appStoryboard = UIStoryboard(name: "Main", bundle: nil)
let navigationController = appStoryboard.instantiateViewController(withIdentifier: "MainNavigation")
let castContainerVC: GCKUICastContainerViewController = GCKCastContext.sharedInstance().createCastContainerController(for: navigationController)
castContainerVC.miniMediaControlsItemEnabled = true
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = castContainerVC
self.window?.makeKeyAndVisible()

但我无法理解,我如何设计和实例化我的控制器+将它添加到窗口+隐藏什么都没有播放。

我忘了提及,该应用程序已经启动并运行。导航栏中有大约30个视图控制器

2 个答案:

答案 0 :(得分:0)

我会在当前窗口的顶部创建一个窗口,我将放置该无线电视图。然后,无线电视图将始终位于标准窗口中的视图层次结构之上。要允许触摸事件由无线电窗口下的标准窗口处理,您需要在无线电窗口中覆盖hitTest以确保它不会处理不应由它处理的事件。

您可以将此作为示例:

import UIKit

class RadioController: UIViewController {

    fileprivate struct Static {
        static let window: UIHigherWindow = {
            let window = UIHigherWindow(frame: UIScreen.main.bounds)
            window.rootViewController = RadioController()
            window.windowLevel = UIWindowLevelAlert - 1
            return window
        }()
    }

    override func loadView() {
        // use passView, as it will pass the touch events tu underlying window
        self.view = PassView()
        self.view.backgroundColor = UIColor.clear
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // configure whatever subview you want, in your case the radio view
        let radioView = UIView(frame: CGRect(x: 0, y: UIScreen.main.bounds.height - 50, width: UIScreen.main.bounds.width, height: 50))
        radioView.backgroundColor = .red
        self.view.addSubview(radioView)
    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        // this will now define the status bar style, as it will become the topmost window for most of the time
        return .default
    }

    static var showing: Bool {
        get {
            return !Static.window.isHidden
        }
    }

    static func present() {
        Static.window.isHidden = false
    }

    static func hide() {
        Static.window.isHidden = true
    }
}

// MARK: Passing touch events to the back view
class PassView: UIView {}

class UIHigherWindow: UIWindow {

    // this will allow touch events to be processed by the default window
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let hitView = super.hitTest(point, with: event)
        if hitView!.isKind(of: PassView.self) {
            return nil
        }
        return hitView
    }
}

答案 1 :(得分:0)

解决方案

  1. 将初始视图控制器嵌入容器视图控制器
  2. 将您的子视图添加到容器vc
  3. 的视图底部
  4. 对齐子视图,使其位于主视图下方的屏幕外
  5. 创建一个方法,在调用时为子视图设置动画 底部到适当的位置和另一个动画的 子视图回到底部
  6. 在代码中适当地调用动画方法
  7. 备注

      

    您需要为容器vc添加自定义类,以便可以   在它上面调用动画方法