GCD的替代方法,在SwiftUI下延迟运行代码

问题描述 投票:2回答:1

Swift 5,iOS 13

我正在运行此代码,它可以工作。

var body: some View {
...
Button(action: {
  self.animateTLeft() 
  quest = quest + "1"
}) { Wedge(startAngle: .init(degrees: 180), endAngle: .init(degrees: 270)) 
         .fill(Color.red) 
         .frame(width: 200, height: 200)
         .offset(x: 95, y: 95)
         .scaleEffect(self.tLeft ? 1.1 : 1.0)
}.onReceive(rPublisher) { _ in
  self.animateTLeft() 
}
...
}

private func animateTLeft() {
withAnimation(.linear(duration: 0.25)){
  self.tLeft.toggle()
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25, execute: {
  withAnimation(.linear(duration: 0.25)){
    self.tLeft.toggle()
  }
})
}

并且我想尝试使用GCD的其他替代方法not,如果可能的话。因此,我尝试使用无法编译的Timer。我尝试使用perform,但也没有编译。所以我尝试了编译的操作! :)。但是可悲的是,它只能工作一次。除了GCD,没有其他选择。

private func animateTLeft() {

//perform(#selector(animate), with: nil, afterDelay: 0.25)
//Timer.scheduledTimer(timeInterval: 0.15, target: self, selector: #selector(animateRed), userInfo: nil, repeats: false)

let queue = OperationQueue()
let operation1 = BlockOperation(block: {
  withAnimation(.linear(duration: 1)){
    self.tLeft.toggle()
  }
})
let operation2 = BlockOperation(block: {
  withAnimation(.linear(duration: 1)){
    self.tLeft.toggle()
  }
})
operation2.addDependency(operation1)
queue.addOperations([operation1,operation2], waitUntilFinished: true)

}

为什么要这样做,因为我有四个要制作动画的片段,但是我想要的代码更少。我有红色,绿色,黄色和蓝色的切片。我编写了一个通用例程为它们设置动画,并提供颜色作为参数。这是我的代码。

private func animateSlice(slice: inout Bool) {
withAnimation(.linear(duration: 0.25)){
  slice.toggle()
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25, execute: {
  withAnimation(.linear(duration: 0.25)){
    slice.toggle()
  }
})
}

但是这不会与inout参数一起编译,并给出红色错误消息“转义闭包捕获'inout'参数'slice'”,这不是很好。我可以使其成为副本,而不是inout参数。可以编译,但是当然不起作用,因为它没有更改愚蠢的值。

也尝试过此方法,但不会编译。也许有人可以使其正常工作。

private func animateSliceX(slice: String) {
var ptr = UnsafeMutablePointer<Bool>.allocate(capacity: 1)
switch slice {
case "red": ptr = &tLeft
case "green": ptr = &tRight
case "yellow": ptr = &bLeft
default: ptr = &bRight
}
withAnimation(.linear(duration: 0.25)){
  ptr.toggle()
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25, execute: {
  withAnimation(.linear(duration: 0.25)){
    ptr.toggle()
  }
})
}

谢谢...

swift swiftui grand-central-dispatch nsoperationqueue nsoperation
1个回答
0
投票

我不认为还有另一种方法(至少更容易使用该GCD,但您可以使用以下可重复使用的功能。

© www.soinside.com 2019 - 2024. All rights reserved.