您需要创建一个覆盖 canBecomeFocused 的 UIView 子类以返回 true。如果您想响应焦点,您可能还想覆盖 didUpdateFocus(in:with:) 。
作为参考,我制作了一个实用程序类,让我拥有可聚焦的 UIView,并响应远程滑动和点击。
import UIKit
@available (iOS, unavailable)
@available (macCatalyst, unavailable)
class UserInputView: UIView {
weak var pressDelegate: PressableDelegate?
weak var touchDelegate: TouchableDelegate?
var touchStarted: CGFloat = 0
var lastTouch: CGFloat = 0
override init(frame: CGRect) {
super.init(frame: frame)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
touchStarted = touches.first?.location(in: nil).x ?? 0
lastTouch = touchStarted
touchDelegate?.touchDown()
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let thisTouch = touches.first?.location(in: nil).x ?? 0
touchDelegate?.touchMove(amount: Double((thisTouch - lastTouch)/(touches.first?.window?.frame.width ?? 1920)))
lastTouch = touches.first?.location(in: nil).x ?? 0
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
touchDelegate?.touchUp()
}
override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
if isClick(presses) {
pressDelegate?.press(pressed: true)
} else {
superview?.pressesBegan(presses, with: event)
}
}
override func pressesEnded(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
if isClick(presses) {
pressDelegate?.press(pressed: false)
pressDelegate?.clicked()
} else {
superview?.pressesEnded(presses, with: event)
}
}
private func isClick(_ presses: Set<UIPress>?) -> Bool {
return presses?.map({ $0.type }).contains(.select) ?? false
}
override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
pressDelegate?.focus(focused: isFocused)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var canBecomeFocused: Bool {
return true
}
}