问题描述
我最近开发了一个简单的音乐应用,在我停用的 iPhone 上运行良好。从那以后,我买了一台 Mac mini,这样我就可以使用 Mac Catalyst 在该平台上本地运行它。到目前为止,它已经适应得很好,但我被 UILabels 和 UiSlider 阻碍了不更新的已用和剩余播放时间。我上周在这里研究了这个问题,但还没有解决方案。这些包括在视图控制器激活时调用字符串变量以及在主线程上更新标签。
timer2 = Timer.scheduledTimer(timeInterval: 1.0,target: self,selector: #selector(self.tick),userInfo: nil,repeats: true)
@objc func tick() {
let date = Date()
labelTime.text = DateFormatter.localizedString(from: date,dateStyle: .none,timeStyle: .medium)
if let curTrack = mp.NowPlayingItem {
//Call length of track in seconds
let trackDuration = curTrack.playbackDuration
//Get elapsed time by calling currentPlaybackTime
let trackElapsed = mp.currentPlaybackTime
// avoid crash
if trackElapsed.isNaN
{
return
}
// display running time
let trackElapsedMins = Int(trackElapsed / 60)
let trackElapsedSecs = Int(trackElapsed.truncatingRemainder(dividingBy: 60))
if trackElapsedSecs < 10 {
labelElapsed.text = "\(trackElapsedMins):0\(trackElapsedSecs)"
} else {
labelElapsed.text = "\(trackElapsedMins):\(trackElapsedSecs)"
}
//display remaining time: subtract elapsed from duration
let trackRemaining = Int(trackDuration) - Int(trackElapsed)
let trackRemainingMins = trackRemaining / 60
let trackRemainingSecs = trackRemaining % 60
if trackRemainingSecs < 10 {
labelRem.text = "\(trackRemainingMins):0\(trackRemainingSecs)"
} else {
labelRem.text = "\(trackRemainingMins):\(trackRemainingSecs)"
}
sliderTime.maximumValue = Float(trackDuration)
sliderTime.value = Float(trackElapsed)
}
标签和滑块是您的标准插座:
@IBOutlet weak var labelTime: UILabel!
@IBOutlet weak var labelElapsed: UILabel!
@IBOutlet weak var labelRem: UILabel!
@IBOutlet weak var sliderTime: UiSlider!
我看到该函数正在运行,因为时钟忠实地计算秒数,并且当我插入断点时所有变量都包含数据,但标签和滑块仅在我的应用程序启动时显示音乐应用程序中正在进行的播放时间,而没有任何内容更多的。操纵滑块时,滑块会跳到歌曲中的不同点,但之后不会更新。所以我的问题是:什么会阻止 Mac Catalyst 中的这些更新操作?
解决方法
就其价值而言,我现在确定问题不在于 Catalyst 而是严重缺乏音乐应用程序 API,它似乎只会在初始化或暂停时调用正确的 currentPlaybackTime
,否则其值将恢复为0. 我在运行 iOS 14 的活动 iPhone 上安装了该应用程序,但它有同样的问题。也许这会在未来的版本中得到解决,但考虑到这里和其他地方关于类似问题的抱怨可以追溯到几个月前,我没有屏住呼吸......
更新:对于那些发现这篇文章寻求解决方案的类似困境的人,这是我的解决方法......
在拒绝使用单独的计时器(太不准确)和 AppleScript 桥来返回播放器位置属性的值(在 Mac Catalyst 中可能无法实现)的想法后,我发现每次点击播放按钮时 currentPlaybackTime
都会刷新。所以我建立了这个功能
@objc func playTime() -> Double {
let trackElapsed = mp.currentPlaybackTime
if isPlaying == true {
mp.play()
}
return trackElapsed
}
在 play
变量为真时每秒发送一个 isPlaying
命令,从而将更新的播放头位置值返回到我的标签和滑块。问题解决了……