欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

純swift實(shí)現(xiàn)ipad版簡單美團(tuán)界面功能

 更新時間:2017年11月30日 15:23:12   作者:蕭家大公子  
這篇文章主要為大家詳細(xì)介紹了純swift實(shí)現(xiàn)ipad版簡單美團(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界面效果,能看出來,一個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)橥ㄟ^下面方法獲取對導(dǎo)航條的設(shè)置,很有可能會造成導(dǎo)航條呈現(xiàn)黑色的情況.

UINavigationBar.appearance()

4 用圖片包裝導(dǎo)航條

//設(shè)置導(dǎo)航條的樣式
navigationBar.setBackgroundImage(UIImage(named: "bg_navigationBar_normal"), forBarMetrics: .Default)

5 注意不要忘了將導(dǎo)航控制器的類型改為自定義類型,否則會加載不出來的

六 導(dǎo)航條相關(guān)內(nèi)容處理

1 思路 : 通過觀察導(dǎo)航條中的按鈕,我們可以看出, 按鈕都是由圖片;主標(biāo)題;子標(biāo)題組成的,所以我們可以通過xib來描述,并且用一個UIView將按鈕包裹住,方便修改設(shè)置

2 創(chuàng)建繼承UIView的類,同時創(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方法和對應(yīng)的get方法,方便外邊調(diào)用修改

//對頭部標(biāo)題提供Set方法
 var title : String? {
  didSet{
   return title_Label.text = title
  }
 }
 //對頭部子標(biāo)題提供set方法
 var subtitle : String? {
  didSet{
   return subtitleLabel.text = subtitle
  }
 }
 //對按鈕頭像提供set方法(平常的圖片)
 var normalName : String? {
  didSet{
   return iconButton.setImage(UIImage(named: normalName!), forState: .Normal)
  }
 }
 //對按鈕頭像提供set方法(點(diǎn)擊后的圖片)
 var heightName : String? {
  didSet{
   return iconButton.setImage(UIImage(named: heightName!), forState: .Highlighted)
  }
 }
 //對按鈕提供一個get方法
 var getIconButton : UIButton {
  get{
   return iconButton
  }
 }

8 提供一個加載xib的類方法,讓外界能通過該方法快速創(chuàng)建xib

//MARK: - 給類擴(kuò)展一個方法(加載xib)
extension XFJTopView {
 //提供一個快速創(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)建的對象
  return topView
 }
}

9 添加頂部的按鈕

—-> 9.1 思路 : 通過添加到由導(dǎo)航條管理的item中的數(shù)組中來實(shí)現(xiàn)對加載xib的時候按鈕的添加

—-> 9.2 導(dǎo)航控制器的根控制器

—-> 9.3 XFJHomeViewController類對導(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)
  //對導(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è)置第一個item
  let topItem = UIBarButtonItem(customView: item1)
  //對按鈕的監(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)建三個類來管理彈出的Popover

2 對頂部三個item所彈出的控制做懶加載創(chuàng)建,保證用到的時候在創(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類型,我們也可以看出是由兩個UITableView組成,并且各占控制器的一半,那么我們這部分也可以通過xib來實(shí)現(xiàn).

—-> 3.1 創(chuàng)建一個類來管理,同時創(chuàng)建xib

3.2 xib內(nèi)部圖

4 彈出Popover(通過在9.3中對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ù)(全部由對應(yīng)的模型來決定)

1 獲取xib中的對象并且提供一個快速創(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]?
 //定義一個屬性,用來記錄用戶點(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的個數(shù)

//MARK: - 數(shù)據(jù)源方法
extension XFJLRTableView : UITableViewDataSource {
 //cell的個數(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)建一個屬性記錄按鈕的點(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)識
    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,彈出對應(yīng)的控制器.但是上面的代碼只是寫了對其中一個點(diǎn)擊item彈出的業(yè)邏輯,還有中間的item并沒與處理,如果采用這樣的方法處理,那么代碼量太多了,并且看起來也顯得沒什么技術(shù)含量,我們最終將不會采用這種方法實(shí)現(xiàn).

十二 代理 協(xié)議(最終實(shí)現(xiàn)的方案)

1 需要實(shí)現(xiàn)的功能 : 通過代理協(xié)議的方式,實(shí)現(xiàn)用戶點(diǎn)擊彈出控制器的左邊部分,顯示出右邊部分,并且將對應(yīng)的頭像和主標(biāo)題,子標(biāo)題顯示到item中

2 定義協(xié)議方法 : (包括可實(shí)現(xiàn)和可不實(shí)現(xiàn))–> 因?yàn)?: 當(dāng)點(diǎn)擊左邊的tableView中的cell的時候,有右邊有些內(nèi)容是空的,所以如果都定義為必須實(shí)現(xiàn)的,會出現(xiàn)問題

3 定義在XFJLRTableView中的協(xié)議方法第一部分

///MARK : - 定義協(xié)議,用協(xié)議的方法來控制top中沒個按鈕的點(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 注意 : 在對協(xié)議實(shí)現(xiàn)的部分方法中,已經(jīng)在XFJLRTableView類中的數(shù)據(jù)源方法這種實(shí)現(xiàn)了或者是做出了判斷.(上面數(shù)據(jù)源方法中有介紹)

6 對分類用戶點(diǎn)擊后實(shí)現(xiàn)協(xié)議相關(guān)的方法

—-> 6.1 設(shè)置對應(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)容顯示到對應(yīng)的top按鈕中
@objc protocol XFJTableViewDelegate : NSObjectProtocol {
  //點(diǎn)擊了左邊,告訴代理選擇了左邊的哪一行,只要告訴代理不需返回參數(shù)
  func lrTableView(seletLeftButton leftRow : Int)
  //點(diǎn)擊了右邊,高度代理點(diǎn)擊了右邊的哪一行,同時告訴代理選中了左邊的哪一行,不需要返回
  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è)哪一行,同時告訴代理選中了左側(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中對應(yīng)的文字和圖片顯示到item中?

—-> 1.1 我們采用發(fā)送通知的方法將相關(guān)數(shù)據(jù)傳遞到item中

2 創(chuàng)建一個文件用來保存通知需要的參數(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è)哪一行,同時告訴代理選中了左側(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)行在橫屏的時候,沒有問題,但是當(dāng)在運(yùn)行的之后轉(zhuǎn)換為豎屏,導(dǎo)航條中item間的距離會被拉伸,這怎么解決呢?

—-> 1.1 產(chǎn)生這種現(xiàn)象的原因 : autoresizing導(dǎo)致屏幕旋轉(zhuǎn)的時候,子控件跟隨父控件的拉伸而拉伸

—-> 1.2 解決 :(如下圖)—> 將正方形中間的紅線去除就可以

 

2 當(dāng)點(diǎn)擊某個item的時候,發(fā)現(xiàn)再點(diǎn)擊其他的item的時候,前一個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的時候,允許用戶交互,調(diào)用下面代碼來允許交互

@objc private func setEnabled() {
    topItem?.enabled = true
    gzItem?.enabled = true
    sortItem?.enabled = true
  }

—-> 2.3 在實(shí)現(xiàn)對item按鈕的監(jiān)聽方法中,我們設(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)這種情況的方法,同時對通知的運(yùn)用也是捎帶了,沒有怎么細(xì)說.希望你們盡量看吧,看不懂的話,在給我私信吧.能幫到大家的,我一定幫忙.

2 最后還是那句話,大家如果覺得我寫的博客還寫的話,麻煩大家多多關(guān)注我的官方博客,謝謝!

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Swift實(shí)現(xiàn)表格視圖單元格單選(2)

    Swift實(shí)現(xiàn)表格視圖單元格單選(2)

    這篇文章主要為大家詳細(xì)介紹了Swift實(shí)現(xiàn)表格視圖單元格單選的第二篇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Swift中的限定擴(kuò)展詳析

    Swift中的限定擴(kuò)展詳析

    擴(kuò)展就是向一個已有的類、結(jié)構(gòu)體或枚舉類型添加新功能。下面這篇文章主要給大家介紹了關(guān)于Swift中限定擴(kuò)展的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2018-03-03
  • switch實(shí)現(xiàn)一個兩數(shù)的運(yùn)算代碼示例

    switch實(shí)現(xiàn)一個兩數(shù)的運(yùn)算代碼示例

    這篇文章主要介紹了switch實(shí)現(xiàn)一個兩數(shù)的運(yùn)算代碼示例,需要的朋友可以參考下
    2017-06-06
  • swift中的@UIApplicationMain示例詳解

    swift中的@UIApplicationMain示例詳解

    這篇文章主要給大家介紹了關(guān)于swift中@UIApplicationMain的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-12-12
  • swift中可選值?和!使用的方法示例

    swift中可選值?和!使用的方法示例

    這篇文章主要給大家介紹了關(guān)于swift中可選值?和!使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • Swift教程之繼承詳解

    Swift教程之繼承詳解

    這篇文章主要介紹了Swift教程之繼承詳解,一個類可以從另外一個類中繼承方法,屬性或者其它的一些特性,當(dāng)一個類繼承于另外一個類時,這個繼承的類叫子類,被繼承的類叫父類,需要的朋友可以參考下
    2015-01-01
  • Swift如何為網(wǎng)頁承載頁面添加更多功能詳解

    Swift如何為網(wǎng)頁承載頁面添加更多功能詳解

    這篇文章主要給大家介紹了關(guān)于Swift如何為網(wǎng)頁承載頁面添加更多功能的相關(guān)資料,包括添加菊花加載的效果、添加跳轉(zhuǎn)到Safari的功能、添加復(fù)制鏈接的功能以及添加分享網(wǎng)頁的功能,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-05-05
  • Swift編程中數(shù)組的使用方法指南

    Swift編程中數(shù)組的使用方法指南

    這篇文章主要介紹了Swift編程中數(shù)組的使用方法指南,是Swift入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-11-11
  • 深入理解Swift中的訪問控制關(guān)鍵字

    深入理解Swift中的訪問控制關(guān)鍵字

    這篇文章主要給大家介紹了Swift中訪問控制關(guān)鍵字的相關(guān)資料,文中介紹的非常詳細(xì),對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。
    2017-03-03
  • swift 3.0 正則表達(dá)式查找/替換字符的實(shí)現(xiàn)代碼

    swift 3.0 正則表達(dá)式查找/替換字符的實(shí)現(xiàn)代碼

    正則表達(dá)式使用單個字符串來描述、匹配一系列符合某個句法規(guī)則的字符串。本文重點(diǎn)給大家介紹swift 3.0 正則表達(dá)式查找/替換字符的實(shí)現(xiàn)代碼,需要的朋友參考下吧
    2017-08-08

最新評論