iOS 11 UIWebView 適配

iOS 11 引入了安全區(qū)(safeArea)的概念嗡载,如果UIWebView從(0,0)開(kāi)始布局雨效,即UIWebView延伸到statusBar或navigationBar下方微宝,則WebView.scrollView.contentInset將自動(dòng)調(diào)整為:

// statusBarHeight: 狀態(tài)欄高度
// navigationBarHeight: 導(dǎo)航欄高度
// originalInsetTop: 開(kāi)發(fā)者設(shè)置的contentInset.top,默認(rèn)為0
WebView.scrollView.contentInset = UIEdgeInsetsMake(customInsetTop + statusBarHeight + navigationBarHeight, 0, 0, 0)

因此蝎宇,如果UIWebView從(0弟劲,0)開(kāi)始布局且存在狀態(tài)欄和導(dǎo)航欄的情況下,UIWebView將整體向下偏移(statusBarHeight + navigationBarHeight)

目前主要有兩種解決方案(同樣適用于WKWebView):
1姥芥、客戶端適配:

WebView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;

2兔乞、H5適配:

<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">

采用上面兩種方法雖然解決了UIWebView整體向下偏移的問(wèn)題,但是發(fā)現(xiàn)部分頁(yè)面中使用-webkit-overflow-scrolling屬性的子列表依然會(huì)向下偏移,用Xcode查看視圖層級(jí)后發(fā)現(xiàn):一旦使用-webkit-overflow-scrolling屬性庸追,WebView.scrollView內(nèi)部將生成一個(gè)新的UIScrollView:(準(zhǔn)確地說(shuō)是UIWebOverflowScrollView霍骄,這是UIScrollView的子類,)而且UIWebOverflowScrollView的contentInset被自動(dòng)調(diào)整為:

UIWebOverflowScrollView.contentInset = UIEdgeInsetsMake(statusBarHeight + navigationBarHeight, 0, 0, 0)

這導(dǎo)致了子列表向下偏移的現(xiàn)象锚国,通過(guò)調(diào)整contentInsetAdjustmentBehavior屬性:

UIWebOverflowScrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;

可以將UIWebOverflowScrollView向上提回到正常位置腕巡,但是UIWebOverflowScrollView是WebKit根據(jù)H5使用-webkit-overflow-scrolling屬性而動(dòng)態(tài)生成的私有圖層,H5調(diào)用的時(shí)機(jī)和WebKit生成UIWebOverflowScrollView的時(shí)機(jī)并不確定血筑,客戶端很難準(zhǔn)確地獲取到UIWebOverflowScrollView绘沉。目前看,使用viewport-fit=cover也只能調(diào)整UIWebView.scrollView不要根據(jù)safeArea自動(dòng)偏移, 但是對(duì)UIWebView.scrollView內(nèi)部生成的子scrollView豺总,如UIWebOverflowScrollView卻無(wú)能為力(當(dāng)然车伞,WKWebView不存在這樣的問(wèn)題,蘋(píng)果積極地fix了這個(gè)Bug), UIWebView卻是比較尷尬了喻喳。

我們注意到iOS 11 UIViewController新增的屬性additionalSafeAreaInsets可以調(diào)整安全區(qū)域的大小另玖,根據(jù)文檔推測(cè):既然子列表向下偏移是因?yàn)榘踩珔^(qū)域?qū)е碌模敲赐ㄟ^(guò)調(diào)整additionalSafeAreaInsets的值將安全區(qū)從導(dǎo)航下方延伸到整個(gè)手機(jī)屏幕表伦,應(yīng)該可以解決子列表向下偏移的問(wèn)題:

webViewController.additionalSafeAreaInsets = UIEdgeInsetsMake(-64, 0, 0, 0)

這樣調(diào)整后谦去,安全區(qū)確實(shí)可以延伸到導(dǎo)航欄下方,但是依然無(wú)法延伸到狀態(tài)欄下方蹦哼,而狀態(tài)欄的高度為20pt, 這導(dǎo)致UIWebView.scrollView自動(dòng)向下偏移20pt, 實(shí)際上我們要調(diào)整當(dāng)前window根視圖控制器的additionalSafeAreaInsets才能將安全區(qū)延伸到statusBar下:

window.rootViewController.navigationController.additionalSafeAreaInsets = UIEdgeInsetsMake(-64, 0, 0, 0)

但是這樣要調(diào)整rootViewController感覺(jué)也不是很優(yōu)雅鳄哭,最后我們使出黑魔法,直接hook了UIScrollView的初始化方法

@implementation UIScrollView (Swizzle)

+ (void)load
{
    [self jr_swizzleMethod:@selector(initWithFrame:) withMethod:@selector(qzInitWithFrame:) error:nil];
}

- (UIScrollView *)qzInitWithFrame:(CGRect)frame
{
    UIScrollView *scrollview = [self qzInitWithFrame:frame];
    if (scrollview && [scrollview isKindOfClass:NSClassFromString([NSString stringWithFormat:@"U%@Ov%@Scr%@", @"IWeb", @"erflow", @"ollView"])]) {
        if (@available(iOS 11.0, *)) {
            scrollview.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
        }
    }
    return scrollview;
}
@end

Reference

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末纲熏,一起剝皮案震驚了整個(gè)濱河市妆丘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌局劲,老刑警劉巖勺拣,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異鱼填,居然都是意外死亡药有,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)苹丸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)塑猖,“玉大人,你說(shuō)我怎么就攤上這事谈跛。” “怎么了塑陵?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵感憾,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)阻桅,這世上最難降的妖魔是什么凉倚? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮嫂沉,結(jié)果婚禮上稽寒,老公的妹妹穿的比我還像新娘。我一直安慰自己趟章,他們只是感情好杏糙,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蚓土,像睡著了一般宏侍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蜀漆,一...
    開(kāi)封第一講書(shū)人閱讀 49,071評(píng)論 1 285
  • 那天谅河,我揣著相機(jī)與錄音,去河邊找鬼确丢。 笑死绷耍,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鲜侥。 我是一名探鬼主播褂始,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼剃毒!你這毒婦竟也來(lái)了病袄?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤赘阀,失蹤者是張志新(化名)和其女友劉穎益缠,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體基公,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡幅慌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了轰豆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胰伍。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖酸休,靈堂內(nèi)的尸體忽然破棺而出骂租,到底是詐尸還是另有隱情,我是刑警寧澤斑司,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布渗饮,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏互站。R本人自食惡果不足惜私蕾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望胡桃。 院中可真熱鬧踩叭,春花似錦、人聲如沸翠胰。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)亡容。三九已至嗤疯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間闺兢,已是汗流浹背茂缚。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留屋谭,地道東北人脚囊。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像桐磁,于是被迫代替她去往敵國(guó)和親悔耘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

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

  • 01 C姑娘18歲看峻,一個(gè)人在離家萬(wàn)里之外的外地讀書(shū),周?chē)鷽](méi)有什么親戚朋友衙吩。 C姑娘學(xué)醫(yī)互妓,平時(shí)基本很少出校門(mén),只有周...
    之葤閱讀 1,182評(píng)論 1 3
  • 餐謀長(zhǎng)?導(dǎo)讀:拿著自己的積蓄好不容易開(kāi)個(gè)餐廳卻經(jīng)營(yíng)失敗了灼狰,這是為什么?每個(gè)人創(chuàng)業(yè)都是抱著美好的想法去的,但卻在實(shí)施...
    燕乖乖閱讀 278評(píng)論 0 0
  • 新聞發(fā)布會(huì)上林帆侃侃而談浮禾,講訴著他的勵(lì)志故事伏嗜,從最初的一窮二白坛悉,到現(xiàn)在名下?lián)碛袛?shù)家公司,他分享著自己成功...
    少年也老閱讀 1,043評(píng)論 22 35
  • 參考地址:http://blog.csdn.net/echoisland/article/details/6993756
    YY915閱讀 205評(píng)論 0 0