定場詩
道德三皇五帝,功名夏侯商周;五霸七雄鬧春秋,頃刻興亡過手!青史幾行名姓,北邙無數(shù)荒丘;前人埋坑后填,說不盡的苦澀難言.
前言
? ? ?我們懷揣青春,碼下一行行的變量.我們憧憬人生,寫下一段段函數(shù).我們擁抱著夢想,敲出一曲曲方法.我們彎著腰幻想著自己可能是指尖程序世界的造物主,我們駝著背笑看著鍵盤上飛舞著的似乎是跳躍的精靈,我們卯足了勁兒只為了自己創(chuàng)造的不僅僅是代碼更是藝術(shù)品.然而我們卻一次次被絆倒在了坑下,泥濘不堪,愈撕扯愈渾濁.
前言就是瞎扯淡
拿出了小學(xué)生作文(低年級版)的水平寫了個前言抒發(fā)一下自己寂寥~寂寥~的心情,打算從今天開始開一個系列(手動不要臉)和大家分享一下自己遇到的聽到的那些在 iOS 開發(fā)中的那些坑與解決方案. 括弧,扯淡為主代碼為輔,生活甚是百般苛刻,人生真的需要笑對....
主題和背景
今天要分享的是一個關(guān)于 UITextView 的坑,這個坑其實說大不小,說小也不小,至少看起挺嚴(yán)重.改這個 bug 你得有過日子的心.至少其中一個的坑是我在廁所釋放內(nèi)存的時候想到的解決方案.
背景是我們這個工程中關(guān)于 textView 的使用中,有一個復(fù)制粘貼大段文字出現(xiàn)的一個bug,這個 bug 主要是出現(xiàn)在環(huán)信的文字輸入框中.
bug1: ?當(dāng)我復(fù)制了大段的問題,這個所自適應(yīng)的文本高度已經(jīng)超過了 textView 所設(shè)定的最大自適應(yīng)高度時,就會這樣:
但是當(dāng)你的小手指輕輕的撫摸滑動他一下,文字就全滾動下來了...就像這樣
bug2:當(dāng)我復(fù)制粘貼來的文字并沒有那么多,剛好夠觸發(fā)了剛好超過了 textView 的最小高度,又小于最大高度,這個時候,由于 textView.contentSize.height 是小于 textView 的 frame 高度的,又不會觸發(fā)滾動,就成了這個鬼樣子:
當(dāng)然,如果你再輸入些字,只要觸發(fā)了文本的自適應(yīng)高度變化了,就會正常顯示了
心酸的 Fix 之路
本來在這個 bug 會報出來之初呢,我還是很懵逼的,因為之前也用過環(huán)信,也自己寫過 textView, 從來都沒發(fā)現(xiàn)這樣的問題,而且實際上,在另一個功能點上也報出來類似bug1的那種問題,我知道,這個問題肯定出現(xiàn)在某些角落中,但是當(dāng)時任務(wù)纏身,工期短,任務(wù)重,代碼早已經(jīng)被前面的開發(fā)人員搞的千瘡百孔,任務(wù)需求也是零散瑣碎,重寫來不及,迭代更是心力交瘁,如果你有代碼潔癖,來讀讀我們的源碼,分分鐘治好你!所以這個問題就一直在延后.
解決 Bug1
直到前幾天,我們的兩個客戶端終于有了相對穩(wěn)定一些的版本,大問題也修的差不多了,我終于有了一些精力來思考一下這些嚴(yán)重的小問題,于是在一個剛剛解決了一個大bug的下午,我決定去廁所 release 一些占用內(nèi)存許久的 bian 量, 在整潔的隔間,和尚存余溫的圈圈上,我開始陷入了沉思,環(huán)信在底層用的是系統(tǒng)的 UITextView,我在另一個功能點也用的是 UITextView,在谷歌上百度了一大圈也沒發(fā)現(xiàn)有人跟我遇到一樣的問題啊,我自己單開了一個 demo 寫了一簡單的 textView 也沒這個問題啊?那既然不是原生控件的 bug, 到底有哪些代碼會不需要寫代碼就可以改變?nèi)值目丶?
臥槽!垂死病中驚坐起!忽然想起來之前有個孩兒為了不用手動寫 TextView 的隨鍵盤滾動,曾經(jīng)集成過一個第三方,叫 IQKeyboardManager, ?會不會是因為這個???急忙離開溫暖的圈圈,坐在電腦前機(jī)智的 cmd + shift + o?
去 delegate 中, 洋洋灑灑的寫到:
[IQKeyboardManager sharedManager].shouldFixTextViewClip = NO;[IQKeyboardManager sharedManager].canAdjustTextView = NO;
cmd + R, 復(fù)制, 粘貼, 顯示正常,點擊解決,機(jī)智如我,開始和 iOS 小伙伴 Jack 吹比去
但此時的我,并沒有意識到,真正的危機(jī)才剛剛開始
ps: IQKeyboardManager 的確可以省去很多關(guān)于鍵盤滾動的處理,并且還能帶來一些 toolBar,但是挺雞肋的其實,并且會對很多已經(jīng)寫好的功能造成影響,所以刪掉,或全局禁用就好了.
Bug2
然而, bug2 并沒有解決,當(dāng)我復(fù)制了沒有那么多問題的時候,提測,被打回,我發(fā)現(xiàn), bug2 依然沒有解決, 加上產(chǎn)品提的 bug 需求上說,復(fù)制粘貼了文字后就不能動,要可以滾動才行,只是我就將焦點放在了 contentSize. 并沒有在代碼邏輯中發(fā)現(xiàn)任何問題.但是注意到了環(huán)信 UI 中有一段代碼:
self.version 是系統(tǒng)版本,當(dāng)設(shè)備的系統(tǒng)版本小于7.0 中間textView 的 setContentOffSet ,后面跟的是 point, 這是設(shè)置 content 坐標(biāo)偏移量的代碼,點進(jìn)去看,并沒有發(fā)現(xiàn)蘋果 API 棄用了這個方法,但問題是當(dāng)系統(tǒng)版大于等于7.0的情況完全沒有做任何處理. 搜一下其他用到系統(tǒng)版本的地方,發(fā)現(xiàn)在獲取 tableview 高度的地方是這樣設(shè)置的
由于 UITextView 繼承了 scrollview ,他的滾動也是通過 containSize 和 size 進(jìn)行比對,只有 containSize 大于 size 才可以觸發(fā)滾動,不可以滾動是正常的,但是從現(xiàn)象上看像是向上偏移了,于是打開模擬器,勾選Color Blended Layers 模式,發(fā)現(xiàn)
進(jìn)一步調(diào)試,進(jìn)到 View Hierarchy 中瞅瞅看
深入調(diào)試:
這樣經(jīng)過調(diào)試終于發(fā)現(xiàn), containerView 和文字,并沒有被截掉,而是坐標(biāo)偏移量上移了,并在 visible 層被遮擋.
所以,在環(huán)信代碼中用于7.0以下的方法,設(shè)置containOffSet是有用的,環(huán)信的代碼邏輯不嚴(yán)謹(jǐn),但是為了不破壞環(huán)信的整體代碼結(jié)構(gòu),也為了避免出現(xiàn)其他問題而打臉,我采用了一種機(jī)智的辦法:
妥了,完美解決~~~~~周一和環(huán)信客服撕逼去咯~~~~~~
最后,通過一個小 Demo 模擬了一下復(fù)制粘貼的現(xiàn)象
我用三種方式發(fā)現(xiàn)依然是這樣
說明在蘋果原生的方法中,面度大段的復(fù)制文字,的確會造成 containerView 的偏移,解決方案就是,將視圖滾到 visible層,或者將重新設(shè)置偏移量
scrollRangeToVisible
setContentOffset
收尾
我們在開發(fā)過程中總是會遇到這樣或那樣的坑,時不時的會在填坑和埋坑中周而復(fù)始,但是最終我們回過頭來或許會發(fā)現(xiàn),我們在填坑中不斷成長.
/*
*
**你只有非常努力才能看起來毫不費力
*/
/****************** ? 10 月 22 日 第一次更新 ******************************/