- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章纯swift实现ipad版简单美团界面功能由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文实例为大家分享了swift实现ipad版美团界面功能的具体代码,供大家参考,具体内容如下 。
一 总体功能图一 : (ipad竖屏) 。
二 总体功能图二 : (ipad横屏) 。
三 讲解内容 。
1 搭建美团界面(掌握) 。
2 ios8.0之后的Popover的运用(重点) 。
3 协议(掌握) 。
4 通知(掌握) 。
5 细节处理 。
四总体界面 。
1 由总体的app界面效果,能看出来,一个UIViewController控制器作为UINavigationController的根控制器就能满足条件. 。
五 导航条设置 。
1 自定义导航条 : (系统的导航条不能满足需求) 。
2 创建导航控制器类 。
3 获取全局的导航条 : (用来作为设置) 。
1
2
|
//获取导航条
let navigationBar = UINavigationBar.appearanceWhenContainedInInstancesOfClasses([self.classForCoder])
|
3.1 注意 :一定要用上面的方法来获取,不要用下面的方法来获取,因为通过下面方法获取对导航条的设置,很有可能会造成导航条呈现黑色的情况. 。
1
|
UINavigationBar.appearance()
|
4 用图片包装导航条 。
1
2
|
//设置导航条的样式
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拖线,拿到内部属性 。
1
2
3
4
5
6
|
//按钮头像
@IBOutlet weak var iconButton: UIButton!
//头部子标题
@IBOutlet weak var subtitleLabel: UILabel!
//头部标题
@IBOutlet weak var title_Label: UILabel!
|
7 给xib中的属性提供set方法和对应的get方法,方便外边调用修改 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
//对头部标题提供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 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
//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的管理(该部分代码比较多,我们通过类扩展来实现) 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
//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所弹出的控制做懒加载创建,保证用到的时候在创建 。
。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
//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代码块一
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
//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代码块二
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
extension XFJHomeViewController {
@objc
private
func presentPopGzViewClick() {
//弹出位置
districtVC.popoverPresentationController?.barButtonItem = gzItem
//设置背景颜色
districtVC.popoverPresentationController?.backgroundColor = UIColor.clearColor()
//
//model出控制器
presentViewController(districtVC, animated:
true
, completion: nil)
//取消UIBarButtonItem的交互
setDisabled()
//设置代理
districtVC.popoverPresentationController?.delegate = self
}
}
|
—-> 4.1 弹出Popover代码块三
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
extension XFJHomeViewController {
@objc
private
func presentPopSortViewClick() {
//弹出控制器的位置
sortsVC.popoverPresentationController?.barButtonItem = sortItem
//设置背景颜色
sortsVC.popoverPresentationController?.backgroundColor = UIColor.whiteColor()
//model出控制器
presentViewController(sortsVC, animated:
true
, completion: nil)
//取消UIBarButtonItem的交互
setDisabled()
//设置代理
sortsVC.popoverPresentationController?.delegate = self
}
}
|
八 处理弹出的Popover相关数据(全部由对应的模型来决定) 。
1 获取xib中的对象并且提供一个快速创建xib的类方法 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//左边的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"
, owner: nil, options: nil).last as! XFJLRTableView
}
//分类的子数据
private
var subData : [String]?
|
2 通过在xib中设置代理和数据源实现有关数据源方法 。
—-> 2.1 数据源方法一 : cell的个数 。
1
2
3
4
5
6
7
8
9
10
11
|
//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的内容 。
。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
//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做出的相应数据改变 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
//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 模型属性一 :(分类中所需要的模型属性) 。
1
2
3
4
5
6
7
|
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 模型属性二 : (全部模块中所需要的模型属性) 。
1
2
|
var name = String?()
var subregions = [String]?()
|
—-> 2.3 模型属性三 : (排序模块中所需要的模型属性) 。
1
2
|
var label = String?()
var value = Int?()
|
3 在各自管理的类中懒加载模型(采用MJ框架加载模型) 。
—-> 3.1 分类模块中懒加载模型 。
1
2
3
4
5
6
|
//懒加载模型
private
lazy var categories : [XFJCategories] = {
let categoriesData = XFJCategories.objectArrayWithFilename(
"categories.plist"
) as NSArray
//返回模型
return
categoriesData as! [XFJCategories]
}()
|
—-> 3.2 地区模块中懒加载模型 。
1
2
3
4
5
6
|
//懒加载
private
lazy var DistrictView :[XFJDistrict] = {
let DistrictData = XFJDistrict.objectArrayWithFilename(
"gz.plist"
) as NSArray
//返回模型数据
return
DistrictData as! [XFJDistrict]
}()
|
—-> 3.3 排序模块中懒加载模型 。
1
2
3
4
5
6
7
8
9
|
//创建一个属性记录按钮的点击状态
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 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
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 。
。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
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: 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"
)
}
}
|
十一 上半部分总结 。
1 用上面这些方法确实可以达到用户点击item,弹出对应的控制器.但是上面的代码只是写了对其中一个点击item弹出的业逻辑,还有中间的item并没与处理,如果采用这样的方法处理,那么代码量太多了,并且看起来也显得没什么技术含量,我们最终将不会采用这种方法实现. 。
十二 代理 协议(最终实现的方案) 。
1 需要实现的功能 : 通过代理协议的方式,实现用户点击弹出控制器的左边部分,显示出右边部分,并且将对应的头像和主标题,子标题显示到item中 。
2 定义协议方法 : (包括可实现和可不实现)–> 因为 : 当点击左边的tableView中的cell的时候,有右边有些内容是空的,所以如果都定义为必须实现的,会出现问题 。
3 定义在XFJLRTableView中的协议方法第一部分 。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
///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 设置代理 :(分类模块代理) 。
1
2
|
///设置代理(处理弹出的控制器)
weak var delegateSource : XFJTableViewDataSource?
|
5 注意 : 在对协议实现的部分方法中,已经在XFJLRTableView类中的数据源方法这种实现了或者是做出了判断.(上面数据源方法中有介绍) 。
6 对分类用户点击后实现协议相关的方法 。
—-> 6.1 设置对应的控制器为代理 。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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 实现协议方法 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
///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 定义协议
1
2
3
4
5
6
7
|
///MARK : - 定义协议,用来传递当用户选择了弹出的控制器中的某行,将cell中显示的内容显示到对应的top按钮中
@objc protocol XFJTableViewDelegate : NSObjectProtocol {
//点击了左边,告诉代理选择了左边的哪一行,只要告诉代理不需返回参数
func lrTableView(seletLeftButton leftRow : Int)
//点击了右边,高度代理点击了右边的哪一行,同时告诉代理选中了左边的哪一行,不需要返回
func lrTableView(seletRightButton rightRow : Int,seletLeftButton leftRow : Int)
}
|
—-> 8.2 设置代理
1
2
|
///设置代理(处理选中弹出的控制器中的哪一行)
weak var delegate : XFJTableViewDelegate?
|
—-> 8.3 实现协议中的方法 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
///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, object: nil, userInfo: [XFJCategoryNotificationKey : catrgoriesData, XFJSubCategoryNotificationKey : subCatrgoriesData])
}
}
|
十三 通知 。
1 我们是如何将cell中对应的文字和图片显示到item中?
—-> 1.1 我们采用发送通知的方法将相关数据传递到item中 。
2 创建一个文件用来保存通知需要的参数 。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//分类
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 代码块一
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//用户点击了左侧,告诉代理点击了左侧的哪一行
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])
}
}
|
—-> 3.2 代码块二
1
2
3
4
5
6
7
8
9
|
//用户点击了右侧,高度代理点击了右侧哪一行,同时告诉代理选中了左侧哪一行
func lrTableView(seletRightButton rightRow: Int, seletLeftButton leftRow: Int) {
//从模型中获取数据
let catrgoriesData = categories[leftRow]
//取出子数据
let subCatrgoriesData = catrgoriesData.subcategories![rightRow]
//发送通知
NSNotificationCenter.defaultCenter().postNotificationName(XFJCategoryNotification, object: nil, userInfo: [XFJCategoryNotificationKey : catrgoriesData, XFJSubCategoryNotificationKey : subCatrgoriesData])
}
|
4 接收通知 : 虽然发送的通知是匿名通知,但是最好让能将数据提供给谁的一方接收通知,这样也方便设置相关数据 。
—-> 4.1 item是属于XFJHomeViewController类的,就让该类来接收通知,并实现通知中的方法 。
—-> 4.2 接收通知代码
1
2
3
4
5
6
|
//接收分类通知
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 移除通知 (重要点) 。
1
2
3
4
|
//移除通知
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
|
5 实现接收通知中的方法 。
—-> 5.2 分类 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
///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 地区 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
///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 排序 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
///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都取消交互调用下面代码 。
1
2
3
4
5
|
@objc
private
func setDisabled() {
topItem?.enabled =
false
gzItem?.enabled =
false
sortItem?.enabled =
false
}
|
—-> 2.2 在实现接收通知中调用的方法中,在poper被dismiss的时候,允许用户交互,调用下面代码来允许交互 。
1
2
3
4
5
|
@objc
private
func setEnabled() {
topItem?.enabled =
true
gzItem?.enabled =
true
sortItem?.enabled =
true
}
|
—-> 2.3 在实现对item按钮的监听方法中,我们设置poper的代理为当前控制器(这里只说明一段代码,其它模块也是一样的) 。
1
2
|
//设置代理
categoryVC.popoverPresentationController?.delegate = self
|
—-> 2.4 实现代理方法 。
1
2
3
4
5
6
7
|
///MARK: - 实现popver代理方法
extension XFJHomeViewController : UIPopoverPresentationControllerDelegate {
func popoverPresentationControllerDidDismissPopover(popoverPresentationController: UIPopoverPresentationController) {
//允许交互
setEnabled()
}
}
|
十五 总结 。
1 这篇博客我写的可能有点乱,代码太多,我也没办法具体到某一点,只是说了大概,介绍了协议可以实现这种情况的方法,同时对通知的运用也是捎带了,没有怎么细说.希望你们尽量看吧,看不懂的话,在给我私信吧.能帮到大家的,我一定帮忙. 。
2 最后还是那句话,大家如果觉得我写的博客还写的话,麻烦大家多多关注我的官方博客,谢谢.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:http://blog.csdn.net/xf931456371/article/details/51327511 。
最后此篇关于纯swift实现ipad版简单美团界面功能的文章就讲到这里了,如果你想了解更多关于纯swift实现ipad版简单美团界面功能的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
有没有办法在 .swift 文件(编译成 .swift 模块)中声明函数,如下所示: 你好.swift func hello_world() { println("hello world")
我正在尝试使用 xmpp_messenger_ios 和 XMPPFramework 在 iOS 上执行 MUC 这是加入房间的代码。 func createOrJoinRoomOnXMPP()
我想在我的应用程序上创建一个 3D Touch 快捷方式,我已经完成了有关快捷方式本身的所有操作,它显示正确,带有文本和图标。 当我运行这个快捷方式时,我的应用程序崩溃了,因为 AppDelegate
我的代码如下: let assetTag = Expression("asset_tag") let query2 = mdm.select(mdm[assetTag],os, mac, lastRe
我的 swift 代码如下所示 Family.arrayTuple:[(String,String)]? = [] Family.arrayTupleStorage:String? Family.ar
这是我的 JSON,当我读取 ord 和 uniq 数据时出现错误 let response2 : [String: Any] = ["Response":["status":"SUCCESS","
我想将 swift 扩展文件移动到 swift 包中。但是,将文件移动到 swift 包后,我遇到了这种错误: "Type 'NSAttributedString' has no member 'ma
使用CocoaPods,我们可以设置以下配置: pod 'SourceModel', :configurations => ['Debug'] 有什么方法可以用 Swift Package Manag
我正在 Xcode 中开发一个 swift 项目。我将其称为主要项目。我大部分都在工作。我在日期选择器、日期范围和日期数学方面遇到了麻烦,因此我开始了另一个名为 StarEndDate 的项目,其中只
这是 ObjectiveC 代码: CCSprite *progress = [CCSprite spriteWithImageNamed:@"progress.png"]; mProgressBar
我正在创建一个命令行工具,在 Xcode 中使用 Swift。我想使用一个类似于 grunt 的配置文件确实如此,但我希望它是像 Swift 包管理器的 package.swift 文件那样的快速代码
我假设这意味着使用系统上安装的任何 swift 运行脚本:#!/usr/bin/swift 如何指定脚本适用的解释器版本? 最佳答案 Cato可用于此: #!/usr/bin/env cato 1.2
代码说完全没问题,没有错误,但是当我去运行模拟器的时候,会出现这样的字样: (Swift.LazyMapCollection (_base:[ ] 我正在尝试创建一个显示报价的报价应用。 这是导入
是否可以在运行 Swift(例如 Perfect、Vapor、Kitura 等)的服务器上使用 RealmSwift 并使用它来存储数据? (我正在考虑尝试将其作为另一种解决方案的替代方案,例如 no
我刚开始学习编程,正在尝试完成 Swift 编程书中的实验。 它要求““编写一个函数,通过比较两个 Rank 值的原始值来比较它们。” enum Rank: Int { case Ace = 1 ca
在您将此问题标记为重复之前,我检查了 this question 它对我不起作用。 如何修复这个错误: error: SWIFT_VERSION '5.0' is unsupported, suppo
从 Xcode 9.3 开始,我在我的模型中使用“Swift.ImplicitlyUnwrappedOptional.some”包裹了我的字符串变量 我不知道这是怎么发生的,但它毁了我的应用程序! 我
这个问题在这里已经有了答案: How to include .swift file from other .swift file in an immediate mode? (2 个答案) 关闭 6
我正在使用 Swift Package Manager 创建一个应用程序,我需要知道构建项目的配置,即 Debug 或 Release。我试图避免使用 .xcodeproj 文件。请有人让我知道这是否
有一个带有函数定义的文件bar.swift: func bar() { println("bar") } 以及一个以立即模式运行的脚本foo.swift: #!/usr/bin/xcrun s
我是一名优秀的程序员,十分优秀!