[iOS]簡書個人頁效果(上下滾動時菜單懸停且可左右切換)

演示

本文主要介紹 上下滾動時菜單懸停在頂端,并且可以左右滑動切換的特殊視圖的實(shí)現(xiàn)方式。涉及知識包含事件響應(yīng)鏈助琐,UIScorllView滾動模擬,以及刷新控件的基本原理面氓。

一兵钮、前言

隨著業(yè)務(wù)的發(fā)展,系統(tǒng)提供的常規(guī)視圖已經(jīng)難以滿足需求舌界,偉大的UI設(shè)計師總能想出一些特殊的違反常理的視圖來挑戰(zhàn)程序員的腦細(xì)胞掘譬。這種上下滾動還可左右滑動切換最初也不知是哪家提出來的,但是經(jīng)過這么久發(fā)展呻拌,這種視圖展現(xiàn)方式也被越來越多的App使用葱轩,此類開源框架也有不少,實(shí)現(xiàn)處理方式也很奇妙,但也各有缺點(diǎn)和限制靴拱。

二垃喊、部分框架

2.1 YX_UITableView_IN_UITableView

此類視圖常見的做法便是UIScorllView套UIScorllView,使內(nèi)層的UITableView(TAB欄里面)和外層的UITableView同時響應(yīng)用戶的手勢滑動事件袜炕。當(dāng)用戶從頁面頂端從下往上滑動到TAB欄的過程中本谜,使外層的UITableView跟隨用戶手勢滑動,內(nèi)層的UITableView不跟隨手勢滑動偎窘。當(dāng)用戶繼續(xù)往上滑動的時候乌助,讓外層的UITableView不跟隨手勢滑動,讓內(nèi)層的UITableView跟隨手勢滑動陌知。反之從下往上滑動也一樣他托。

缺點(diǎn):當(dāng)用戶從頁面頂端從下往上滑動到TAB欄的過程中,會停住不會有單獨(dú)scrollview那如絲滑一般的滾動效果纵诞。

大部分類似框架都存在該問題上祈,如 MXSegmentedPager也是如此,本來這樣效果也挺好了浙芙,但是UI說你看看簡書就可以登刺,美妝心得就可以,產(chǎn)品說如果沒有如絲滑一般的滾動不如不上......

2.2 HHHorizontalPagingView

為了滿足UI和產(chǎn)品的需求嗡呼,筆者輾轉(zhuǎn)反側(cè) 夜不能寐終于發(fā)現(xiàn)了曙光纸俭,該作者的思路非常巧妙:

HHHorizontalPagingView 通過重寫 - (UIView *)hitTest:(CGPoint)point 
withEvent:(UIEvent *)event方法 將headerView 上的響應(yīng)作用在了 
self.currentScrollView (當(dāng)前展現(xiàn)的scrollerView)上,滾動就根據(jù)contentOffset來移動
headerView南窗。點(diǎn)擊就調(diào)用 @property (nonatomic, copy) void 
(^clickEventViewsBlock)(UIView *eventView); 
eventView 是hitTest方法查找到的view揍很。

缺點(diǎn):1.只要headerView稍微復(fù)雜點(diǎn),點(diǎn)擊事件就非常難以處理万伤。
     2.破壞了headerView的事件響應(yīng)鏈窒悔,如果想在headerView上添加輪播圖就無法手勢左右滑動了。

針對以上兩個缺點(diǎn)敌买,缺點(diǎn)2 限于攔截的實(shí)現(xiàn)方法導(dǎo)致系統(tǒng)的手勢處理都沒作用在headerView简珠,已是無法實(shí)現(xiàn)。缺點(diǎn)1在筆者冥思苦想下做出了一種解決方案虹钮。

點(diǎn)擊難以處理主要是聋庵,作者為了實(shí)現(xiàn)該效果,重寫hitTest方法芙粱,導(dǎo)致了headerView響應(yīng)者鏈條的斷裂祭玉,雖然作者提供了一個block回調(diào),但對于點(diǎn)擊處理無疑是反人類春畔。我的想法是在點(diǎn)擊處理時將響應(yīng)者鏈條接起來脱货。關(guān)于響應(yīng)者鏈條可以看看該文章岛都。
Huanhoo 使用@property (nonatomic, copy) void (^clickEventViewsBlock)
(UIView *eventView);來處理點(diǎn)擊事件,而eventView就是 命中測試view 蹭劈, 而我要做的
就是通過這個命中測試view向上查找處理該事件疗绣。

實(shí)現(xiàn)方法:
引入UIView+WhenTappedBlocks這是一個手勢處理的分類,
#pragma mark - 模擬響應(yīng)者鏈條 由被觸發(fā)的View 向它的兄弟控件 父控件 延伸查找響應(yīng)
    - (void)viewWasTappedPoint:(CGPoint)point{
        [self clickOnThePoint:point];
    }
    
    - (BOOL)clickOnThePoint:(CGPoint)point{
        
        if ([self.superview isKindOfClass:[UIWindow class]]) {
            return NO;
        }
        
        if (self.block) {
            self.block();
            return YES;
        }
        
        __block BOOL click = NO;
        // 看兄弟控件
        [self.superview.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            // 轉(zhuǎn)換坐標(biāo)系 看點(diǎn)是否在View上
            CGPoint objPoint = [obj convertPoint:point fromView:self];
            if (!CGRectContainsPoint(obj.frame, objPoint)) {
                //            NSLog(@"-----%@",NSStringFromCGPoint(objPoint));
                return;
            }
            if (self.block) {
                self.block();
                click = YES;
                *stop = YES;
            }
        }];
        
        if (!click) {
            return [self.superview clickOnThePoint:point];
        }
        
        return click;
    }
    
正常響應(yīng)铺韧,有點(diǎn)擊手勢觸發(fā)方法來執(zhí)行block多矮,非正常點(diǎn)擊 主動調(diào)用
- (void)viewWasTappedPoint:(CGPoint)point;方法就可以接起響應(yīng)者鏈條。

關(guān)于以上的實(shí)現(xiàn)可以看 JYHHHorizontalPagingView 1.1.0版本這是筆者對
HHHorizontalPagingView的一個優(yōu)化處理讓點(diǎn)擊易于處理哈打,但是也僅僅只能接起點(diǎn)擊事件塔逃。在headerView上加輪播圖無法實(shí)現(xiàn),甚至UIButton的長按高亮效果在headerView上也會失效料仗。但是它有絲滑一般的滑動湾盗,headerView和下部的每一個ScrollView滾動效果都是一體的。

三立轧、 JYHHHorizontalPagingView模擬ScrollView的滾動

上面介紹的框架限于實(shí)現(xiàn)方式都各有缺陷格粪,那到底能不能做到完美,答案是肯定的氛改,畢竟美妝心得做到了帐萎,簡書做到了(UIButton 的長按高亮效果猶在說明headerView上的響應(yīng)并沒有被破環(huán))。我的思路是在headerView上添加拖拽手勢改變下方scrollView的contentOffset胜卤,模擬scrollView的減速滑動以及彈簧效果疆导。

3.1模擬彈簧效果
  彈簧效果的實(shí)現(xiàn)很簡單使用UIView 動畫即可。
        [UIView animateWithDuration:0.35 animations:^{
            self.currentScrollView.contentOffset = CGPointMake(contentOffset.x, border);
            [self layoutIfNeeded];
        }];
3.2模擬減速滑動效果

減速滑動效果確實(shí)不好實(shí)現(xiàn)葛躏,我嘗試過不少方法效果都不太好澈段,后來看到了餓了么一位開發(fā)者的博客,他是通過UIDynamic的物理特性來模擬scrollView滾動舰攒。按照他的方法完美實(shí)現(xiàn)了模擬败富。作者的博客地址目前好像無法進(jìn)去就貼一個推酷的轉(zhuǎn)載用UIKit Dynamics模仿UIScrollView,具體的一些說明作者講的很清晰我就不多說了摩窃,大家可以自己看看兽叮,也可以直接看我的代碼。

四偶芍、擴(kuò)展功能

到目前為止,該類視圖的功能可以說是相當(dāng)完美了德玫,但是需求永遠(yuǎn)是難以滿足的匪蟀,某天產(chǎn)品說現(xiàn)在數(shù)據(jù)沒有更新機(jī)制只能上拉刷新,不能下拉刷新宰僧。what材彪?這么反人類的功能你還要加下拉刷新......

針對此類需求,筆者為此添加了單獨(dú)下拉刷新以及整體下拉刷新,由于篇幅問題段化,筆者就不再多說了嘁捷,感興趣的同學(xué)可以去 github -JYHHHorizontalPagingView看具體介紹說明。

五显熏、結(jié)尾

如果我的文章對你有幫助或者給了你一些啟發(fā)雄嚣,希望你能在github給個小星星,如果你在使用過程中遇到了Bug請留言反饋喘蟆,我會及時解決缓升。歡迎轉(zhuǎn)載(在文章開頭標(biāo)明來源即可)。

六蕴轨、補(bǔ)充

1.很多人反饋有偏移啥的港谊,看下 self.edgesForExtendedLayout = UIRectEdgeNone;

  1. pod 1.2.1 版本已經(jīng)支持自定義 SegmentView,自定義view只需支持JYSegmentViewProtocol協(xié)議即可。具體可參考默認(rèn)的JYSegmentView 橙弱。

七歧寺、最后再推薦一個(相當(dāng)給力,可定制性強(qiáng))

github -HVScrollView
感謝 S型身材的豬

思路:
首先最底部是一個全屏的scrollView棘脐,這個scrollView的作用是橫向滑動斜筐,scrollView上面添加若干個tableView,然后每個tableView上設(shè)置頂部內(nèi)邊距荆残,頂部由內(nèi)邊距空出來的地方就放headerView和菜單欄奴艾。headerView和菜單欄放在控制器 view上。當(dāng)滑動tableView時内斯,讓headerView的y值隨著 scrollview的偏移量時刻改變蕴潦,刷新也不會有問題。

我看了下代碼俘闯,相當(dāng)給力潭苞,思路實(shí)現(xiàn)都相當(dāng)好值得學(xué)習(xí)。
大家看評論的話真朗,作者有這么一句話:
不知道為什么網(wǎng)上幾個人封裝都去用collectionView搞那么復(fù)雜此疹。

為什么這么復(fù)雜呢?一個功能又是響應(yīng)鏈的打斷遮婶,又是模擬滾動蝗碎,view還一層套一層。針對一種特殊需求的出現(xiàn)旗扑,前期并沒有太多的開源代碼供大家學(xué)習(xí)和研究蹦骑,在時間的緊逼之下,大家都選擇了自己的處理方式臀防,隨著后期的迭代眠菇,為了達(dá)到需要的效果边败,各個流派在原有基礎(chǔ)上做出了相應(yīng)處理。這些方案也許并不是最好的捎废,最簡單的笑窜,但它們都包含了作者的智慧與思想。對于這些作者我們應(yīng)心存感激登疗,因?yàn)樗麄冮_源排截,他們無私的分享了自己的思路,這些如今看來也許并不友好的實(shí)現(xiàn)方式卻是在我們最迷茫最需要時給了我們幫助與啟發(fā)谜叹。也正因?yàn)橛兴麄兊姆桨竵肀WC項(xiàng)目的正常上線匾寝,我們才敢嘗試更簡單更高效的方法。最后感謝開源荷腊。

本文所列舉的一些DEMO都有自己的實(shí)現(xiàn)方式艳悔,大家可研究學(xué)習(xí)一下選擇最適合的。感謝這些開源作者女仰。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末猜年,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子疾忍,更是在濱河造成了極大的恐慌乔外,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件一罩,死亡現(xiàn)場離奇詭異杨幼,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)聂渊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門差购,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人汉嗽,你說我怎么就攤上這事欲逃。” “怎么了饼暑?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵稳析,是天一觀的道長。 經(jīng)常有香客問我弓叛,道長彰居,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任撰筷,我火速辦了婚禮陈惰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘闭专。我一直安慰自己奴潘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布影钉。 她就那樣靜靜地躺著画髓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪平委。 梳的紋絲不亂的頭發(fā)上奈虾,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天,我揣著相機(jī)與錄音廉赔,去河邊找鬼肉微。 笑死,一個胖子當(dāng)著我的面吹牛蜡塌,可吹牛的內(nèi)容都是我干的碉纳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼馏艾,長吁一口氣:“原來是場噩夢啊……” “哼劳曹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起琅摩,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤铁孵,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后房资,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蜕劝,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年轰异,在試婚紗的時候發(fā)現(xiàn)自己被綠了岖沛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡溉浙,死狀恐怖烫止,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情戳稽,我是刑警寧澤馆蠕,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站惊奇,受9級特大地震影響互躬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜颂郎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一吼渡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧乓序,春花似錦寺酪、人聲如沸坎背。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽得滤。三九已至,卻和暖如春盒犹,著一層夾襖步出監(jiān)牢的瞬間懂更,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工急膀, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留沮协,地道東北人。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓卓嫂,卻偏偏與公主長得像慷暂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子晨雳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 為關(guān)注的人點(diǎn)贊
    346e82fe5086閱讀 121評論 0 0
  • 路邊乞丐彈吉他呜呐, 人人聽了人人夸。 不知你在笑個啥悍募, 難 道你還有才華蘑辑。
    晚風(fēng)輕語閱讀 155評論 1 10
  • 周幽王在位時,西周國勢衰落坠宴,社會矛盾尖銳洋魂,潛伏著政治和經(jīng)濟(jì)的諸多危機(jī)。但他不思進(jìn)取喜鼓,一味貪求淫蕩奢靡的生活副砍。他為博...
    顧晴晞閱讀 330評論 0 0
  • 知己圖片發(fā)自肉肉菜菜 作者肉肉菜菜 有與無,有區(qū)別嗎庄岖? 一個是屬于自己豁翎, 一個是屬于別人, 這就是區(qū)別隅忿。 知己又是...
    南末森森書卷記閱讀 863評論 4 24
  • 我與寶爸2008年年底心剥,匆匆走進(jìn)婚姻,沒有共同話題背桐,沒有居住的小窩优烧,沒有婚禮×辞停婚后畦娄,我們與父母住一起,來自新化...
    7be5afaf5ed4閱讀 238評論 0 0