UITextField設置左側圖片、文字居中(占位符的位置)

一、我們通常在設計登錄界面時會用到UITextField,如下圖所示:
通常想實現(xiàn)下面幾點:

1、左邊顯示圖片
2、textField中添加默認的占位符(提示文字),并且希望占位符和左邊圖片有一點的距離,或者讓占位符居中,
3、點擊textField輸入時光標的位置應該緊在占位符左側,并緊挨著占位符
最終實現(xiàn)效果如下圖所示:
4.如何更好地限制一個UITextField的輸入長度

20151130083016624.png

二、左邊顯示圖片很簡單下面幾行代碼搞定(右邊顯示圖片同理):

UIImageView *passwordImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"passwordIcon"]];
    password.leftView = passwordImage;
    password.leftViewMode = UITextFieldViewModeAlways;

提示:上下兩個圖片的寬度要保持一致,不然會導致占位符的左邊無法對其!

三、而設置占位符的位置和編輯狀態(tài)時光標的位置試了很多方法感覺都不好使,最終找到一個方法,自定義一個basicTextField繼承自UITextField;然后可以重寫下面的幾個方法:

- (CGRect)borderRectForBounds:(CGRect)bounds;
- (CGRect)textRectForBounds:(CGRect)bounds;
- (CGRect)placeholderRectForBounds:(CGRect)bounds;
- (CGRect)editingRectForBounds:(CGRect)bounds;
- (CGRect)clearButtonRectForBounds:(CGRect)bounds;
- (CGRect)leftViewRectForBounds:(CGRect)bounds;
- (CGRect)rightViewRectForBounds:(CGRect)bounds;

四、下面是具體的代碼實現(xiàn):
(1)設置左視圖

- (CGRect)leftViewRectForBounds:(CGRect)bounds{
    CGRect iconRect = [super leftViewRectForBounds:bounds];
    iconRect.origin.x += 10;
    return iconRect;
}

(2)重寫占位符的x值

- (CGRect)placeholderRectForBounds:(CGRect)bounds{
    CGRect placeholderRect = [super placeholderRectForBounds:bounds];
    placeholderRect.origin.x += 1;
    return placeholderRect;
}

(3)重寫文字輸入時的X值

- (CGRect)editingRectForBounds:(CGRect)bounds{
    CGRect editingRect = [super editingRectForBounds:bounds];
    editingRect.origin.x += 20;
    return editingRect;
}

(4)重寫文字顯示時的X值

- (CGRect)textRectForBounds:(CGRect)bounds{
    CGRect textRect = [super editingRectForBounds:bounds];
    textRect.origin.x += 20;
    return textRect;
}
第四個問題:如何更好地限制一個UITextField的輸入長度

要限制一個UITextField的輸入字數(shù)(參考鏈接),首先想到的應該是通過

UITextFieldDelegate

的代理方法來限制

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;   // return NO to not change text

比如要設置字數(shù)限制為20:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (textField == self.titleField) {
        if (textField.length > 20) return NO;
    }

    return YES;
}

但是這樣的限制簡單粗暴,可能會影響用戶正常邏輯下的輸入,比如輸入了20個字符后,要退格回刪字符。
這時候我們可能會考慮“Detect backspace in UITextField”,比如簡單地判斷replacementString的長度是否為0。
接著我們可能還會遇到用戶已經輸入20個字符了,這時候繼續(xù)輸入---不過是選擇了部分文本進行替換-----無法進行了,這也妨礙了用戶的正常操作,所以限制的代碼版本可能會演進為:

#pragma mark - UITextFieldDelegate

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (textField == self.titleField) {
        if (string.length == 0) return YES;

        NSInteger existedLength = textField.text.length;
        NSInteger selectedLength = range.length;
        NSInteger replaceLength = string.length;
        if (existedLength - selectedLength + replaceLength > 20) {
            return NO;
        }
    }

    return YES;
}

到這里可能會覺得基本大功告成了,但是當你輸入19個字符后,第20個字符以中文漢字的形式繼續(xù)輸入,那么系統(tǒng)會在鍵盤上方提供后續(xù)的一系列聯(lián)想詞,你會發(fā)現(xiàn)通過這種方式可以連續(xù)選字輸入從而突破20個字符的限制。WTF

到了這里,我們可能會希望有個類似

  • (void)textFieldDidChange:(UITextField *)textField
    的回調方法,但可惜沒有。
    當然,我們還可以通過

  • (void)textFieldDidEndEditing:(UITextField *)textField;
    回調方法在結束編輯的時候把文本截斷,雖然在用戶體驗上會有點突兀。
    不過當我們點進去UITextField.h頭文件里尋覓上述回調方法而不得時,可能會發(fā)現(xiàn)最下面有這么個消息通知名稱:

UIKIT_EXTERN NSString *const UITextFieldTextDidChangeNotification;
不過,監(jiān)聽消息還要記得解除監(jiān)聽,通常我還習慣把監(jiān)聽消息的代碼統(tǒng)一放在一個方法中,看起來有點“大動干戈”。
所幸的是UITextField本身提供了相應的事件監(jiān)聽:

[textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
- (void)textFieldDidChange:(UITextField *)textField
{
    if (textField == self.titleField) {
        if (textField.text.length > 20) {
            textField.text = [textField.text substringToIndex:20];
        }
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容