iOS 解決UIScrollView布局問題(布局受statusBar和NavigationBar影響)

主題 UIScrollView

iOS APP中有一個(gè)非常好用的功能,那就是當(dāng)我們?cè)跐L動(dòng)一個(gè)UIScrollView滾動(dòng)了很遠(yuǎn)很遠(yuǎn)的時(shí)候,假如我們想讓UIScrollView回到頂部,我們絕大多數(shù)人的做法就是慢慢慢慢的滾動(dòng)UIScrollView直到他回到頂部,但是iOS給我們提供了一個(gè)非常有用的功能,那就是只要我們一點(diǎn)擊屏幕上的狀態(tài)欄,就能讓UIScrollView自動(dòng)回到頂部(初始位置),其實(shí)我也是今天學(xué)到了這個(gè)知識(shí)點(diǎn)才知道了這個(gè)功能:sweat_smile::joy::joy:感謝MJ

讓UIScrollView自動(dòng)回到頂部(初始位置)的原理:要使UIScrollView滾動(dòng)到某一個(gè)位置,無非就是設(shè)置

CGPoint offect = scrollView.contentOffset;

offect.y = - scrollView.contentInset.top;

[scrollView setContentOffset:offect animated:YES];

當(dāng)控制器上只有一個(gè)UIScrollView時(shí),系統(tǒng)就會(huì)去遍歷主窗口上所有的view,當(dāng)遍歷到那個(gè)UIScrollView時(shí),就會(huì)為他設(shè)置:

CGPoint offect = scrollView.contentOffset;

offect.y = - scrollView.contentInset.top;

[scrollView setContentOffset:offect animated:YES];

當(dāng)我們一點(diǎn)擊statusBar時(shí),就會(huì)執(zhí)行上述代碼讓UIScrollView回滾到初始位置

這個(gè)功能的不足之處:

當(dāng)控制器上面只有一個(gè)UIScrollView的時(shí)候,系統(tǒng)才會(huì)為這個(gè)UIScrollView添加這個(gè)自動(dòng)回滾到頂部的功能

當(dāng)一個(gè)控制器上有多個(gè)UIScrollView時(shí),系統(tǒng)就懵了,因?yàn)樗淮_定到底要為那個(gè)UIScrollView設(shè)置這個(gè)自動(dòng)回滾到頂部的功能,這個(gè)時(shí)候就只能有我們coder明確的告訴系統(tǒng):我們要為哪個(gè)UIScrollView設(shè)置自動(dòng)回滾到頂部的功能

解決辦法:

既然系統(tǒng)不能在有多個(gè)UIScrollView的時(shí)候設(shè)置上述功能,那哥就自己來設(shè)置,問題是在眾多的UIScrollView中,我們應(yīng)該為那個(gè)UIScrollView設(shè)置這種功能呢??

答案是:我們只為顯示在用戶眼前的UIScrollView設(shè)置那個(gè)功能

1.新建一個(gè)類LXBTopWindow,我們要在里面控制window的創(chuàng)建,顯示和隱藏,我們并不會(huì)用到系統(tǒng)自帶的一個(gè)UIWindow的方法或者屬性,因此繼承自NSObject就夠了,為了調(diào)用方便,過設(shè)計(jì)為類方法

2.由于在iOS9中,所有的window都必須要有一個(gè)rootViewController,因此我們新建一個(gè)類LXBTopViewController讓他作為window的rootViewController

3.遍歷window上的所有UIScrollView,為滿足實(shí)際要求的UIScrollView設(shè)置回滾到初始位置的功能

Paste_Image.png

Paste_Image.png

Paste_Image.png

大家都知道自iOS7之后,statusBar的樣式是交給控制器來管理的,現(xiàn)在我們?cè)趕tatusBar上蓋了一個(gè)window,系統(tǒng)就會(huì)認(rèn)為statusBar既然已經(jīng)看不見了,就沒必要多此一舉地在用控制器去控制statusBar的樣式,因此控制器中控制statusBar樣式的代碼將會(huì)失效

失效代碼如下:

- (UIStatusBarStyle)preferredStatusBarStyle

{

return UIStatusBarStyleLightContent;

}

解決辦法:

1.既然這個(gè)問題是window引起的,那么自然可以從window下手,window一顯示出來,控制器中控制statusBar樣式的代碼就要失效,因此解決之道就是讓window隱藏就可以了

2.自iOS7之后,statusBar的樣式是交給控制器來管理的,但是在iOS7以前statusBar的樣式是由UIApplication來管理的,既然window一顯示出來,控制器中控制statusBar樣式的代碼就要失效,那么我們可不可以重新把statusBar樣式交給UIApplication來管理呢?? 你控制器失效就失效,哥把statusBar的樣式重新交給UIApplication來管理

答案是:YES,我們可以把statusBar的樣式重新交給UIApplication來管理,只需要在Info.plist文件中添加如下字典:

Paste_Image.png

這樣statusBar的樣式就會(huì)被UIApplication來管理了,我們可以通過:

[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;

去控制statusBar的樣式,值得注意的是,由于此時(shí)我們對(duì)statusBar的操作是應(yīng)用級(jí)別的,因此整個(gè)應(yīng)用程序中的statusBar的樣式都被修改為UIStatusBarStyleLightContent,但是有的地方是不能用UIStatusBarStyleLightContent的,因此我們要在合適的地方(比如這個(gè)控制器被彈出屏幕的時(shí)候),將statusBar的樣式復(fù)原:

[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;

文章二:

如果在UINavigationController內(nèi)設(shè)置一個(gè)UIViewControlller里烦,而UIViewController的第一個(gè)子視圖是UIScrollView的話,UIScrollview里面所有的subView都會(huì)發(fā)生下移辞色,如圖所示

代碼為

- (void)viewDidLoad

{

[super viewDidLoad];

UIScrollView *tempScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 64, 320, 200)];

[tempScroll setBackgroundColor:[UIColor grayColor]];

[tempScroll setContentSize:CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height)];

[self.view addSubview:tempScroll];

UIButton *tempButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];

[tempButton setBackgroundColor:[UIColor redColor]];

[tempButton setTitle:@"subView A" forState:UIControlStateNormal];

[tempButton setFrame:CGRectMake(80, 0, 80, 100)];

NSLog(@"%d",tempScroll.subviews.count);

[tempScroll addSubview:tempButton];

}

經(jīng)過驗(yàn)證性的代碼圃阳,我發(fā)現(xiàn)ios7有一個(gè)機(jī)制

在navigationBar配乓,以及statusBar都顯示的情況下撮胧,Navigation的當(dāng)前VC训措,他的VC的view的子視圖樹的根部的第一個(gè)子視圖鳖宾,如果是Scrollview的話篙梢,這個(gè)scrollview的所有子視圖都會(huì)被下移64個(gè)像素顷帖。

發(fā)現(xiàn)了這個(gè)機(jī)制之后,怎么去修正呢庭猩?

修正方案有兩個(gè)

1窟她、把scrollview的所有子視圖上移64個(gè)像素。

UIView *targetView = self.view;

while (targetView.subviews.count >0 && ![targetView isKindOfClass:[UIScrollView class]]) {

targetView = [targetView.subviews objectAtIndex:0];

}

if ([targetView isKindOfClass:[UIScrollView class]]) {

NSLog(@"you are a scrollview");

CGSize tempSize = ((UIScrollView *)targetView).contentSize;

tempSize.height -= 64;

[(UIScrollView *)targetView setContentSize:tempSize];

for (UIView *subView in targetView.subviews) {

CGRect tempRect = subView.frame;

tempRect.origin.y -= 64;

[subView setFrame:tempRect];

}

}

2蔼水、把scrollView更改地位震糖,是它不是子視圖樹的根部第一個(gè)子視圖。

- (void)viewDidLoad

{

[super viewDidLoad];

UIView *tempBackGround = [[UIView alloc] initWithFrame:self.view.bounds];

[self.view addSubview:tempBackGround];

UIScrollView *tempScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 64, 320, 200)];

[tempScroll setBackgroundColor:[UIColor grayColor]];

[tempScroll setContentSize:CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height)];

[self.view addSubview:tempScroll];

UIButton *tempButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];

[tempButton setBackgroundColor:[UIColor redColor]];

[tempButton setTitle:@"subView A" forState:UIControlStateNormal];

[tempButton setFrame:CGRectMake(80, 0, 80, 100)];

NSLog(@"%d",tempScroll.subviews.count);

[tempScroll addSubview:tempButton];

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末趴腋,一起剝皮案震驚了整個(gè)濱河市吊说,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌优炬,老刑警劉巖颁井,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蠢护,居然都是意外死亡雅宾,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門葵硕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來眉抬,“玉大人,你說我怎么就攤上這事懈凹∈癖洌” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵介评,是天一觀的道長(zhǎng)库北。 經(jīng)常有香客問我爬舰,道長(zhǎng),這世上最難降的妖魔是什么寒瓦? 我笑而不...
    開封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任情屹,我火速辦了婚禮,結(jié)果婚禮上杂腰,老公的妹妹穿的比我還像新娘屁商。我一直安慰自己,他們只是感情好颈墅,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著雾袱,像睡著了一般恤筛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上芹橡,一...
    開封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天毒坛,我揣著相機(jī)與錄音,去河邊找鬼林说。 笑死煎殷,一個(gè)胖子當(dāng)著我的面吹牛腿箩,可吹牛的內(nèi)容都是我干的豪直。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼珠移,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼弓乙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起钧惧,我...
    開封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤暇韧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后浓瞪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體懈玻,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年乾颁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了涂乌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡钮孵,死狀恐怖骂倘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情巴席,我是刑警寧澤历涝,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響荧库,放射性物質(zhì)發(fā)生泄漏堰塌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一分衫、第九天 我趴在偏房一處隱蔽的房頂上張望场刑。 院中可真熱鬧,春花似錦蚪战、人聲如沸牵现。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瞎疼。三九已至,卻和暖如春壁畸,著一層夾襖步出監(jiān)牢的瞬間贼急,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工捏萍, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留太抓,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓令杈,卻偏偏與公主長(zhǎng)得像走敌,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子这揣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

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