無情最是臺城柳,依舊煙籠十里提!<滑頭小子||奸詐蜥>
效果圖:
- 思路:
① 這里我用的是兩個 tableView (執(zhí)行操作(代理)方法時候根據(jù) tag 值加以區(qū)分), 先用StoryBoard布局兩個 tableView. 然后實現(xiàn)代理方法讓兩個欄顯示各自的內(nèi)容(左欄一個分區(qū)row顯示總類, 右欄分區(qū)數(shù)是左欄 row 的數(shù)目),
② 接下來實現(xiàn)第一種需求: 點擊左欄的 row 右欄選中對應(yīng)分區(qū)的第一個row, 點擊右側(cè)欄任一分區(qū)的 row,左欄選中對應(yīng)分區(qū)的 row, 這個在點擊方法中實現(xiàn)起來問題不大
③ 另外一個要求就是, 滑動右欄的時候左欄對應(yīng)會選中右欄分區(qū)對應(yīng)的總類 row; 解決這個問題思路就是在右欄的頭視圖出現(xiàn)和消失的時候進行判斷左欄的選中哪個row , 關(guān)鍵點就是我們要判斷頭視圖出現(xiàn)是從下面還是上面, 也就是你滑動的方向,一般情況下我們需要的是左欄的 row 類名, 是我們右欄最上分區(qū)的名; 那么滑動右欄下滑時候出現(xiàn)的區(qū)就是左欄顯示的 row 名, 而上滑右欄消失的區(qū)的下一個區(qū)就是左欄顯示的 row 名;就這兩個情況
④ 上面是我做之前的思考思路, 還有些出現(xiàn)的問題, 我們遇到了在進行解決.
代碼解析:
- 定義需要的屬性:
#不要忘了遵循協(xié)議 class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
// 把兩個欄拖成屬性
@IBOutlet weak var leftTableView: UITableView!
@IBOutlet weak var rightTableView: UITableView!
// 存左欄 總類數(shù)據(jù) 并設(shè)置假總類數(shù)據(jù)
var dataArrayForKind: NSMutableArray? = ["騎士", "勇士", "尼克斯", "快船", "公牛", "CBA"]
// 存右欄 分類細節(jié)數(shù)據(jù) 并設(shè)置分類詳情假數(shù)據(jù)
var dataArrayForSubKind: NSMutableArray? = [["詹姆斯", "歐文", "樂福", "TT湯普森", "JR", "香濃波特", "福萊","杰弗森"],["庫里", " 湯普森", "格林", "杜蘭特"],["安東尼", "羅斯"], ["保羅", "格里芬", "小喬丹", "皮爾斯"],["韋德", "巴特勒", "朗多"],["易建聯(lián)", "郭艾倫", "周琦", "周鵬", "丁彥雨航", "李根", "王哲林"]]
// 構(gòu)造一個枚舉(就是為了練練 Swift 枚舉 這里可以用 BOOl 記錄就行) 記錄右側(cè) 分欄 向上滑動 還是 向下滑動
enum UpOrDownScroller
{
case Up
case Down
}
// 用一個枚舉值記錄滑動方向的枚舉
var ScrollState: UpOrDownScroller?
// 記錄右欄滑動的 y 方向的偏移量 便于對比判斷滑動方向
var offSetForNext: CGFloat = 0
# 下面這個是最后的時候加上的屬性 發(fā)現(xiàn)問題加上的 具體的我們看詳情部分 最后會用動態(tài)圖展示不設(shè)置這個屬性的結(jié)果
// 用來記錄 右欄上下滑動原因 這里不用枚舉了 用 BOOL, True代表手指滑動右欄,False 代表是點擊左欄引起的
var rightScrollReason: Bool!
- 在viewDidLoad中相關(guān)操作
self.view.backgroundColor = UIColor.grayColor()
// 設(shè)置兩個分欄tableView 的代理
self.leftTableView.delegate = self
self.leftTableView.dataSource = self
self.rightTableView.delegate = self
self.rightTableView.dataSource = self
// 設(shè)置兩個 TableView 的 tag 值 執(zhí)行代理方法便于區(qū)分
self.leftTableView.tag = 1001
self.rightTableView.tag = 1002
// 關(guān)掉豎直方向的滑條
self.leftTableView.showsVerticalScrollIndicator = false
self.rightTableView.showsVerticalScrollIndicator = false
// 注冊兩個分欄的 cell
self.leftTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Left_Cell")
self.rightTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Right_Cell")
- 執(zhí)行代理方法顯示內(nèi)容
// 設(shè)置分區(qū)數(shù)
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
if tableView.tag == 1002
{
return dataArrayForSubKind!.count
}else
{
return 1
}
}```
```code
// 設(shè)置分區(qū)下面的行數(shù)
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView.tag == 1001
{
return dataArrayForKind!.count
}else
{
return dataArrayForSubKind![section].count
}
}```
```code
// 設(shè)置 cell
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// 設(shè)置讓左欄的 cell 間隔顯示不一樣的顏色好區(qū)分
if tableView.tag == 1001
{
let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Left_Cell")!
cell.textLabel?.text = dataArrayForKind![indexPath.row] as? String
if indexPath.row % 2 != 0
{
cell.backgroundColor = UIColor.cyanColor()
}else
{
cell.backgroundColor = UIColor.greenColor()
}
return cell
}else
{
let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Right_Cell")!
cell.textLabel?.text = dataArrayForSubKind![indexPath.section][indexPath.row] as? String
return cell
}
}```
``` code
// 調(diào)節(jié)行高 按照自己的需要設(shè)置即可
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if tableView.tag == 1001
{
return (self.view.bounds.size.height - 420.0 ) / 3.0
}
else
{
return 60
}
}```
```code
// 設(shè)置右側(cè)頭視圖顯示 讓右側(cè)頭視圖顯示為分區(qū)(總類)的名字
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if tableView.tag == 1002
{
let headTitle: UILabel = UILabel()
headTitle.text = dataArrayForKind![section] as? String
headTitle.font = UIFont.systemFontOfSize(24)
headTitle.textAlignment = NSTextAlignment.Center
return headTitle
}
return nil
}```
```code
// 設(shè)置頭視圖的高度
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if tableView.tag == 1001
{
return 0
}else
{
return 50
}
}```
---------------
下面開始實現(xiàn)兩個分欄的關(guān)聯(lián):
---------------
- 在點擊方法中實現(xiàn)點擊其中一個欄 另一滑動到響應(yīng)的位置
```code
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if tableView.tag == 1001
{
// 這里設(shè)置的false 是由于點擊了左欄 導(dǎo)致右欄滑動 所以不是手指滑動引起的右欄滑動效果 false 表示不是手指滑動的
rightScrollReason = false
# 點擊左欄的 row 右欄選定對應(yīng)分區(qū)的第一個 row
self.rightTableView.selectRowAtIndexPath(NSIndexPath.init(forRow: 0, inSection: indexPath.row), animated: true, scrollPosition: UITableViewScrollPosition.Top
}else
{
# 點擊右欄的某個區(qū)的 row 左欄選定該區(qū)對應(yīng)的 row
self.leftTableView.selectRowAtIndexPath(NSIndexPath.init(forRow: indexPath.section, inSection: 0), animated: true, scrollPosition: UITableViewScrollPosition.Middle
}
}
實現(xiàn)右欄手指滑動左欄對應(yīng)滑動效果:
- 判斷右欄的滑動方向
func scrollViewDidScroll(scrollView: UIScrollView) {
if scrollView.tag == 1002
{// 這個判斷可以帶入打印一下
# 下滑的時候 y 方向偏移為負值 向上時候為正 所以上一個偏移 y 值大于現(xiàn)在這個偏移值, 說明上一個到現(xiàn)在這個位置是下滑導(dǎo)致反之上滑
if offSetForNext > scrollView.contentOffset.y
{
ScrollState = UpOrDownScroller.Down
}else
{
ScrollState = UpOrDownScroller.Up
}
// 每次比較完后記錄當前的偏移量
offSetForNext = scrollView.contentOffset.y
// 判斷滑動原因 如果是手指拖拽的 那么記錄原因 true
if scrollView.dragging
{
rightScrollReason = true
}
}
}
- 設(shè)置右欄 向下滑動時候 有一個頭視圖將要出現(xiàn)的時候 左側(cè)自動選中要出現(xiàn)的這個頭視圖分區(qū)對應(yīng) row
func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
判斷條件滿足 是右欄 tableView 并且是向下滑動 而且滑動原因是手指拖拽滑動 不然的話點擊左欄促使右欄滑動那么又反過來導(dǎo)致左欄滑動
if tableView.tag == 1002 && ScrollState == UpOrDownScroller.Down && rightScrollReason
{
self.leftTableView.selectRowAtIndexPath(NSIndexPath.init(forRow: section, inSection: 0), animated: true, scrollPosition: UITableViewScrollPosition.Middle)
}
}```
- 右欄上滑的時候 有頭視圖要消失的時候 左側(cè)選中將要消失的下一個區(qū)號對應(yīng) row
func tableView(tableView: UITableView, didEndDisplayingHeaderView view: UIView, forSection section: Int) {
# 判斷條件滿足 是右欄 tableView 并且是向上滑動 而且滑動原因是手指拖拽滑動 不然的話點擊左欄促使右欄滑動那么又反過來導(dǎo)致左欄滑動
if tableView.tag == 1002 && ScrollState == UpOrDownScroller.Up && rightScrollReason
{
self.leftTableView.selectRowAtIndexPath(NSIndexPath.init(forRow: section + 1, inSection: 0), animated: true, scrollPosition: UITableViewScrollPosition.Middle)
}
}```
----------
![**不考慮右欄的滑動是不是手指拖拽時效果(bug 點擊左欄右欄滑動同時左欄也滑動了**)](http://upload-images.jianshu.io/upload_images/1523603-f0fa29a4d9628dc8.gif?imageMogr2/auto-orient/strip)