Sn0*_*eze 17 swift watchos swiftui
我正在尝试将 watchOS 应用程序的视图转换为 Swift UI。我想将 watchKit 中的音量控制移植到带有自定义控件的 SwiftUI。在下图中,您可以看到视图的当前状态。
音量控制会根据当前状态更改铃声的进度,volume并且volume在我转动数码表冠时也会更改。如果没有 SwiftUI,就可以在旋转表冠时调用一个函数。这已经改变了,系统只允许我绑定一个变量。
我想知道的是绑定一个变量并在该变量的每次更改时调用一个函数。因为正常的 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:))
Run Code Online (Sandbox Code Playgroud)
OnReceive 将在每次旋转表冠时调用,但也会在视图的每一次其他更新时调用。
所以我想要的是这样的管道:
皇冠旋转?crownAccumulator变化 ?名为 async 的函数?功能更新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:))
Run Code Online (Sandbox Code Playgroud)
Yon*_*nat 14
您可以使用自定义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)
}
)
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所说的“过去我会使用 didSet 来完成此操作,但这不再可用”我测试了下面的代码,它可以完美运行
struct pHome: View {
@State var prog:Int = 2 {
willSet{
print("willSet: newValue =\(newValue) oldValue =\(prog)")
}
didSet{
print("didSet: oldValue=\(oldValue) newValue=\(prog)")
//Write code, function do what ever you want todo
}
}
var body: some View {
VStack{
Button("Update"){
self.prog += 1
}
Text("\(self.prog)%")
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13093 次 |
| 最近记录: |