SwiftUI 提供了.animation()可以在视图中动画更改的绑定。但是,如果某个@Published属性@ObserveredObject“自主”更改(例如,从计时器更改),而视图将响应更改而更新,则没有明显的方法可以让视图以动画形式呈现更改。
在下面的示例中,当isOn从“切换”更改时,它会产生动画,但当从“更改”时,Timer它不会。有趣的是,如果我在这里使用三元条件而不是if/ else,即使切换也不会触发动画。
struct ContentView: View {
@ObservedObject var model: Model
var body: some View {
VStack {
if model.isOn {
MyImage(color: .blue)
} else {
MyImage(color: .clear)
}
Spacer()
Toggle("switch", isOn: $model.isOn.animation(.easeIn(duration: 0.5)))
Spacer()
}
}
}
struct MyImage: View {
var color: Color
var body: some View {
Image(systemName: "pencil.circle.fill")
.resizable()
.frame(width: 100, height: 100)
.foregroundColor(color)
}
}
class Model: ObservableObject {
@Published var …Run Code Online (Sandbox Code Playgroud) 我正在开发的应用程序需要在声音链中动态添加/删除/重新排列组件。
到目前为止,我主要.disconnectOutput()在大多数组件上使用该方法,然后重新连接所有组件。这在大多数情况下都有效,但有时似乎一个节点连接在声音链中的多个点,如果节点连接到AudioKit.output.
AudioKit 提供了许多公共方法,例如.detach(), .disconnectInput(),.disconnect()我不太清楚修改声音链的最干净或最安全的方法。做这个的最好方式是什么?
另外,是否有某种方法可以跟踪哪些节点连接到哪些节点?
以非常严格的时间安排重复任务的最佳方法是什么(对于音乐排序足够准确和可靠)?从 Apple 文档中,很明显 NSTimer 在这个意义上是不可靠的(即“计时器不是实时机制”)。我从 AudioKit 的AKPlaygroundLoop借用的一种方法在大约 4 毫秒内似乎是一致的(如果不是很准确),并且可能是可行的:
class JHLoop: NSObject{
var trigger: Int {
return Int(60 * duration) // 60fps * t in seconds
}
var counter: Int = 0
var duration: Double = 1.0 // in seconds, but actual loop is ~1.017s
var displayLink: CADisplayLink?
weak var delegate: JHLoopDelegate?
init(dur: Double) {
duration = dur
}
func stopLoop() {
displayLink?.invalidate()
}
func startLoop() {
counter = 0
displayLink = CADisplayLink(target: self, selector: "update")
displayLink?.frameInterval = …Run Code Online (Sandbox Code Playgroud) 我正在使用AudioKit开发一个音频应用程序,它涉及定期停止AudioKit,重新安排或替换AKNode子类链,然后重新启动AudioKit.这一直顺利进行,直到我尝试过AKMicrophone.
如果AKMicrophone在初始声音链中存在,即,当我第一次调用时AudioKit.start(,它可以正常工作.但是,如果我AKMicrophone在之前的调用之后的某个时刻进入声音链AudioKit.start(),则应用程序将在下一次AudioKit.start()调用时崩溃,从而产生以下错误消息:
...[avae] AVAudioEngine.mm:149:-[AVAudioEngine prepare]: Engine@0x1c0007170: could not initialize, error = -10875
...[mcmx] 338: input bus 0 sample rate is 0
...[avae] AVAEInternal.h:103:_AVAE_CheckNoErr: [AVAudioEngineGraph.mm:1266:Initialize:
(err = AUGraphParser::InitializeActiveNodesInOutputChain(ThisGraph, kOutputChainOptimizedTraversal, *GetOutputNode(), isOutputChainActive)): error -10875
Run Code Online (Sandbox Code Playgroud)
为了说明,以下代码顺利运行:
let mic = AKMicrophone()
if let input = AudioKit.inputDevice {
try! mic.setDevice(input)
}
AudioKit.output = mic
AudioKit.start()
Run Code Online (Sandbox Code Playgroud)
但是如果它之前被调用AudioKit.start()就会崩溃:
AudioKit.output = AKOscillator()
AudioKit.start()
AudioKit.stop()
let mic = AKMicrophone()
if let input = …Run Code Online (Sandbox Code Playgroud) onFocusChange修饰符中的闭包允许focusable(_:onFocusChange:)我在子视图聚焦时为父视图设置属性,如下所示:
struct ContentView: View {
@State var text: String
var body: some View {
VStack {
Text(text)
Text("top")
.padding()
.focusable(true, onFocusChange: { focused in
text = "top focus"
})
Text("bottom")
.padding()
.focusable(true, onFocusChange: { focused in
text = "bottom focus"
})
}
}
}
Run Code Online (Sandbox Code Playgroud)
但在 2020 年 WWDC 视频中focusable,明确指出该包装器不打算与按钮和列表等本质上可聚焦的视图一起使用。如果我在这里使用按钮代替文本,则 onFocusChange 可以工作,但按钮的正常焦点行为会中断:
struct ContentView: View {
@State var text: String
var body: some View {
VStack {
Text(text)
Button("top") {}
.padding()
.focusable(true, onFocusChange: { focused in …Run Code Online (Sandbox Code Playgroud)