由于只是个Demo,所以用的是最简单的Cell来演示,VC里面只需要不到100行代码就可以实现。实际上在项目中的用法是差不多的,只是需要根据UI的设计,自定义Cell。
首先先在storyboard上面拖好界面,主要是两个tableView的位置放好,底下的购买按钮是凑数的。
把两个tableView拉到viewController里面
这里需要用到一个我自己封装的轻量级的TableViewManager框架,不需要实现tableView的代理方法,不然两个tableView的代理方法在一起处理,会让ViewController很臃肿。
剩下的代码:
class ViewController: UIViewController {
/// 左侧分类的tableView
@IBOutlet weak var categoryTableView: UITableView!
/// 右侧商品的tableview
@IBOutlet weak var productTableView: UITableView!
var categoryManager: ZJTableViewManager!
var productManager: ZJTableViewManager!
//是否在向上滚动
var isScrollUp:Bool = false
var lastOffsetY:CGFloat = 0
override func viewDidLoad() {
super.viewDidLoad()
//初始化tableviewManager
self.categoryManager = ZJTableViewManager(tableView: self.categoryTableView)
self.productManager = ZJTableViewManager(tableView: self.productTableView)
self.productManager.delegate = self
//假数据
let arrCategory = ["分类1","分类2","分类3","分类4","分类5","分类6"]
let arrProduct = ["面包", "蛋糕", "香蕉", "牛奶", "饼干", "猫粮"]
//添加分类数据
let categorySection = ZJTableViewSection()
self.categoryManager?.add(section: categorySection)
for category in arrCategory {
let categoryItem = ZJTableViewItem(title: category)
categoryItem.isAutoDeselect = false
categorySection.add(item: categoryItem)
//分类的点击事件
categoryItem.setSelectionHandler(selectHandler: {[weak self] (item) in
self?.productManager.tableView.scrollToRow(at: IndexPath(row: 0, section: item.indexPath.row), at: .top, animated: true)
})
}
//添加商品数据
for category in arrCategory {
//添加分区标题
let sectionHeader = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 40))
sectionHeader.text = category
sectionHeader.backgroundColor = UIColor.red
let section = ZJTableViewSection(headerView: sectionHeader)
self.productManager.add(section: section)
//商品列表滑动时与分类列表联动
section.setHeaderWillDisplayHandler({[weak self] (currentSection) in
//手动拖才和左边联动
if ((self?.productManager.tableView.isDragging)! && !(self?.isScrollUp)!){
let currentSection = self?.productTableView.indexPathsForVisibleRows?.first?.section ?? 0
self?.categoryTableView.selectRow(at: IndexPath(item: currentSection, section: 0), animated: false, scrollPosition: .middle)
}
})
section.setHeaderDidEndDisplayHandler {[weak self] (currentSection) in
//手动拖才和左边联动
if ((self?.productManager.tableView.isDragging)! && (self?.isScrollUp)!){
self?.categoryTableView.selectRow(at: IndexPath(item: currentSection.index + 1, section: 0), animated: false, scrollPosition: .middle)
}
}
//添加商品
for product in arrProduct {
let item = ZJTableViewItem(title: product)
item.cellHeight = 90
section.add(item: item)
}
}
//先默认选中categoryTableView分类的第一个cell
self.categoryTableView.selectRow(at: IndexPath(row: 0, section: 0), animated: true, scrollPosition: UITableView.ScrollPosition.top)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension ViewController:ZJTableViewDelegate{
func scrollViewDidScroll(_ scrollView: UIScrollView) {
isScrollUp = lastOffsetY < scrollView.contentOffset.y;
lastOffsetY = scrollView.contentOffset.y;
}
}
其实难点在于左边商品列表滑动时和右边分类的联动。
ViewController里面有两个属性,lastOffsetY
用来记录productTableView上一刻的contentOffset.y的值,和此刻的做比较,判断是向上滑动还是向下滑动,赋值给isScrollUp
。
然后就是逻辑处理:
这里先理一下页面的逻辑。前提是必须是用户在手动滑动productTableView,假设productTableView当前显示的是分类3,向上滑动时,由于sectionHeader是悬浮的,那么分类3 header消失的时候,说明当前要显示分类3+1,此时左边分类触发显示分类4。向下滑动时,分类3 header向下走,分类2的header出现在顶部,此时此时左边分类触发显示分类2。
对这两种情况做处理:
//商品列表滑动时与分类列表联动
section.setHeaderWillDisplayHandler({[weak self] (currentSection) in
//手动拖才和左边联动
if ((self?.productManager.tableView.isDragging)! && !(self?.isScrollUp)!){
let currentSection = self?.productTableView.indexPathsForVisibleRows?.first?.section ?? 0
self?.categoryTableView.selectRow(at: IndexPath(item: currentSection, section: 0), animated: false, scrollPosition: .middle)
}
})
section.setHeaderDidEndDisplayHandler {[weak self] (currentSection) in
//手动拖才和左边联动
if ((self?.productManager.tableView.isDragging)! && (self?.isScrollUp)!){
self?.categoryTableView.selectRow(at: IndexPath(item: currentSection.index + 1, section: 0), animated: false, scrollPosition: .middle)
}
}
Demo我放到TableViewManager的Demo2里面,感兴趣的话可以去看看,顺便帮忙star一下哈:)