Swiftui:@AppStorage为什么与我的自定义绑定有所不同?

发布于 2025-01-28 12:12:22 字数 1667 浏览 6 评论 0原文

我有一个模态提出的,该应基于userDefault bool显示。 我写了一个UI检验,该测试驳回了表格,并使用启动参数来控制默认值。

但是,当我尝试使用@AppStorage最初时,它似乎并没有持续过该值,还是秘密地不编写它?我的测试失败了,因为“删除”模态弹出后,由于值没有变化。

为了解决这个问题,我写了一个自定义绑定。但是我不确定这两个实现之间的行为差​​异是什么?测试通过这种方式。

有人知道我不理解的是吗?

干杯!

简单示例

1。 AppStorage

struct ContentView: View {
  @AppStorage("should.show.sheet") private var binding: Bool = true

  var body: some View {
    Text("Content View")
      .sheet(isPresented: $binding) {
        Text("Sheet")
      }
  }
}

2。自定义绑定:

struct ContentView: View {
  var body: some View {
    let binding = Binding<Bool> {
        UserDefaults.standard.bool(forKey: "should.show.sheet")
    } set: {
        UserDefaults.standard.set($0, forKey: "should.show.sheet")
    }
      
    Text("Content View")
      .sheet(isPresented: binding) {
        Text("Sheet")
      }
  }
}

测试案例:

final class SheetUITests: XCTestCase {
  override func setUpWithError() throws {
      continueAfterFailure = false
  }
  
  func testDismiss() {
      // Given 'true' userdefault value to show sheet on launch
      let app = XCUIApplication()
      app.launchArguments += ["-should.show.sheet", "<true/>"]
      app.launch()
      
      // When the user dismisses the modal view
      app.swipeDown()
      
      // Wait a second for animation (make sure it doesn't pop back)
      sleep(1)
      
      // Then the sheet should not be displayed
      XCTAssertFalse(app.staticTexts["Sheet"].exists)
  }
}

I have a modal presented Sheet which should display based on a UserDefault bool.
I wrote a UI-Test which dismisses the sheet and I use launch arguments to control the defaults value.

However, when I tried using @AppStorage initially it didn't seem to persist the value, or was secretly not writing it? My test failed as after 'dismissing' the modal pops back up as the value is unchanged.

To work around this I wrote a custom binding. But i'm not sure what the behaviour difference is between the two implementations? The test passes this way.

Does anyone know what i'm not understanding sorry?

Cheers!

Simple Example

1. AppStorage

struct ContentView: View {
  @AppStorage("should.show.sheet") private var binding: Bool = true

  var body: some View {
    Text("Content View")
      .sheet(isPresented: $binding) {
        Text("Sheet")
      }
  }
}

2. Custom Binding:

struct ContentView: View {
  var body: some View {
    let binding = Binding<Bool> {
        UserDefaults.standard.bool(forKey: "should.show.sheet")
    } set: {
        UserDefaults.standard.set($0, forKey: "should.show.sheet")
    }
      
    Text("Content View")
      .sheet(isPresented: binding) {
        Text("Sheet")
      }
  }
}

Test Case:

final class SheetUITests: XCTestCase {
  override func setUpWithError() throws {
      continueAfterFailure = false
  }
  
  func testDismiss() {
      // Given 'true' userdefault value to show sheet on launch
      let app = XCUIApplication()
      app.launchArguments += ["-should.show.sheet", "<true/>"]
      app.launch()
      
      // When the user dismisses the modal view
      app.swipeDown()
      
      // Wait a second for animation (make sure it doesn't pop back)
      sleep(1)
      
      // Then the sheet should not be displayed
      XCTAssertFalse(app.staticTexts["Sheet"].exists)
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寂寞陪衬 2025-02-04 12:12:22
  1. ,即使在运行应用程序运行时也无法工作,因此,它也是如此。在关键名称中(看起来这是AppStorage限制,因此请使用简单的符号,例如issheet

  2. IMO,测试案例不正确,因为它通过参数域覆盖默认值,但是它是读取的 - 只是,因此尝试写入持续域,但是那里可能存在相同的值,因此没有更改(读取didset)事件,因此UI中没有更新。

  3. 要测试它,应该是配对事件 应用程序,即。一个给出appstorage value true ,另一个给出 false

*注意:布尔值在参数中以0/1(不是xml)的-issheet 1

  1. It does not work even when running app, because of that "." in key name (looks like this is AppStorage limitation, so use simple notation, like isSheet.

  2. IMO the test-case is not correct, because it overrides defaults by arguments domain, but it is read-only, so writing is tried into persistent domain, but there might be same value there, so no change (read didSet) event is generated, so there no update in UI.

  3. To test this it should be paired events inside app, ie. one gives AppStorage value true, other one gives false

*Note: boolean value is presented in arguments as 0/1 (not XML), lie -isSheet 1

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文