Cập nhật: Tôi đã sai. Bạn thực sự có thể sử dụng UIApplication.shared.sendAction(_:to:from:for:)để gọi phản hồi đầu tiên được thể hiện trong liên kết này: http://stackoverflow.com/a/14135456/746890 .
Hầu hết các câu trả lời ở đây thực sự không thể tìm thấy phản hồi đầu tiên hiện tại nếu nó không nằm trong hệ thống phân cấp chế độ xem. Ví dụ, AppDelegatehoặc các UIViewControllerlớp con.
Có một cách để đảm bảo bạn tìm thấy nó ngay cả khi đối tượng phản hồi đầu tiên không phải là a UIView.
Trước tiên, hãy thực hiện phiên bản đảo ngược của nó, sử dụng thuộc nexttính của UIResponder:
extension UIResponder {
var nextFirstResponder: UIResponder? {
return isFirstResponder ? self : next?.nextFirstResponder
}
}
Với thuộc tính được tính toán này, chúng ta có thể tìm thấy phản hồi đầu tiên hiện tại từ dưới lên trên ngay cả khi nó không UIView . Ví dụ: từ a viewđếnUIViewController ai đang quản lý nó, nếu bộ điều khiển xem là trả lời đầu tiên.
Tuy nhiên, chúng ta vẫn cần một độ phân giải từ trên xuống, một var để có được phản hồi đầu tiên hiện tại.
Đầu tiên với hệ thống phân cấp xem:
extension UIView {
var previousFirstResponder: UIResponder? {
return nextFirstResponder ?? subviews.compactMap { $0.previousFirstResponder }.first
}
}
Điều này sẽ tìm kiếm phản hồi đầu tiên ngược và nếu không thể tìm thấy nó, nó sẽ bảo các cuộc phỏng vấn của nó làm điều tương tự (bởi vì cuộc phỏng vấn của nó next nó không nhất thiết phải là chính nó). Với điều này, chúng tôi có thể tìm thấy nó từ bất kỳ xem, bao gồm cả UIWindow.
Và cuối cùng, chúng ta có thể xây dựng điều này:
extension UIResponder {
static var first: UIResponder? {
return UIApplication.shared.windows.compactMap({ $0.previousFirstResponder }).first
}
}
Vì vậy, khi bạn muốn truy xuất phản hồi đầu tiên, bạn có thể gọi:
let firstResponder = UIResponder.first