「 iOS知識小集 」2018 · 第 38 期
更新:前兩週我們發了一條小集
《Xcode 10.1 並沒有修復由於 Assets 引起的在 iOS 9 上的崩潰問題》
,根據最新訊息,蘋果已經在伺服器端解決了這個問題,開發者通過Xcode 10.1
打的 ipa 包在上傳到蘋果後臺,蘋果在處理包的過程中會自動修復。小夥伴們已親自驗證,不會在 iOS 9 上 Crash 啦~
上週公眾號釋出的以下文章:
本期知識小集的主要內容包括:
- 研究 wkwebview 的子 view 和 的關係
- 如何使 UIImagePickerController 支援橫屏
- 句子拆分
- Safe Area 的一些零散點
研究 WKWebview 的子 view 和 的關係
作者: hite和落雁
這個問題來自需求:當 webview
下拉 bounce
的時候,在漏出的部分顯示自定義的 view。類似在微信開啟一個公眾號後顯示的“此頁面由 **** 提供”
,這樣的互動。
中間經過若干測試,實現此功能有三個關鍵點;
- 設定
webview.scrollView.backgroundColor = [UIColor clearColor];
目的為了下拉整個頁面時,能夠漏出我們自定義 view。(這裡需要指出的是,下拉頁面出現bounce
wkscrollview
;為什麼這樣,我猜測是因為 Safari 渲染的時候,bounce 效果是出在wkscrollview
上,可參看這個測試頁面,請在 Safari 裡開啟) - 結合 1,將這個自定義 view,放在
WKWebview
和WKScrollView
之間(猜測,webview.scrollView
是WKScrollView
的代理物件,而WKScrollView
是 的代理元素,是否真的這樣需要看看原始碼)。 - 新增自定義 view 到
WKScrollView
裡的時機是- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
因為不同頁面書寫方式,導致有些樣式會生效時機不同,頁面載入完畢並不是個很好的時機。
在生成 webview 的時候,設定 webview.scrollView.backgroundColor = [UIColor clearColor];
。特別的需要說明下,當 h5 在 body 上寫內聯樣式 <body style="background-color:red">;
或者寫 style 樣式;或者外聯 <link rel="stylesheet" href>
三種寫法,去設定 body 的顏色,是否生效看不同的情況;
- 當設定的 body 顏色是
#ffffff
白色時,不論什麼時候去設定 body 顏色都不會覆蓋webview.scrollView.backgroundColor
的顏色。 - 當設定的顏色是非白色時,會覆蓋
webview.scrollView.backgroundColor
通過對照 HTML 的 DOM 層級和 WKWebview 的層級,
有以下發現;
- html 裡下拉時, bounce 效果後面的背景元素是
WKScrollView
,所以設定 body 顏色會設定到WKScrollView
的背景色。 - html 裡其他元素全部由
WKContentView
巢狀。當整個頁面是長頁面需要分頁時,會分多個WKCompositingView
逐個顯示;
使用上述方案實現下拉時顯示自定義元素有個問題;
- 在開始滑動
scrollView
時候,設定webview.scrollView.backgroundColor
的顏色,會將 h5 自己設定的背景色覆蓋,所以 h5 要儘量不要依賴 body 的背景色做滑動背景; - 某些頁面,如測試頁面2, 頭部有個
fixed
元素,下拉時也會漏出 bounce 背景色。此時如果背景色設定透明後出現一個很奇怪的 漏出,這時候不應該漏出。如果解決這個問題呢,如果真的要解決這個問題,可能需要去讀 html 的樣式,這樣就比較麻煩了。 - 對問題 2 ,有個討巧的方案就是將漏出的自定義元素放在
fixed
元素的後面,如微信那樣。具體樣式可以將 測試頁面2 放到微信裡看效果。
如果真正要解決問題 2 ,目前還需要再找找方案,希望看到 webkit2 的原始碼後能有方案。
如何使 UIImagePickerController 支援橫屏
作者: halohily
很多同學在開發橫屏應用時,使用系統的 UIImagePickerController
會發現它預設只支援豎屏。筆者也遇到了這個問題,經過一番探究,如下的方式效果是最佳的:
首先,在 present 這裡的 UIImagePickerController
物件 picker 之前,設定 picker 的 modalPresentationStyle
為 UIModalPresentationOverCurrentContext
,這時執行會發現橫屏時它也可以正常彈出了,只是旋轉裝置時它不能跟隨裝置方向正常轉動。
接下來,為 UIImagePickerController
新增一個 category,重寫 shouldAutorotate
方法返回 true,重寫 supportedInterfaceOrientations
方法返回 UIInterfaceOrientationMaskAll
。這時再執行會發現不僅可以橫屏彈出,也可以正常旋轉了。
句子拆分
作者: Lefe_x
把下面這段話拆分成句子,你會用什麼方案呢?
知識小集是由幾位志同道合的夥伴組成。你瞭解這個團隊嗎?我們在一起相處了 1 年多的時光!我想說:“我們是最棒的!”
複製程式碼
我想到的方案有:正則表示式;使用 NSScanner
;使用 componentsSeparatedByCharactersInSet
: ;但這幾種方案都比較麻煩,後來不經意間發現了下面這個方法。
程式碼如下:
NSString *text = @"知識小集是由幾位志同道合的夥伴組成。你瞭解這個團隊嗎?我們在一起相處了 1 年多的時光!我想說:“我們是最棒的!”";
[text enumerateSubstringsInRange:NSMakeRange(0, [text length]) options:NSStringEnumerationBySentences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
NSLog(@"sentence: %@ range: %@", substring, NSStringFromRange(substringRange));
}];
複製程式碼
執行結果如下:
sentence: 知識小集是由幾位志同道合的夥伴組成。 range: {0, 18}
sentence: 你瞭解這個團隊嗎? range: {18, 9}
sentence: 我們在一起相處了 1 年多的時光! range: {27, 17}
sentence: 我想說:“我們是最棒的!” range: {44, 13}
複製程式碼
Safe Area 的一些零散點
作者: 這個湯圓沒有餡weibo.com/u/660346950…
先看圖一尺寸圖。
我們都知道,iOS 11
引入了 Safe Area
這個概念。在 xib
或者 storyboard
上新增 subview
,都是會新增在 Safe Area
上的。例如:在 vc 上新增一個 view,上下左右約束分別為 0
,在 iPhone X 和 iPhone 6 上展示不一樣,如下圖。純程式碼建立的時候不會出現這個問題,因為 subview 是直接新增在 self.view
上面。
很明顯,在 iPhone X 上底下會有一個 34pt
高度的留白區。分別列印一下兩個機型的 self.view.safeAreaInsets
,如下圖。
那麼假使現在,我希望在 iPhone X 機型上,底下不要留白。頁面展示效果跟 iPhone 6 一樣。然而 safeAreaInsets
是隻讀屬性,無法通過修改值達到目的。
第一種方法,Align Bottom to:Safe Area 的值改為-34。但是如果後期出了新的機型,那麼這個值就不再適配,因為不推薦。
第二種方法,在 bottom 的約束上,直接以superView為參照,如下圖。
另外補充幾點:
- additionalSafeAreaInsets:controller
可以擴充套件安全區域,如果我們設定self.additionalSafeAreaInsets = UIEdgeInsetsMake(20, 0, 0, 20);
意思就是在原有的 safeAreaInsets 值中增加對應的邊距值。如果原來的是 {10, 0, 0, 10} , 則最後得出的邊距是 {30, 0, 0, 30}。- (void)viewSafeAreaInsetsDidChange:
當檢視的安全區域發生變更時會觸發該方法,可以通過該方法來處理安全區域變更時的UI佈局。- insetsLayoutMarginsFromSafeArea:
預設值是YES,如果設定為 NO,所有的檢視佈局將會忽略safeAreaInsets
這個屬性了。這個只對純程式碼佈局檢視有效,如果是xib
或者storyboard
佈局的話不起作用。一般用於tableView
居多。
關注我們
歡迎關注我們的公眾號:iOS-Tips,也歡迎加入我們的群組討論問題。可以公眾號留言 ios
、flutter
等關鍵詞獲取入群方式。