问题描述
以下是示例代码(使用Introspect包):
import SwiftUI
import Introspect
struct ContentView: View {
let tag = 123
let id = "abc"
var body: some View {
ScrollView {
Text("Hello,world!")
.tag(tag)
.accessibility(identifier: id)
}.introspectScrollView { (scrollView) in
/// - Note: find with tag
if scrollView.viewWithTag(tag) != nil {
print("OK")
} else {
print("NOT OK")
}
/// - Note: find with accessibilityIdentifier
if findViewWithID(id,in: scrollView) != nil {
print("OK")
} else {
print("NOT OK")
}
}
}
func findViewWithID(_ id: String,in uiView: UIView) -> UIView? {
if uiView.accessibilityIdentifier == id {
return uiView
}
for view in uiView.subviews {
if let view = findViewWithID(id,in: view) {
return view
}
}
return nil
}
}
为什么tag
或accessibilityIdentifier
无法正确传播到基础视图层次结构?
解决方法
无论如何,解决方法非常简单:
- 由于“标记”视图与UIKit视图(即使将其包装在UIViewRepresentable中)配合得很好,因此这种简单的包装有助于:
struct TagView: UIViewRepresentable {
let tag: Int
func makeUIView(context: Context) -> UIView {
let uiView = UIView()
uiView.tag = tag
return uiView
}
func updateUIView(_ uiView: UIView,context: Context) {
uiView.tag = tag
}
}
- 然后,我们可以直接将其添加到包含已标记UIKit视图的先前包装器的ZStack中,而不是尝试直接标记SwiftUI视图,稍后可以使用
viewWithTag(_:)
在视图层次结构中找到它:
ZStack {
TagView(tag: 123)
Text("Hello,world!")
}