【问题标题】:Strange Behavior of Stepper in SwiftUISwiftUI 中 Stepper 的奇怪行为
【发布时间】:2020-03-16 12:28:08
【问题描述】:

我想使用 onIncrement 和 onDecrement 在手动(非绑定)模式下使用 Stepper 视图。当我尝试实现下限和上限时,会有一个奇怪的行为,例如。年龄值不低于 1 或高于 10。

如果你尝试下面的代码,你可以在它已经有值“1”之后按两次“-”。它并没有像预期的那样低于 1,但是在另外两次按下“-”按钮后,“-”按钮突然被禁用。如果您然后按“+”,则不会发生任何事情。仅在再按 2 次“+”后,计数器才会按预期做出反应并变为 2。

这是一个错误吗?

struct StepperTest: View {
    @State private var age = 5

    var body: some View {
        VStack {
            Stepper("Enter your age", onIncrement: {
                if self.age < 10 {
                    self.age += 1
                    print("Adding to age")
                }
            }, onDecrement: {
                guard self.age > 1 else { return }
                self.age -= 1
                print("Subtracting from age")
            })

            Text("Your age is \(age)")
        }
    }
}

【问题讨论】:

  • 你为什么不想为此使用绑定?
  • @MojtabaHosseini:因为我想要完全控制
  • 完全控制什么?您已经可以访问editingChange,并且可以检测到女巫键被触摸。你还需要什么?
  • 主要原因是,我想使用类似 Redux 的架构,其中状态仅由单独模块中的操作更改。使用绑定,可以在各种视图中修改状态。
  • 这就是所谓的单向数据流架构,和这个没有冲突。

标签: swiftui stepper


【解决方案1】:

递增后检查和重置值似乎可行:

Stepper("Enter your age", onIncrement: {
                    self.age += 1
                    if self.age > 10 {self.age = 10}
                }
            }, onDecrement: {
                self.age -= 1
                if self.age < 1 {self.age = 1} 
            })

【讨论】:

    【解决方案2】:

    我认为这里是解释:

    /// 如果尝试递增,onIncrement 将被初始化为 nil
    /// value 将无效。同样,onDecrement 将被初始化
    /// 到nil 如果尝试减少value 将无效。

    如果你尝试

    Stepper("Enter your age", onIncrement: {
        print("Adding to age")
    }, onDecrement: {
        print("Subtracting from age")
    })
    

    ...您会看到步进器进入了与您描述的相同的状态,因此 Apple 跟踪步进器视图的重建,如果用户对步进器的操作没有启动重建(即无效),它会自行禁用。

    另一个问题是为什么不是一次...

    【讨论】:

    • 我不完全了解您将如何使用它。我希望有这两个处理程序 onIncrement 和 onDecrement 以及两个属性来启用/禁用加号和减号按钮...
    • 这是 Apple 的一个问题 )),但这是一个记录在案的行为。
    • 我认为这是一个错误。即使我的onIncrementonDecrement 中没有任何if/else 逻辑,我也会得到同样的怪异行为。它只是停止并使“+”或“-”变灰。然后,如果您点击另一个进入错误的方向。该评论语法错误且难以理解。
    【解决方案3】:

    我看到了同样的事情。在我看来,这绝对是苹果方面的一个错误。作为提到的评论者之一,您可以使用 onEditingChanged 参数。这应该为您提供所需的所有功能。随着绑定变量随步进器输入而变化,您可以采取行动。它看起来像这样:

    Stepper(value: $age, in: 1...10, step: 1, onEditingChanged: { didChange in
            // take some action or make a calculation
    }) 
    {
            Text("Your age is \(age)")
    }
    

    【讨论】:

      【解决方案4】:

      我看到了与在 Xcode 12.5.1 中使用 iOS 14.5 描述的类似行为。我发现了这个描述错误的开放雷达:https://openradar.appspot.com/FB7669491

      在我的例子中,我在初始化Stepper 时直接将视图模型中的函数作为onIncrementonDecrement 参数传递:

      Stepper("Label", onIncrement: viewModel.increment, onDecrement: viewModel.decrement)
      

      基于读取雷达,当前问题是由将函数在视图之外作为这些参数的值传递的。将我的代码更改为此解决了我的问题:

      Stepper("Label", onIncrement: { viewModel.increment }, onDecrement: { viewModel.decrement })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-07
        • 1970-01-01
        • 1970-01-01
        • 2020-11-15
        • 2022-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多