我有一个模式呈现的Sheet
,它应该基于UserDefault
bool 值显示。
我编写了一个 UI 测试,它会关闭该工作表,并使用启动参数来控制默认值。
但是,当我最初尝试使用 @AppStorage
时,它似乎没有保留该值,或者 secret 地没有写入它?我的测试失败了,因为“关闭”后,模式会弹出,因为值未更改。
为了解决这个问题,我编写了一个自定义绑定(bind)。但我不确定这两种实现之间的行为差异是什么?这样测试就通过了。
有人知道我不明白什么吗?抱歉?
干杯!
简单示例
<强>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。自定义绑定(bind):
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)
}
}
最佳答案
即使在运行应用程序时它也不起作用,因为“。”键名称中(看起来这是 AppStorage 的限制,因此请使用简单的符号,例如
isSheet
。IMO 测试用例不正确,因为它通过参数域覆盖默认值,但它是只读的,因此尝试写入持久域,但那里可能有相同的值,所以没有变化( read
didSet
) 事件已生成,因此 UI 中没有更新。要测试这一点,它应该在应用程序内部配对事件,即。一个给出
AppStorage
值 true,另一个给出 false
*注意: bool 值在参数中显示为 0/1(不是 XML),即 -isSheet 1
关于SwiftUI:为什么 @AppStorage 的工作方式与我的自定义绑定(bind)不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72223809/