純swift實(shí)現(xiàn)ipad版簡(jiǎn)單美團(tuán)界面功能
本文實(shí)例為大家分享了swift實(shí)現(xiàn)ipad版美團(tuán)界面功能的具體代碼,供大家參考,具體內(nèi)容如下
一 總體功能圖一 : (ipad豎屏)

二 總體功能圖二 : (ipad橫屏)

三 講解內(nèi)容
1 搭建美團(tuán)界面(掌握)
2 ios8.0之后的Popover的運(yùn)用(重點(diǎn))
3 協(xié)議(掌握)
4 通知(掌握)
5 細(xì)節(jié)處理
四總體界面
1 由總體的app界面效果,能看出來,一個(gè)UIViewController控制器作為UINavigationController的根控制器就能滿足條件.
五 導(dǎo)航條設(shè)置
1 自定義導(dǎo)航條 : (系統(tǒng)的導(dǎo)航條不能滿足需求)
2 創(chuàng)建導(dǎo)航控制器類

3 獲取全局的導(dǎo)航條 : (用來作為設(shè)置)
//獲取導(dǎo)航條 let navigationBar = UINavigationBar.appearanceWhenContainedInInstancesOfClasses([self.classForCoder])
3.1 注意 :一定要用上面的方法來獲取,不要用下面的方法來獲取,因?yàn)橥ㄟ^下面方法獲取對(duì)導(dǎo)航條的設(shè)置,很有可能會(huì)造成導(dǎo)航條呈現(xiàn)黑色的情況.
UINavigationBar.appearance()
4 用圖片包裝導(dǎo)航條
//設(shè)置導(dǎo)航條的樣式 navigationBar.setBackgroundImage(UIImage(named: "bg_navigationBar_normal"), forBarMetrics: .Default)
5 注意不要忘了將導(dǎo)航控制器的類型改為自定義類型,否則會(huì)加載不出來的
六 導(dǎo)航條相關(guān)內(nèi)容處理
1 思路 : 通過觀察導(dǎo)航條中的按鈕,我們可以看出, 按鈕都是由圖片;主標(biāo)題;子標(biāo)題組成的,所以我們可以通過xib來描述,并且用一個(gè)UIView將按鈕包裹住,方便修改設(shè)置
2 創(chuàng)建繼承UIView的類,同時(shí)創(chuàng)建同類名的xib

3 xib圖

4 xib內(nèi)部分布結(jié)構(gòu)圖

5 如何在xib中分離圖片和標(biāo)題之間的距離? 5.1 下圖解答

6 通過給xib拖線,拿到內(nèi)部屬性
//按鈕頭像 @IBOutlet weak var iconButton: UIButton! //頭部子標(biāo)題 @IBOutlet weak var subtitleLabel: UILabel! //頭部標(biāo)題 @IBOutlet weak var title_Label: UILabel!
7 給xib中的屬性提供set方法和對(duì)應(yīng)的get方法,方便外邊調(diào)用修改
//對(duì)頭部標(biāo)題提供Set方法
var title : String? {
didSet{
return title_Label.text = title
}
}
//對(duì)頭部子標(biāo)題提供set方法
var subtitle : String? {
didSet{
return subtitleLabel.text = subtitle
}
}
//對(duì)按鈕頭像提供set方法(平常的圖片)
var normalName : String? {
didSet{
return iconButton.setImage(UIImage(named: normalName!), forState: .Normal)
}
}
//對(duì)按鈕頭像提供set方法(點(diǎn)擊后的圖片)
var heightName : String? {
didSet{
return iconButton.setImage(UIImage(named: heightName!), forState: .Highlighted)
}
}
//對(duì)按鈕提供一個(gè)get方法
var getIconButton : UIButton {
get{
return iconButton
}
}
8 提供一個(gè)加載xib的類方法,讓外界能通過該方法快速創(chuàng)建xib
//MARK: - 給類擴(kuò)展一個(gè)方法(加載xib)
extension XFJTopView {
//提供一個(gè)快速創(chuàng)建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創(chuàng)建的對(duì)象
return topView
}
}
9 添加頂部的按鈕
—-> 9.1 思路 : 通過添加到由導(dǎo)航條管理的item中的數(shù)組中來實(shí)現(xiàn)對(duì)加載xib的時(shí)候按鈕的添加
—-> 9.2 導(dǎo)航控制器的根控制器

—-> 9.3 XFJHomeViewController類對(duì)導(dǎo)航條中的item的管理(該部分代碼比較多,我們通過類擴(kuò)展來實(shí)現(xiàn))
//MARK: - 設(shè)置導(dǎo)航條中的item
extension XFJHomeViewController {
@objc private func setUpTabBarItem() {
//設(shè)置值item的圖片(0)
let logoItem = UIBarButtonItem(image: UIImage(named: "icon_meituan_logo"), style: .Plain, target: nil, action: nil)
//對(duì)導(dǎo)航條最左邊的item賦值
navigationItem.leftBarButtonItem = logoItem
//取消導(dǎo)航條左邊的item點(diǎn)擊
logoItem.enabled = false
//設(shè)置其他的items(一)
let item1 = XFJTopView.topView("美團(tuán)", subTitle: "全部分類", normalImageName: "icon_category_-1", heightImageName: "icon_category_highlighted_-1")
//設(shè)置第一個(gè)item
let topItem = UIBarButtonItem(customView: item1)
//對(duì)按鈕的監(jiān)聽
item1.getIconButton.addTarget(self, action: "presentPopTopViewClick", forControlEvents: .TouchUpInside)
//賦值
self.topItem = topItem
//設(shè)置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
//設(shè)置items(三)
let item3 = XFJTopView.topView("排序", subTitle: "默認(rèn)排序", normalImageName: "icon_sort", heightImageName: "icon_sort_highlighted")
let sortItem = UIBarButtonItem(customView: item3)
item3.getIconButton.addTarget(self, action: "presentPopSortViewClick", forControlEvents: .TouchUpInside)
//賦值
self.sortItem = sortItem
//將item添加到數(shù)組中
navigationItem.leftBarButtonItems = [logoItem,topItem,gzItem,sortItem]
}
}
七 Popover的彈出
1 分別創(chuàng)建三個(gè)類來管理彈出的Popover

2 對(duì)頂部三個(gè)item所彈出的控制做懶加載創(chuàng)建,保證用到的時(shí)候在創(chuàng)建
//MARK: - 懶加載控制器(一)
private lazy var categoryVC : XFJCategoryViewController = {
//創(chuàng)建控制器
let categoryVC = XFJCategoryViewController()
//設(shè)置控制器的樣式
categoryVC.modalPresentationStyle = .Popover
//返回控制器
return categoryVC
}()
//MARK: - 懶加載控制器(二)
private lazy var districtVC : XFJDistrictViewController = {
//創(chuàng)建控制器
let districtVC = XFJDistrictViewController()
//設(shè)置控制器的樣式
districtVC.modalPresentationStyle = .Popover
//返回控制器
return districtVC
}()
//MARK: - 懶加載控制器(三)
private lazy var sortsVC : XFJSortsViewController = {
//創(chuàng)建控制器
let sortsVC = XFJSortsViewController()
//設(shè)置控制器的樣式
sortsVC.modalPresentationStyle = .Popover
//返回控制器
return sortsVC
}()
3 根據(jù)彈出的Popover類型,我們也可以看出是由兩個(gè)UITableView組成,并且各占控制器的一半,那么我們這部分也可以通過xib來實(shí)現(xiàn).
—-> 3.1 創(chuàng)建一個(gè)類來管理,同時(shí)創(chuàng)建xib

3.2 xib內(nèi)部圖

4 彈出Popover(通過在9.3中對(duì)item的監(jiān)聽)
—-> 4.1 彈出Popover代碼塊一 :
//MARK : - 實(shí)現(xiàn)監(jiān)聽方法
extension XFJHomeViewController {
@objc private func presentPopTopViewClick() {
//彈出位置
categoryVC.popoverPresentationController?.barButtonItem = topItem
//設(shè)置背景顏色
categoryVC.popoverPresentationController?.backgroundColor = UIColor.clearColor()
//model出控制器
presentViewController(categoryVC, animated: true, completion: nil)
//取消UIBarButtonItem的交互
setDisabled()
//設(shè)置代理
categoryVC.popoverPresentationController?.delegate = self
}
}
—-> 4.1 彈出Popover代碼塊二:
extension XFJHomeViewController {
@objc private func presentPopGzViewClick() {
//彈出位置
districtVC.popoverPresentationController?.barButtonItem = gzItem
//設(shè)置背景顏色
districtVC.popoverPresentationController?.backgroundColor = UIColor.clearColor()
//
//model出控制器
presentViewController(districtVC, animated: true, completion: nil)
//取消UIBarButtonItem的交互
setDisabled()
//設(shè)置代理
districtVC.popoverPresentationController?.delegate = self
}
}
—-> 4.1 彈出Popover代碼塊三 :
extension XFJHomeViewController {
@objc private func presentPopSortViewClick() {
//彈出控制器的位置
sortsVC.popoverPresentationController?.barButtonItem = sortItem
//設(shè)置背景顏色
sortsVC.popoverPresentationController?.backgroundColor = UIColor.whiteColor()
//model出控制器
presentViewController(sortsVC, animated: true, completion: nil)
//取消UIBarButtonItem的交互
setDisabled()
//設(shè)置代理
sortsVC.popoverPresentationController?.delegate = self
}
}
八 處理彈出的Popover相關(guān)數(shù)據(jù)(全部由對(duì)應(yīng)的模型來決定)
1 獲取xib中的對(duì)象并且提供一個(gè)快速創(chuàng)建xib的類方法
//左邊的tableView
@IBOutlet weak var leftTableView: UITableView!
//右邊的tableView
@IBOutlet weak var rightTableView: UITableView!
//模型分類數(shù)據(jù)
var categories : [XFJCategories]?
//地區(qū)模塊的數(shù)據(jù)
var DistrictData : [XFJDistrict]?
//定義一個(gè)屬性,用來記錄用戶點(diǎn)擊了左側(cè)的哪一行
var seletIndex : Int?
//快速創(chuàng)建xib的類方法
class func lrTableView() ->XFJLRTableView {
return NSBundle.mainBundle().loadNibNamed("XFJLRTableView", owner: nil, options: nil).last as! XFJLRTableView
}
//分類的子數(shù)據(jù)
private var subData : [String]?
2 通過在xib中設(shè)置代理和數(shù)據(jù)源實(shí)現(xiàn)有關(guān)數(shù)據(jù)源方法
—-> 2.1 數(shù)據(jù)源方法一 : cell的個(gè)數(shù)
//MARK: - 數(shù)據(jù)源方法
extension XFJLRTableView : UITableViewDataSource {
//cell的個(gè)數(shù)
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//判斷是左邊還是右邊
if tableView == leftTableView { //左邊
return (delegateSource?.numberOfRowsInLeft(self))!
}else{ //右邊
return subData?.count ?? 0
}
}
—-> 2.2 數(shù)據(jù)源方法二 : cell的內(nèi)容
//cell的內(nèi)容
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//創(chuàng)建cell
var cell = UITableViewCell?()
//判斷
if tableView == leftTableView {
//創(chuàng)建自定義cell
cell = XFJLeftViewCell.leftViewCell(tableView)
//設(shè)置文字
cell?.textLabel?.text = delegateSource?.lrTableView(titleDataSource: indexPath.row)
//設(shè)置頭像(平常圖)--注意 :lrTableViewWithNormalImageInLeft千萬要注意大小寫
if delegate?.respondsToSelector("lrTableViewWithNormalImageInLeft:") == true {
cell?.imageView?.image = UIImage(named: (delegateSource?.lrTableView!(normalImageInLeft: indexPath.row))!)
}
//設(shè)置頭像(高亮圖)--注意 :lrTableViewWithHighlightImageLeft千萬要注意大小寫
if delegate?.respondsToSelector("lrTableViewWithHighlightImageLeft:") == true {
cell?.imageView?.highlightedImage = UIImage(named: (delegateSource?.lrTableView!(highlightImageLeft: indexPath.row))!)
}
}else{
cell = XFJRightViewCell.righViewCell(tableView)
//設(shè)置內(nèi)容
cell?.textLabel?.text = subData![indexPath.row]
}
return cell!
}
—-> 2.3 數(shù)據(jù)源方法三 : 點(diǎn)擊cell做出的相應(yīng)數(shù)據(jù)改變
//MARK: - 點(diǎn)擊左邊的cell
extension XFJLRTableView : UITableViewDelegate {
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//判斷是否是左邊
if tableView == leftTableView {//左邊
//獲取子數(shù)據(jù)
subData = delegateSource?.lrTableView(subDataSource: indexPath.row)
//調(diào)用協(xié)議方法(傳入用戶點(diǎn)擊的哪行)
delegate?.lrTableView(seletLeftButton: indexPath.row)
//記錄用戶點(diǎn)擊了左側(cè)的哪行
seletIndex = indexPath.row
//刷新表格
rightTableView.reloadData()
}else{ //右邊
//調(diào)用協(xié)議方法,傳入右側(cè)點(diǎn)擊了哪行和左側(cè)選中了哪行
delegate?.lrTableView(seletRightButton: indexPath.row, seletLeftButton: seletIndex!)
}
}
}
九 創(chuàng)建模型
1 導(dǎo)入plist文件
2 創(chuàng)建繼承NSObject的類,用來設(shè)置需要用到的模型屬性

-> 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 地區(qū)模塊中懶加載模型
//懶加載
private lazy var DistrictView :[XFJDistrict] = {
let DistrictData = XFJDistrict.objectArrayWithFilename("gz.plist") as NSArray
//返回模型數(shù)據(jù)
return DistrictData as! [XFJDistrict]
}()
—-> 3.3 排序模塊中懶加載模型
//創(chuàng)建一個(gè)屬性記錄按鈕的點(diǎn)擊狀態(tài)
var previousButton = UIButton()
//懶加載
private lazy var sortsData : [XFJSorts] = {
//模型轉(zhuǎn)化
let sortsDatas = XFJSorts.objectArrayWithFilename("sorts.plist") as NSArray
//返回模型
return sortsDatas as! [XFJSorts]
}()
十 自定義cell
1 通過功能圖知道Popover出來的控制器中cell中既展示圖片又展示文字,所以我們通過自定義cell來設(shè)置 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)
//設(shè)置背景圖片
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 該方法是在數(shù)據(jù)源方法中調(diào)用的,用來加載cell
3 自定義右邊的tableViewCell
class XFJRightViewCell: UITableViewCell {
//右邊的tableView
class func righViewCell(tableView : UITableView) ->XFJRightViewCell {
//定義cell的標(biāo)識(shí)
let rightCell = "rightCell"
//創(chuàng)建cell
var cell = tableView.dequeueReusableCellWithIdentifier(rightCell)
//判斷
if cell == nil {
cell = XFJRightViewCell(style: .Default, reuseIdentifier: rightCell)
}
//返回cell
return cell as! XFJRightViewCell
}
//設(shè)置cell的背景圖片
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, 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")
}
}
十一 上半部分總結(jié)
1 用上面這些方法確實(shí)可以達(dá)到用戶點(diǎn)擊item,彈出對(duì)應(yīng)的控制器.但是上面的代碼只是寫了對(duì)其中一個(gè)點(diǎn)擊item彈出的業(yè)邏輯,還有中間的item并沒與處理,如果采用這樣的方法處理,那么代碼量太多了,并且看起來也顯得沒什么技術(shù)含量,我們最終將不會(huì)采用這種方法實(shí)現(xiàn).
十二 代理 協(xié)議(最終實(shí)現(xiàn)的方案)
1 需要實(shí)現(xiàn)的功能 : 通過代理協(xié)議的方式,實(shí)現(xiàn)用戶點(diǎn)擊彈出控制器的左邊部分,顯示出右邊部分,并且將對(duì)應(yīng)的頭像和主標(biāo)題,子標(biāo)題顯示到item中
2 定義協(xié)議方法 : (包括可實(shí)現(xiàn)和可不實(shí)現(xiàn))–> 因?yàn)?: 當(dāng)點(diǎn)擊左邊的tableView中的cell的時(shí)候,有右邊有些內(nèi)容是空的,所以如果都定義為必須實(shí)現(xiàn)的,會(huì)出現(xiàn)問題
3 定義在XFJLRTableView中的協(xié)議方法第一部分
///MARK : - 定義協(xié)議,用協(xié)議的方法來控制top中沒個(gè)按鈕的點(diǎn)擊,彈出控制器設(shè)置相應(yīng)的內(nèi)容
@objc protocol XFJTableViewDataSource : NSObjectProtocol {
///左邊的cell顯示的總行數(shù)(需要將左邊的tableView作為參數(shù)傳遞進(jìn)去)
func numberOfRowsInLeft (leftTableView : XFJLRTableView) ->Int
///左邊的cell顯示的數(shù)據(jù)
func lrTableView(titleDataSource leftRow: Int) ->String?
///左邊的cell顯示的子數(shù)據(jù)
func lrTableView(subDataSource leftRow : Int) ->[String]
///左邊的cell顯示的平常圖片(有些是不存在圖片的)
optional func lrTableView(normalImageInLeft leftRow : Int) ->String
///左邊的cell顯示的高亮圖片(有些是不存在圖片的)
optional func lrTableView(highlightImageLeft leftRow : Int) ->String
}
4 設(shè)置代理 :(分類模塊代理)
///設(shè)置代理(處理彈出的控制器) weak var delegateSource : XFJTableViewDataSource?
5 注意 : 在對(duì)協(xié)議實(shí)現(xiàn)的部分方法中,已經(jīng)在XFJLRTableView類中的數(shù)據(jù)源方法這種實(shí)現(xiàn)了或者是做出了判斷.(上面數(shù)據(jù)源方法中有介紹)
6 對(duì)分類用戶點(diǎn)擊后實(shí)現(xiàn)協(xié)議相關(guān)的方法
—-> 6.1 設(shè)置對(duì)應(yīng)的控制器為代理
override func viewDidLoad() {
super.viewDidLoad()
//快速創(chuàng)建xib
let lrTableView = XFJLRTableView.lrTableView()
//設(shè)置尺寸
lrTableView.frame = view.bounds
//添加tableView
view.addSubview(lrTableView)
//設(shè)置代理(處理的是彈出控制器的部分)
lrTableView.delegateSource = self
//設(shè)置代理(處理的是用戶點(diǎn)擊cell的業(yè)務(wù)邏輯)
lrTableView.delegate = self
}
7 實(shí)現(xiàn)協(xié)議方法
///MARK : - 實(shí)現(xiàn)分類的代理方法(處理的是彈出控制器的部分)
extension XFJCategoryViewController : XFJTableViewDataSource {
///MARK : - 左側(cè)cell的行數(shù)
func numberOfRowsInLeft(leftTableView: XFJLRTableView) -> Int {
return categories.count
}
///MARK : - 左側(cè)cell的標(biāo)題
func lrTableView(titleDataSource leftRow: Int) -> String? {
//取出模型數(shù)據(jù)
let categorie = categories[leftRow]
return categorie.name
}
///MARK : - 左側(cè)cell的子標(biāo)題
func lrTableView(subDataSource leftRow: Int) -> [String] {
//取出模型數(shù)據(jù)
let categorie = categories[leftRow]
//判斷
return categorie.subcategories ?? []
}
///MARK : - cell平常圖片
func lrTableView(normalImageInLeft leftRow: Int) -> String {
//取出模型數(shù)據(jù)
let categorie = categories[leftRow]
return categorie.small_icon!
}
///MARK : - cell的高亮圖片
func lrTableView(highlightImageLeft leftRow: Int) -> String {
//取出模型數(shù)據(jù)
let categorie = categories[leftRow]
return categorie.small_highlighted_icon!
}
}
8 處理用戶點(diǎn)擊item中的某行cell,將cell中顯示的圖片和主標(biāo)題,子標(biāo)題顯示在item中
—-> 8.1 定義協(xié)議 :
///MARK : - 定義協(xié)議,用來傳遞當(dāng)用戶選擇了彈出的控制器中的某行,將cell中顯示的內(nèi)容顯示到對(duì)應(yīng)的top按鈕中
@objc protocol XFJTableViewDelegate : NSObjectProtocol {
//點(diǎn)擊了左邊,告訴代理選擇了左邊的哪一行,只要告訴代理不需返回參數(shù)
func lrTableView(seletLeftButton leftRow : Int)
//點(diǎn)擊了右邊,高度代理點(diǎn)擊了右邊的哪一行,同時(shí)告訴代理選中了左邊的哪一行,不需要返回
func lrTableView(seletRightButton rightRow : Int,seletLeftButton leftRow : Int)
}
—-> 8.2 設(shè)置代理 :
///設(shè)置代理(處理選中彈出的控制器中的哪一行) weak var delegate : XFJTableViewDelegate?
—-> 8.3 實(shí)現(xiàn)協(xié)議中的方法
///MARK : - 實(shí)現(xiàn)分類的代理方法(處理的是用戶點(diǎn)擊cell的業(yè)務(wù)邏輯)
extension XFJCategoryViewController : XFJTableViewDelegate {
//用戶點(diǎn)擊了左側(cè),告訴代理點(diǎn)擊了左側(cè)的哪一行
func lrTableView(seletLeftButton leftRow: Int) {
//從模型中取出數(shù)據(jù)
let catrgoryData = categories[leftRow]
//判斷左側(cè)是否有子數(shù)據(jù)
let subCatroyData = catrgoryData.subcategories?.count
//如果沒有子數(shù)據(jù),就將數(shù)據(jù)發(fā)送給外界,進(jìn)行數(shù)據(jù)更改
if subCatroyData == 0 {
//通過通知的方式發(fā)送
NSNotificationCenter.defaultCenter().postNotificationName(XFJCategoryNotification, object: nil, userInfo: [XFJCategoryNotificationKey : catrgoryData])
}
}
//用戶點(diǎn)擊了右側(cè),高度代理點(diǎn)擊了右側(cè)哪一行,同時(shí)告訴代理選中了左側(cè)哪一行
func lrTableView(seletRightButton rightRow: Int, seletLeftButton leftRow: Int) {
//從模型中獲取數(shù)據(jù)
let catrgoriesData = categories[leftRow]
//取出子數(shù)據(jù)
let subCatrgoriesData = catrgoriesData.subcategories![rightRow]
//發(fā)送通知
NSNotificationCenter.defaultCenter().postNotificationName(XFJCategoryNotification, object: nil, userInfo: [XFJCategoryNotificationKey : catrgoriesData, XFJSubCategoryNotificationKey : subCatrgoriesData])
}
}
十三 通知
1 我們是如何將cell中對(duì)應(yīng)的文字和圖片顯示到item中?
—-> 1.1 我們采用發(fā)送通知的方法將相關(guān)數(shù)據(jù)傳遞到item中
2 創(chuàng)建一個(gè)文件用來保存通知需要的參數(shù)

//分類 let XFJCategoryNotification = "XFJCategoryNotification" let XFJCategoryNotificationKey = "XFJCategoryNotificationKey" let XFJSubCategoryNotificationKey = "XFJSubCategoryNotificationKey" //地區(qū) let XFJDistrictNotification = "XFJDistrictNotification" let XFJDistrictNotificationKey = "XFJDistrictNotificationKey" let XFJSubDistrictNotificationKey = "XFJSubDistrictNotificationKey" //排序 let XFJSortsNotification = "XFJSortsNotification" let XFJSortsNotificationKey = "XFJSortsNotificationKey"
3 發(fā)送通知(分類模塊)—-> 通知書寫位置: 協(xié)議方法中
—-> 3.1 代碼塊一 :
//用戶點(diǎn)擊了左側(cè),告訴代理點(diǎn)擊了左側(cè)的哪一行
func lrTableView(seletLeftButton leftRow: Int) {
//從模型中取出數(shù)據(jù)
let catrgoryData = categories[leftRow]
//判斷左側(cè)是否有子數(shù)據(jù)
let subCatroyData = catrgoryData.subcategories?.count
//如果沒有子數(shù)據(jù),就將數(shù)據(jù)發(fā)送給外界,進(jìn)行數(shù)據(jù)更改
if subCatroyData == 0 {
//通過通知的方式發(fā)送
NSNotificationCenter.defaultCenter().postNotificationName(XFJCategoryNotification, object: nil, userInfo: [XFJCategoryNotificationKey : catrgoryData])
}
}
—-> 3.2 代碼塊二 :
//用戶點(diǎn)擊了右側(cè),高度代理點(diǎn)擊了右側(cè)哪一行,同時(shí)告訴代理選中了左側(cè)哪一行
func lrTableView(seletRightButton rightRow: Int, seletLeftButton leftRow: Int) {
//從模型中獲取數(shù)據(jù)
let catrgoriesData = categories[leftRow]
//取出子數(shù)據(jù)
let subCatrgoriesData = catrgoriesData.subcategories![rightRow]
//發(fā)送通知
NSNotificationCenter.defaultCenter().postNotificationName(XFJCategoryNotification, object: nil, userInfo: [XFJCategoryNotificationKey : catrgoriesData, XFJSubCategoryNotificationKey : subCatrgoriesData])
}
4 接收通知 : 雖然發(fā)送的通知是匿名通知,但是最好讓能將數(shù)據(jù)提供給誰的一方接收通知,這樣也方便設(shè)置相關(guān)數(shù)據(jù)
—-> 4.1 item是屬于XFJHomeViewController類的,就讓該類來接收通知,并實(shí)現(xiàn)通知中的方法
—-> 4.2 接收通知代碼 :
//接收分類通知
NSNotificationCenter.defaultCenter().addObserver(self, selector: "categoriesNotic:", name: XFJCategoryNotification, object: nil)
//接收地區(qū)通知
NSNotificationCenter.defaultCenter().addObserver(self, selector: "districtNotic:", name: XFJDistrictNotification, object: nil)
//接收排序通知
NSNotificationCenter.defaultCenter().addObserver(self, selector: "sortsNotic:", name: XFJSortsNotification, object: nil)
—-> 4.3 移除通知 (重要點(diǎn))
//移除通知
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
5 實(shí)現(xiàn)接收通知中的方法
—-> 5.2 分類
///MARK : - 實(shí)現(xiàn)接收分類通知的中調(diào)用的方法
extension XFJHomeViewController {
@objc private func categoriesNotic(nic : NSNotification) {
//取出通知中的內(nèi)容
let catrgoryData = nic.userInfo![XFJCategoryNotificationKey] as! XFJCategories
//此處(有可能沒有子數(shù)據(jù),所以這里不需強(qiáng)轉(zhuǎn))
let subCatroyData = nic.userInfo![XFJSubCategoryNotificationKey]
//設(shè)置數(shù)據(jù)(獲取頂部的view)
let categoryTopView = topItem?.customView as! XFJTopView
//子數(shù)據(jù)
let count = catrgoryData.subcategories?.count
//判斷
if count == 0 {
categoryTopView.title = "美團(tuán)"
categoryTopView.subtitle = catrgoryData.name
}else{
categoryTopView.title = catrgoryData.name
categoryTopView.subtitle = subCatroyData as! String?
}
//設(shè)置圖標(biāo)
categoryTopView.normalName = catrgoryData.icon
categoryTopView.heightName = catrgoryData.highlighted_icon
//退出poper
categoryVC.dismissViewControllerAnimated(true) { () -> Void in
//dismiss后允許交互
self.setEnabled()
}
}
}
—-> 5.2 地區(qū)
///MARK : - 實(shí)現(xiàn)接收地區(qū)通知的中調(diào)用的方法
extension XFJHomeViewController {
@objc private func districtNotic(disNic : NSNotification){
//取出通知中的內(nèi)容
let districtData = disNic.userInfo![XFJDistrictNotificationKey] as! XFJDistrict
//此處(有可能沒有子數(shù)據(jù),所以這里不需強(qiáng)轉(zhuǎn))
let subDistrictData = disNic.userInfo![XFJSubDistrictNotificationKey]
//設(shè)置數(shù)據(jù)(獲取頂部的view)
let districtTopView = gzItem?.customView as! XFJTopView
//子數(shù)據(jù)
let count = districtData.subregions?.count
//判斷
if count == 0 {
districtTopView.title = "美團(tuán)"
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 : - 實(shí)現(xiàn)接收排序通知的中調(diào)用的方法
extension XFJHomeViewController {
@objc private func sortsNotic(sortsNic :NSNotification){
//獲取通知中的內(nèi)容
let sortsData = sortsNic.userInfo![XFJSortsNotificationKey] as! XFJSorts
//獲取頂部的view
let sortsView = sortItem?.customView as! XFJTopView
//設(shè)置數(shù)據(jù)
sortsView.subtitle = sortsData.label
//移除poper
sortsVC.dismissViewControllerAnimated(true) { () -> Void in
//dismiss后允許交互
self.setEnabled()
}
}
}
十四 細(xì)節(jié)處理
1 我們發(fā)現(xiàn)當(dāng)運(yùn)行在橫屏的時(shí)候,沒有問題,但是當(dāng)在運(yùn)行的之后轉(zhuǎn)換為豎屏,導(dǎo)航條中item間的距離會(huì)被拉伸,這怎么解決呢?
—-> 1.1 產(chǎn)生這種現(xiàn)象的原因 : autoresizing導(dǎo)致屏幕旋轉(zhuǎn)的時(shí)候,子控件跟隨父控件的拉伸而拉伸
—-> 1.2 解決 :(如下圖)—> 將正方形中間的紅線去除就可以
2 當(dāng)點(diǎn)擊某個(gè)item的時(shí)候,發(fā)現(xiàn)再點(diǎn)擊其他的item的時(shí)候,前一個(gè)item并沒有退出,這樣給用戶的體驗(yàn)不好.我們通過代碼來設(shè)置.
—-> 2.1 在監(jiān)聽用戶點(diǎn)擊的按鈕中讓所有的item都取消交互調(diào)用下面代碼
@objc private func setDisabled() {
topItem?.enabled = false
gzItem?.enabled = false
sortItem?.enabled = false
}
—-> 2.2 在實(shí)現(xiàn)接收通知中調(diào)用的方法中,在poper被dismiss的時(shí)候,允許用戶交互,調(diào)用下面代碼來允許交互
@objc private func setEnabled() {
topItem?.enabled = true
gzItem?.enabled = true
sortItem?.enabled = true
}
—-> 2.3 在實(shí)現(xiàn)對(duì)item按鈕的監(jiān)聽方法中,我們?cè)O(shè)置poper的代理為當(dāng)前控制器(這里只說明一段代碼,其它模塊也是一樣的)
//設(shè)置代理
categoryVC.popoverPresentationController?.delegate = self
—-> 2.4 實(shí)現(xiàn)代理方法
///MARK: - 實(shí)現(xiàn)popver代理方法
extension XFJHomeViewController : UIPopoverPresentationControllerDelegate {
func popoverPresentationControllerDidDismissPopover(popoverPresentationController: UIPopoverPresentationController) {
//允許交互
setEnabled()
}
}
十五 總結(jié)
1 這篇博客我寫的可能有點(diǎn)亂,代碼太多,我也沒辦法具體到某一點(diǎn),只是說了大概,介紹了協(xié)議可以實(shí)現(xiàn)這種情況的方法,同時(shí)對(duì)通知的運(yùn)用也是捎帶了,沒有怎么細(xì)說.希望你們盡量看吧,看不懂的話,在給我私信吧.能幫到大家的,我一定幫忙.
2 最后還是那句話,大家如果覺得我寫的博客還寫的話,麻煩大家多多關(guān)注我的官方博客,謝謝!
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Swift實(shí)現(xiàn)表格視圖單元格單選(2)
這篇文章主要為大家詳細(xì)介紹了Swift實(shí)現(xiàn)表格視圖單元格單選的第二篇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
switch實(shí)現(xiàn)一個(gè)兩數(shù)的運(yùn)算代碼示例
這篇文章主要介紹了switch實(shí)現(xiàn)一個(gè)兩數(shù)的運(yùn)算代碼示例,需要的朋友可以參考下2017-06-06
swift 3.0 正則表達(dá)式查找/替換字符的實(shí)現(xiàn)代碼
正則表達(dá)式使用單個(gè)字符串來描述、匹配一系列符合某個(gè)句法規(guī)則的字符串。本文重點(diǎn)給大家介紹swift 3.0 正則表達(dá)式查找/替換字符的實(shí)現(xiàn)代碼,需要的朋友參考下吧2017-08-08

