UIScrollView嵌套滾動方案

預期效果

如圖1所示:
UIScrollView進行嵌套組合庭瑰,最外層是一個UIScrollView喂走,為了說明方便蜕该,稱為父UIScrollView
里面嵌套著頭部區(qū)栓拜、懸停區(qū)和一個UIScrollView一膨,稱為子UIScrollView

圖1

要求頭部區(qū)展示在屏幕時呀邢,滾動內(nèi)容為父UIScrollView,一旦頭部區(qū)域消失在屏幕中時豹绪,這個時候滾動的內(nèi)容為子UIScrollView价淌,懸停區(qū)懸停在屏幕頂部。如圖2 所示


圖2

解決方案

方案1

通過監(jiān)聽父UIScrollView的contentOffset瞒津,如果偏移量小于于頭部區(qū)的高度蝉衣,則設置父UIScrollView的scrollEnabled為YES,設置子UIScrollView的scrollEnable為NO巷蚪。如果偏移量大于頭部區(qū)的高度病毡,則設置父UIScrollView的scrollEnabled為NO,設置子UIScrollView的scrollEnable為YES.
這個方案存在最大的問題是一旦快速滑動屏幕屁柏,到臨界值那邊會卡住啦膜,需要重新施加一次滑動手勢,才能繼續(xù)滾動淌喻。

方案2

讓一次手勢同時擁有多個響應者僧家,即一次滑動手勢無論子UIScrollView或者父UIScrollView都能作為響應者進行滾動,然后我們根據(jù)自己的需要進行重置不需要的滾動效果裸删。
要達到手勢能夠被多個UIView進行響應八拱,需要在父UIScrollView實現(xiàn) UIGestureRecognizerDelegate 代理方法

//支持手勢同步到其他接收者
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

在他們所在的父View或ViewController中實現(xiàn) UIScrollViewDelegate 的

-(void)scrollViewDidScroll:(UIScrollView *)scrollView

默認只能滾動父UIScrollView,子UIScrollView在未被允許滾動的情況涯塔,偏移量會被重置為0肌稻。 比對父UIScrollView的偏移量和頭部區(qū)的高度,如果偏移量大于等于頭部區(qū)的高度匕荸,則開始重置父頭部區(qū)的高度的偏移量為頭部區(qū)高度爹谭,子UIScrollView不再重置偏移量為0.

具體代碼實現(xiàn)

定義一個父UIScrollView為 FatherScrollView

// FatherScrollView.h
#import <UIKit/UIKit.h>

@interface FatherScrollView : UIScrollView<UIGestureRecognizerDelegate>

@end


//FatherScrollView.m
#import "FatherScrollView.h"

@implementation FatherScrollView

//支持手勢同步到其他接收者
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

@end

定義一個ViewController進行內(nèi)容展示

#import "ViewController.h"
#import "FatherScrollView.h"

@interface ViewController ()<UIScrollViewDelegate>
//父UIScrollView
@property (nonatomic, strong) FatherScrollView *fatherscrollView;
//頭部區(qū)
@property (nonatomic, strong) UIView *headerView;
//子UIScrollView
@property (nonatomic, strong) UIScrollView *childScrollView;
//父UIScrollView是否能滾動
@property (nonatomic, assign) BOOL enableFatherViewScroll;
//子UIScrollView是否能滾動
@property (nonatomic, assign) BOOL enableChildViewScroll;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = UIColor.whiteColor;
    self.enableChildViewScroll = NO;
    self.enableFatherViewScroll = YES;
    self.automaticallyAdjustsScrollViewInsets = NO;
    
    self.fatherscrollView = [[FatherScrollView alloc] initWithFrame:self.view.bounds];
    self.fatherscrollView.delegate = self;
    self.fatherscrollView.bounces = YES;
    self.fatherscrollView.backgroundColor = UIColor.grayColor;
    self.fatherscrollView.contentSize = CGSizeMake(0, self.view.bounds.size.height+200);
    [self.view addSubview:self.fatherscrollView];
    
    self.headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 200)];
    self.headerView.backgroundColor = UIColor.greenColor;
    [self.fatherscrollView addSubview:self.headerView];
    UILabel *label = [[UILabel alloc] init];
    label.text = @"懸浮標題";
    label.textAlignment = NSTextAlignmentCenter;
    label.frame = CGRectMake(0, 160, self.view.bounds.size.width, 40);
    label.backgroundColor = UIColor.whiteColor;
    [self.headerView addSubview:label];
    
    self.childScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 200, self.view.bounds.size.width, self.view.bounds.size.height)];
    self.childScrollView.delegate = self;
    self.childScrollView.contentSize = CGSizeMake(0, self.view.bounds.size.height * 1.5);
    self.childScrollView.backgroundColor = UIColor.redColor;
    [self.fatherscrollView addSubview:self.childScrollView];
    
    UILabel *contentLabel = [[UILabel alloc] init];
    contentLabel.font = [UIFont systemFontOfSize:50];
    contentLabel.text = @"子滾動內(nèi)容";
    contentLabel.textAlignment = NSTextAlignmentCenter;
    contentLabel.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
    [self.childScrollView addSubview:contentLabel];
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat contentOffset = 160 - [UIApplication sharedApplication].statusBarFrame.size.height;
    if (scrollView == self.fatherscrollView) {
        if (!self.enableFatherViewScroll) {
            scrollView.contentOffset = CGPointMake(0, contentOffset);
            self.enableChildViewScroll = YES;
        } else {
            if (scrollView.contentOffset.y >= contentOffset) {
                scrollView.contentOffset = CGPointMake(0, contentOffset);
                if (self.enableFatherViewScroll) {
                    self.enableFatherViewScroll = NO;
                    self.enableChildViewScroll = YES;
                }
            }
        }
    } else {
        if (!self.enableChildViewScroll) {
            scrollView.contentOffset = CGPointMake(0, 0);
        } else {
            if (scrollView.contentOffset.y <= 0) {
                self.enableChildViewScroll = NO;
                self.enableFatherViewScroll = YES;
            }
        }
    }
}

@end
開發(fā)中的問題

1、這種嵌套的設計榛搔,往往會包含有多個子UIScrollView并且可以進行左右滑動切換旦棉,子UIScrollView區(qū)域往往會當獨封閉齿风,如果都在UIViewController這邊進行處理的話,會有大量的耦合代碼出現(xiàn)
2绑洛、不得不為父UIScrollView創(chuàng)建一個新的UIScrollView在子類救斑,實現(xiàn) (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer

針對上面問題,我這邊對UIScrollView嵌套方案進行了簡要的封裝真屯,方便開發(fā)中直接使用
Demo地址:CCNestScrollView

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末脸候,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子绑蔫,更是在濱河造成了極大的恐慌运沦,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件配深,死亡現(xiàn)場離奇詭異携添,居然都是意外死亡,警方通過查閱死者的電腦和手機篓叶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門烈掠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缸托,你說我怎么就攤上這事左敌。” “怎么了俐镐?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵矫限,是天一觀的道長。 經(jīng)常有香客問我佩抹,道長叼风,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任棍苹,我火速辦了婚禮无宿,結果婚禮上,老公的妹妹穿的比我還像新娘廊勃。我一直安慰自己,他們只是感情好经窖,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布坡垫。 她就那樣靜靜地躺著,像睡著了一般画侣。 火紅的嫁衣襯著肌膚如雪冰悠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天配乱,我揣著相機與錄音溉卓,去河邊找鬼皮迟。 笑死,一個胖子當著我的面吹牛桑寨,可吹牛的內(nèi)容都是我干的伏尼。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼尉尾,長吁一口氣:“原來是場噩夢啊……” “哼爆阶!你這毒婦竟也來了?” 一聲冷哼從身側響起沙咏,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤辨图,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后肢藐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體故河,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年吆豹,在試婚紗的時候發(fā)現(xiàn)自己被綠了鱼的。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡瞻讽,死狀恐怖鸳吸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情速勇,我是刑警寧澤晌砾,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站烦磁,受9級特大地震影響养匈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜都伪,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一呕乎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧陨晶,春花似錦猬仁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至褐耳,卻和暖如春诈闺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背铃芦。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工雅镊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留襟雷,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓仁烹,卻偏偏與公主長得像耸弄,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子晃危,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

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