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

VisionOS中Popover内使用ColorPicker报错‘不允许空间呈现’,求解决方案

解决VisionOS Popover中使用ColorPicker触发“Spatial presentations are not permitted”异常的方案

在VisionOS应用的Popover中使用系统ColorPicker时,选择颜色会抛出异常:Spatial presentations are not permitted from popovers,但其他选择器(如数字列表)可正常工作。这是因为系统ColorPicker默认采用空间化展示界面,而Popover容器不允许从内部触发空间展示。

以下是两种可行的解决方案:

方案一:自定义简化颜色选择器

通过创建自定义的颜色选择器,使用预设颜色网格替代系统组件,避免触发空间展示:

struct CustomColorPicker: View {
    @Binding var selectedColor: Color
    // 可根据需求扩展颜色列表
    let colors: [Color] = [.red, .green, .blue, .yellow, .purple, .orange, .pink, .gray]
    
    var body: some View {
        VStack(spacing: 12) {
            Text("选择颜色")
                .font(.headline)
            LazyVGrid(columns: [GridItem(.adaptive(minimum: 50))], spacing: 12) {
                ForEach(colors, id: \.self) { color in
                    Button {
                        selectedColor = color
                    } label: {
                        Circle()
                            .fill(color)
                            .frame(width: 40, height: 40)
                            .overlay(selectedColor == color ? Circle().stroke(.white, lineWidth: 3) : nil)
                    }
                }
            }
        }
        .padding()
    }
}

在ContentView中替换系统ColorPicker:

struct ContentView: View {
    @State var popoverPresented = false
    @State var color: Color = .red
    
    var body: some View {
        VStack {
            Button("Show Popover") {
                popoverPresented = true
            }
            .popover(isPresented: $popoverPresented) {
                CustomColorPicker(selectedColor: $color)
            }
        }
    }
}

方案二:使用UIKit颜色选择器包装视图

如果需要完整的颜色选择功能(包括自定义颜色),可以将UIKit的UIColorPickerViewController包装为SwiftUI视图,它不会触发空间展示:

struct UIKitColorPicker: UIViewControllerRepresentable {
    @Binding var selectedColor: Color
    @Binding var isPresented: Bool
    
    func makeUIViewController(context: Context) -> UIColorPickerViewController {
        let picker = UIColorPickerViewController()
        picker.delegate = context.coordinator
        picker.selectedColor = UIColor(selectedColor)
        return picker
    }
    
    func updateUIViewController(_ uiViewController: UIColorPickerViewController, context: Context) {
        uiViewController.selectedColor = UIColor(selectedColor)
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, UIColorPickerViewControllerDelegate {
        let parent: UIKitColorPicker
        
        init(_ parent: UIKitColorPicker) {
            self.parent = parent
        }
        
        func colorPickerViewControllerDidSelectColor(_ viewController: UIColorPickerViewController) {
            parent.selectedColor = Color(viewController.selectedColor)
        }
        
        func colorPickerViewControllerDidFinish(_ viewController: UIColorPickerViewController) {
            parent.isPresented = false
        }
    }
}

修改ContentView,通过按钮触发该选择器:

struct ContentView: View {
    @State var popoverPresented = false
    @State var colorPickerPresented = false
    @State var color: Color = .red
    
    var body: some View {
        VStack {
            Button("Show Popover") {
                popoverPresented = true
            }
            .popover(isPresented: $popoverPresented) {
                VStack(spacing: 20) {
                    Text("当前颜色")
                        .font(.headline)
                    Circle()
                        .fill(color)
                        .frame(width: 60, height: 60)
                    Button("选择颜色") {
                        colorPickerPresented = true
                    }
                    .buttonStyle(.borderedProminent)
                }
                .padding()
                .sheet(isPresented: $colorPickerPresented) {
                    UIKitColorPicker(selectedColor: $color, isPresented: $colorPickerPresented)
                }
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 10:04:50