第六天
终于有时间可以在更新这个swift的demo了,一看时间,已经是8个月以后,swift都已经更新4.0了,但是目前这个demo依然用3.0去写
之前我们完成了新浪微博是授权,并且成功登陆了我们的微博,今天我们就开始布局首页的微博视图,今天只对原创微博进行处理,转发微博只是在原创微博的基础上添加一个评论
1.创建XQWBStatusCell
和对应的xib文件,并且拖入对应的空间,设置约束
- 注意: 为了体现封装,我们将配图视图(XQWBStatusPictureView)和工具栏视图(XQWBStatusToolBar)分别封装,这样会cell中的代码会更加清晰
2.在cell的XQWBStatusViewModel(后边我们会讲到这个Viewmodel)属性的setter方法中,给各个控件渲染
/// 微博视图模型
var viewModel: XQWBStatusViewModel? {
didSet {
// 微博文本
statusLabel?.text = viewModel?.status.text
// 姓名
nameLabel.text = viewModel?.status.user?.screen_name
// 设置会员图标 (直接使用属性不用计算)
memberIconView.image = viewModel?.memberIcon
// 认证图标
vipIconView.image = viewModel?.vipIcon
// 用户头像
iconView.xq_setImage(urlString: viewModel?.status.user?.profile_image_url, placeholderImage: UIImage(named: "avatar_default_big"), isAvatar:true)
// 底部工具栏
toolBar.viewModel = viewModel
// 配图视图的高度
pictureView.heightCons.constant = viewModel?.pictureViewSize.height ?? 0
// 配图视图的数据
pictureView.urls = viewModel?.status.pic_urls
}
}
-
2.1 配图视图的处理 我们首先将9个图片全部创建并且隐藏,在我们设置图片的时候,根据图片数组的数量,将对应的UIImageView显示, 这样的做可以优化一些性能(尽量避免动态创建视图)
// 创建9个UIImageView for i in 0..<9 { let iv = UIImageView() iv.contentMode = .scaleAspectFill iv.clipsToBounds = true // 行 - > Y let row = CGFloat(i / 3) // 列 - > X let col = CGFloat(i % 3) iv.frame = rect.offsetBy(dx: col * (itemWidth + InnerMargin), dy: row * (itemWidth + InnerMargin)) addSubview(iv) } // 在设置图片数组的时候讲对应的UIImageView显示 var urls : [XQWBStatusPicture]? { didSet { // 1. 隐藏所有的iv for v in subviews { v.isHidden = true } // 遍历urls 顺序设置图像 var index = 0 for url in urls ?? [] { // 获得对应的imageView let iv = subviews[index] as! UIImageView if index == 1 && urls?.count == 4 { index += 1 } // 设置图像 iv.xq_setImage(urlString: url.thumbnail_pic, placeholderImage: nil) // 显示图像 iv.isHidden = false index += 1 } }
-
2.2 设置XQWBStatusToolBar
var viewModel: XQWBStatusViewModel? { didSet { retweetedBtn.setTitle(viewModel?.retweetedStr, for: .normal) commentBtn.setTitle(viewModel?.commentStr, for: .normal) likeBtn.setTitle(viewModel?.likeStr, for: .normal) } }
3. 修改我们之前在controller中绑定的cell,并且进行数据渲染
// 1.取出cell
let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath) as! XQWBStatusCell
// 2.设置cell
let viewModel = listViewModel.statusList[indexPath.row]
cell.viewModel = viewModel
4.进行数据处理,这里是最关键的一步,我们要充分体验到viewModel的使用及其优点
-
4.1 我们单独创建XQWBStatusViewModel,管理每一条微博的数据, 其中包含以下属性
/// 微博模型 var status: XQWBStatus /// 会员图标 var memberIcon: UIImage? /// vip 认证类型 var vipIcon: UIImage? /// 转发文字 var retweetedStr: String? /// 评论文字 var commentStr: String? /// 点赞文字 var likeStr: String? /// 配图视图大小 var pictureViewSize = CGSize()
-
4.2 在设置重写的构造方法中,我们对每个属性进行计算赋值
init(model: XQWBStatus) { self.status = model // 会员等级 if (model.user?.mbrank)! > 0 && (model.user?.mbrank)! < 7 { let imageName = "common_icon_membership_level\(model.user?.mbrank ?? 1)" memberIcon = UIImage(named: imageName) } // 认证图标 switch model.user?.verified_type ?? -1 { case 0: vipIcon = UIImage(named: "avatar_vip") case 2, 3, 4: vipIcon = UIImage(named: "avatar_enterprise_vip") case 220: vipIcon = UIImage(named: "avatar_grassroot") default: break } // 设置toolbar 字符串 retweetedStr = countStr(count: model.reposts_count, defaultStr: "转发") commentStr = countStr(count: model.comments_count, defaultStr: "评论") likeStr = countStr(count: model.attitudes_count, defaultStr: "赞") // 计算配图视图大小 pictureViewSize = calcPictureViewSize(count: status.pic_urls?.count) }
-
4.3 在处理构造函数中有几个子方法单独处理
// 设置评论,转发等数字格式 private func countStr(count: Int, defaultStr: String) -> String { if count == 0 { return defaultStr } if count < 10000 { return count.description } return String(format: "%.02f万", Double(count) / 10000.0) } // 根据配图的数量计算配图视图大小 private func calcPictureViewSize(count: Int?) -> CGSize { if count == 0 || count == nil { return CGSize() } // 1.计算宽度 (common) // 2.计算高度 let row = (count!-1) / 3 + 1 // 行数 var height = OutterMargin height += CGFloat(row) * itemWidth height += CGFloat(row - 1) * InnerMargin return CGSize(width: ViewWidth, height: height) }
-
这样在cell的XQWBStatusViewModel属性的setter方法中,我们就可以直接根据计算处理好的数据直接对UI进行渲染