2025/12/16 新改版后隐藏pickerV选中背景
// viewDidLayoutSubviews 中调用, 因为这个view在布局完成后才会被加上去,在创建的时候调用没效果
///移除pickerV的灰色圆角背景 [startHourPicker, startMinutePicker, endHourPicker, endMinutePicker] .forEach { removeSystemSelectionHighlight(from: $0) } private func removeSystemSelectionHighlight(from picker: UIPickerView) { picker.subviews.forEach { subview in // 判断条件:高度小(不是内容层) + 有背景色 if subview.frame.height < 100 && (subview.backgroundColor?.alpha ?? 0) > 0 { subview.backgroundColor = .clear } } }
//隐藏中间两条分割线 if pickerV.subviews.count >= 3{ pickerV.subviews[1].isHidden = true pickerV.subviews[2].isHidden = true } //修改选中行的背景色 for subView in pickerV.subviews { if subView.subviews.count != 0 { let contentViews = subView.subviews[0] for rowView in contentViews.subviews { if rowView.center.y == contentViews.center.y { //背景view rowView.backgroundColor = UIColor.init(hexString: "#F5F5F5") break } } break } }
// 推荐 显示需要 label 。文字大小, 颜色等 func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView { //显示的文字 var showStr = "" switch component { case 0: showStr = "\(self.dataArr[component][row].selectTextStr)年" case 1: showStr = "\(self.dataArr[component][row].selectTextStr)月" case 2: showStr = "\(self.dataArr[component][row].selectTextStr)日" default:break } //修改字体大小, 颜色 let arrStr = NSAttributedString.highLightText(showStr, highLightString: "", normalFont: UIFont.systemFont(ofSize: 16, weight: UIFont.Weight.regular), highLightFont: nil, normalColor: UIColor.init(hexString: "#333333"), highLightColor: nil) //这里宽度随便给的, 高度也是随便给的 不能比row的高度大,能显示出来就行 let showLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 34)) showLabel.textAlignment = .center //重新加载label的文字内容 showLabel.attributedText = arrStr return showLabel } // //改变字体颜色,目前字体大小更改不了,不推荐 // func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? { // // // var str = "" // switch component { // case 0: // str = "\(self.dataArr[component][row].selectTextStr)年" // case 1: // str = "\(self.dataArr[component][row].selectTextStr)月" // case 2: // str = "\(self.dataArr[component][row].selectTextStr)日" // default:break // } // return NSAttributedString.highLightText(str, highLightString: "", normalFont: UIFont.systemFont(ofSize: 16, weight: UIFont.Weight.regular), highLightFont: nil, normalColor: UIColor.init(hexString: "#333333"), highLightColor: nil) // } //每行的高度 func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat { return 34 }
案例:选择器 数据 07:00—21:00
// MARK: - 电话告警时间选择器 数据 07:00—21:00 class AlarmTimeRangePicker: UIViewController { // 回调:确定时返回 (开始时间, 结束时间) var onConfirm: ((_ startTimeStr: String, _ endTimeStr: String) -> ())? // 当前选中值 private var startHour = 7 private var startMinute = 0 private var endHour = 21 private var endMinute = 0 private let hours = Array(0...23) private let minutes = [0, 10, 20, 30, 40, 50] private let rowHeight: CGFloat = 50 // UI private lazy var containerView: UIView = { let v = UIView() v.backgroundColor = .white v.layer.cornerRadius = 16 v.clipsToBounds = true return v }() private lazy var titleLabel: UILabel = { let l = UILabel() l.text = "电话告警时间选择" l.font = .systemFont(ofSize: 18, weight: .medium) l.textAlignment = .center l.textColor = .black return l }() private lazy var startHourPicker = createPicker(tag: 0) private lazy var startMinutePicker = createPicker(tag: 1) private lazy var endHourPicker = createPicker(tag: 2) private lazy var endMinutePicker = createPicker(tag: 3) private lazy var toLabel: UILabel = { let l = UILabel() l.text = "至" l.font = .yd.emTitleRegular l.textColor = R.color.color_242942_FFFFFF() return l }() private lazy var selectionOverlay: UIView = { let v = UIView() v.backgroundColor = UIColor(white: 0.95, alpha: 1) v.layer.cornerRadius = 12 v.isUserInteractionEnabled = false return v }() init(defaultStart: String = "07:00", defaultEnd: String = "21:00", onConfirm: ((String, String) -> Void)? = nil) { self.onConfirm = onConfirm super.init(nibName: nil, bundle: nil) modalPresentationStyle = .overFullScreen modalTransitionStyle = .crossDissolve parseDefaultTime(defaultStart: defaultStart, defaultEnd: defaultEnd) } required init?(coder: NSCoder) { fatalError() } override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = UIColor.black.withAlphaComponent(0.4) setupUI() startHourPicker.selectRow(startHour, inComponent: 0, animated: false) startMinutePicker.selectRow(minutes.firstIndex(of: startMinute) ?? 0, inComponent: 0, animated: false) endHourPicker.selectRow(endHour, inComponent: 0, animated: false) endMinutePicker.selectRow(minutes.firstIndex(of: endMinute) ?? 0, inComponent: 0, animated: false) } ///处理默认时间 private func parseDefaultTime(defaultStart: String = "07:00", defaultEnd: String = "21:00") { let startParts = defaultStart.split(separator: ":").compactMap { Int($0) } let endParts = defaultEnd.split(separator: ":").compactMap { Int($0) } startHour = startParts.count > 0 ? startParts[0] : 7 startMinute = startParts.count > 1 ? (startParts[1] / 10 * 10) : 0 endHour = endParts.count > 0 ? endParts[0] : 21 endMinute = endParts.count > 1 ? (endParts[1] / 10 * 10) : 0 // 保证结束时间不小于开始时间 if endHour < startHour || (endHour == startHour && endMinute < startMinute) { endHour = startHour + 1 endMinute = 0 } } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() containerView.addCorner(conrners: [.topLeft, .topRight], radius: 12) ///移除pickerV的灰色圆角背景 [startHourPicker, startMinutePicker, endHourPicker, endMinutePicker].forEach { removeSystemSelectionHighlight(from: $0) } } ///移除pickerV的灰色圆角背景 private func removeSystemSelectionHighlight(from picker: UIPickerView) { picker.subviews.forEach { subview in if subview.frame.height < 100 && (subview.backgroundColor?.alpha ?? 0) > 0 { subview.backgroundColor = .clear } } } private func createPicker(tag: Int) -> UIPickerView { let p = UIPickerView() p.tag = tag p.delegate = self p.dataSource = self p.backgroundColor = .clear return p } private func setupUI() { view.addSubview(containerView) containerView.snp.makeConstraints { make in make.left.bottom.right.equalToSuperview() } let centerStackV = createCenterPickerStackView() let actionBgV = createActionBgView() [titleLabel, centerStackV, actionBgV] .forEach { containerView.addSubview($0) } titleLabel.snp.makeConstraints { make in make.top.equalTo(24) make.centerX.equalToSuperview() } centerStackV.snp.makeConstraints { make in make.left.right.equalToSuperview().inset(16) make.top.equalTo(titleLabel.snp.bottom) } actionBgV.snp.makeConstraints { make in make.left.right.bottom.equalToSuperview() make.top.equalTo(centerStackV.snp.bottom) } } //中间的 选择器 private func createCenterPickerStackView() -> UIStackView { // 横向排列四个 Picker + “至” let pickerRow = UIStackView() pickerRow.axis = .horizontal pickerRow.spacing = 0 // pickerRow.spacing = 20 pickerRow.alignment = .center // pickerRow.distribution = .equalSpacing pickerRow.distribution = .fill [startHourPicker, startMinutePicker, toLabel, endHourPicker, endMinutePicker] .forEach { pickerRow.addArrangedSubview($0) } // 每个 Picker 宽度 + 高度(上下间距更大) let pickerWidth: CGFloat = 80 let pickerHeight: CGFloat = 230 // 上下间距更大 [startHourPicker, startMinutePicker, endHourPicker, endMinutePicker].forEach { p in p.snp.makeConstraints { make in make.width.equalTo(pickerWidth) make.height.equalTo(pickerHeight) } } // toLabel.snp.makeConstraints { make in // make.width.equalTo(30) // } //选中的高亮背景 pickerRow.addSubview(selectionOverlay) pickerRow.sendSubviewToBack(selectionOverlay) selectionOverlay.snp.makeConstraints { make in make.left.right.centerY.equalToSuperview() make.height.equalTo(rowHeight) } return pickerRow } ///底部操作按钮 private func createActionBgView() -> UIView { let bgV = UIView() let lineV = UIView() lineV.backgroundColor = R.color.text()?.withAlphaComponent(0.05) let cancelBtn = UIButton(type: .system) cancelBtn.setTitle("取消", for: .normal) cancelBtn.titleLabel?.font = .yd.buttonRegular cancelBtn.setTitleColor(R.color.text_sub(), for: .normal) cancelBtn.backgroundColor = .clear cancelBtn.layer.cornerRadius = 12 cancelBtn.layer.borderWidth = 1 cancelBtn.layer.borderColor = R.color.text_sub()?.cgColor cancelBtn.addTarget(self, action: #selector(cancelTapped), for: .touchUpInside) let confirmBtn = UIButton(type: .system) confirmBtn.setTitle("确定", for: .normal) confirmBtn.titleLabel?.font = .systemFont(ofSize: 18, weight: .medium) confirmBtn.setTitleColor(.white, for: .normal) confirmBtn.backgroundColor = .black confirmBtn.layer.cornerRadius = 12 confirmBtn.addTarget(self, action: #selector(confirmTapped), for: .touchUpInside) ///添加渐变色 confirmBtn.yd_setGradientBackground(with: AppTheme.Gradient.black.colors, locations: [0], start: CGPoint(x: 0, y: 0), end: CGPointMake(1, 0)) [lineV, cancelBtn, confirmBtn] .forEach { bgV.addSubview($0) } lineV.snp.makeConstraints { make in make.left.top.right.equalToSuperview() make.height.equalTo(1) } cancelBtn.snp.makeConstraints { make in make.left.equalTo(16) make.top.equalTo(lineV.snp.bottom).offset(16) make.height.equalTo(51) make.bottom.equalTo(-ydBottomBarHeight()-32) } confirmBtn.snp.makeConstraints { make in make.size.centerY.equalTo(cancelBtn) make.left.equalTo(cancelBtn.snp.right).offset(16) make.right.equalTo(-16) } return bgV } @objc private func cancelTapped() { dismiss(animated: true) } @objc private func confirmTapped() { let start = String(format: "%02d:%02d", startHour, startMinute) let end = String(format: "%02d:%02d", endHour, endMinute) onConfirm?(start, end) dismiss(animated: true) } } // MARK: - UIPickerView Delegate & DataSource + 选中行蓝色 + 限制逻辑 extension AlarmTimeRangePicker: UIPickerViewDelegate, UIPickerViewDataSource { func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { switch pickerView.tag { case 0, 2: return hours.count default: return minutes.count } } func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { switch pickerView.tag { case 0, 2: return String(format: "%02d时", hours[row]) default: return String(format: "%02d分", minutes[row]) } } func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { switch pickerView.tag { case 0: startHour = hours[row] case 1: startMinute = minutes[row] case 2: endHour = hours[row] case 3: endMinute = minutes[row] default: break } // 自动限制结束时间不能小于开始时间 if endHour < startHour || (endHour == startHour && endMinute < startMinute) { endHour = startHour endMinute = startMinute endHourPicker.selectRow(endHour, inComponent: 0, animated: true) endMinutePicker.selectRow(minutes.firstIndex(of: endMinute) ?? 0, inComponent: 0, animated: true) } // 刷新所有 Picker [startHourPicker, startMinutePicker, endHourPicker, endMinutePicker].forEach { $0.reloadAllComponents() } } func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView { var label = view as? UILabel if label == nil { label = UILabel() label?.textAlignment = .center label?.font = .systemFont(ofSize: 18, weight: .medium) label?.backgroundColor = .clear } var text: String = "" switch pickerView.tag { case 0, 2: text = String(format: "%02d时", hours[row]) default: text = String(format: "%02d分", minutes[row]) } let isSelected = pickerView.selectedRow(inComponent: component) == row label?.text = text label?.font = isSelected ? .yd.emTitleBold : UIFont.systemFont(ofSize: 17, weight: UIFont.Weight.regular) label?.textColor = R.color.color_242942_FFFFFF() return label! } func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat { return rowHeight } }
无限滚动版本
// MARK: - 电话告警时间选择器 数据 07:00—21:00 class AlarmTimeRangePicker: UIViewController { // 是否开启无限循环滚动(默认开启) var isInfiniteLoop: Bool = true // 循环倍数(仅在开启无限循环时使用) private let loopMultiplier = 1000 // 回调:确定时返回 (开始时间, 结束时间) var onConfirm: ((_ startTimeStr: String, _ endTimeStr: String) -> ())? // 当前选中值 private var startHour = 7 private var startMinute = 0 private var endHour = 21 private var endMinute = 0 private let hours = Array(0...23) private let minutes = [0, 10, 20, 30, 40, 50] private let rowHeight: CGFloat = 50 // UI private lazy var containerView: UIView = { let v = UIView() v.backgroundColor = .white v.layer.cornerRadius = 16 v.clipsToBounds = true return v }() private lazy var titleLabel: UILabel = { let l = UILabel() l.text = "电话告警时间选择" l.font = .systemFont(ofSize: 18, weight: .medium) l.textAlignment = .center l.textColor = .black return l }() private lazy var startHourPicker = createPicker(tag: 0) private lazy var startMinutePicker = createPicker(tag: 1) private lazy var endHourPicker = createPicker(tag: 2) private lazy var endMinutePicker = createPicker(tag: 3) private lazy var toLabel: UILabel = { let l = UILabel() l.text = "至" l.font = .yd.emTitleRegular l.textColor = R.color.color_242942_FFFFFF() return l }() private lazy var selectionOverlay: UIView = { let v = UIView() v.backgroundColor = UIColor(white: 0.95, alpha: 1) v.layer.cornerRadius = 12 v.isUserInteractionEnabled = false return v }() init(defaultStart: String = "07:00", defaultEnd: String = "21:00", isInfiniteLoop: Bool = true, onConfirm: ((String, String) -> Void)? = nil) { self.onConfirm = onConfirm self.isInfiniteLoop = isInfiniteLoop super.init(nibName: nil, bundle: nil) modalPresentationStyle = .overFullScreen modalTransitionStyle = .crossDissolve parseDefaultTime(defaultStart: defaultStart, defaultEnd: defaultEnd) } required init?(coder: NSCoder) { fatalError() } override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = UIColor.black.withAlphaComponent(0.4) setupUI() startHourPicker.selectRow( isInfiniteLoop ? displayedRow(from: startHour, isHour: true) : startHour, inComponent: 0, animated: false) startMinutePicker.selectRow( isInfiniteLoop ? displayedRow(from: startMinute, isHour: false) : (minutes.firstIndex(of: startMinute) ?? 0), inComponent: 0, animated: false) endHourPicker.selectRow( isInfiniteLoop ? displayedRow(from: endHour, isHour: true) : endHour, inComponent: 0, animated: false) endMinutePicker.selectRow( isInfiniteLoop ? displayedRow(from: endMinute, isHour: false) : (minutes.firstIndex(of: endMinute) ?? 0), inComponent: 0, animated: false) } // 计算显示行(仅无限循环时使用) private func displayedRow(from realValue: Int, isHour: Bool) -> Int { let array = isHour ? hours : minutes let index = array.firstIndex(of: realValue) ?? 0 return index + array.count * (loopMultiplier / 2) } // 计算真实行 private func realRow(from displayedRow: Int, totalCount: Int) -> Int { return displayedRow % totalCount } ///处理默认时间 private func parseDefaultTime(defaultStart: String = "07:00", defaultEnd: String = "21:00") { let startParts = defaultStart.split(separator: ":").compactMap { Int($0) } let endParts = defaultEnd.split(separator: ":").compactMap { Int($0) } startHour = startParts.count > 0 ? startParts[0] : 7 startMinute = startParts.count > 1 ? (startParts[1] / 10 * 10) : 0 endHour = endParts.count > 0 ? endParts[0] : 21 endMinute = endParts.count > 1 ? (endParts[1] / 10 * 10) : 0 // 保证结束时间不小于开始时间 if endHour < startHour || (endHour == startHour && endMinute < startMinute) { endHour = startHour + 1 endMinute = 0 } } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() containerView.addCorner(conrners: [.topLeft, .topRight], radius: 12) ///移除pickerV的灰色圆角背景 [startHourPicker, startMinutePicker, endHourPicker, endMinutePicker].forEach { removeSystemSelectionHighlight(from: $0) } } ///移除pickerV的灰色圆角背景 private func removeSystemSelectionHighlight(from picker: UIPickerView) { picker.subviews.forEach { subview in if subview.frame.height < 100 && (subview.backgroundColor?.alpha ?? 0) > 0 { subview.backgroundColor = .clear } } } private func createPicker(tag: Int) -> UIPickerView { let p = UIPickerView() p.tag = tag p.delegate = self p.dataSource = self p.backgroundColor = .clear return p } private func setupUI() { view.addSubview(containerView) containerView.snp.makeConstraints { make in make.left.bottom.right.equalToSuperview() } let centerStackV = createCenterPickerStackView() let actionBgV = createActionBgView() [titleLabel, centerStackV, actionBgV] .forEach { containerView.addSubview($0) } titleLabel.snp.makeConstraints { make in make.top.equalTo(24) make.centerX.equalToSuperview() } centerStackV.snp.makeConstraints { make in make.left.right.equalToSuperview().inset(16) make.top.equalTo(titleLabel.snp.bottom) } actionBgV.snp.makeConstraints { make in make.left.right.bottom.equalToSuperview() make.top.equalTo(centerStackV.snp.bottom) } } //中间的 选择器 private func createCenterPickerStackView() -> UIStackView { // 横向排列四个 Picker + “至” let pickerRow = UIStackView() pickerRow.axis = .horizontal pickerRow.spacing = 0 // pickerRow.spacing = 20 pickerRow.alignment = .center // pickerRow.distribution = .equalSpacing pickerRow.distribution = .fill [startHourPicker, startMinutePicker, toLabel, endHourPicker, endMinutePicker] .forEach { pickerRow.addArrangedSubview($0) } // 每个 Picker 宽度 + 高度(上下间距更大) let pickerWidth: CGFloat = 80 let pickerHeight: CGFloat = 230 // 上下间距更大 [startHourPicker, startMinutePicker, endHourPicker, endMinutePicker].forEach { p in p.snp.makeConstraints { make in make.width.equalTo(pickerWidth) make.height.equalTo(pickerHeight) } } // toLabel.snp.makeConstraints { make in // make.width.equalTo(30) // } //选中的高亮背景 pickerRow.addSubview(selectionOverlay) pickerRow.sendSubviewToBack(selectionOverlay) selectionOverlay.snp.makeConstraints { make in make.left.right.centerY.equalToSuperview() make.height.equalTo(rowHeight) } return pickerRow } ///底部操作按钮 private func createActionBgView() -> UIView { let bgV = UIView() let lineV = UIView() lineV.backgroundColor = R.color.text()?.withAlphaComponent(0.05) let cancelBtn = UIButton(type: .system) cancelBtn.setTitle("取消", for: .normal) cancelBtn.titleLabel?.font = .yd.buttonRegular cancelBtn.setTitleColor(R.color.text_sub(), for: .normal) cancelBtn.backgroundColor = .clear cancelBtn.layer.cornerRadius = 12 cancelBtn.layer.borderWidth = 1 cancelBtn.layer.borderColor = R.color.text_sub()?.cgColor cancelBtn.addTarget(self, action: #selector(cancelTapped), for: .touchUpInside) let confirmBtn = UIButton(type: .system) confirmBtn.setTitle("确定", for: .normal) confirmBtn.titleLabel?.font = .systemFont(ofSize: 18, weight: .medium) confirmBtn.setTitleColor(.white, for: .normal) confirmBtn.backgroundColor = .black confirmBtn.layer.cornerRadius = 12 confirmBtn.addTarget(self, action: #selector(confirmTapped), for: .touchUpInside) ///添加渐变色 confirmBtn.yd_setGradientBackground(with: AppTheme.Gradient.black.colors, locations: [0], start: CGPoint(x: 0, y: 0), end: CGPointMake(1, 0)) [lineV, cancelBtn, confirmBtn] .forEach { bgV.addSubview($0) } lineV.snp.makeConstraints { make in make.left.top.right.equalToSuperview() make.height.equalTo(1) } cancelBtn.snp.makeConstraints { make in make.left.equalTo(16) make.top.equalTo(lineV.snp.bottom).offset(16) make.height.equalTo(51) make.bottom.equalTo(-ydBottomBarHeight()-32) } confirmBtn.snp.makeConstraints { make in make.size.centerY.equalTo(cancelBtn) make.left.equalTo(cancelBtn.snp.right).offset(16) make.right.equalTo(-16) } return bgV } @objc private func cancelTapped() { dismiss(animated: true) } @objc private func confirmTapped() { let start = String(format: "%02d:%02d", startHour, startMinute) let end = String(format: "%02d:%02d", endHour, endMinute) onConfirm?(start, end) dismiss(animated: true) } } // MARK: - UIPickerView Delegate & DataSource + 选中行蓝色 + 限制逻辑 extension AlarmTimeRangePicker: UIPickerViewDelegate, UIPickerViewDataSource { // 判断是否是小时 Picker private func isHourPicker(_ pickerView: UIPickerView) -> Bool { return pickerView.tag == 0 || pickerView.tag == 2 } // 判断是否是分钟 Picker private func isMinutePicker(_ pickerView: UIPickerView) -> Bool { return pickerView.tag == 1 || pickerView.tag == 3 } func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { let baseCount = isHourPicker(pickerView) ? hours.count : minutes.count return isInfiniteLoop ? baseCount * loopMultiplier : baseCount } func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { let baseCount = isHourPicker(pickerView) ? hours.count : minutes.count let realRow = isInfiniteLoop ? realRow(from: row, totalCount: baseCount) : row let value = isHourPicker(pickerView) ? hours[realRow] : minutes[realRow] return isHourPicker(pickerView) ? String(format: "%02d时", value) : String(format: "%02d分", value) } func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { let baseCount = isHourPicker(pickerView) ? hours.count : minutes.count let realRow = isInfiniteLoop ? realRow(from: row, totalCount: baseCount) : row let value = isHourPicker(pickerView) ? hours[realRow] : minutes[realRow] switch pickerView.tag { case 0: startHour = value case 1: startMinute = value case 2: endHour = value case 3: endMinute = value default: break } // 自动限制结束时间不能小于开始时间 if endHour < startHour || (endHour == startHour && endMinute < startMinute) { endHour = startHour endMinute = startMinute let endHourRow = isInfiniteLoop ? displayedRow(from: endHour, isHour: true) : endHour let endMinuteRow = isInfiniteLoop ? displayedRow(from: endMinute, isHour: false) : minutes.firstIndex(of: endMinute) ?? 0 endHourPicker.selectRow(endHourRow, inComponent: 0, animated: true) endMinutePicker.selectRow(endMinuteRow, inComponent: 0, animated: true) } // 刷新所有 Picker [startHourPicker, startMinutePicker, endHourPicker, endMinutePicker].forEach { $0.reloadAllComponents() } } func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView { var label = view as? UILabel if label == nil { label = UILabel() label?.textAlignment = .center label?.font = .systemFont(ofSize: 18, weight: .medium) label?.backgroundColor = .clear } // 1. 计算真实行号(支持无限循环) let isHour = (pickerView.tag == 0 || pickerView.tag == 2) let baseCount = isHour ? hours.count : minutes.count let realRow = isInfiniteLoop ? (row % baseCount) : row // 2. 获取当前值 let value = isHour ? hours[realRow] : minutes[realRow] // 3. 生成显示文字 let text = isHour ? String(format: "%02d时", value) : String(format: "%02d分", value) // 4. 判断是否是当前选中行 let selectedValue: Int switch pickerView.tag { case 0: selectedValue = startHour case 1: selectedValue = startMinute case 2: selectedValue = endHour case 3: selectedValue = endMinute default: selectedValue = 0 } let isSelected = value == selectedValue label?.text = text label?.font = isSelected ? .yd.emTitleBold : UIFont.systemFont(ofSize: 17, weight: UIFont.Weight.regular) label?.textColor = R.color.color_242942_FFFFFF() return label! } func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat { return rowHeight } }
浙公网安备 33010602011771号