所有控制器上的快速播放器小部件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了所有控制器上的快速播放器小部件相关的知识,希望对你有一定的参考价值。
我在我的应用程序中做广播播放器。并希望拥有带有信息+控制按钮的小部件,这些按钮将在播放时保留在应用程序中的所有控制器上。就像在itunes或像谷歌chromecast容器一样,将从底部推送其他viewcontroller的所有元素(不是覆盖元素)
我知道覆盖视图可以在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个视图控制器
答案
我会在当前窗口的顶部创建一个窗口,我将放置该无线电视图。然后,无线电视图将始终位于标准窗口中的视图层次结构之上。要允许触摸事件由无线电窗口下的标准窗口处理,您需要在无线电窗口中覆盖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
}
}
另一答案
解
- 将初始视图控制器嵌入容器视图控制器中
- 将子视图添加到容器vc的视图底部
- 对齐子视图,使它们位于主视图下方的屏幕外
- 创建一种方法,在调用时将子视图从底部设置为适当的位置,将另一个方法设置为将子视图设置为底部下方的动画
- 在适当的代码中调用动画方法
笔记
您将需要向容器vc添加自定义类,以便可以在其上调用动画方法
以上是关于所有控制器上的快速播放器小部件的主要内容,如果未能解决你的问题,请参考以下文章
此应用小部件片段中所有意图 (PendingIntents) 的逻辑流
AppCompat v22.1.0 没有为片段正确主题化所有 xml 小部件