簡體   English   中英

SwiftUI:為什么@AppStorage 的工作方式與我的自定義綁定不同?

[英]SwiftUI: Why does @AppStorage work differently to my custom binding?

我有一個模態Sheet ,它應該基於UserDefault布爾值顯示。 我編寫了一個 UI-Test 來關閉工作表,並使用啟動參數來控制默認值。

但是,當我最初嘗試使用@AppStorage時,它​​似乎並沒有保留該值,還是偷偷地不寫它? 我的測試失敗了,因為在“關閉”后,模式會因為值不變而重新彈出。

為了解決這個問題,我編寫了一個自定義綁定。 但我不確定這兩種實現之間的行為差​​異是什么? 測試通過這種方式。

有誰知道我不明白什么對不起?

干杯!

簡單示例

1.應用存儲

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)
  }
}
  1. 即使在運行應用程序時它也不起作用,因為那個“。” 在鍵名中(看起來這是 AppStorage 的限制,所以使用簡單的符號,比如isSheet

  2. IMO 測試用例不正確,因為它通過參數域覆蓋默認值,但它是只讀的,因此嘗試寫入持久域,但那里可能有相同的值,因此不會生成更改(讀取didSet )事件,因此 UI 中沒有更新。

  3. 為了測試這一點,它應該在應用程序配對事件,即。 一個給出AppStoragetrue ,另一個給出false

*注意:布爾值在參數中顯示為 0/1(不是 XML),謊言-isSheet 1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM