swiftui - 如何在 SwiftUI 中使 UIViewRepresentable 可聚焦在

标题说明了一切 - 我无法在 tvOS 上的 SwiftUI 中关注 UIViewRepresentable。任何符合 View 协议(protocol)的 View 都可以毫无问题地聚焦,但 UIViewRepresentableUIViewControllerRepresentable 都不能。

有什么想法吗?

此代码有效:

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
            .focusable()
            .onExitCommand {
                print("Menu button pressed")
        }
    }
}

这个没有:

struct ContentView: View {
    var body: some View {
        ViewRepresentable()
            .focusable()
            .onExitCommand {
                print("Menu button pressed")
        }
    }
}

struct ViewRepresentable: UIViewRepresentable {
    func makeUIView(context: Context) -> UIView {
        let view = UIView()
        view.backgroundColor = .red

        return view
    }

    func updateUIView(_ uiView: UIView, context: Context) {

    }
}

谢谢!

最佳答案

您需要制作一个 UIView 子类来覆盖 canBecomeFocused 以返回 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
    }
}

关于swiftui - 如何在 SwiftUI 中使 UIViewRepresentable 可聚焦在 tvOS 上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61394186/

相关文章:

css - Stylus error : "expected "indent", got "outd

ruby-on-rails - URL 参数被转换为看似乱码的字符

javascript - 排序 mongoose-aggregate-paginate-v2 更改顺

python - 使用(常量)参数保存/加载 Keras 模型

c# - 找不到 Xamarin.Forms 资源文件

domain-driven-design - DDD : How to save the order

r - 如何使用 knitr::kable() 将两个不同大小的表并排顶部对齐

java - 获取对 java LinkedList 中最近添加的节点的引用

vue.js - vue js项目中的动态站点地图生成器

asp.net-mvc - Azure 应用服务授权/简易身份验证与 ASP.NET 表单例份验证冲