0

我想为 uiviews 的 alpha 设置动画,但我似乎无法做到。它的行为很奇怪,并说运行 UI 更改不建议在后台线程上运行,但我不知道如何让它在主线程上运行。有人可以帮助我吗?我相信它会跳过第一个 UIView.animate 块并在没有任何动画的情况下执行第二个块。

func animateSemaphore() {

circleRed.alpha = 0.2
circleOrange.alpha = 0.2
circleGreen.alpha = 1

let dispatchSemaphore = DispatchSemaphore(value: 0)
let dispatchQueue = DispatchQueue.global(qos: .background)

dispatchQueue.async {
    UIView.animate(withDuration: 0.5, delay: 5, options: .curveEaseInOut) {
        self.circleOrange.alpha = 1
        self.circleGreen.alpha = 0.2
    } completion: { (_) in
        print("1")
        dispatchSemaphore.signal()
    }
    
    dispatchSemaphore.wait()
    UIView.animate(withDuration: 0.5, delay: 3, options: .curveEaseInOut) {
        self.circleOrange.alpha = 0.2
        self.circleRed.alpha = 1
    } completion: { (_) in
        dispatchSemaphore.signal()
    }
    
    dispatchSemaphore.wait()
    UIView.animate(withDuration: 0.5, delay: 5, options: .curveEaseInOut) {
        self.circleOrange.alpha = 1
    } completion: { (_) in
        dispatchSemaphore.signal()
    }
    
    dispatchSemaphore.wait()
    UIView.animate(withDuration: 0.5, delay: 1, options: .curveEaseInOut) {
        self.circleOrange.alpha = 0.2
        self.circleRed.alpha = 0.2
        self.circleGreen.alpha = 1
    } completion: { (_) in
        self.animateSemaphore()
    }
}

}

4

2 回答 2

1

您需要在主线程中插入任何与 ui/animate 相关的代码,而不是在后台队列中

func animateSemaphore() {
    circleRed.alpha = 0.2
    circleOrange.alpha = 0.2
    circleGreen.alpha = 1
        
    UIView.animate(withDuration: 0.5, delay: 5, options: .curveEaseInOut) {
        self.circleOrange.alpha = 1
        self.circleGreen.alpha = 0.2
    } completion: { (_) in
        UIView.animate(withDuration: 0.5, delay: 3, options: .curveEaseInOut) {
            self.circleOrange.alpha = 0.2
            self.circleRed.alpha = 1
        } completion: { (_) in
            UIView.animate(withDuration: 0.5, delay: 5, options: .curveEaseInOut) {
                self.circleOrange.alpha = 1
            } completion: { (_) in
                UIView.animate(withDuration: 0.5, delay: 1, options: .curveEaseInOut) {
                    self.circleOrange.alpha = 0.2
                    self.circleRed.alpha = 0.2
                    self.circleGreen.alpha = 1
                } completion: { (_) in 
                }
            }
        }
    }
 }

或玩delay而不是嵌套动画

func animateSemaphore() {

    circleRed.alpha = 0.2
    circleOrange.alpha = 0.2
    circleGreen.alpha = 1

    UIView.animate(withDuration: 0.5, delay: 5, options: .curveEaseInOut) {
        self.circleOrange.alpha = 1
        self.circleGreen.alpha = 0.2
    } completion: { (_) in
        print("1")
      
    }
    
   
    UIView.animate(withDuration: 0.5, delay: 8.5, options: .curveEaseInOut) {
        self.circleOrange.alpha = 0.2
        self.circleRed.alpha = 1
    } completion: { (_) in
        
    }
    
   
    UIView.animate(withDuration: 0.5, delay: 14, options: .curveEaseInOut) {
        self.circleOrange.alpha = 1
    } completion: { (_) in
       
    }
    
  
    UIView.animate(withDuration: 0.5, delay: 15.5, options: .curveEaseInOut) {
        self.circleOrange.alpha = 0.2
        self.circleRed.alpha = 0.2
        self.circleGreen.alpha = 1
    } completion: { (_) in
        
    }
}
于 2021-04-22T11:45:20.823 回答
1

您还可以创建用于创建动画的配置(可以在此处找到草稿) https://gist.github.com/maximkrouk/76163b3f2775dafc73c5633d15536​​8cb 并添加一些扁平化

public struct UIViewAnimation {
    private init(
        provider: UIViewAnimatiorProvider?,
        animations: @escaping () -> Void,
        completion: ((Bool) -> Void)? = nil
    ) {
        self.provider = provider
        self.animations = animations
        self.completion = completion
    }
    
    public init(
        config: UIViewAnimatiorProvider,
        animations: @escaping () -> Void,
        completion: ((Bool) -> Void)? = nil
    ) {
        self.init(
            provider: config,
            animations: animations,
            completion: completion
        )
    }
    
    let provider: UIViewAnimatiorProvider?
    let animations: () -> Void
    let completion: ((Bool) -> Void)?
    
    public func run() {
        if let provider = provider {
            provider.makeAnimator(
                for: animations,
                completion: completion ?? { _ in }
            ).animate()
        } else {
            animations()
            completion?(true)
        }
    }
    
    public func appendingCompletion(_ completion: @escaping (Bool) -> Void) -> UIViewAnimation {
        UIViewAnimation(
            provider: provider,
            animations: animations,
            completion: { isFinished in
                self.completion?(isFinished)
                completion(isFinished)
            }
        )
    }
    
    public static let empty: UIViewAnimation = .init(
        provider: nil,
        animations: {},
        completion: nil
    )
}

extension UIViewAnimation {
    public static func sequence(_ animations: UIViewAnimation...) -> UIViewAnimation {
        guard var animation = animations.last else { return .empty }
        animations.dropLast().reversed().forEach { prevAnimation in
            let animate = animation.run
            animation = prevAnimation.appendingCompletion { _ in animate() }
        }
        return animation
    }
}

并像使用它一样

extension UIView {
    func animateSemaphore() {
        let initialBackground = backgroundColor
        UIViewAnimation.sequence(
            UIViewAnimation(config: .init(duration: 2)) {
                self.backgroundColor = .red
            },
            UIViewAnimation(config: .init(duration: 2)) {
                self.backgroundColor = .green
            },
            UIViewAnimation(config: .init(duration: 2)) {
                self.backgroundColor = .red
            },
            UIViewAnimation(config: .init(duration: 2)) {
                self.backgroundColor = .green
            },
            UIViewAnimation(config: .init(duration: 2)) {
                self.backgroundColor = initialBackground
            }
        ).run()
    }
}

UIView().animateSemaphore()
于 2021-04-22T15:04:46.100 回答