「 iOS知識小集 」2018 · 第 38 期

原文連接html

更新:前兩週咱們發了一條小集《Xcode 10.1 並無修復因爲 Assets 引發的在 iOS 9 上的崩潰問題》,根據最新消息,蘋果已經在服務器端解決了這個問題,開發者經過 Xcode 10.1 打的 ipa 包在上傳到蘋果後臺,蘋果在處理包的過程當中會自動修復。小夥伴們已親自驗證,不會在 iOS 9 上 Crash 啦~ios

上週公衆號發佈的如下文章:git

本期知識小集的主要內容包括:github

  • 研究 wkwebview 的子 view 和 的關係
  • 如何使 UIImagePickerController 支持橫屏
  • 句子拆分
  • Safe Area 的一些零散點

研究 WKWebview 的子 view 和 的關係

做者: hite和落雁web

這個問題來自需求:當 webview 下拉 bounce 的時候,在漏出的部分顯示自定義的 view。相似在微信打開一個公衆號後顯示的「此頁面由 **** 提供」,這樣的交互。正則表達式

中間通過若干測試,實現此功能有三個關鍵點;objective-c

  1. 設置 webview.scrollView.backgroundColor = [UIColor clearColor]; 目的爲了下拉整個頁面時,可以漏出咱們自定義 view。(這裏須要指出的是,下拉頁面出現 bounce 效果時,漏出的 是 wkscrollview;爲何這樣,我猜想是由於 Safari 渲染的時候,bounce 效果是出在 wkscrollview上,可參看這個測試頁面,請在 Safari 裏打開)
  2. 結合 1,將這個自定義 view,放在 WKWebviewWKScrollView 之間(猜想,webview.scrollViewWKScrollView 的代理對象,而 WKScrollView 是 的代理元素,是否真的這樣須要看看源碼)。
  3. 添加自定義 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 的顏色,是否生效看不一樣的狀況;安全

  1. 當設置的 body 顏色是 #ffffff 白色時,不論何時去設置 body 顏色都不會覆蓋 webview.scrollView.backgroundColor 的顏色。
  2. 當設置的顏色是非白色時,會覆蓋 webview.scrollView.backgroundColor

經過對照 HTML 的 DOM 層級和 WKWebview 的層級,服務器

有如下發現;微信

  1. html 裏下拉時, bounce 效果後面的背景元素是 WKScrollView,因此設置 body 顏色會設置到 WKScrollView 的背景色。
  2. html 裏其餘元素所有由 WKContentView 嵌套。當整個頁面是長頁面須要分頁時,會分多個 WKCompositingView 逐個顯示;

使用上述方案實現下拉時顯示自定義元素有個問題;

  1. 在開始滑動 scrollView 時候,設置 webview.scrollView.backgroundColor 的顏色,會將 h5 本身設置的背景色覆蓋,因此 h5 要儘可能不要依賴 body 的背景色作滑動背景;
  2. 某些頁面,如測試頁面2, 頭部有個 fixed 元素,下拉時也會漏出 bounce 背景色。此時若是背景色設置透明後出現一個很奇怪的 漏出,這時候不該該漏出。若是解決這個問題呢,若是真的要解決這個問題,可能須要去讀 html 的樣式,這樣就比較麻煩了。
  3. 對問題 2 ,有個討巧的方案就是將漏出的自定義元素放在 fixed 元素的後面,如微信那樣。具體樣式能夠將 測試頁面2 放到微信裏看效果。

若是真正要解決問題 2 ,目前還須要再找找方案,但願看到 webkit2 的源碼後能有方案。

如何使 UIImagePickerController 支持橫屏

做者: halohily

不少同窗在開發橫屏應用時,使用系統的 UIImagePickerController 會發現它默認只支持豎屏。筆者也遇到了這個問題,通過一番探究,以下的方式效果是最佳的:

首先,在 present 這裏的 UIImagePickerController 對象 picker 以前,設置 picker 的 modalPresentationStyleUIModalPresentationOverCurrentContext,這時運行會發現橫屏時它也能夠正常彈出了,只是旋轉設備時它不能跟隨設備方向正常轉動。

接下來,爲 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,也歡迎加入咱們的羣組討論問題。能夠公衆號留言 iosflutter 等關鍵詞獲取入羣方式。

相關文章
相關標籤/搜索