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

如何移除UIPickerView中的不透明灰色矩形?附相关实现代码参考

解决方法

要移除UIPickerView默认的灰色选中指示框,只需在makeUIView方法初始化UIPickerView后补充以下代码:

// 隐藏旧版本系统的选中指示框
picker.showsSelectionIndicator = false
// iOS13及以上系统清空选中指示条颜色
if #available(iOS 13.0, *) {
    picker.selectionIndicatorColor = .clear
}

代码优化建议

  • 不要把数据源data定义为全局变量,建议将其作为CustomPicker的内部存储属性,初始化时传入对应数据,提升组件复用性
  • 实现viewForRow代理方法时复用系统提供的回收视图,避免每次滚动都新建视图,提升滚动性能
  • 补充空实现的updateUIView方法逻辑,实现外部绑定selected值变化时,选择器自动滚动到对应选项
  • 行高、行宽、字体样式、颜色等常量建议抽离为可配置属性,避免硬编码,后续调整样式无需修改组件内部逻辑
  • 给文字标签添加自适应字号属性,避免内容过长时显示截断

修改后完整代码

struct CustomPicker: UIViewRepresentable {
    @Binding var selected: String
    // 数据源改为组件内部属性,初始化时传入
    let data: [String]
    // 可配置样式常量,也可新增更多自定义属性
    private let rowWidth: CGFloat = 155
    private let rowHeight: CGFloat = 77
    private let fontSize: CGFloat = 40
    private let textColor = UIColor(red: 0.1215686277, green: 0.01176470611, blue: 0.4235294163, alpha: 1)
    
    func makeCoordinator() -> Coordinator {
        return CustomPicker.Coordinator(parent: self)
    }
    
    func makeUIView(context: Context) -> UIPickerView {
        let picker = UIPickerView()
        // 隐藏选中指示框
        picker.showsSelectionIndicator = false
        if #available(iOS 13.0, *) {
            picker.selectionIndicatorColor = .clear
        }
        picker.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
        picker.dataSource = context.coordinator
        picker.delegate = context.coordinator
        return picker
    }

    func updateUIView(_ uiView: UIPickerView, context: Context) {
        // 外部绑定值变化时自动同步选择器选中状态
        guard let row = data.firstIndex(of: selected) else { return }
        uiView.selectRow(row, inComponent: 0, animated: false)
    }
    
    class Coordinator: NSObject, UIPickerViewDelegate, UIPickerViewDataSource {
        var parent: CustomPicker
        init(parent: CustomPicker) {
            self.parent = parent
        }
        
        func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return 1
        }
        
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            return parent.data.count
        }
        
        func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
            let labelTag = 1001
            let targetView: UIView
            let targetLabel: UILabel
            
            // 复用回收的视图
            if let reusedView = view, let label = reusedView.viewWithTag(labelTag) as? UILabel {
                targetView = reusedView
                targetLabel = label
            } else {
                // 不存在可复用视图时新建
                let newView = UIView(frame: CGRect(x: 0, y: 0, width: parent.rowWidth, height: parent.rowHeight))
                newView.clipsToBounds = true
                newView.layer.cornerRadius = parent.rowHeight / 2
                newView.backgroundColor = .clear
                
                let newLabel = UILabel(frame: newView.bounds)
                newLabel.tag = labelTag
                newLabel.textAlignment = .center
                newLabel.font = .systemFont(ofSize: parent.fontSize, weight: .regular)
                newLabel.textColor = parent.textColor
                newLabel.adjustsFontSizeToFitWidth = true
                newView.addSubview(newLabel)
                
                targetView = newView
                targetLabel = newLabel
            }
            
            targetLabel.text = parent.data[row]
            return targetView
        }
        
        func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
            return parent.rowWidth
        }
        
        func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
            return parent.rowHeight
        }
        
        func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
            parent.selected = parent.data[row]
        }
    }
}

// 使用示例
// struct DemoView: View {
//     @State private var selected = "25"
//     private let data = ["23","24","25","26","27","28","29"]
//     var body: some View {
//         CustomPicker(selected: $selected, data: data)
//             .frame(height: 300)
//     }
// }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 03:39:03