自定義UIScrollView翻頁寬度

預(yù)覽

ScrollView.gif

前言

好奇心日報的有的文章頁面是這樣展示的滤蝠,點擊其中一個就可以進(jìn)入單個的文章詳情頁面李根,于是想了一下該怎么實現(xiàn)。

思路

一開始想的是用一個ScrollView去實現(xiàn)几睛,后來發(fā)現(xiàn)一個ScrollView實現(xiàn)的話最后一頁會有問題,也沒有想到解決方案粤攒,于是就用兩個ScrollView來實現(xiàn)

屏幕快照 2017-02-21 下午3.32.44.png

屏幕快照 2017-02-21 下午3.32.55.png

第一張圖藍(lán)色標(biāo)記的是底下的小的ScrollView,它的作用是實現(xiàn)翻頁效果所森,第二張圖藍(lán)色標(biāo)記的是上層的大的ScrollView,用來展示內(nèi)容夯接,用小的UIScrollView來帶動大的ScrollView滑動焕济,大的ScrollView不參與用戶滑動事件

實現(xiàn)

假設(shè)展示4頁內(nèi)容

一些宏定義

#define kScreenWidth ([UIScreen mainScreen].bounds.size.width)
#define kScreenHeight ([UIScreen mainScreen].bounds.size.height)
#define kContentWidth 250
#define kContentHeight 400
#define kPadding 20

SmallScrollView

需要注意的是,小的ScrollView最后一頁的寬度需要計算一下

self.smallScrollView = ({
        UIScrollView *scroll = [[UIScrollView alloc] init];
        scroll.delegate = self;
        scroll.showsHorizontalScrollIndicator = NO;
        scroll.pagingEnabled = YES;
        [self addSubview:scroll];
        [scroll makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(self).offset(UIEdgeInsetsMake(0, kPadding / 2, 0, kScreenWidth - kPadding - kContentWidth - kPadding / 2));
        }];
        
        UIView *content = [[UIView alloc] init];
        [scroll addSubview:content];
        [content makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(scroll);
            make.height.equalTo(scroll);
        }];
        
        UIView *lastView;
        
        for (NSInteger i=0; i<4; i++) {
            UIView *view = [[UIView alloc] init];
            [content addSubview:view];
            if (i == 0) {
                [view makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(kPadding / 2);
                    make.top.bottom.equalTo(content);
                    make.width.equalTo(kContentWidth);
                    make.height.equalTo(kContentHeight);
                }];
            } else if (i == 3) {
                [view makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(lastView.right).offset(kPadding);
                    make.top.bottom.equalTo(content);
                    make.width.equalTo(kContentWidth - (kScreenWidth - kPadding * 2 - kContentWidth));
                    make.height.equalTo(kContentHeight);
                }];
            } else {
                [view makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(lastView.right).offset(kPadding);
                    make.top.bottom.equalTo(content);
                    make.width.equalTo(kContentWidth);
                    make.height.equalTo(kContentHeight);
                }];
            }
            lastView = view;
        }
        [content makeConstraints:^(MASConstraintMaker *make) {
            make.right.equalTo(lastView.right).offset(kPadding / 2);
        }];
        
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(smallScrollTap:)];
        [scroll addGestureRecognizer:tap];
        
        scroll;
    });

BigScrollView

self.bigScrollView = ({
        UIScrollView *scroll = [[UIScrollView alloc] init];
        scroll.clipsToBounds = NO;
        scroll.showsHorizontalScrollIndicator = NO;
        [self addSubview:scroll];
        [scroll makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(self).offset(UIEdgeInsetsMake(0, kPadding / 2, 0, kPadding / 2));
        }];
        
        UIView *content = [[UIView alloc] init];
        [scroll addSubview:content];
        [content makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(scroll);
            make.height.equalTo(scroll);
        }];
        
        UIView *lastView;
        
        for (NSInteger i=0; i<4; i++) {
            UIView *view = [[UIView alloc] init];
            view.backgroundColor = [self randomColor];
            [content addSubview:view];
            if (i == 0) {
                [view makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(kPadding / 2);
                    make.top.equalTo(content);
                    make.width.equalTo(kContentWidth);
                    make.height.equalTo(kContentHeight);
                }];
            } else {
                [view makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(lastView.right).offset(kPadding);
                    make.top.equalTo(content);
                    make.width.equalTo(kContentWidth);
                    make.height.equalTo(kContentHeight);
                }];
            }
            lastView = view;
            
//            UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
//            [btn setBackgroundColor:[UIColor lightGrayColor]];
//            [btn setTitle:@"Button" forState:UIControlStateNormal];
//            [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
//            [view addSubview:btn];
//            [btn makeConstraints:^(MASConstraintMaker *make) {
//                make.centerX.equalTo(view);
//                make.width.equalTo(100);
//                make.height.equalTo(50);
//                make.bottom.equalTo(-50);
//            }];
        }
        [content makeConstraints:^(MASConstraintMaker *make) {
            make.right.equalTo(lastView.right).offset(kPadding / 2);
        }];
        
        scroll;
    });

其它

前面說到大的ScrollView不參與用戶事件盔几,那該怎樣做到呢晴弃?

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    return self.smallScrollView;
}

就是這么簡單。。上鞠。所有事件都讓底下的小的ScrollView去處理际邻,實現(xiàn)ScrollView的代理方法,進(jìn)而帶動大的ScrollView滑動

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView == self.smallScrollView) {
        [self.bigScrollView setContentOffset:scrollView.contentOffset animated:NO];
    }
}

關(guān)于滑動的就處理完了

點擊事件

下面就是處理用戶點擊單個頁面了,給小的ScrollView添加單擊手勢芍阎,然后將點轉(zhuǎn)化到大的ScrollView即完成了單擊手勢的檢測世曾,假如頁面上有button,判斷點是否在button內(nèi)進(jìn)而處理

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(smallScrollTap:)];
        [scroll addGestureRecognizer:tap];
- (void)smallScrollTap:(UITapGestureRecognizer *)sender{
    [self.bigSubViews removeAllObjects];
    [self listSubviewsOfView:self.bigScrollView];
    CGPoint bigPoint = [sender locationInView:self.bigScrollView];
    for (UIView *view in self.bigSubViews.reverseObjectEnumerator) {
        if ([view isKindOfClass:[UIButton class]]) {
            CGPoint buttonPoint = [view convertPoint:bigPoint fromView:self.bigScrollView];
            if (CGRectContainsPoint(view.bounds, buttonPoint)) {
                [(UIButton *)view sendActionsForControlEvents:UIControlEventTouchUpInside];
            }
        }
    }
}

- (void)listSubviewsOfView:(UIView *)view {
    NSArray *subviews = [view subviews];
    if ([subviews count] == 0) return;
    for (UIView *subview in subviews) {
        [self.bigSubViews addObject:subview];
        [self listSubviewsOfView:subview];
    }
}

不足

我也不清楚別人是怎么實現(xiàn)這種ScrollView效果的谴咸,這個方法我也不清楚是不是最好的轮听,只是我能想到的方法,當(dāng)然有些許不足岭佳,比如都交給小的ScrollView處理血巍,展示的內(nèi)容如果有button,button在normall,highlighted,selected狀態(tài)設(shè)置了不同的樣式珊随,該實現(xiàn)是沒有辦法展示的述寡,因為我只是發(fā)送了一個事件過去。所以如果你有更好的方法玫恳,不妨發(fā)表一下辨赐!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市京办,隨后出現(xiàn)的幾起案子掀序,更是在濱河造成了極大的恐慌,老刑警劉巖惭婿,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件不恭,死亡現(xiàn)場離奇詭異,居然都是意外死亡财饥,警方通過查閱死者的電腦和手機(jī)换吧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來钥星,“玉大人沾瓦,你說我怎么就攤上這事∏矗” “怎么了贯莺?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長宁改。 經(jīng)常有香客問我缕探,道長,這世上最難降的妖魔是什么还蹲? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任爹耗,我火速辦了婚禮耙考,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘潭兽。我一直安慰自己倦始,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布讼溺。 她就那樣靜靜地躺著楣号,像睡著了一般。 火紅的嫁衣襯著肌膚如雪怒坯。 梳的紋絲不亂的頭發(fā)上炫狱,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天,我揣著相機(jī)與錄音剔猿,去河邊找鬼视译。 笑死,一個胖子當(dāng)著我的面吹牛归敬,可吹牛的內(nèi)容都是我干的酷含。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼汪茧,長吁一口氣:“原來是場噩夢啊……” “哼椅亚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起舱污,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤呀舔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后扩灯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體媚赖,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年珠插,在試婚紗的時候發(fā)現(xiàn)自己被綠了惧磺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡捻撑,死狀恐怖磨隘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情顾患,我是刑警寧澤琳拭,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站描验,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏坑鱼。R本人自食惡果不足惜膘流,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一絮缅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧呼股,春花似錦耕魄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至缠局,卻和暖如春则奥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背狭园。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工读处, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人唱矛。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓罚舱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親管闷。 傳聞我的和親對象是個殘疾皇子窃肠,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,678評論 2 354

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,094評論 25 707
  • 為了能預(yù)覽GitHub上的頁面呕臂,GitHub推出了 GitHub Pages 功能歧蒋,以下是設(shè)置GitHub Pag...
    chiang24閱讀 1,484評論 0 0
  • 一個走在偽文藝道路上,混吃騙喝阐虚,愛健身蚌卤,愛美食,愛攝影的編程妞帶你一起領(lǐng)略做飯這件小事 不知道從什么時候開始喜歡上...
    編程妞閱讀 313評論 2 1
  • 兒子現(xiàn)在已有四歲三個月有余避矢,在我的記憶中只有一次审胸,在2015年九月份去濟(jì)南學(xué)習(xí)歹嘹,分開一晚尺上;除此之外我們娘倆沒有分開...
    Sunny仔仔閱讀 382評論 1 0
  • 天晴的時候,放一只紙鳶豆赏,鳶在天上飛掷邦,人在地上跑抚岗。他們之間宣蔚,有一根連線胚委,叫做思念亩冬。
    童真的眼睛閱讀 174評論 0 0