【发布时间】:2020-04-10 05:53:01
【问题描述】:
我正在尝试将我的 watchOS 应用程序的视图转换为 Swift UI。 我想通过自定义控件将 watchKit 中的音量控件移植到 SwiftUI。在下图中,您可以看到视图的当前状态。
音量控制会根据当前状态volume 改变铃声的进度,当我转动Digital Crown 时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:))
OnReceive 将在每次旋转表冠时调用,但也会在视图的其他所有更新时调用。
所以我想要的是这样的管道:
表冠旋转 → 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:))
【问题讨论】:
-
你是如何解决的 "@State var songTitle: String = "很长的歌名,应该滚动" 我有同样的问题,我的文字不适合