SwiftUI 在变量更改时调用函数 [英] SwiftUI call function on variable change

查看:26
本文介绍了SwiftUI 在变量更改时调用函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to convert a view of my watchOS App to Swift UI. I wanted to port the volume control that can be found in watchKit to SwiftUI with custom controls. In the image below you can see the current state of the view.

音量控制根据当前状态改变响铃的进度volume,当我转动数码表冠时volume也会改变.如果没有 SwiftUI,就可以在旋转表冠时调用一个函数.这已经改变了,系统只允许我绑定一个变量.

The volume control changes the progress of the ring according to current state volume and the volume also changes when I turn the Digital Crown. Without SwiftUI it was possible to call a function on the turn of the crown. This has changed and the system only allows me to bind a variable to it.

我想知道的是绑定一个变量并在该变量的每次更改时调用一个函数.因为正常的 Digital Crown 行为不能满足我的需求.

What I want to do know is to bind a variable and call a function on every change of that variable. Because the normal Digital Crown behavior does not fulfill my needs.

有一件事行得通,但远非完美:

One thing that works, but is far from perfect is:

.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 将在每次旋转表冠时调用,但也会在视图的每次其他更新时调用.

OnReceive will be called with every twist of the crown, but it will also be called with every other update to the view.

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

So what I want is a pipeline like this:

Crown 旋转 → crownAccumulator 变化 → 函数调用 async → 函数更新 volume

Crown rotates → crownAccumulator changes → Function called async → Function updates volume

过去我会用 didSet 来做这件事,但现在已经不可用了

In the past I would have done this with a didSet, but this is no longer available

代码如下:


    @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:))


这是当前视图:

Here's the current view:

推荐答案

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

You can use a custom Binding, that calls some code in set. For example from :

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 在变量更改时调用函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆