【纯代码】Swift-自定义PickerView单选(可修改分割线颜色、修改字体大小、修改字体颜色。)(可根据需要自己扩展)
typealias PopPickerViewCallBackClosure = (_ resultStr:NSString?) -> () class PopPickerView : UIView { var dismissCallBack = {} var rowAndComponentCallBack:PopPickerViewCallBackClosure? fileprivate var blockContent : NSString? var titleLabel : UILabel? var divideLine : UIView? var confirmButton : UIButton? var cancelButton : UIButton? var overlayView : UIControl? var keyWindow : UIWindow? override init(frame: CGRect) { super.init(frame: frame) self.backgroundColor = UIColor.white; if (keyWindow == nil) { self.keyWindow = UIApplication.shared.keyWindow } overlayView = UIControl.init(frame: UIScreen.main.bounds) overlayView?.backgroundColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.5) overlayView?.addTarget(self, action: #selector(hide), for: .touchUpInside) overlayView?.alpha = 0 let toolView:UIView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: Int(self.bounds.size.width), height: Int(40))) toolView.backgroundColor = .white addSubview(toolView) cancelButton = UIButton.init(frame: CGRect.init(x: 18, y: 0, width: 40, height: toolView.bounds.size.height)) cancelButton?.setTitle("取消", for: .normal) cancelButton?.setTitleColor(newColor(225, 185, 0), for: .normal) cancelButton?.titleLabel?.font = UIFont.systemFont(ofSize: 14) cancelButton?.contentHorizontalAlignment = .left cancelButton?.addTarget(self, action: #selector(cancelAction), for: .touchUpInside) toolView.addSubview(cancelButton!) confirmButton = UIButton.init(frame: CGRect.init(x: (toolView.bounds.size.width - 30 - 18), y: 0, width: 30, height: toolView.bounds.size.height)) confirmButton?.setTitle("确定", for: .normal) confirmButton?.setTitleColor(newColor(225, 185, 0), for: .normal) confirmButton?.titleLabel?.font = UIFont.systemFont(ofSize: 14) confirmButton?.contentHorizontalAlignment = .left confirmButton?.addTarget(self, action: #selector(confirmAction), for: .touchUpInside) toolView.addSubview(confirmButton!) titleLabel = UILabel.init(frame: CGRect(x: CGFloat(Int(self.bounds.size.width)/2 - 75), y: 0, width: 150, height: toolView.bounds.size.height)) titleLabel?.text = "汽车排量" titleLabel?.textColor = newColor(1, 1, 1) titleLabel?.font = UIFont.systemFont(ofSize: 14) titleLabel?.textAlignment = .center toolView.addSubview(titleLabel!) divideLine = UIView.init(frame: CGRect(x: 0, y: (confirmButton?.superview?.frame.maxY)!, width: toolView.bounds.size.width, height: 1)) divideLine?.backgroundColor = colorWithHexString("0xe5e5e5") toolView.addSubview(divideLine!) } convenience init(frame: CGRect,dataSource:NSArray,title:String) { self.init(frame: frame) titleLabel?.text = title if (dataSource.count != 0) { let picker = PickerViewBuilder.init(frame: CGRect.init(x: 38, y: ((confirmButton?.superview?.frame.maxY)! + 1), width: UIScreen.main.bounds.size.width - CGFloat(76), height: CGFloat(215)),dataSource:dataSource,contentCallBack:{ [weak self] (resultStr) in self?.blockContent = resultStr }) picker.rowAndComponentCallBack = {[weak self](resultStr) in self?.blockContent = resultStr } self.addSubview(picker) }else{ assert(dataSource.count != 0, "dataSource is not allowed to be nil") } } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } func show(){ keyWindow?.addSubview(overlayView!) keyWindow?.addSubview(self) UIView.animate(withDuration: 0.25, animations: { self.overlayView?.alpha = 1.0 var frame = self.frame frame.origin.y = UIScreen.main.bounds.size.height - self.bounds.size.height self.frame = frame }) { (isFinished) in } } @objc func hide() { self.dismissCallBack() UIView.animate(withDuration: 0.25, animations: { self.overlayView?.alpha = 0 var frame = self.frame frame.origin.y = UIScreen.main.bounds.size.height self.frame = frame }) { (isFinished) in self.overlayView?.removeFromSuperview() self.removeFromSuperview() } } @objc func cancelAction() { hide() } @objc func confirmAction() { if blockContent == "" { showAlert(withTitle: "提示", message: "未选择任何一项!") }else{ self.rowAndComponentCallBack!(blockContent) } hide() } @objc private func showAlert(withTitle title: String?, message: String?) { let alertVc = UIAlertController.init(title: title, message: message, preferredStyle: UIAlertController.Style.alert) alertVc.addAction(UIAlertAction.init(title: "我知道了", style: UIAlertAction.Style.cancel, handler: nil)) UIApplication.shared.keyWindow?.rootViewController?.present(alertVc, animated: true, completion: nil) } } class PickerViewBuilder : UIPickerView, UIPickerViewDelegate,UIPickerViewDataSource { fileprivate var rowAndComponentCallBack:PopPickerViewCallBackClosure?//选择内容回调 lazy var currentSelectRow : NSInteger = 0 lazy var dataArr = NSMutableArray() override init(frame: CGRect) { super.init(frame: frame) } convenience init(frame:CGRect,dataSource:NSArray,contentCallBack:PopPickerViewCallBackClosure?) { self.init(frame: frame) self.backgroundColor = UIColor.white self.dataArr = NSMutableArray.init(array: dataSource) self.selectedRow(inComponent: 0) self.delegate = self self.dataSource = self } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return dataArr.count } func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView { //设置分割线 for view in pickerView.subviews { if view.frame.size.height <= 1 { view.isHidden = false view.frame = CGRect(x: 0, y: view.frame.origin.y, width: UIScreen.main.bounds.size.width, height: 1) view.backgroundColor = colorWithHexString("0xe5e5e5") } } var pickerLabel = view as? UILabel if pickerLabel == nil { pickerLabel = UILabel() pickerLabel?.textAlignment = .center if currentSelectRow == row { pickerLabel?.font = UIFont.systemFont(ofSize: 16) pickerLabel?.textColor = newColor(225, 185, 0) }else{ pickerLabel?.font = UIFont.systemFont(ofSize: 12) pickerLabel?.textColor = newColor(153, 153, 153) } } pickerLabel?.text = dataArr[row] as? String return pickerLabel! } func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return dataArr[row] as? String } func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat { return 33 } func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { currentSelectRow = row rowAndComponentCallBack!(dataArr[currentSelectRow] as? NSString) self.reloadAllComponents() } }
使用:
let pickerView = PopPickerView.init(frame: CGRect(x: 0, y: UIScreen.main.bounds.size.height, width: UIScreen.main.bounds.size.width, height: 256), dataSource: selectParams[indexPath.row - 1] as NSArray,title:titleArr[indexPath.row]) pickerView.rowAndComponentCallBack = {(resultStr) in print(resultStr as Any) self.currentSelectCell?.rightSelectLabel.text = resultStr! as String } pickerView.show()
效果图:
仅限于Component内容,想要多行,可自行扩展。
自定义弹窗、可修改分割线颜色、修改字体大小、修改字体颜色。