纯swift实现ipad版简单美团界面功能
本文实例为大家分享了swift实现ipad版美团界面功能的具体代码,供大家参考,具体内容如下 一 总体功能图一 : (ipad竖屏) 二 总体功能图二 : (ipad横屏) 三 讲解内容 1 搭建美团界面(掌握) 2 ios8.0之后的Popover的运用(重点) 3 协议(掌握) 4 通知(掌握) 5 细节处理 四总体界面 1 由总体的app界面效果,能看出来,一个UIViewController控制器作为UINavigationController的根控制器就能满足条件. 五 导航条设置 1 自定义导航条 : (系统的导航条不能满足需求) 2 创建导航控制器类 3 获取全局的导航条 : (用来作为设置) //获取导航条 let navigationBar = UINavigationBar.appearanceWhenContainedInInstancesOfClasses([self.classForCoder]) 3.1 注意 :一定要用上面的方法来获取,不要用下面的方法来获取,因为通过下面方法获取对导航条的设置,很有可能会造成导航条呈现黑色的情况. UINavigationBar.appearance() 4 用图片包装导航条 //设置导航条的样式 navigationBar.setBackgroundImage(UIImage(named: "bg_navigationBar_normal"),forBarMetrics: .Default) 5 注意不要忘了将导航控制器的类型改为自定义类型,否则会加载不出来的 六 导航条相关内容处理 1 思路 : 通过观察导航条中的按钮,我们可以看出,按钮都是由图片;主标题;子标题组成的,所以我们可以通过xib来描述,并且用一个UIView将按钮包裹住,方便修改设置 2 创建继承UIView的类,同时创建同类名的xib 3 xib图 4 xib内部分布结构图 5 如何在xib中分离图片和标题之间的距离? 5.1 下图解答 6 通过给xib拖线,拿到内部属性 //按钮头像 @IBOutlet weak var iconButton: UIButton! //头部子标题 @IBOutlet weak var subtitleLabel: UILabel! //头部标题 @IBOutlet weak var title_Label: UILabel! 7 给xib中的属性提供set方法和对应的get方法,方便外边调用修改 //对头部标题提供Set方法 var title : String? { didSet{ return title_Label.text = title } } //对头部子标题提供set方法 var subtitle : String? { didSet{ return subtitleLabel.text = subtitle } } //对按钮头像提供set方法(平常的图片) var normalName : String? { didSet{ return iconButton.setImage(UIImage(named: normalName!),forState: .Normal) } } //对按钮头像提供set方法(点击后的图片) var heightName : String? { didSet{ return iconButton.setImage(UIImage(named: heightName!),forState: .Highlighted) } } //对按钮提供一个get方法 var getIconButton : UIButton { get{ return iconButton } } 8 提供一个加载xib的类方法,让外界能通过该方法快速创建xib //MARK: - 给类扩展一个方法(加载xib) extension XFJTopView { //提供一个快速创建xib的类方法 class func topView(title : String,subTitle : String,normalImageName : String,heightImageName : String) ->XFJTopView { let topView = NSBundle.mainBundle().loadNibNamed("XFJTopView",owner: nil,options: nil).last! as! XFJTopView //给属性赋值 topView.title_Label.text = title topView.subtitleLabel.text = subTitle topView.iconButton.setImage(UIImage(named: normalImageName),forState: .Normal) topView.iconButton.setImage(UIImage(named: heightImageName),forState: .Highlighted) //返回通过xib创建的对象 return topView } } 9 添加顶部的按钮 ―-> 9.1 思路 : 通过添加到由导航条管理的item中的数组中来实现对加载xib的时候按钮的添加 ―-> 9.2 导航控制器的根控制器 ―-> 9.3 XFJHomeViewController类对导航条中的item的管理(该部分代码比较多,我们通过类扩展来实现) //MARK: - 设置导航条中的item extension XFJHomeViewController { @objc private func setUpTabBarItem() { //设置值item的图片(0) let logoItem = UIBarButtonItem(image: UIImage(named: "icon_meituan_logo"),style: .Plain,target: nil,action: nil) //对导航条最左边的item赋值 navigationItem.leftBarButtonItem = logoItem //取消导航条左边的item点击 logoItem.enabled = false //设置其他的items(一) let item1 = XFJTopView.topView("美团",subTitle: "全部分类",normalImageName: "icon_category_-1",heightImageName: "icon_category_highlighted_-1") //设置第一个item let topItem = UIBarButtonItem(customView: item1) //对按钮的监听 item1.getIconButton.addTarget(self,action: "presentPopTopViewClick",forControlEvents: .TouchUpInside) //赋值 self.topItem = topItem //设置items(二) let item2 = XFJTopView.topView("广州",subTitle: "全部",normalImageName: "icon_district",heightImageName: "icon_district_highlighted") let gzItem = UIBarButtonItem(customView: item2) item2.getIconButton.addTarget(self,action: "presentPopGzViewClick",forControlEvents: .TouchUpInside) //赋值 self.gzItem = gzItem //设置items(三) let item3 = XFJTopView.topView("排序",subTitle: "默认排序",normalImageName: "icon_sort",heightImageName: "icon_sort_highlighted") let sortItem = UIBarButtonItem(customView: item3) item3.getIconButton.addTarget(self,action: "presentPopSortViewClick",forControlEvents: .TouchUpInside) //赋值 self.sortItem = sortItem //将item添加到数组中 navigationItem.leftBarButtonItems = [logoItem,topItem,gzItem,sortItem] } } 七 Popover的弹出 1 分别创建三个类来管理弹出的Popover 2 对顶部三个item所弹出的控制做懒加载创建,保证用到的时候在创建
//MARK: - 懒加载控制器(一) private lazy var categoryVC : XFJCategoryViewController = { //创建控制器 let categoryVC = XFJCategoryViewController() //设置控制器的样式 categoryVC.modalPresentationStyle = .Popover //返回控制器 return categoryVC }() //MARK: - 懒加载控制器(二) private lazy var districtVC : XFJDistrictViewController = { //创建控制器 let districtVC = XFJDistrictViewController() //设置控制器的样式 districtVC.modalPresentationStyle = .Popover //返回控制器 return districtVC }() //MARK: - 懒加载控制器(三) private lazy var sortsVC : XFJSortsViewController = { //创建控制器 let sortsVC = XFJSortsViewController() //设置控制器的样式 sortsVC.modalPresentationStyle = .Popover //返回控制器 return sortsVC }() 3 根据弹出的Popover类型,我们也可以看出是由两个UITableView组成,并且各占控制器的一半,那么我们这部分也可以通过xib来实现. ―-> 3.1 创建一个类来管理,同时创建xib 3.2 xib内部图 4 弹出Popover(通过在9.3中对item的监听) ―-> 4.1 弹出Popover代码块一 : //MARK : - 实现监听方法 extension XFJHomeViewController { @objc private func presentPopTopViewClick() { //弹出位置 categoryVC.popoverPresentationController?.barButtonItem = topItem //设置背景颜色 categoryVC.popoverPresentationController?.backgroundColor = UIColor.clearColor() //model出控制器 presentViewController(categoryVC,animated: true,completion: nil) //取消UIBarButtonItem的交互 setDisabled() //设置代理 categoryVC.popoverPresentationController?.delegate = self } } ―-> 4.1 弹出Popover代码块二: extension XFJHomeViewController { @objc private func presentPopGzViewClick() { //弹出位置 districtVC.popoverPresentationController?.barButtonItem = gzItem //设置背景颜色 districtVC.popoverPresentationController?.backgroundColor = UIColor.clearColor() // //model出控制器 presentViewController(districtVC,completion: nil) //取消UIBarButtonItem的交互 setDisabled() //设置代理 districtVC.popoverPresentationController?.delegate = self } } ―-> 4.1 弹出Popover代码块三 : extension XFJHomeViewController { @objc private func presentPopSortViewClick() { //弹出控制器的位置 sortsVC.popoverPresentationController?.barButtonItem = sortItem //设置背景颜色 sortsVC.popoverPresentationController?.backgroundColor = UIColor.whiteColor() //model出控制器 presentViewController(sortsVC,completion: nil) //取消UIBarButtonItem的交互 setDisabled() //设置代理 sortsVC.popoverPresentationController?.delegate = self } } 八 处理弹出的Popover相关数据(全部由对应的模型来决定) 1 获取xib中的对象并且提供一个快速创建xib的类方法 //左边的tableView @IBOutlet weak var leftTableView: UITableView! //右边的tableView @IBOutlet weak var rightTableView: UITableView! //模型分类数据 var categories : [XFJCategories]? //地区模块的数据 var DistrictData : [XFJDistrict]? //定义一个属性,用来记录用户点击了左侧的哪一行 var seletIndex : Int? //快速创建xib的类方法 class func lrTableView() ->XFJLRTableView { return NSBundle.mainBundle().loadNibNamed("XFJLRTableView",options: nil).last as! XFJLRTableView } //分类的子数据 private var subData : [String]? 2 通过在xib中设置代理和数据源实现有关数据源方法 ―-> 2.1 数据源方法一 : cell的个数 //MARK: - 数据源方法 extension XFJLRTableView : UITableViewDataSource { //cell的个数 func tableView(tableView: UITableView,numberOfRowsInSection section: Int) -> Int { //判断是左边还是右边 if tableView == leftTableView { //左边 return (delegateSource?.numberOfRowsInLeft(self))! }else{ //右边 return subData?.count ?? 0 } } ―-> 2.2 数据源方法二 : cell的内容
//cell的内容 func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { //创建cell var cell = UITableViewCell?() //判断 if tableView == leftTableView { //创建自定义cell cell = XFJLeftViewCell.leftViewCell(tableView) //设置文字 cell?.textLabel?.text = delegateSource?.lrTableView(titleDataSource: indexPath.row) //设置头像(平常图)--注意 :lrTableViewWithNormalImageInLeft千万要注意大小写 if delegate?.respondsToSelector("lrTableViewWithNormalImageInLeft:") == true { cell?.imageView?.image = UIImage(named: (delegateSource?.lrTableView!(normalImageInLeft: indexPath.row))!) } //设置头像(高亮图)--注意 :lrTableViewWithHighlightImageLeft千万要注意大小写 if delegate?.respondsToSelector("lrTableViewWithHighlightImageLeft:") == true { cell?.imageView?.highlightedImage = UIImage(named: (delegateSource?.lrTableView!(highlightImageLeft: indexPath.row))!) } }else{ cell = XFJRightViewCell.righViewCell(tableView) //设置内容 cell?.textLabel?.text = subData![indexPath.row] } return cell! } ―-> 2.3 数据源方法三 : 点击cell做出的相应数据改变 //MARK: - 点击左边的cell extension XFJLRTableView : UITableViewDelegate { func tableView(tableView: UITableView,didSelectRowAtIndexPath indexPath: NSIndexPath) { //判断是否是左边 if tableView == leftTableView {//左边 //获取子数据 subData = delegateSource?.lrTableView(subDataSource: indexPath.row) //调用协议方法(传入用户点击的哪行) delegate?.lrTableView(seletLeftButton: indexPath.row) //记录用户点击了左侧的哪行 seletIndex = indexPath.row //刷新表格 rightTableView.reloadData() }else{ //右边 //调用协议方法,传入右侧点击了哪行和左侧选中了哪行 delegate?.lrTableView(seletRightButton: indexPath.row,seletLeftButton: seletIndex!) } } } 九 创建模型 1 导入plist文件 2 创建继承NSObject的类,用来设置需要用到的模型属性 -> 2.1 模型属性一 :(分类中所需要的模型属性) var highlighted_icon = String?() var icon = String?() var name = String?() var small_highlighted_icon = String?() var small_icon = String?() var map_icon = String?() var subcategories = [String]?() ―-> 2.2 模型属性二 : (全部模块中所需要的模型属性) var name = String?() var subregions = [String]?() ―-> 2.3 模型属性三 : (排序模块中所需要的模型属性) var label = String?() var value = Int?() 3 在各自管理的类中懒加载模型(采用MJ框架加载模型) ―-> 3.1 分类模块中懒加载模型 //懒加载模型 private lazy var categories : [XFJCategories] = { let categoriesData = XFJCategories.objectArrayWithFilename("categories.plist") as NSArray //返回模型 return categoriesData as! [XFJCategories] }() ―-> 3.2 地区模块中懒加载模型 //懒加载 private lazy var DistrictView :[XFJDistrict] = { let DistrictData = XFJDistrict.objectArrayWithFilename("gz.plist") as NSArray //返回模型数据 return DistrictData as! [XFJDistrict] }() ―-> 3.3 排序模块中懒加载模型 //创建一个属性记录按钮的点击状态 var previousButton = UIButton() //懒加载 private lazy var sortsData : [XFJSorts] = { //模型转化 let sortsDatas = XFJSorts.objectArrayWithFilename("sorts.plist") as NSArray //返回模型 return sortsDatas as! [XFJSorts] }() 十 自定义cell 1 通过功能图知道Popover出来的控制器中cell中既展示图片又展示文字,所以我们通过自定义cell来设置 2 自定义左边的tableViewCell
class XFJLeftViewCell: UITableViewCell { //左边的tableView class func leftViewCell(tableView : UITableView) ->XFJLeftViewCell { //绑定cell类型 let leftCell = "leftCell" var cell = tableView.dequeueReusableCellWithIdentifier(leftCell) //判断cell是否为空 if cell == nil { cell = XFJLeftViewCell(style: .Default,reuseIdentifier: leftCell) } return cell as! XFJLeftViewCell } override init(style: UITableViewCellStyle,reuseIdentifier: String?) { super.init(style: style,reuseIdentifier: reuseIdentifier) //设置背景图片 backgroundView = UIImageView(image: UIImage(named:"bg_dropdown_leftpart")) selectedBackgroundView = UIImageView(image: UIImage(named:"bg_dropdown_left_selected")) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } 2.1 该方法是在数据源方法中调用的,用来加载cell 3 自定义右边的tableViewCell
class XFJRightViewCell: UITableViewCell { //右边的tableView class func righViewCell(tableView : UITableView) ->XFJRightViewCell { //定义cell的标识 let rightCell = "rightCell" //创建cell var cell = tableView.dequeueReusableCellWithIdentifier(rightCell) //判断 if cell == nil { cell = XFJRightViewCell(style: .Default,reuseIdentifier: rightCell) } //返回cell return cell as! XFJRightViewCell } //设置cell的背景图片 override init(style: UITableViewCellStyle,reuseIdentifier: reuseIdentifier) backgroundView = UIImageView(image: UIImage(named: "bg_dropdown_rightpart")) selectedBackgroundView = UIImageView(image: UIImage(named:"bg_dropdown_right_selected")) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } 十一 上半部分总结 1 用上面这些方法确实可以达到用户点击item,弹出对应的控制器.但是上面的代码只是写了对其中一个点击item弹出的业逻辑,还有中间的item并没与处理,如果采用这样的方法处理,那么代码量太多了,并且看起来也显得没什么技术含量,我们最终将不会采用这种方法实现. 十二 代理 协议(最终实现的方案) 1 需要实现的功能 : 通过代理协议的方式,实现用户点击弹出控制器的左边部分,显示出右边部分,并且将对应的头像和主标题,子标题显示到item中 2 定义协议方法 : (包括可实现和可不实现)C> 因为 : 当点击左边的tableView中的cell的时候,有右边有些内容是空的,所以如果都定义为必须实现的,会出现问题 3 定义在XFJLRTableView中的协议方法第一部分 ///MARK : - 定义协议,用协议的方法来控制top中没个按钮的点击,弹出控制器设置相应的内容 @objc protocol XFJTableViewDataSource : NSObjectProtocol { ///左边的cell显示的总行数(需要将左边的tableView作为参数传递进去) func numberOfRowsInLeft (leftTableView : XFJLRTableView) ->Int ///左边的cell显示的数据 func lrTableView(titleDataSource leftRow: Int) ->String? ///左边的cell显示的子数据 func lrTableView(subDataSource leftRow : Int) ->[String] ///左边的cell显示的平常图片(有些是不存在图片的) optional func lrTableView(normalImageInLeft leftRow : Int) ->String ///左边的cell显示的高亮图片(有些是不存在图片的) optional func lrTableView(highlightImageLeft leftRow : Int) ->String } 4 设置代理 :(分类模块代理) ///设置代理(处理弹出的控制器) weak var delegateSource : XFJTableViewDataSource? 5 注意 : 在对协议实现的部分方法中,已经在XFJLRTableView类中的数据源方法这种实现了或者是做出了判断.(上面数据源方法中有介绍) 6 对分类用户点击后实现协议相关的方法 ―-> 6.1 设置对应的控制器为代理 override func viewDidLoad() { super.viewDidLoad() //快速创建xib let lrTableView = XFJLRTableView.lrTableView() //设置尺寸 lrTableView.frame = view.bounds //添加tableView view.addSubview(lrTableView) //设置代理(处理的是弹出控制器的部分) lrTableView.delegateSource = self //设置代理(处理的是用户点击cell的业务逻辑) lrTableView.delegate = self } 7 实现协议方法 ///MARK : - 实现分类的代理方法(处理的是弹出控制器的部分) extension XFJCategoryViewController : XFJTableViewDataSource { ///MARK : - 左侧cell的行数 func numberOfRowsInLeft(leftTableView: XFJLRTableView) -> Int { return categories.count } ///MARK : - 左侧cell的标题 func lrTableView(titleDataSource leftRow: Int) -> String? { //取出模型数据 let categorie = categories[leftRow] return categorie.name } ///MARK : - 左侧cell的子标题 func lrTableView(subDataSource leftRow: Int) -> [String] { //取出模型数据 let categorie = categories[leftRow] //判断 return categorie.subcategories ?? [] } ///MARK : - cell平常图片 func lrTableView(normalImageInLeft leftRow: Int) -> String { //取出模型数据 let categorie = categories[leftRow] return categorie.small_icon! } ///MARK : - cell的高亮图片 func lrTableView(highlightImageLeft leftRow: Int) -> String { //取出模型数据 let categorie = categories[leftRow] return categorie.small_highlighted_icon! } } 8 处理用户点击item中的某行cell,将cell中显示的图片和主标题,子标题显示在item中 ―-> 8.1 定义协议 : ///MARK : - 定义协议,用来传递当用户选择了弹出的控制器中的某行,将cell中显示的内容显示到对应的top按钮中 @objc protocol XFJTableViewDelegate : NSObjectProtocol { //点击了左边,告诉代理选择了左边的哪一行,只要告诉代理不需返回参数 func lrTableView(seletLeftButton leftRow : Int) //点击了右边,高度代理点击了右边的哪一行,同时告诉代理选中了左边的哪一行,不需要返回 func lrTableView(seletRightButton rightRow : Int,seletLeftButton leftRow : Int) } ―-> 8.2 设置代理 : ///设置代理(处理选中弹出的控制器中的哪一行) weak var delegate : XFJTableViewDelegate? ―-> 8.3 实现协议中的方法 ///MARK : - 实现分类的代理方法(处理的是用户点击cell的业务逻辑) extension XFJCategoryViewController : XFJTableViewDelegate { //用户点击了左侧,告诉代理点击了左侧的哪一行 func lrTableView(seletLeftButton leftRow: Int) { //从模型中取出数据 let catrgoryData = categories[leftRow] //判断左侧是否有子数据 let subCatroyData = catrgoryData.subcategories?.count //如果没有子数据,就将数据发送给外界,进行数据更改 if subCatroyData == 0 { //通过通知的方式发送 NSNotificationCenter.defaultCenter().postNotificationName(XFJCategoryNotification,object: nil,userInfo: [XFJCategoryNotificationKey : catrgoryData]) } } //用户点击了右侧,高度代理点击了右侧哪一行,同时告诉代理选中了左侧哪一行 func lrTableView(seletRightButton rightRow: Int,seletLeftButton leftRow: Int) { //从模型中获取数据 let catrgoriesData = categories[leftRow] //取出子数据 let subCatrgoriesData = catrgoriesData.subcategories![rightRow] //发送通知 NSNotificationCenter.defaultCenter().postNotificationName(XFJCategoryNotification,userInfo: [XFJCategoryNotificationKey : catrgoriesData,XFJSubCategoryNotificationKey : subCatrgoriesData]) } } 十三 通知 1 我们是如何将cell中对应的文字和图片显示到item中? ―-> 1.1 我们采用发送通知的方法将相关数据传递到item中 2 创建一个文件用来保存通知需要的参数 //分类 let XFJCategoryNotification = "XFJCategoryNotification" let XFJCategoryNotificationKey = "XFJCategoryNotificationKey" let XFJSubCategoryNotificationKey = "XFJSubCategoryNotificationKey" //地区 let XFJDistrictNotification = "XFJDistrictNotification" let XFJDistrictNotificationKey = "XFJDistrictNotificationKey" let XFJSubDistrictNotificationKey = "XFJSubDistrictNotificationKey" //排序 let XFJSortsNotification = "XFJSortsNotification" let XFJSortsNotificationKey = "XFJSortsNotificationKey" 3 发送通知(分类模块)―-> 通知书写位置: 协议方法中 ―-> 3.1 代码块一 : //用户点击了左侧,userInfo: [XFJCategoryNotificationKey : catrgoryData]) } } ―-> 3.2 代码块二 : //用户点击了右侧,XFJSubCategoryNotificationKey : subCatrgoriesData]) } 4 接收通知 : 虽然发送的通知是匿名通知,但是最好让能将数据提供给谁的一方接收通知,这样也方便设置相关数据 ―-> 4.1 item是属于XFJHomeViewController类的,就让该类来接收通知,并实现通知中的方法 ―-> 4.2 接收通知代码 : //接收分类通知 NSNotificationCenter.defaultCenter().addObserver(self,selector: "categoriesNotic:",name: XFJCategoryNotification,object: nil) //接收地区通知 NSNotificationCenter.defaultCenter().addObserver(self,selector: "districtNotic:",name: XFJDistrictNotification,object: nil) //接收排序通知 NSNotificationCenter.defaultCenter().addObserver(self,selector: "sortsNotic:",name: XFJSortsNotification,object: nil) ―-> 4.3 移除通知 (重要点) //移除通知 deinit { NSNotificationCenter.defaultCenter().removeObserver(self) } 5 实现接收通知中的方法 ―-> 5.2 分类 ///MARK : - 实现接收分类通知的中调用的方法 extension XFJHomeViewController { @objc private func categoriesNotic(nic : NSNotification) { //取出通知中的内容 let catrgoryData = nic.userInfo![XFJCategoryNotificationKey] as! XFJCategories //此处(有可能没有子数据,所以这里不需强转) let subCatroyData = nic.userInfo![XFJSubCategoryNotificationKey] //设置数据(获取顶部的view) let categoryTopView = topItem?.customView as! XFJTopView //子数据 let count = catrgoryData.subcategories?.count //判断 if count == 0 { categoryTopView.title = "美团" categoryTopView.subtitle = catrgoryData.name }else{ categoryTopView.title = catrgoryData.name categoryTopView.subtitle = subCatroyData as! String? } //设置图标 categoryTopView.normalName = catrgoryData.icon categoryTopView.heightName = catrgoryData.highlighted_icon //退出poper categoryVC.dismissViewControllerAnimated(true) { () -> Void in //dismiss后允许交互 self.setEnabled() } } } ―-> 5.2 地区 ///MARK : - 实现接收地区通知的中调用的方法 extension XFJHomeViewController { @objc private func districtNotic(disNic : NSNotification){ //取出通知中的内容 let districtData = disNic.userInfo![XFJDistrictNotificationKey] as! XFJDistrict //此处(有可能没有子数据,所以这里不需强转) let subDistrictData = disNic.userInfo![XFJSubDistrictNotificationKey] //设置数据(获取顶部的view) let districtTopView = gzItem?.customView as! XFJTopView //子数据 let count = districtData.subregions?.count //判断 if count == 0 { districtTopView.title = "美团" districtTopView.subtitle = districtData.name }else{ districtTopView.title = districtData.name districtTopView.subtitle = subDistrictData as! String? } //退出poper districtVC.dismissViewControllerAnimated(true) { () -> Void in //dismiss后允许交互 self.setEnabled() } } } ―-> 5.3 排序 ///MARK : - 实现接收排序通知的中调用的方法 extension XFJHomeViewController { @objc private func sortsNotic(sortsNic :NSNotification){ //获取通知中的内容 let sortsData = sortsNic.userInfo![XFJSortsNotificationKey] as! XFJSorts //获取顶部的view let sortsView = sortItem?.customView as! XFJTopView //设置数据 sortsView.subtitle = sortsData.label //移除poper sortsVC.dismissViewControllerAnimated(true) { () -> Void in //dismiss后允许交互 self.setEnabled() } } } 十四 细节处理 1 我们发现当运行在横屏的时候,没有问题,但是当在运行的之后转换为竖屏,导航条中item间的距离会被拉伸,这怎么解决呢? ―-> 1.1 产生这种现象的原因 : autoresizing导致屏幕旋转的时候,子控件跟随父控件的拉伸而拉伸 ―-> 1.2 解决 :(如下图)―> 将正方形中间的红线去除就可以 2 当点击某个item的时候,发现再点击其他的item的时候,前一个item并没有退出,这样给用户的体验不好.我们通过代码来设置. ―-> 2.1 在监听用户点击的按钮中让所有的item都取消交互调用下面代码 @objc private func setDisabled() { topItem?.enabled = false gzItem?.enabled = false sortItem?.enabled = false } ―-> 2.2 在实现接收通知中调用的方法中,在poper被dismiss的时候,允许用户交互,调用下面代码来允许交互 @objc private func setEnabled() { topItem?.enabled = true gzItem?.enabled = true sortItem?.enabled = true } ―-> 2.3 在实现对item按钮的监听方法中,我们设置poper的代理为当前控制器(这里只说明一段代码,其它模块也是一样的) //设置代理 categoryVC.popoverPresentationController?.delegate = self ―-> 2.4 实现代理方法 ///MARK: - 实现popver代理方法 extension XFJHomeViewController : UIPopoverPresentationControllerDelegate { func popoverPresentationControllerDidDismissPopover(popoverPresentationController: UIPopoverPresentationController) { //允许交互 setEnabled() } } 十五 总结 1 这篇博客我写的可能有点乱,代码太多,我也没办法具体到某一点,只是说了大概,介绍了协议可以实现这种情况的方法,同时对通知的运用也是捎带了,没有怎么细说.希望你们尽量看吧,看不懂的话,在给我私信吧.能帮到大家的,我一定帮忙. 2 最后还是那句话,大家如果觉得我写的博客还写的话,麻烦大家多多关注我的官方博客,谢谢! 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |