iOS-UITextField右對(duì)齊無(wú)法輸入空格解決方案

問(wèn)題說(shuō)明

今天使用UITextfield需要右對(duì)齊輸入,但是當(dāng)設(shè)置右對(duì)齊第一個(gè)字符輸入空格后,神奇的一幕發(fā)生了瓶蚂,如下圖,如果第一個(gè)字符輸入的是空格宣吱,那么光標(biāo)會(huì)跳到左側(cè)窃这;如果輸入其它字符,然后輸入空格凌节,此時(shí)輸入的空格不會(huì)立即顯示钦听,直到再次輸入其它字符時(shí)該空格會(huì)與輸入的字符同時(shí)顯示出來(lái)

解決思路

解決思路很簡(jiǎn)單倍奢,就是將我們輸入的普通空格使用Non-breaking space代替。

解決方案

方案1:通過(guò)代理方法監(jiān)聽(tīng)textfield的輸入垒棋。

1.首先設(shè)置控制器作為textfield的代理卒煞,

self.textField.delegate = self;

2.監(jiān)聽(tīng)文本的輸入,做如下處理

- (BOOL)textField:(UITextField *)textField 
        shouldChangeCharactersInRange:(NSRange)range 
        replacementString:(NSString *)string
{
    /* 如果不是右對(duì)齊叼架,直接返回YES畔裕,不做處理 */
    if (textField.textAlignment != NSTextAlignmentRight) {
        return YES;
    }
    
    /* 在右對(duì)齊的情況下*/
    // 如果string是@""衣撬,說(shuō)明是刪除字符(剪切刪除操作),則直接返回YES扮饶,不做處理
    // 如果把這段刪除具练,在刪除字符時(shí)光標(biāo)位置會(huì)出現(xiàn)錯(cuò)誤
    if ([string isEqualToString:@""]) {
        return YES;
    }

    /* 在輸入單個(gè)字符或者粘貼內(nèi)容時(shí)做如下處理,已確定光標(biāo)應(yīng)該停留的正確位置甜无,
    沒(méi)有下段從字符中間插入或者粘貼光標(biāo)位置會(huì)出錯(cuò) */
    // 首先使用 non-breaking space 代替默認(rèn)輸入的@“ ”空格
    string = [string stringByReplacingOccurrencesOfString:@" " 
                     withString:@"\u00a0"];
    textField.text = [textField.text stringByReplacingCharactersInRange:range 
                                     withString:string];
    //確定輸入或者粘貼字符后光標(biāo)位置
    UITextPosition *beginning = textField.beginningOfDocument;
    UITextPosition *cursorLoc = [textField positionFromPosition:beginning 
                                 offset:range.location+string.length];
    // 選中文本起使位置和結(jié)束為止設(shè)置同一位置
    UITextRange *textRange = [textField textRangeFromPosition:cursorLoc 
                                        toPosition:cursorLoc];
    // 選中字符范圍(由于textRange范圍的起始結(jié)束位置一樣所以并沒(méi)有選中字符)
    [textField setSelectedTextRange:textRange];
    
    return NO;
}

3.如果需要拿到textfield中的text使用扛点,在使用前記得將 non-breaking space替換回來(lái)

[self.textField.text stringByReplacingOccurrencesOfString:@"\u00a0" 
                     withString:@" "]; 

弊端分析:上面代理方法textField: shouldChangeCharactersInRange: replacementString:對(duì)于很多輸入字符返回的是NO,因此不能很好的監(jiān)聽(tīng)UITextFieldTextDidChangeNotification岂丘,因此不推薦使用陵究。

效果演示

方案2:通過(guò)addTarget: action: forControlEvents: 給textField添加響應(yīng)事件

在此,自定義了一個(gè)textField奥帘,code如下:

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
    
    // 給textfield添加響應(yīng)事件
        [self addTarget:self 
        action:@selector(replaceNormalSpaceUsingNonbreakingSpace) 
        forControlEvents:UIControlEventEditingChanged];
        }
    return self;
}

// 在響應(yīng)事件中將@" "替換為non-breaking space
- (void)replaceNormalSpaceUsingNonbreakingSpace
{
    UITextRange *textRange = self.selectedTextRange;
    self.text = [self.text stringByReplacingOccurrencesOfString:@" " 
                           withString:@"\u00a0"];
    [self setSelectedTextRange:textRange];
}

說(shuō)明:如果需要拿到textfield中的text使用铜邮,同樣需要將 non-breaking space替換回來(lái)。

該方法可以有效的解決問(wèn)題寨蹋,還能監(jiān)聽(tīng)UITextFieldTextDidChangeNotification松蒜,推薦使用。

效果演示

仍存在的問(wèn)題

當(dāng)我們最后輸入的是空格的時(shí)候已旧,那么當(dāng)textfield不是第一響應(yīng)者的時(shí)候牍鞠,那么最后的空格依然不可見(jiàn)。如下所示:

解決思路:可以在textfield右側(cè)放一個(gè)view评姨,當(dāng)輸入結(jié)束時(shí)难述,計(jì)算輸入內(nèi)容最后面空格的寬度,然后作為view的寬度吐句,當(dāng)textfield成為第一響應(yīng)者時(shí)胁后,令view的寬度為0。

PS:誰(shuí)有更好的方法@一下哦嗦枢。

參考

基本是下面解決方案的匯總攀芯,下面有的回答也存在一些其他小問(wèn)題。
clickme

源碼示例SFUITextFieldInputSpaceFromRight

最后編輯于
?著作權(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)離奇詭異丸相,居然都是意外死亡搔确,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)膳算,“玉大人座硕,你說(shuō)我怎么就攤上這事√榉洌” “怎么了华匾?”我有些...
    開封第一講書人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)机隙。 經(jīng)常有香客問(wèn)我蜘拉,道長(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)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了违寿?” 一聲冷哼從身側(cè)響起湃交,我...
    開封第一講書人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎藤巢,沒(méi)想到半個(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
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)深浮。三九已至压怠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間飞苇,已是汗流浹背菌瘫。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(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)容