原文來自:QLViewController在iOS7下的自定義
原先的專案使用了quicklook framework,用於在iPhone上瀏覽各類檔案,除了txt文字會有亂碼的問題,其他檔案的顯示都非常正確。為了使得功能顯得不那麼單一,專案中繼承了QLPreviewController,這樣可以自定義新增navigationBar上的按鈕,比如儲存檔案,編輯某些型別的檔案等等。
這一切在iOS7釋出前都正常執行,在iOS7上執行卻出現了奇怪的現象:自定義新增的按鈕不見了,只存在一個QLPreviewController提供的預設按鈕。
於是debug,結果發現無論是在viewDidload或是viewDidAppear裡新增按鈕,最終都沒有顯示自定義的按鈕。還好我在viewDidAppear里加了斷點,然後可以依稀的看到導航欄上自定義的按鈕出現了短暫的一會,緊接著就消失了。由此進行合理的推測,必定是QLPreviewController在iOS7上的行為有了重大變化。進行了google以後發現stackoverflow上有了端倪:
iOS 6 UIGestures (Tap) stops working with QLPreviewController
答案裡提到了RemoteController的概念,具體的博文可以看答案中的連結(注意雖然文章中提到的是iOS6,但是我所遇到的問題只在iOS7上出現)。博文是以MailComposerViewController為例來介紹RemoteController(還有很多也是RemoteController,比如我遇到的QLPreviewController),主要提到的就是RemoteController是以XPC的方式執行。XPC有幾個好處:
- 以簡單高效的方式,進行程式間非同步的通訊
- OS系統來控制XPC程式的生命週期
簡單的理解就是QLPreviewController就是單獨一個程式,你的App通過作業系統來與之通訊後,QLPreviewController怎麼執行和你的App沒有關係,由作業系統來控制。這樣說來,新增的按鈕一閃而過就說得過去了。XPC在Max OS系統上就有廣泛的應用,這裡就不多說了,有興趣的自己研究。
下面說一下,iOS7下如何修改呢?使用QuickLook主要是想使用其檔案瀏覽功能,如果不能用的話,那就只能使用webView來實現瀏覽檔案的功能了。但是webview還是有很多不足之處:
- 文字檔案的顯示容易出現亂碼
- 換行符有時不能正常的顯示
- 大檔案,如docx,exlc等檔案顯示的效率低
考慮再三,還是覺得需要慎用UIWebView,最好還是能使用QLPreviewController。考慮到之前之所以要繼承QLPreviewController,也只是想“hack”系統,從而可以更改navigationItem。雖然呼叫的是子類,但實際執行的相當於是QLPreviewController。那如果新建立一個viewController A,然後把QLPreviewController的view作為一個子view新增到A的view上,是不是可以迴避iOS7本身的一些特性呢?果然,經過嘗試,這種方式可以解決遇到的問題。
雖然這種view的“組合”方式很山寨,但也不失為解決問題的一種方法,尤其在時間緊迫任務繁重的情況。如果有更好的方法來實現,希望大家共享下~