- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 SwiftUI 中工作,并且有一个 AudioPlayer 类型,它是 AVPlayer 的子类;它发布 AVPlayer 的 timeControllerStatus(?)(.playing、.paused 和其他?)。我不想继承 AVPlayer,而是想传入一个 AVPlayer 并让它在某些 View 中使用 .onReceive 通知我。这是我目前拥有的功能类型:
import AVKit
import Combine
class AudioPlayer: AVPlayer, ObservableObject {
@Published var buffering: Bool = false
override init() {
super.init()
registerObservers()
}
private func registerObservers() {
self.addObserver(self, forKeyPath: "timeControlStatus", options: [.old, .new], context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "timeControlStatus", let change = change, let newValue = change[NSKeyValueChangeKey.newKey] as? Int, let oldValue = change[NSKeyValueChangeKey.oldKey] as? Int {
let oldStatus = AVPlayer.TimeControlStatus(rawValue: oldValue)
let newStatus = AVPlayer.TimeControlStatus(rawValue: newValue)
if newStatus != oldStatus {
DispatchQueue.main.async {[weak self] in
if newStatus == .playing || newStatus == .paused {
self?.buffering = false
} else {
self?.buffering = true
}
}
}
}
}
}
下面是我想要的类的示例(取自 Chris Mash's tutorial on SwiftUI & AVPlayer):
import Combine
import AVFoundation
class PlayerItemObserver {
let publisher = PassthroughSubject<Bool, Never>()
private var itemObservation: NSKeyValueObservation?
init(player: AVPlayer) {
// Observe the current item changing
itemObservation = player.observe(\.currentItem) { [weak self] player, change in
guard let self = self else { return }
// Publish whether the player has an item or not
self.publisher.send(player.currentItem != nil)
}
}
deinit {
if let observer = itemObservation {
observer.invalidate()
}
}
}
非常感谢您的帮助。
最佳答案
据我了解,您需要像文章示例中一样观察 timeControlStatus
。为此,您可以替换观察者:
import Combine
import AVFoundation
class PlayerItemObserver {
let controlStatusChanged = PassthroughSubject<AVPlayer.TimeControlStatus, Never>()
private var itemObservation: NSKeyValueObservation?
init(player: AVPlayer) {
itemObservation = player.observe(\.timeControlStatus) { [weak self] player, change in
guard let self = self else { return }
self.controlStatusChanged.send(player.timeControlStatus)
}
}
deinit {
if let observer = itemObservation {
observer.invalidate()
}
}
}
// MARK: init view
let player = AudioPlayer()
let playerObserver = PlayerItemObserver(player: player)
let contentView = SongListView(playerObserver: playerObserver)
// MARK: react on changing in view:
struct ContentView: View {
let playerObserver: PlayerItemObserver
var body: some View {
Text("Any view")
.onReceive(playerObserver.controlStatusChanged) { newStatus in
switch newStatus {
case .waitingToPlayAtSpecifiedRate:
print("waiting")
case .paused:
print("paused")
case .playing:
print("playing")
}
}
}
}
更新您可以在没有“老派”observe
的情况下使用@Published
和AnyCancellable
实现相同的目的。最后一个偶don't need extra code in deinit
.这是这个解决方案:
import Combine
import AVFoundation
class PlayerItemObserver {
@Published var currentStatus: AVPlayer.TimeControlStatus?
private var itemObservation: AnyCancellable?
init(player: AVPlayer) {
itemObservation = player.publisher(for: \.timeControlStatus).sink { newStatus in
self.currentStatus = newStatus
}
}
}
// MARK: you need to change view with new observation, but in general it will be the same
struct ContentView: View {
let playerObserver: PlayerItemObserver
var body: some View {
Text("Any view")
.onReceive(playerObserver.$currentStatus) { newStatus in
switch newStatus {
case nil:
print("nothing is here")
case .waitingToPlayAtSpecifiedRate:
print("waiting")
case .paused:
print("paused")
case .playing:
print("playing")
}
}
}
}
关于SwiftUI 结合 .onReceive 通知与 AVPlayer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60646857/
是否可以让通知启动广播接收器? 我试过这段代码,但它不起作用。 通知已创建,但当我点击它时没有任何反应。 注意:当我将 notificationIntent 更改为从 MyBroadcastRecei
下面是我的 Java 代码和 XML 代码。有人可以告诉我为什么我的 onReceieve 方法永远不会被调用吗? Java: public class PopUPSMS extends Activi
onReceive 永远不会接到电话!我已经完成了这个工作,并且做了一些更改,现在我已经为此工作了 5 个小时,并且不知道当我向它发送短信时我的 onReceive 没有被调用! public voi
我正在尝试遵循这个例子: What is the correct way for sharing data among AppWidgetProvider and RemoteViewsService
我在 Activity 中创建了一个接收器,用于在连接互联网时自动调用网络服务。 代码如下 //Create receiver for while network will come auto cal
最近对Android开发很感兴趣, friend 给了我一本《Android应用开发傻瓜书》。在书中,有一个名为 Silent Toggle Mode 的示例应用程序。稍后它会教您为应用程序制作主屏幕
我在 mainfest.xml 中声明了我的 BroadcastReceiver 但从未调用过 onReceive() 方法。怎么了?我不想使用注册/注销方法。 Activity : Intent s
我有以下代码我想检测手机屏幕但是永远不会调用函数 onReceive谁能给我一个解决方案。请帮忙。如果有人有任何其他工作代码,请提供帮助。谢谢 package com.pack; import and
我创建了一个 broadcastreceiver 来 Hook 日历 EVENT_REMINDER 并获取有关事件的信息 public void onCreate(Bundle savedInstan
我读了这篇文章:Broadcast receiver onReceive() getting called multiple times 但我没有找到所需的答案。 我创建了一个小实用函数,它覆盖了 B
onReceive 方法中的线程在完成之前是否符合垃圾回收条件? @Override public void onReceive(final Context context, Intent inten
我正在使用此代码来检测屏幕何时被锁定并调用 toast,每次屏幕被锁定时它都会工作。但是,每当我离开应用程序时,它就会停止工作。它仅在应用程序打开时有效。 public class BatterySa
public class BroadcastTest extends Activity { BroadcastReceiver receiver; /** Called when the activi
我有一个从其他应用程序获取数据的服务。 当我得到日期时,我会向 broadCast 发送消息以刷新 UI。 多次调用onReceive方法,多次显示数据。 这是我的代码: DataService.ja
当我尝试接收的变量是@EnvironmentObject 的@Published 属性时,有什么方法可以防止在 View 最初加载时触发onReceive? 这是 View : struct Cont
我正在使用 Picker 来显示分段控件,并希望知道选择器值何时更改,以便我可以执行非 UI 操作。使用建议的 onReceive() 修饰符(如建议的 here )不起作用,因为每次渲染主体时都会调
我是 Android 初学者,遇到以下问题。我正在尝试从(不同的)应用程序 B 调用应用程序 A 注册的广播接收器。在应用程序 A 的广播接收器中,我实现了以下 onReceive() 方法,用于测试
我正在尝试开发一个短信应用程序。当我选择此应用程序作为默认短信应用程序并且当我收到带有此 SmsReceiver 代码的新短信时,会出现以下问题: 1) 每条新短信我都会收到 2 个 onReceiv
我正在设置一个内部BroadcastReceiver来获取 Activity 转换更新,例如步行、in_Vehicle。但 onReceive 方法永远不会被调用。 onCreate @Overri
我正在编写一个 Android 应用程序,它有一个受权限保护的广播接收器。广播接收器在接收来自经过身份验证的应用程序的请求时扫描硬编码 IP 地址的端口 80。它返回套接字连接尝试的结果。在我的代码中
我是一名优秀的程序员,十分优秀!