UITextField使用中,一些導(dǎo)致內(nèi)部布局偏移的坑

輸入狀態(tài)切換時(shí),輸入內(nèi)容發(fā)生少量偏移的問題.

現(xiàn)象

原因

有兩種情況會(huì)造成這個(gè)問題:

  • 使用自定義字體.
  • 使用系統(tǒng)字體的某些字號(hào).

造成這個(gè)問題的原因要從UITextField的內(nèi)部實(shí)現(xiàn)說起.
UITextField在BeginEditing/EndEditing這兩個(gè)狀態(tài),用來顯示輸入內(nèi)容的是兩個(gè)不同類型的view.
BeginEditing狀態(tài)使用一個(gè)類型為UIFieldEditor的view來顯示. EndEditing則使用類型為UITextFieldLabel的view顯示.
應(yīng)該是這兩種狀態(tài)下的view和對(duì)應(yīng)的布局計(jì)算邏輯不同,導(dǎo)致了布局的少許偏差.
(惡心的是,iOS8/9/10這三個(gè)系統(tǒng)上,偏差的方式不同,需要分別修復(fù))

可以通過在UITextFieldDelegate的方法中打印日志的方式來驗(yàn)證這個(gè)問題.
日志代碼如下:

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    NSLog(@"textFieldDidBeginEditing");
    [self debugTextField:textField];
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    NSLog(@"textFieldDidEndEditing");
    [self debugTextField:textField];
}

- (void)debugTextField:(UITextField *)textField
{
    NSLog(@"textField.frame:%@",NSStringFromCGRect(textField.frame));
    for (CALayer *layer in textField.layer.sublayers) {
        NSLog(@"layer.frame:%@",NSStringFromCGRect(layer.frame));
        NSLog(@"layer.delegate.frame:%@",layer.delegate);
    }
    NSLog(@"");
}

log輸入內(nèi)容如下.可以看到兩種狀態(tài)下,textField.subViews內(nèi)容是不同的.并且高度有0.5(58-57.5)的偏差.

textFieldDidBeginEditing
textField.frame:{{37, 7}, {323, 58}}
layer.frame:{{0, 0}, {323, 58}}
layer.delegate.frame:<UIFieldEditor: 0x7f877288b600; frame = (0 0; 323 58); text = '1,345.0'; clipsToBounds = YES; opaque = NO; gestureRecognizers = <NSArray: 0x608000241c50>; layer = <CALayer: 0x60800023b1a0>; contentOffset: {0, 0}; contentSize: {323, 58}>

textFieldDidEndEditing
textField.frame:{{37, 7}, {323, 58}}
layer.frame:{{293, 0}, {30, 58}}
layer.delegate.frame:<UIView: 0x7f8771543f10; frame = (293 0; 30 58); hidden = YES; gestureRecognizers = <NSArray: 0x6100002437b0>; layer = <CALayer: 0x610000230200>>
layer.frame:{{0, 0}, {323, 57.5}}
layer.delegate.frame:<UITextFieldLabel: 0x7f877153a6f0; frame = (0 0; 323 57.5); text = '1,345.0'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x6100002873a0>>

修復(fù)方式

  • 如果使用了自定義字體,可以自定義UITextField子類,重寫layoutSubviews,根據(jù)不同系統(tǒng)做布局的微調(diào).
@interface CustomTextField

@end

@implementation CustomTextField

-(void)layoutSubviews
{
    [super layoutSubviews];
    //下面邏輯用來解決TextField使用自定義字體時(shí)的一個(gè)視覺bug.
    //TextField.inputText在edit狀態(tài)變化前后,會(huì)產(chǎn)生0.5的偏差,導(dǎo)輸入內(nèi)容"略微跳動(dòng)".
    //根據(jù)實(shí)測(cè),系統(tǒng)不同,修復(fù)方式也不一樣,8.x系統(tǒng)是調(diào)整top,9.x與10.x是調(diào)整高度.
    if ([self.subviews count] == 1) {
        UIView *view = [self.subviews objectAtIndex:0];
        if (AUSystemVersion() >= 10.0) {
            view.height += 0.5;
        }else if(AUSystemVersion() >= 9.0){
            view.height -= 0.5;
        }else if(AUSystemVersion() >= 8.0){
            view.top -= 0.5;
        }
    }
}

@end

輸入過程中重置字號(hào)后,輸入內(nèi)容產(chǎn)生偏移的問題.(iOS8/iOS9)

現(xiàn)象

原因及修復(fù)方式

這個(gè)問題在iOS10系統(tǒng)被修復(fù)了.看來在較早的系統(tǒng)(iOS8/9),重設(shè)字號(hào)還不會(huì)觸發(fā)重新布局的邏輯.
可以在重置字號(hào)后手動(dòng)調(diào)用[self.textField setNeedsLayout]來解決.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌望艺,老刑警劉巖窿凤,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伟叛,死亡現(xiàn)場(chǎng)離奇詭異恰梢,居然都是意外死亡般卑,警方通過查閱死者的電腦和手機(jī)藻烤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門绷雏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人怖亭,你說我怎么就攤上這事涎显。” “怎么了兴猩?”我有些...
    開封第一講書人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵期吓,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我倾芝,道長(zhǎng)讨勤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任晨另,我火速辦了婚禮潭千,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘借尿。我一直安慰自己刨晴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開白布路翻。 她就那樣靜靜地躺著狈癞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪帚桩。 梳的紋絲不亂的頭發(fā)上亿驾,一...
    開封第一講書人閱讀 52,158評(píng)論 1 308
  • 那天嘹黔,我揣著相機(jī)與錄音账嚎,去河邊找鬼莫瞬。 笑死,一個(gè)胖子當(dāng)著我的面吹牛郭蕉,可吹牛的內(nèi)容都是我干的疼邀。 我是一名探鬼主播,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼召锈,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼旁振!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起涨岁,我...
    開封第一講書人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤拐袜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后梢薪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蹬铺,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年秉撇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了甜攀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡琐馆,死狀恐怖规阀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瘦麸,我是刑警寧澤谁撼,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站滋饲,受9級(jí)特大地震影響彤敛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜了赌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一墨榄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧勿她,春花似錦袄秩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至砍聊,卻和暖如春背稼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背玻蝌。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工蟹肘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留词疼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓帘腹,卻偏偏與公主長(zhǎng)得像贰盗,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子阳欲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

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