有没有人知道有没有办法实现这个呢?
DatePicker("Jump to", selection: $date, in: dateRange, displayedComponents: [.date])
以下是对@rob mayoff答案的测试。我仍然无法弄清楚为什么它还没有起作用。我在Xcode 14.2上进行了测试,使用iOS 16.2模拟器的iPhone 14,以及在设备上进行了测试。我注意到的是,尽管调用了
triggerDatePickerPopover()
,但它永远无法到达button.accessibilityActivate()
。import SwiftUI
struct ContentView: View {
@State var date: Date = .now
let dateRange: ClosedRange<Date> = Date(timeIntervalSinceNow: -864000) ... Date(timeIntervalSinceNow: 864000)
var pickerId: String { "picker" }
var body: some View {
VStack {
DatePicker(
"Jump to",
selection: $date,
in: dateRange,
displayedComponents: [.date]
)
.accessibilityIdentifier(pickerId)
Button("Clicky") {
triggerDatePickerPopover()
print("Clicky Triggered")
}
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
extension NSObject {
func accessibilityDescendant(passing test: (Any) -> Bool) -> Any? {
if test(self) { return self }
for child in accessibilityElements ?? [] {
if test(child) { return child }
if let child = child as? NSObject, let answer = child.accessibilityDescendant(passing: test) {
return answer
}
}
for subview in (self as? UIView)?.subviews ?? [] {
if test(subview) { return subview }
if let answer = subview.accessibilityDescendant(passing: test) {
return answer
}
}
return nil
}
}
extension NSObject {
func accessibilityDescendant(identifiedAs id: String) -> Any? {
return accessibilityDescendant {
// For reasons unknown, I cannot cast a UIView to a UIAccessibilityIdentification at runtime.
return ($0 as? UIView)?.accessibilityIdentifier == id
|| ($0 as? UIAccessibilityIdentification)?.accessibilityIdentifier == id
}
}
func buttonAccessibilityDescendant() -> Any? {
return accessibilityDescendant { ($0 as? NSObject)?.accessibilityTraits == .button }
}
}
extension ContentView {
func triggerDatePickerPopover() {
if
let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let window = scene.windows.first,
let picker = window.accessibilityDescendant(identifiedAs: pickerId) as? NSObject,
let button = picker.buttonAccessibilityDescendant() as? NSObject
{
print("triggerDatePickerPopover")
button.accessibilityActivate()
}
}
}
更新2:
我按照调试指示进行了跟进。看起来使用完全相同的代码,我的检查器缺少可访问性标识符。不知道为什么...现在感觉很困扰。
这里有一个下载项目的链接 https://www.icloud.com/iclouddrive/040jHC0jwwJg3xgAEvGZShqFg#DatePickerTest
更新3: @rob mayoff的解决方案非常棒!对于任何阅读此文的人。如果在您的情况下没有起作用,请耐心等待。这可能只是由于设备或模拟器正在准备可访问性。