首页 > 解决方案 > SwiftUI + Timer + AVPlayer - 音频播放时,onReceive(timer) 未触发

问题描述

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

我有一个SlidingText视图的实现。基本上只是将其框中的文本从左向右移动,然后从右向左移动。Timer此动画每 5 秒触发一次。我有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)
    }
}

我在这里使用计时器的方式有什么问题吗?感谢您对未来的任何帮助!

标签: swifttimerswiftuiavplayer

解决方案


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

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

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()
    }
}

推荐阅读