参考:LYDropListView
感兴趣的老表可以从git上搜下看下这个项目 不过他的是swift3.0 ,最新的xcode已经不支持了。。所以我修改兼容了下。。
进入正文
效果
用的核心三个类 可以把这个目录copy到工程直接使用
新建Group LyDropList
新建
// // TDCommon.swift // Tudou // // Created by discover on 2017/8/9. // Copyright © 2017年 李雨. All rights reserved. // import UIKit //适配参数 let iphone5 = UIScreen.instancesRespond(to:#selector(getter: UIScreen.main.currentMode)) ? __CGSizeEqualToSize(CGSize(width:960,height:1336), (UIScreen.main.currentMode?.size)!) : false let iphone6 = UIScreen.instancesRespond(to:#selector(getter: UIScreen.main.currentMode)) ? __CGSizeEqualToSize(CGSize(width:750,height:1334), (UIScreen.main.currentMode?.size)!) : false let iphone6p = UIScreen.instancesRespond(to:#selector(getter: UIScreen.main.currentMode)) ? __CGSizeEqualToSize(CGSize(width:1242,height:2208), (UIScreen.main.currentMode?.size)!) : false let iphone6pBigMode = UIScreen.instancesRespond(to:#selector(getter: UIScreen.main.currentMode)) ? __CGSizeEqualToSize(CGSize(width:1125,height:2001), (UIScreen.main.currentMode?.size)!) : false let iphoneX = UIScreen.instancesRespond(to:#selector(getter: UIScreen.main.currentMode)) ? __CGSizeEqualToSize(CGSize(width:1125,height:2436), (UIScreen.main.currentMode?.size)!) : false func RGBA (r:CGFloat, g:CGFloat, b:CGFloat, a:CGFloat)->UIColor { return UIColor.init(red: r/255.0, green: g/255.0, blue: b/255.0, alpha: a) } let kNaviHeight:CGFloat = iphoneX ? 88 : 64 let kTabbarHeight:CGFloat = 49 // 屏幕高度 let screenHeight = iphoneX ? UIScreen.main.bounds.height - 34 : UIScreen.main.bounds.height // 屏幕宽度 let screenWidth = UIScreen.main.bounds.width let suitParm:CGFloat = (iphone6p ? 1.12 : (iphone6 ? 1.0 : (iphone6pBigMode ? 1.01 : (iphoneX ? 1.0 : 0.85))))新建
// // LYDropListTItleView.swift // LYDropListView // // Created by discover on 2017/9/28. // Copyright © 2017年 LY. All rights reserved. // import UIKit import SnapKit typealias GesClosure = (_ selected:Bool)->Void class LYDropListTItleView: UIView { var label:UILabel! var icon:UIImageView! var ly_width:CGFloat? var title:String?{ didSet{ self.ly_width = self.getLabWidth(labelStr: self.title!, font: UIFont.systemFont(ofSize: 14), height: 14) + 2 label.text = self.title layout() } } var _isSelect:Bool = false var gesClosure:GesClosure? var isSelected:Bool?{ didSet{ self._isSelect = isSelected! if isSelected! { UIView.animate(withDuration: 0.2, animations: { self.icon.transform = CGAffineTransform.init(rotationAngle: CGFloat(Double.pi)) }) }else{ UIView.animate(withDuration: 0.2, animations: { self.icon.transform = CGAffineTransform.identity }) } } } init(frame: CGRect,title:String) { super.init(frame: frame) self.title = title self.ly_width = self.getLabWidth(labelStr: self.title!, font: UIFont.systemFont(ofSize: 14), height: 14) + 2 setUI() layout() setGes() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } func setGes(){ let ges = UITapGestureRecognizer.init(target: self, action: #selector(tapAction)) self.addGestureRecognizer(ges) } @objc func tapAction(){ self._isSelect = !self._isSelect self.isSelected = self._isSelect if (self.gesClosure != nil){ self.gesClosure!(self.isSelected!) } } func setUI(){ label = UILabel() addSubview(label) label.font = UIFont.systemFont(ofSize: 14) label.text = self.title icon = UIImageView.init() icon.image = UIImage.init(named:"下箭头灰") addSubview(icon) } func layout(){ label.snp.removeConstraints() icon.snp.removeConstraints() label.snp.makeConstraints { (make) in make.centerY.equalTo(self) make.centerX.equalTo(self) make.height.equalTo(14) make.width.equalTo(ly_width!) } icon.snp.makeConstraints { (make) in make.left.equalTo(label.snp.right).offset(2*suitParm) make.centerY.equalTo(label) make.width.equalTo(12) make.height.equalTo(12) } } func getLabWidth(labelStr:String,font:UIFont,height:CGFloat) -> CGFloat { let statusLabelText: NSString = labelStr as NSString let size = CGSize(width:900, height:height) let dic = NSDictionary(object: font, forKey: NSAttributedString.Key.font as NSCopying) let strSize = statusLabelText.boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: dic as! [NSAttributedString.Key : Any], context: nil).size return strSize.width } }新建
// // LYDropListView.swift // LYDropListView // // Created by discover on 2017/9/28. // Copyright © 2017年 LY. All rights reserved. // import UIKit class LYDropListView: UIView,UITableViewDelegate,UITableViewDataSource{ fileprivate var cellid = "cellid" lazy var titleArray = [String]() lazy var tableArray = [[String]]() var maskViewSS:UIView? var selectClosure:((_ tag:Int,_ row:Int)->Void)? init(frame: CGRect,tableArr:[[String]],selectClosure : @escaping (_ tag:Int,_ row:Int)->Void) { super.init(frame: frame) self.titleArray = tableArr.map({ (arr) -> String in return arr[0] }) self.tableArray = tableArr self.selectClosure = selectClosure self.backgroundColor = UIColor.white self.setTitleButton() setMaskView() setTableView() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } func setMaskView(){ maskViewSS = UIView.init(frame: CGRect.init(x: 0, y: 40, width: screenWidth, height: screenHeight-40-kNaviHeight)) maskViewSS?.backgroundColor = RGBA(r: 0, g: 0, b: 0, a: 0.3) let tap = UITapGestureRecognizer.init(target: self, action: #selector(tapAction)) maskViewSS?.alpha = 0 maskViewSS?.addGestureRecognizer(tap) } @objc func tapAction(){ // self.maskViewSS?.removeFromSuperview() for i in 0..<self.tableArray.count{ let tableView = self.viewWithTag(100+i) as! UITableView let drop = self.viewWithTag(1000+i) as! LYDropListTItleView if tableView.frame.height>1{ drop.isSelected = false // UIView.animate(withDuration: 0.2, animations: { // tableView.frame = CGRect.init(x: 0, y: 40, width: screenWidth, height: 1) // }) UIView.animate(withDuration: 0.2, animations: { tableView.frame = CGRect.init(x: 0, y: 40, width: screenWidth, height: 1) self.maskViewSS?.alpha = 0 }, completion: { (idCom) in self.maskViewSS?.removeFromSuperview() }) } } } func setTitleButton(){ let totalArry:Array<Array<String>> = self.tableArray let width:CGFloat = screenWidth/CGFloat(titleArray.count) for i in 0..<self.titleArray.count{ let view = LYDropListTItleView.init(frame: CGRect.init(x: CGFloat(i)*width, y: 0, width: width, height: 40), title: titleArray[i]) view.tag = 1000+i view.gesClosure = { (select)->Void in self.insertSubview(self.maskViewSS!, at: 0) UIView.animate(withDuration: 0.2, animations: { self.maskViewSS?.alpha = 1 }) if select { for n in 0..<self.titleArray.count { let drop = self.viewWithTag(1000+n) as! LYDropListTItleView let tableView = self.viewWithTag(100+n) as! UITableView if i == n { drop.isSelected = true }else{ drop.isSelected = false } let arr = totalArry[n] as [String] tableView.reloadData() if i == n { let animHeight = (CGFloat(arr.count)*40.0 + 20.0) > screenHeight - kNaviHeight - 40 ?screenHeight - kNaviHeight - 40:(CGFloat(arr.count)*40.0) UIView.animate(withDuration: 0.2, animations: { tableView.frame = CGRect.init(x: 0, y: 40, width: screenWidth, height:animHeight ) }) }else{ UIView.animate(withDuration: 0.2, animations: { tableView.frame = CGRect.init(x: 0, y: 40, width: screenWidth, height: 1) }) } } }else{ let tableView = self.viewWithTag(100+i) as! UITableView UIView.animate(withDuration: 0.2, animations: { tableView.frame = CGRect.init(x: 0, y: 40, width: screenWidth, height: 1) self.maskViewSS?.alpha = 0 }, completion: { (idCom) in self.maskViewSS?.removeFromSuperview() }) } } self.addSubview(view) } } func setTableView(){ let totalArry:Array<Array<String>> = self.tableArray for i in 0..<totalArry.count{ let tableView = UITableView.init(frame: CGRect.init(x: 0, y: 40, width: screenWidth, height: 1), style: .plain) tableView.delegate = self tableView.dataSource = self tableView.tag = 100+i tableView.backgroundColor = UIColor.white tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellid) tableView.rowHeight = 40 tableView.isScrollEnabled = false // tableView.separatorStyle = .none self.addSubview(tableView) } } override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { var view = super.hitTest(point, with: event) if view == nil { for subView in self.subviews { let tp = subView.convert(point, from: self) if subView.bounds.contains(tp) { view = subView } } } return view } } extension LYDropListView{ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let drop = self.viewWithTag(tableView.tag-100+1000) as! LYDropListTItleView let cell = tableView.cellForRow(at: indexPath) drop.title = cell?.textLabel?.text if self.selectClosure != nil { self.selectClosure!(tableView.tag,indexPath.row) } drop.isSelected = false // self.maskViewSS?.removeFromSuperview() // UIView.animate(withDuration: 0.2, animations: { // tableView.frame = CGRect.init(x: 0, y: 40, width: screenWidth, height: 1) // }) UIView.animate(withDuration: 0.2, animations: { tableView.frame = CGRect.init(x: 0, y: 40, width: screenWidth, height: 1) self.maskViewSS?.alpha = 0 }, completion: { (idCom) in self.maskViewSS?.removeFromSuperview() }) } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { let drop = self.viewWithTag(tableView.tag-100+1000) as! LYDropListTItleView if drop.isSelected == nil { return 0 }else{ return drop.isSelected! ? self.tableArray[tableView.tag-100].count : 0 } } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: cellid, for: indexPath) as UITableViewCell cell.textLabel?.font = UIFont.systemFont(ofSize: 14) cell.textLabel?.text = tableArray[tableView.tag - 100][indexPath.row] return cell } }使用也很方便
// // ViewController.swift // LYDropListView // // Created by discover on 2017/9/28. // Copyright © 2017年 LY. All rights reserved. // import UIKit class ViewController: UIViewController { let moneyArray:[String] = ["不限金额","0~1000元","1001~2000元","2001~3000元","3001~5000元","5000元以上"] let limitArray:[String] = ["不限期限","0~14天","15~30天","30~60天","60~90天","90~180天","180~360天","360天以上"] let sortArray:[String] = ["默认排序","贷款成功率 ↓","日费率 ↑"] lazy var dropList:LYDropListView = { //传入一个二维数组即可 let drop = LYDropListView.init(frame: CGRect.init(x: 0, y: kNaviHeight, width: screenWidth, height: 40), tableArr: [self.moneyArray,self.limitArray,self.sortArray], selectClosure: { (tag, row) in //tag - 100是第几个标题菜单,row是菜单第几行 print(tag-100,row) }) return drop }() override func viewDidLoad() { super.viewDidLoad() view.addSubview(dropList) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }