在網(wǎng)上看到一些寫新浪微博個人主頁的實現(xiàn)思路和代碼的文章宴凉,實際按他們的思路來做項目的時候發(fā)現(xiàn)有些效果跟真正的新浪微博不太一樣琼梆。特別是頭視圖與幾個subTableView的交互效果度液,比如有些demo的頭視圖無法實現(xiàn)懸停豆巨,有的demo頭視圖無法點擊響應事件或者上下滾動浅浮,有些Demo無法左右滾動幾個subTableView的同時保持頭視圖不動暴浦。
后來經(jīng)過各種嘗試,終于自己在項目中將所有效果都實現(xiàn)了崇败,現(xiàn)在把思路和代碼分享下盅称。
一、頁面交互效果分析:
1.主頁面上下滑動時是在一個subTableView中滑動后室,左右滑動是切換到其他的subTableView缩膝;
2.有一個頭部headerView,無論哪個subTableView上下滑動岸霹,頭部視圖都會貼著隨之上下運動疾层,而且向下滾動到極限時帶彈性效果;左右滑動的時候subTableView時松申,headerView的位置固定不變云芦;
3.headerView上滑時慢慢消失俯逾,露出導航欄,下拉時慢慢出現(xiàn)舅逸,導航欄消失桌肴;header頭部視圖滑動到頂部時上面自帶的子菜單欄會懸停在導航欄下方;選擇子菜單欄能夠切換subTableView琉历;
4.在headerView區(qū)域觸摸也可以上下滾動坠七,效果和在subTableView上的滾動效果一模一樣;headerView區(qū)域有各種控件旗笔,點擊有事件響應彪置;
5.如果headerView滾到最頂部即子菜單欄處于懸停狀態(tài),切換subTableView時蝇恶,各subTableView的滾動位置不變拳魁;否則,滾動時第二個subTableView會自動滾動到頂部撮弧;
6.navigationBar和title的透明度效果變化:第一個使用的是動態(tài)添加透明度變化的backGroundImage潘懊,第二個是動態(tài)改變titleView的alpha
二、實現(xiàn)思路及主要代碼:
1.要想實現(xiàn)頁面中的subTableView手勢上下左右滾動效果贿衍,必然是要將幾個subTableView加載到一個水平方向滾動的horizontalScrollView上授舟;
// 水平滾動的containScrollView
view.addSubview(containScrollView)
// 第1個tableView
let firstVC = HLProfileTableViewController.init(style: UITableViewStyle.grouped) firstVC.coverHeight = cacu_coverHeight + seperatorLineHeight containScrollView.addSubview(firstVC.view)
self.addChildViewController(firstVC)
// 第2個tableView
let secondVC = HLWeiboTableViewController.init(style: UITableViewStyle.grouped) secondVC.coverHeight = cacu_coverHeight + seperatorLineHeight containScrollView.addSubview(secondVC.view) self.addChildViewController(secondVC)
// 第3個tableView let thirdVC = HLNewsTableViewController.init(style: UITableViewStyle.grouped) thirdVC.coverHeight = cacu_coverHeight + seperatorLineHeight containScrollView.addSubview(thirdVC.view)
self.addChildViewController(thirdVC)
// 頭部視圖放在主視圖的最外面
view.addSubview(headerView)
headerView.frame = CGRect.init(x: 0, y: 0, width: ScreenW, height: headerHeight)
2.headerView的層級,根據(jù)它的UI交互方式贸辈,作為subTableView的子視圖的方式非常難以處理释树,這里是放在控制器主視圖的最外層。這樣subTableView水平滾動時它可以不會受影響擎淤;subTableView上下滾動的時候使用代理動態(tài)的調(diào)整headerView的高度即可奢啥;
var transform_y = scrollView.contentOffset.y
//tableView同步的滾動極限
let scrollLimit = cacu_coverHeight - switchMenuHeight + seperatorLineHeight if transform_y > scrollLimit {
transform_y = scrollLimit navigationController?.navigationBar.isTranslucent = false }else{ navigationController?.navigationBar.isTranslucent = true } navigationController?.navigationBar.setBackgroundImage(self.imageWithColor(color: UIColor.init(white:1 , alpha: transform_y/scrollLimit)), for: UIBarMetrics.default) titleLabel.textColor = UIColor.init(white:0 , alpha: transform_y/scrollLimit) // 因為有個seperatorLine,所有scrollView的滾動范圍有可能小于帶上switchMenuHeight的總高度嘴拢, if headerHeight - transform_y < switchMenuHeight + CYTStatusBarHeight + CYTNavigationBarHeightForSwi {
// 如果滾到范圍到了小于switchMenuHeight高度的時候扫尺,headerView高度保持不變
headerView.frame = CGRect.init(x: 0, y: 0, width: ScreenW, height: switchMenuHeight + CYTStatusBarHeight + CYTNavigationBarHeightForSwi)
}else{
headerView.frame = CGRect.init(x: 0, y: 0, width: ScreenW, height: headerHeight - transform_y)
}
3.headerView上的UI交互方式處理方式如下:使用HitTest方法進行判斷,如果headerView的子視圖需要進行UI交互炊汤,就讓該視圖接收手勢;否則就返回nil弊攘,也即是將手勢方法傳遞到headerView下面的tableView上抢腐,這樣headerView不點擊子視圖只是上下滾動就和直接滾動tableView效果一樣。代碼:
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
//需要交互的元素襟交,點擊時觸發(fā)點擊響應
for view in interactionItems {
if view.frame.contains(point){
return view
}
}
//點擊需要交互的元素以外的區(qū)域迈倍,不觸發(fā)點擊響應
return nil
}