Tại sao điều này lại xảy ra?
Điều này là do khi lượt xem phụ của bạn nằm ngoài giới hạn của lượt xem phụ, các sự kiện chạm thực sự xảy ra trên lượt xem phụ đó sẽ không được chuyển đến lượt xem phụ đó. Tuy nhiên, nó SẼ được chuyển đến superview của nó.
Bất kể lượt xem phụ có được cắt bớt một cách trực quan hay không, các sự kiện chạm luôn tuân theo hình chữ nhật giới hạn của chế độ xem mục tiêu. Nói cách khác, các sự kiện chạm xảy ra trong một phần của chế độ xem nằm bên ngoài hình chữ nhật giới hạn của chế độ xem siêu cao sẽ không được phân phối đến chế độ xem đó. Liên kết
Bạn cần gì để làm?
Khi superview của bạn nhận được sự kiện chạm được đề cập ở trên, bạn sẽ cần phải nói rõ ràng với UIKit rằng subview của tôi phải là người nhận được sự kiện chạm này.
Điều gì về mã?
Trong chế độ giám sát của bạn, hãy triển khai func hitTest(_ point: CGPoint, with event: UIEvent?)
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if isHidden || alpha == 0 || clipsToBounds { return super.hitTest(point, with: event) }
// convert the point into subview's coordinate system
let subviewPoint = self.convert(point, to: subview)
// if the converted point lies in subview's bound, tell UIKit that subview should be the one that receives this event
if !subview.isHidden && subview.bounds.contains(subviewPoint) { return subview }
return super.hitTest(point, with: event)
}
Gotchya hấp dẫn: bạn phải đi đến "siêu chế độ siêu nhỏ cao nhất"
Bạn phải đi "lên" chế độ xem "cao nhất" mà chế độ xem vấn đề nằm bên ngoài.
Ví dụ điển hình:
Giả sử bạn có một màn hình S, với một khung nhìn vùng chứa C. Khung nhìn của bộ điều khiển khung nhìn vùng chứa là V. (Nhớ lại V sẽ nằm bên trong C và có cùng kích thước.) V có một khung nhìn phụ (có thể là một nút) B. B là vấn đề chế độ xem thực sự nằm ngoài V.
Nhưng lưu ý rằng B cũng nằm ngoài C.
Trong ví dụ này, bạn phải áp dụng các giải pháp override hitTest
trên thực tế đến C, chứ không phải để V . Nếu bạn áp dụng nó cho V - nó không có tác dụng gì.