【问题标题】:SwiftUI + Timer + AVPlayer - When audio playing, onReceive(timer) not triggeredSwiftUI + Timer + AVPlayer - 音频播放时,onReceive(timer) 未触发
【发布时间】:2020-09-08 20:35:19
【问题描述】:

我无法让我的计时器(和我的动画)正常工作。如果AVPlayer 当前正在播放,我的计时器不会被触发。一旦我暂停它,我的计时器就会恢复......

我有一个SlidingText 视图的实现。基本上只是将其框中的文本从左向右移动,然后从右向左移动。此动画每 5 秒触发一次Timer。 我有一个 AVPlayer 正在播放一些东西,同时带有一个暂停/播放按钮。

这是SlidingText 的实现。而AVPlayer 只是被一个触发player.play()player.pause() 的按钮调用。

import SwiftUI

struct SlidingText: View {
    let geometryProxy: GeometryProxy
    @Binding var text: String
    let font: Font

    @State private var animateSliding: Bool = false
    private let timer = Timer.publish(every: 5, on: .main, in: .common).autoconnect()
    private let slideDuration: Double = 3

    var body: some View {
        ZStack(alignment: .leading, content: {
            VStack(content: {
                Text(text)
                    .font(self.font)
                    .foregroundColor(.white)
                    .background(Color.red)
            })
                .id("SlidingText-Animation")
                .fixedSize(horizontal: false, vertical: true)
                .frame(width: geometryProxy.size.width, alignment: animateSliding ? .trailing : .leading)
                .clipped()
                .animation(Animation.linear(duration: slideDuration))
                .onReceive(timer, perform: { _ in
                    self.animateSliding.toggle()
                })
        })
            .frame(width: self.geometryProxy.size.width, height: self.geometryProxy.size.height)
            .background(Color.yellow)
    }
}

我在这里使用计时器的方式有什么问题吗? 感谢您以后的帮助!

【问题讨论】:

  • 不清楚没有完整的上下文在运行时发生了什么。也许您的 SlidingText 在播放过程中被重新创建,因此重新创建了计时器...尝试将计时器保持在视野之外。
  • 我的错,我想我可能错误地实现了Timer。我正在为播放器使用这个库。 github.com/jorgenhenrichsen/SwiftAudio

标签: swift timer swiftui avplayer


【解决方案1】:

好吧,我最终没有使用计时器,因为它有问题。

对于那些对它现在看起来像这样感兴趣的人,我正在使用动画属性。 不再干扰音频播放器。

struct SlidingText: View {
    let geometryProxy: GeometryProxy
    @Binding var text: String
    let font: Font

    @State private var animateSliding: Bool = false
    private let slideDelay: Double = 3
    private let slideDuration: Double = 6

    private var isTextLargerThanView: Bool {
        if text.size(forWidth: geometryProxy.size.width, andFont: font).width < geometryProxy.size.width {
            return false
        }
        return true
    }

    var body: some View {
        ZStack(alignment: .leading, content: {
            VStack(content: {
                Text(text)
                    .font(self.font)
                    .foregroundColor(.white)
                    .background(Color.red)
            })
                .id("SlidingText-Animation")
                .fixedSize()
                .animation(Animation.linear(duration: slideDuration).delay(slideDelay).repeatForever(autoreverses: true))
                .frame(width: geometryProxy.size.width,
                       alignment: isTextLargerThanView ? (animateSliding ? .trailing : .leading) : .center)
                .onAppear(perform: {
                    self.animateSliding.toggle()
                })
        })
            .clipped()
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多