gpt4 book ai didi

SwiftUI 在变量更改时调用函数

转载 作者:行者123 更新时间:2023-12-03 09:16:23 24 4
gpt4 key购买 nike

我正在尝试将我的 watchOS 应用程序的 View 转换为 Swift UI。
我想通过自定义控件将 watchKit 中的音量控件移植到 SwiftUI。在下图中,您可以看到 View 的当前状态。

音量控制根据当前状态改变铃声的进度volumevolume当我转动数码表冠时也会发生变化。
如果没有 SwiftUI,就可以在转动表冠时调用函数。这已经改变,系统只允许我将一个变量绑定(bind)到它。

我想知道的是绑定(bind)一个变量并在该变量的每次更改时调用一个函数。因为正常的 Digital Crown 行为无法满足我的需求。

有效但远非完美的一件事是:

.digitalCrownRotation($crownAccumulator, from: -100.0, through: 100.0, by: 1, sensitivity: .low, isContinuous: true, isHapticFeedbackEnabled: true)
.onReceive(Just(self.crownAccumulator), perform: self.crownChanged(crownAccumulator:))

OnReceive 将在每次旋转表冠时调用,但也会在 View 的其他所有更新时调用。

所以我想要的是这样的管道:

表冠旋转 → crownAccumulator更改 → 函数调用异步 → 函数更新 volume
在过去,我会使用 didSet 来完成此操作,但这不再可用

这里是它的代码:


@ObservedObject var group: Group
@State var animateSongTitle: Bool = false

@State var songTitle: String = "Very long song title that should be scrolled"
@State var artist: String = "Artist name"


@State var volume: Int = 30
@State var isMuted = false
@State var crownAccumulator: CGFloat = 0.0


var body: some View {

VStack(alignment: .center) {
TitleView(songTitle: $songTitle, artist: $artist)
GroupControlButtons(
skipPreviousAction: skipPrevious,
skipNextAction: skipNext,
playPauseAction: playPause,
group: group)

ZStack {
HStack {
VolumeControl(
volumeLevel: $volume,
isMuted: $isMuted,
muteAction: self.muteButtonPressed)
.frame(minWidth: 40.0, idealWidth: 55, minHeight: 40.0, idealHeight: 55, alignment: .center)
.aspectRatio(1.0, contentMode: .fit)


}
}


}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
.edgesIgnoringSafeArea([.bottom])
.focusable(true)
// .digitalCrownRotation($crownAccumulator)
.digitalCrownRotation($crownAccumulator, from: -100.0, through: 100.0, by: 1, sensitivity: .low, isContinuous: true, isHapticFeedbackEnabled: true)
.onReceive(Just(self.crownAccumulator), perform: self.crownChanged(crownAccumulator:))



这是当前 View :
Current View

最佳答案

您可以使用自定义 Binding ,调用 set 中的一些代码.例如来自:

extension Binding {
/// Execute block when value is changed.
///
/// Example:
///
/// Slider(value: $amount.didSet { print($0) }, in: 0...10)
func didSet(execute: @escaping (Value) ->Void) -> Binding {
return Binding(
get: {
return self.wrappedValue
},
set: {
self.wrappedValue = $0
execute($0)
}
)
}
}

关于SwiftUI 在变量更改时调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59379132/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com