// // SBTFormView.swift // SolarBT // // Created by weclouds on 2019/2/27. // Copyright © 2019 weclouds. All rights reserved. // import UIKit class SheetLeftView: UITableView { override init(frame: CGRect, style: UITableView.Style) { super.init(frame: frame, style: style) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } class SheetBottomView: UICollectionView { override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) { super.init(frame: frame, collectionViewLayout: layout) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } class SheetContentView: UITableView { override init(frame: CGRect, style: UITableView.Style) { super.init(frame: frame, style: style) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } protocol SBTFormViewDataSource : NSObjectProtocol { //返回表格有多少行 func formView(_ formView:SBTFormView,numberOfRowsIn section:Int ) -> Int //返回表格有多少列 func formView(_ formView:SBTFormView,numberOfColsIn section:Int) -> Int //返回表格某行某列外支商需要显示的内容 func formView(_ formView:SBTFormView,cellForContentItemAt indexRow:IndexPath, indexCol:IndexPath) -> String //返回表格左侧标题列每行需要显示的内容 func formView(_ formView:SBTFormView,cellForLeftColAt indexPath:IndexPath) -> String //返回表格下边标题行每列需要显示的内容 func formView(_ formView:SBTFormView,cellForBottomRowAt indexPath:IndexPath) -> String //返回表格某行是否需要填充颜色 func formView(_ formView:SBTFormView,cellWithColorAt indexRow:IndexPath) -> Bool } protocol SBTFormViewDelegate : NSObjectProtocol { //返回表格每行的高度 func formView(_ formView:SBTFormView,heightForRowAt indexPath:IndexPath ) -> CGFloat //返回表格每列的宽度 func formView(_ formView:SBTFormView,widthForColAt indexPath:IndexPath) -> CGFloat //返回表格某行某列外支商需要显示的内容 // func formView(_ formView:SBTFormView,cellForContentItemAt indexRow:IndexPath) -> String //点击事件 func formView(_ formView:SBTFormView,didSelectItemAt indexRow:IndexPath, indexCol: IndexPath) } class SBTFormView: UIView { var weekData : [OneDayData]? //一周数据 weak var dataSource : SBTFormViewDataSource? weak var delegate :SBTFormViewDelegate? let leftViewCellID = "left.tableview.cell" let bottomViewCellID = "top.collectionview.cell" let contentViewCellID = "content.tableview.cell" var sheetHead : String? // 第一行第一列格子j要显示的内容 var titleColWidth : CGFloat? // 左侧标题列宽度 (必须设置) var titleRowHeight : CGFloat?// 下边标题行高度 var leftView : SheetLeftView? var bottomView : SheetBottomView? var contentView : SheetContentView? var sheetHeadLabel : UILabel? override init(frame: CGRect) { super.init(frame: frame) createUI() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } open func reloadData(){ self.leftView?.reloadData() self.bottomView?.reloadData() self.contentView?.reloadData() } override func layoutSubviews() { super.layoutSubviews() let sheetViewWidth = self.frame.size.width let sheetViewHeight = self.frame.size.height self.leftView?.frame = CGRect(x: 0, y: 0, width: titleColWidth!, height: sheetViewHeight - titleRowHeight!) self.bottomView?.frame = CGRect(x: titleColWidth!, y: sheetViewHeight - titleRowHeight!, width: sheetViewWidth - titleColWidth!, height: titleRowHeight!) contentView?.frame = CGRect(x: titleColWidth!, y: 0, width: sheetViewWidth - titleColWidth!, height: sheetViewHeight - titleRowHeight!) } } extension SBTFormView{ func createUI() { self.layer.borderColor = UIColor.red.cgColor self.layer.cornerRadius = 1 self.layer.borderWidth = 1 leftView = SheetLeftView(frame: CGRect.zero, style: .plain) leftView?.delegate = self leftView?.dataSource = self leftView?.showsVerticalScrollIndicator = false leftView?.backgroundColor = UIColor.clear leftView?.layer.borderColor = UIColor.blue.cgColor leftView?.layer.borderWidth = 1 leftView?.separatorStyle = .none let layout = UICollectionViewFlowLayout() layout.minimumLineSpacing = 1 layout.minimumInteritemSpacing = 1 layout.scrollDirection = .horizontal bottomView = SheetBottomView(frame: CGRect.zero, collectionViewLayout: layout) bottomView?.delegate = self bottomView?.dataSource = self bottomView?.showsHorizontalScrollIndicator = false bottomView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: bottomViewCellID) bottomView?.backgroundColor = UIColor.white bottomView?.layer.borderWidth = 1 bottomView?.layer.borderColor = UIColor.lightGray.cgColor contentView = SheetContentView(frame: CGRect.zero, style: .plain) contentView?.delegate = self contentView?.dataSource = self contentView?.showsVerticalScrollIndicator = false contentView?.separatorStyle = .none contentView?.backgroundColor = UIColor.white addSubview(leftView!) addSubview(bottomView!) addSubview(contentView!) } } extension SBTFormView:UITableViewDelegate,UITableViewDataSource,UICollectionViewDelegate,UICollectionViewDataSource{ func scrollViewDidScroll(_ scrollView: UIScrollView) { if scrollView.isKind(of: SheetLeftView.self) { contentView?.contentOffset = (leftView?.contentOffset)! } if scrollView.isKind(of: SheetLeftView.self) { leftView?.contentOffset = (contentView?.contentOffset)! } if self.isKind(of: UICollectionView.self) { for cell in (contentView?.visibleCells)! { let cell1 = cell as! SBTContentViewCell cell1.cellCollectionView?.contentOffset = scrollView.contentOffset } } } //MARK: -- UITableViewDelegate && UITableVIewDataSource func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return (delegate?.formView(self, heightForRowAt: indexPath))! } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return (self.dataSource?.formView(self, numberOfRowsIn: section))! } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if tableView.isKind(of: SheetLeftView.self) { var cell = tableView.dequeueReusableCell(withIdentifier: leftViewCellID) if cell == nil{ cell = UITableViewCell(style: .default, reuseIdentifier: leftViewCellID) } cell?.selectionStyle = .none for view in (cell?.contentView.subviews)!{ view.removeFromSuperview() } cell?.backgroundColor = UIColor.white cell?.layer.borderColor = UIColor.blue.cgColor cell?.layer.borderWidth = 1 let width = self.titleColWidth let height = self.delegate?.formView(self, heightForRowAt: indexPath) let rect = CGRect(x: 0, y: 0, width: width!, height: height!) let label = UILabel(frame: rect) label.text = self.dataSource?.formView(self, cellForLeftColAt: indexPath) label.textColor = UIColor.black label.textAlignment = .center cell?.contentView.addSubview(label) return cell! } var aCell = tableView.dequeueReusableCell(withIdentifier: contentViewCellID) as? SBTContentViewCell if aCell == nil { aCell = SBTContentViewCell(style: .default, reuseIdentifier: contentViewCellID) } aCell?.selectionStyle = .none aCell?.cellForItemAtIndexPathBlock = { (indexPathInner) in // return (self.dataSource?.formView(self, cellForLeftColAt: indexPathInner))! return (self.dataSource?.formView(self, cellForContentItemAt: indexPath, indexCol: indexPathInner))! } aCell?.numberOfItemsInSectionBlock = {(section) in return (self.dataSource?.formView(self, numberOfRowsIn: section))! } aCell?.sizeForItemAtIndexPathBlock = {(collectionViewLayout,indexPathInner) in let width = self.delegate?.formView(self, widthForColAt: indexPathInner) let height = self.delegate?.formView(self, heightForRowAt: indexPathInner) return CGSize(width: width!, height: height!) } aCell?.ContentViewCellDidScrollBlock = {(scroll) in for cell in (self.contentView?.visibleCells)! { let cell2 = cell as! SBTContentViewCell cell2.cellCollectionView?.contentOffset = scroll.contentOffset } self.bottomView?.contentOffset = scroll.contentOffset } aCell?.cellWithColorAtIndexPathBlock = {(indexPathInner) in return (self.dataSource?.formView(self, cellWithColorAt: indexPath))! } aCell?.didSelectItemBlock = {(indexPathInner) in self.delegate?.formView(self, didSelectItemAt: indexPath, indexCol: indexPathInner) } aCell?.backgroundColor = UIColor.clear aCell?.cellCollectionView?.frame = CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height) aCell?.cellCollectionView?.reloadData() return aCell! } func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { if tableView.isKind(of: SheetLeftView.self) { return } let willDisplayCell = cell as! SBTContentViewCell let didDisplayCell = tableView.visibleCells.first as! SBTContentViewCell if (willDisplayCell.cellCollectionView != nil) && (didDisplayCell.cellCollectionView != nil) && willDisplayCell.cellCollectionView?.contentOffset.x != didDisplayCell.cellCollectionView?.contentOffset.x { willDisplayCell.cellCollectionView?.contentOffset = (didDisplayCell.cellCollectionView?.contentOffset)! } } //MARK:pragma mark -- UICollectionViewDelegate && UICollectionViewDataSource func numberOfSections(in collectionView: UICollectionView) -> Int { return 1 } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return (self.dataSource?.formView(self, numberOfColsIn: section))! } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let width = self.delegate?.formView(self, widthForColAt: indexPath) let height = self.titleRowHeight return CGSize(width: width!, height: height!) } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let bottomCell = collectionView.dequeueReusableCell(withReuseIdentifier: bottomViewCellID, for: indexPath) if bottomCell != nil { for view in bottomCell.contentView.subviews{ view.removeFromSuperview() } bottomCell.backgroundColor = UIColor.white bottomCell.layer.borderColor = UIColor.lightGray.cgColor bottomCell.layer.borderWidth = 1 let width = self.delegate?.formView(self, widthForColAt: indexPath) let height = self.titleRowHeight let rect = CGRect(x: 0, y: 0, width: width!, height: height!) let label = UILabel(frame: rect) label.text = self.dataSource?.formView(self, cellForBottomRowAt: indexPath) label.textColor = UIColor.black label.textAlignment = .center bottomCell.contentView.addSubview(label) } return bottomCell } }