3.新浪微博Swift项目第三天

##第三天

今天我们主要做访客视图的处理

1.因为每个界面都有一个tableView,我们就给BaseViewController添加一个tableView

1.1 添加并设置tableView

/// 表格视图 - 如果没有登录,就不创建
    var tableView:UITableView?
// 设置表格视图
    func setupTableView() {
        tableView = UITableView(frame: view.bounds, style: .plain)
        view.insertSubview(tableView!, belowSubview: navigationBar)
        // 设置数据源和代理
        tableView?.delegate = self
        tableView?.dataSource = self
        // 设置内容缩进
        tableView?.contentInset = UIEdgeInsets(top: navigationBar.bounds.height, left: 0, bottom: tabBarController?.tabBar.bounds.height ?? 49, right: 0)    
    }

1.2 通过一个extension遵守tableView的协议,实现代理方法

 // MARK: - tableView delegate
 extension XQWBBaseViewController: UITableViewDelegate, UITableViewDataSource {
    // 基类准备方法,子类具体实现
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 0
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return UITableViewCell()
    }
}
// 这里return 0 和 return UITableViewCell() 只是为了语法正确,具体的返回还需要子类重写实现
```	
1.3 给tableView绑定假数据,添加上拉/下拉控件	

  - 创建 refreshControl	

/// 刷新控件
var refreshControl: UIRefreshControl?
/// 区分上拉刷新标记
var isPullup = false
- 设置 refreshControl				
  

// 设置刷新控件 refreshControl = UIRefreshControl() tableView?.addSubview(refreshControl!) refreshControl?.addTarget(self, action: #selector(loadData), for: .valueChanged)

- 在tableView的delegate方法中设置上拉刷新和下拉加载

// 在显示最后一行的时候上拉刷新 func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { // 1.判断是不是最后一行 let row = indexPath.row // 行 let section = tableView.numberOfSections - 1 // 最后一组 if row < 0 || section < 0 { return } let count = tableView.numberOfRows(inSection: section) // 最后一点组的的行数 if row == (count - 1) && !isPullup { isPullup = true loadData() } }

- 子类实现loadData()方法加载自己的数据

/// 加载数据 override func loadData() { // 异步延时加载数据 DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {

        for i in 0..<10 {
            if self.isPullup {
                self.statusList.append("上拉\(i)")
            }else {
                self.statusList.insert(i.description, at: 0)
            }
        }
        self.isPullup = false
        self.refreshControl?.endRefreshing()
        self.tableView?.reloadData()
    }
}
PS:到这里,基类tableView就基本设置好了
### 2.设置用户未登录时的访客视图
2.1.这是一个用户标记,判断用户是否登录

/// 用户登录标记 var userLogon = false

2.2 抽取一个继承自UIView的VisitorView	
  - 声明需要的属性
   

// MARK: - 控件 // icon lazy var iconView:UIImageView = UIImageView(image: UIImage(named: "visitordiscover_feed_image_smallicon")) // maskview lazy var maskIconView:UIImageView = UIImageView(image: UIImage(named: "visitordiscover_feed_mask_smallicon")) // house lazy var houseView:UIImageView = UIImageView(image: UIImage(named: "visitordiscover_feed_image_house")) // label lazy var tipLabel:UILabel = UILabel.cz_label(withText: "关注一些人,什么东西,关注一些人,什么东西,关注一些人,什么东西", fontSize: 14, color: UIColor.darkGray) // leftBtn lazy var registorBtn:UIButton = UIButton.cz_textButton("注册", fontSize: 16, normalColor: UIColor.orange, highlightedColor: UIColor.black, backgroundImageName: "common_button_white_disable") // rightBtn lazy var loginBtn:UIButton = UIButton.cz_textButton("登录", fontSize: 16, normalColor: UIColor.darkGray, highlightedColor: UIColor.black, backgroundImageName: "common_button_white_disable")

- 取消autoresiziong,使用iOS原生的自动布局设置界面(这里只列出一个控件的代码)

// 2.取消autoresiziong for v in subviews { v.translatesAutoresizingMaskIntoConstraints = false } // 3.自动布局 let margin:CGFloat = 20; // iconView addConstraint(NSLayoutConstraint(item: iconView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1.0, constant: 0)) addConstraint(NSLayoutConstraint(item: iconView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.0, constant: -60))

```
####PS: 对于iOS 原生的自动布局:
```
view1.attr1 = view2.attr2 * multiplier + constant
// view1的某个属性值 = view2的某个属性值的 multiplier 倍 + 偏移量 constant
// 在定义宽高属性的时候将 toItem 参数设置为 nil即可
```
- 用VFL来写的话,代码如下:

```
// maskIconView
    // views 是VFL 中控件名字和实际控件的名字映射
    // metrics 是VFL 中常数的映射关系
    let viewDict = ["maskIconView":maskIconView,"registorBtn":registorBtn] as [String : AnyObject]
    let metrics = ["spacing":20]
    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[maskIconView]-0-|",
                                                  options: [],
                                                  metrics: nil,
                                                  views: viewDict))
    
    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[maskIconView]-(spacing)-[registorBtn]",
                                                  options: [],
                                                  metrics: metrics,
                                                  views: viewDict))
```
2.3 设置圆圈转动动画

```
// 旋转动画
private func startAnimation() {
    let ani = CABasicAnimation(keyPath: "transform.rotation")
    ani.toValue = 2 * M_PI
    ani.repeatCount = MAXFLOAT
    ani.duration = 15
    ani.isRemovedOnCompletion = false
    iconView.layer.add(ani, forKey: nil)
}

```

3.设置视图数据

3.1 声明一个字典属性,通过disSet方法实现对访客视图数据的加载

```
// MARK: - 设置访客视图信息
// 访客视图信息字典
var visitorInfo : [String:String]? {
    didSet {
        // 1. 取字典信息
        guard let imageName = visitorInfo?["imageName"],
            let message = visitorInfo?["message"] else {
                return
        }
        // 2. 设置消息
        tipLabel.text = message
        // 3. 设置图片 (通过图片名字判断是否为主页)
        if imageName == "" {
            startAnimation()
            return
        }
        iconView.image = UIImage(named: imageName)
        houseView.isHidden = true
        maskIconView.isHidden = true
    }
}
```

3.2 修改创建每个视图时的字典信息,添加visitorView信息

```
// 首页
["clsName":"XQWBHomeViewController", "title":"首页", "imgName":"home", 	"visitorInfo":["imageName":"", "message":"关注一些人,回这里看看有什么惊喜"]]
```

3.3 参考淘宝等APP,tabbar图片在一些特殊的时间会变,修改tabbar信息的获取方式 ####大致流程图如下所示: 网络获取tabbar json数据 - 建立AppDelegate的extension,获取服务器信息

```
private extension AppDelegate {
    func loadAppInfo() {
        // 1. 模拟异步
        DispatchQueue.global().async { 
            // 1. url
            let url = Bundle.main.url(forResource: "main.json", withExtension: nil)
            // 2. data
            let data = NSData(contentsOf: url!)
            // 3. 写入磁盘
            let docDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
            let jsonPath = (docDir as NSString).appendingPathComponent("main.json")
            data?.write(toFile: jsonPath, atomically: true)
            print("程序加载完毕\(jsonPath)")
        }
    }
}
```
- 修改主页面创建子控制器逻辑

```
// 设置所有字控制器
func setupChildControllers() {
    
    // 获取沙盒路径
    let docDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
    let jsonPath = (docDir as NSString).appendingPathComponent("main.json")
    // 加载data
    var data = NSData(contentsOfFile: jsonPath)
    // 判断data是否为空
    if data == nil {
        let path = Bundle.main.path(forResource: "main.json", ofType: nil)
        data = NSData(contentsOfFile: path!)
    }
    // 反序列化
    // 从bundle加载json
    guard  let array = try?JSONSerialization.jsonObject(with: data as! Data, options: []) as! [[String:AnyObject]] else {
        return
    }
    // 遍历数组,创建控制器
    var arrayM = [UIViewController]()
    for dict in array {
        arrayM.append(controller(info: dict as [String : AnyObject]))
    }
    viewControllers = arrayM
}
```

总结

今天我们主要对首页访客视图做了设置,并且学习了从服务器获取tabbar以及图片的方法

往期内容: Swift新浪微博项目更新目录

项目git地址

转载于:https://my.oschina.net/ozawa4865/blog/810282

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值