如何解决使用 SwiftUI 实时更新旋钮 HSVWheel 拖动或点击手势典型的滑块手势这是垂直值滑块
我目前正在尝试将滑块转换为旋钮,但经历了一段艰难的时期。旋钮在设计中工作,但我正在努力在旋钮内设置正确的值,结果实时更改应用程序中的值。
我正在使用 AVAudio 设置一个引擎,供人们使用具有混响和延迟等效果的录音。
混响值在音频类中设置如下:
@Published var reverbValue: Float = 0.0
稍后在函数中引用以更改其值
func changeReverbValue() {
setReverb.wetDryMix = reverbValue
}
当我按如下方式使用常规滑块时,更改有效:
Slider(value: $recordingsettings.reverbValue,in: Float(0.0)...recordingsettings.reverbMaxValue,onEditingChanged: { _ in
self.recordingsettings.changeReverbValue()
}).accentColor(Color.white)
如前所述,旋钮在其设计中运行良好:
ZStack {
Knobs(color: .orange)
.rotationEffect(
.degrees(max(0,initialCircleState()))
)
.gesture(DragGesture(minimumdistance: 0)
.onEnded({ _ in
startDragValue = -1.0
})
.onChanged { dragValue in
let touchDifferential = touchDifference(dragValue)
setinitialDragVal()
let computedTouch = computetouch(touchDifferential)
print(computedTouch)
baseValue = getBaseVal(computedTouch)
let normalizeVal = baseValue / touchAmt
value = Float(normalizeVal * rngOffset(range: bounds) + bounds.lowerBound)
print("vaule is: \(value)")
}
)
GrayCircle(bounds: bounds)
OrangeCircle(baseValue: $value,bounds: bounds)
}
.rotationEffect(bounds.lowerBound < 0 ? .degrees(90) : .degrees(107))
我已经成功地将旋钮连接到混响值,当旋钮移动时滑块也会移动,但是 changeReverbValue 功能不起作用。
成功来自如下设置旋钮视图中的值:
@Binding var value: AUValue
然后在与滑块相同的主视图结构上引用旋钮:
Knob(value: $recordingsettings.reverbValue,bounds: 0...CGFloat(recordingsettings.reverbMaxValue))
.onTapGesture {
self.recordingsettings.changeReverbValue()
}
点击手势是一种我认为在转动旋钮时它可能会调用更改混响值功能但无济于事的方式。
在旋钮中传递的绑定值还有其他挑战。出于某种原因,当我在没有耳机的情况下播放音频然后转动旋钮时,音频开始断断续续。耳机不会发生这种情况,我觉得这很奇怪。
有谁知道我如何在旋钮中引用混响值并同时调用 changeReverbValue 函数?
我只想用看起来更好的东西替换滑块。否则,我将不得不暂时搁置这一点,而是在整个应用程序中实现滑块。
如果我没有在旋钮视图中将旋钮的值设置为 @binding,则曲目在播放时不会断断续续,但我不知道是否可以在没有 @binding var 的情况下更改混响值.
解决方法
我努力从叙述中解析出一个精确的单一问题陈述,所以这可能只是一个离谱的评论,而不是一个解决方案。我走开时认为您的问题是:自定义 UI 组件在交互过程中“跳跃/断断续续”,并对应用状态产生类似的点状效果。
如果那样的话,我在我的第一个 SwiftUI 应用程序中解决了同样的问题。原因可能有两个:
- 无意中使用了正确的异步队列。
- 针对所有全局状态更改强制更新
@State
或@Published
属性。这意味着您正在将之前的陈旧状态推回到交互中,可能使用循环反馈循环。
解决方案非常简单。请求和使用带有值和源标记的模型更新。限制并过滤自标记,以保持本地状态仅响应一个即时数据流。
我在第一个应用程序(免费,Mac 版 Inclusivity
)中使用了该模式来协调 HSV 色轮和颜色通道自定义滑块组件。滚轮、滑块和其他交互馈送/读取共享的组合管道 (CurrentValueSubject<SourcedColorVector,Never>
.erasedToAny())。
一些示例手势,它们只是将门控工作转移到视图模型中:
HSVWheel 拖动或点击手势
private func touchUpInWheel() -> ExclusiveGesture<_ChangedGesture<DragGesture>,_EndedGesture<DragGesture>> {
ExclusiveGesture(
DragGesture(minimumDistance: 10,coordinateSpace: .named(wheel))
.onChanged { change in
let adjusted = CGPoint(x: change.translation.width - targetDiameter + change.startLocation.x / 2,y: change.translation.height - targetDiameter + change.startLocation.y / 2)
vm.setHueSat(drag: adjusted)
},DragGesture(minimumDistance: 0,coordinateSpace: .named(wheel))
.onEnded { end in
let click = CGPoint(x: end.location.x - vm.radius,y: end.location.y - vm.radius)
vm.setHueSat(click: click)
}
)
}
典型的滑块手势(这是垂直值滑块)
private func tapAndDrag() -> _EndedGesture<_ChangedGesture<DragGesture>> {
DragGesture(minimumDistance: 0,coordinateSpace: .named(valuePickerSpace))
.onChanged { value in
let location = value.location.y - .valueSliderGestureOffset
vm.setValueKnobLocation(raw: location)
}
.onEnded { end in
let location = end.location.y - .valueSliderGestureOffset
vm.setValueKnobLocation(raw: location)
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。