UITextField輸入時(shí)文字下移解決方案

問題

UITextField作為輸入常用控件,但是問題卻很多,本篇主要用于解決以下兩個(gè)問題。

  • 輸入時(shí)文字位置自動(dòng)下移;
  • 自動(dòng)布局時(shí)橫屏轉(zhuǎn)豎屏左側(cè)多出大片空白;

當(dāng)設(shè)置masksToBounds = YES時(shí),如果文字長度超過了TextField的寬度,那么文字位置就會(huì)下移,如下圖:

image

當(dāng)設(shè)置masksToBounds = NO時(shí),如果文字長度超過了TextField的寬度且輸入速度過快,那么TextField左側(cè)會(huì)有文字閃動(dòng)的問題,且刪除文字時(shí)文字也會(huì)下移,如下圖:

image

當(dāng)文字長度超過了TextField的寬度由豎屏變?yōu)闄M屏?xí)r,那么TextField左側(cè)會(huì)有大片空白,如下圖:

image

原因分析

UITextField結(jié)構(gòu)如下圖,當(dāng)編輯時(shí)會(huì)成了UIFieldEditorUIFieldEditor是繼承UIScrollView,UIFieldEditor有一個(gè)子視圖_UIFieldEditorContentView, _UIFieldEditorContentView用于展示文字和光標(biāo)(UITextSelectionView)。

image

當(dāng)編輯時(shí),_UIFieldEditorContentView的frame會(huì)動(dòng)態(tài)改變,UIFieldEditorcontentOffset也會(huì)改變,因此就出現(xiàn)了文字下移的問題。

解決方法

因此要防止文字下移,必須設(shè)置UIFieldEditor的contentOffset的y值為0,如果想解決第二張圖中輸入較快時(shí)左側(cè)閃動(dòng),則需設(shè)置masksToBounds = YES(使用者可自己設(shè)置)。

說明:即使設(shè)置了UIFieldEditor的contentOffset的y值為0,如果此時(shí)設(shè)置masksToBounds = YES,那么光標(biāo)下移問題依然存在,這是由于_UIFieldEditorContentView的frame的高度和y值改變導(dǎo)致的,因此需要?jiǎng)討B(tài)調(diào)整UIFieldEditor在y方向的偏移量。

為了解決前三張圖中問題,首先定義HHHTextField繼承自UITextField,在layoutSubviews中動(dòng)態(tài)進(jìn)行布局,代碼如下:


@interface HHHTextField()
{
    CGFloat _defaultYOffset; //標(biāo)記_FieldEditorContentView初始偏y方向移量
}
@end


@implementation HHHTextField

- (void)layoutSubviews {
    [super layoutSubviews];
    for (UIScrollView *fieldEditor in self.subviews) {
        if ([fieldEditor isKindOfClass:[UIScrollView class]]) { // UIFieldEditor
            CGFloat currentYOffset = 0.0f;
            for (UIView *fieldEditorContentView in fieldEditor.subviews) { //_FieldEditorContentView
                currentYOffset = fieldEditorContentView.frame.origin.y;
                if (_defaultYOffset == 0.0f && currentYOffset != 0.0f) {
                    _defaultYOffset = currentYOffset;
                }
            }
            CGPoint offset = fieldEditor.contentOffset;
            if (currentYOffset == 0.0f && _defaultYOffset != 0.0f) {
                offset.y = -_defaultYOffset;
            } else {
                offset.y = 0.0f;
            }
            if (self.text.length == 0 && self.attributedText.length == 0) { //字體為空時(shí)重置_defaultYOffset
                offset.y = 0.0f;
                _defaultYOffset = 0.0f;
            }
            fieldEditor.contentOffset = offset;
            break;
        }
    }
}

@end

源碼示例HHHTextField

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容