You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI开发Apple TV应用如何识别Siri Remote滑动并执行操作 Xcode13

tvOS SwiftUI Siri Remote滑动手势正确实现方案(Xcode 13+)

你遇到的崩溃问题大概率是旧hack方案直接强制解包了UIApplication的keyWindow或者响应链上的可选值导致的,Xcode 13对tvOS的手势响应链做了调整,强制解包全局可选值非常容易触发nil崩溃。以下是两种稳定的无崩溃实现方案:


方案1:UIPanGestureRecognizer桥接实现(支持四向滑动、位移、速度检测)

适合需要获取连续滑动参数的场景,完全避免强制解包逻辑:

import SwiftUI
import UIKit

struct SiriRemotePanGesture: UIViewRepresentable {
    var onSwipe: (UISwipeGestureRecognizer.Direction) -> Void
    var onPan: ((CGPoint, CGFloat) -> Void)? = nil // 可选:返回滑动位移、速度
    
    func makeUIView(context: Context) -> UIView {
        let view = UIView(frame: .zero)
        view.backgroundColor = .clear
        
        // 添加上下左右四向滑动手势
        let directions: [UISwipeGestureRecognizer.Direction] = [.up, .down, .left, .right]
        directions.forEach { direction in
            let swipe = UISwipeGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleSwipe(_:)))
            swipe.direction = direction
            // 仅响应Siri Remote的触摸输入,过滤其他设备输入
            swipe.allowedTouchTypes = [NSNumber(value: UITouch.TouchType.indirect.rawValue)]
            view.addGestureRecognizer(swipe)
        }
        
        // 可选:添加拖动手势获取连续滑动数据
        let pan = UIPanGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handlePan(_:)))
        pan.allowedTouchTypes = [NSNumber(value: UITouch.TouchType.indirect.rawValue)]
        view.addGestureRecognizer(pan)
        
        return view
    }
    
    func updateUIView(_ uiView: UIView, context: Context) {
        context.coordinator.onSwipe = onSwipe
        context.coordinator.onPan = onPan
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(onSwipe: onSwipe, onPan: onPan)
    }
    
    class Coordinator: NSObject {
        var onSwipe: (UISwipeGestureRecognizer.Direction) -> Void
        var onPan: ((CGPoint, CGFloat) -> Void)?
        
        init(onSwipe: @escaping (UISwipeGestureRecognizer.Direction) -> Void, onPan: ((CGPoint, CGFloat) -> Void)?) {
            self.onSwipe = onSwipe
            self.onPan = onPan
        }
        
        @objc func handleSwipe(_ gesture: UISwipeGestureRecognizer) {
            onSwipe(gesture.direction)
        }
        
        @objc func handlePan(_ gesture: UIPanGestureRecognizer) {
            guard let view = gesture.view else { return }
            let translation = gesture.translation(in: view)
            let velocity = gesture.velocity(in: view).x
            onPan?(translation, velocity)
        }
    }
}

使用示例:

struct ContentView: View {
    var body: some View {
        Text("Siri Remote 滑动测试")
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .background {
                // 放在背景层不影响原有视图交互
                SiriRemotePanGesture { direction in
                    switch direction {
                    case .up: print("检测到向上滑动")
                    case .down: print("检测到向下滑动")
                    case .left: print("检测到向左滑动")
                    case .right: print("检测到向右滑动")
                    default: break
                    }
                }
            }
            .focusable(true) // 必须开启可聚焦才能接收遥控器输入
    }
}

方案2:SwiftUI原生API实现(轻量需求优先)

如果只需要检测离散的滑动事件,不需要连续位移参数,用原生方法更简单:

struct ContentView: View {
    var body: some View {
        Text("Siri Remote 滑动测试")
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .focusable(true)
            .onMoveCommand { direction in
                switch direction {
                case .up: print("向上滑动/点击上键")
                case .down: print("向下滑动/点击下键")
                case .left: print("向左滑动/点击左键")
                case .right: print("向右滑动/点击右键")
                @unknown default: break
                }
            }
    }
}

注意事项

  • 必须给接收手势的视图添加focusable(true)修饰符,tvOS下只有可聚焦的视图才能接收遥控器输入
  • 不要强制解包任何UIKit层的可选值(比如keyWindow、firstResponder),所有桥接逻辑都封装在UIViewRepresentable内部,避免访问全局可选值导致崩溃
  • allowedTouchTypes设置为indirect可以过滤掉其他触摸输入,只响应Siri Remote的触控板操作

内容的提问来源于stack exchange,提问作者CoderZack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 02:06:03