您的位置:首页 > 移动开发 > Swift

从头开始swift2.1 仿搜材通项目(十) 趋势图、Cell的重用及View的隐藏

2016-01-28 22:40 411 查看
之前说的第九节时已经是最后一节了,但后面有朋友希望我可以把这个Demo写得更详细一些,那我后面便不定期的更新一下吧,如果有想要什么效果的实现的话,不妨给我留言,大家一起来研究研究。

今天我们来实现一下这个效果,点击Cell进入一个详情页,该详情页分为多个类型(信息价、市场价、供应、求购等),界面的内容按模块分有图片、参数配置、推荐的人、相关的材料,各个模块可能根据类型的不同有所变化,如果有一种类型我们就要写一个界面的话,那实在太麻烦,所以我们来做一个统一的详情页。



这里提一下,图上看到的多个TableView的界面,都是只用了一个ViewController类并继承自前面章节中的BaseTableViewController,核心代码如下:

class PriceListController: BaseTableViewController {

//...

override func viewDidLoad() {
super.viewDidLoad()
initWithParams(query_new_type != 7 ? "PriceCell" : "PriceCell_Inquiry", heightForRowAtIndexPath: PriceCellViewHeight)
tableView?.separatorStyle = UITableViewCellSeparatorStyle.None
}

//...
override func loadData() {
//...
HMRequest<PriceListModel>.go(.POST, url, cache: false, params: params, vc: self, needCallBack: true ) { (model) -> () in
self.loadCompleted(model?.data)
}
}
}


继承BaseTableViewController后只需要关注这两个简单的方法就行了,会自动实现上拉加载下拉刷新相关的动作和逻辑。

好现在我们来分析一下详情界面。我们要做一个通用的模块,那就先把所有通用的功能都加上,刚才说到了,这个界面完整的分为顶部功能按钮(收藏、分享、点赞)、参数配置、价格趋势图、推荐供应商和相关材料:









根据类型的不同,我们动态显示隐藏对应的View即可,扩展UIView实现类似android中View的Gone方法:

func gone(byHeight: Bool = true, _ byWidth: Bool = true) -> (width: CGFloat, height: CGFloat){
let _width = self.bounds.width
let _hight = self.bounds.height

for child in subviews {
child.removeFromSuperview()
}

if byHeight {
updateConstraints(.Height, 0)
}
if byWidth {
updateConstraints(.Width, 0)
}

return (_width, _hight)
}

func updateConstraints(attribute: NSLayoutAttribute, _ constant: CGFloat){
for constraint: NSLayoutConstraint in constraints {
if constraint.firstAttribute == attribute {
constraint.constant = constant
break
}
}
}


例如,我们需要隐藏趋势图的布局:

layout_chart.gone()


这样就可以达到不仅View不可见,并且不占空间了,下面的View也会紧跟上来。这里我先介绍一下在不依赖第三方,并且项目改动最小的方法,其实有一些第三方库可以支持的,后面有机会我再来详细介绍。

然后是趋势图,这个功能如果自己写呢就复杂了,所以我在Github上找了一个库,PNChartSwift,它集成和使用的方法都非常简单:

pod 'PNChartSwift',:git => 'https://github.com/kevinzhow/PNChart-Swift.git'

//使用
let lineChart = PNLineChart.create(view_chart, xLabels: xLabels, dataArray: dataArray)
lineChart.delegate = self

view_chart.addSubview(lineChart)


extension PNLineChart {

static func create(parent:UIView!, xLabels:[String], dataArray:[CGFloat]) -> PNLineChart{

let lineChart:PNLineChart = PNLineChart(frame: CGRectMake(0, 8, UIScreen.mainScreen().bounds.width, parent.bounds.height - 8))
lineChart.yLabelFormat = "%1.0f"
lineChart.showLabel = true
lineChart.backgroundColor = UIColor.clearColor()
lineChart.xLabels = xLabels
lineChart.showCoordinateAxis = true

let data01:PNLineChartData = PNLineChartData()
data01.color = PNGreyColor
data01.itemCount = dataArray.count
data01.inflexionPointStyle = PNLineChartData.PNLineChartPointStyle.PNLineChartPointStyleCycle
data01.getData = ({(index: Int) -> PNLineChartDataItem in
let yValue:CGFloat = dataArray[index]
let item = PNLineChartDataItem(y: yValue)
return item
})

lineChart.chartData = [data01]
lineChart.strokeChart()

return lineChart
}

}


这样运行起来在界面上就会看到一个趋势图展示出来了:



最后一个要点是如何重用UITableViewCell到一个普通的View中,如下图:



当然这里也可以直接放两个UITableView进来,但如果接口返回的数据中只有1~2个Model的话,用UITableView不仅代码复杂,性能也会有所影响,如果用普通的View来填充呢,我们能不能重用外面Cell中的布局呢?答案是可以的,我们修改在Cell中只放一个空白的ContentView就行,然后到Cell编码中修改:



let PriceCellViewHeight:CGFloat = 70
class PriceCell: BaseTableViewCell {

override func setContent(tag:Any?, tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, dataList:[HMObject] ){

let view:PriceCellView = PriceCellView.create(self.contentView)
let query = anyTag as! Query
view.setContent(query, tableView: tableView, cellForRowAtIndexPath: indexPath, dataList: dataList)
self.contentView.addSubview(view)
}

}


PriceCellView的xib:



class func create(parentView: UIView) -> PriceCellView {
let view = NSBundle.mainBundle().loadNibNamed("PriceCellView", owner: nil, options: nil).first as! PriceCellView
view.frame = CGRect(x: 0, y: 0, width: parentView.bounds.width, height: PriceCellViewHeight)
return view
}

func setContent(query: Query, data: PriceModel){
//...
}


这样,不仅在TableView列表界面中可以使用这个布局,在普通的View中一样也可以了:

for i in 0 ... data!.recommendMaterial!.count - 1 {
let obj = data!.recommendMaterial![i]
let item: PriceCellView =  PriceCellView.create(view_recommend_person)
item.frame = CGRect(x: 0, y: CGFloat(i) * PriceCellViewHeight, width: UIScreen.mainScreen().bounds.width, height: PriceCellViewHeight)
item.setBgColor(i)
item.setContent(args_query, data: obj)

view_same_material.addSubview(item)
}


OK,这3个知识点就学到这里,下一节我们看看如何使用BaseTableViewController达到自适应Cell实现类似朋友圈的效果(其实代码几乎和固定cell高度的完全一样),如果有同学需要的话,别吝啬啦。



附效果图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: