目錄前言一、監聽UITextField 內容變化1. 代理2. 通知3. 目標動作事件二、監聽UITextView文本內容高度變化三、cell中的文本框,在reloadData or reloadRow後失去焦點四、手機號碼、銀行卡號格式化 前言 本文總結了在使用 UITextField & UIT ...
目錄
前言
本文總結了在使用 UITextField & UITextView 時遇到的一些問題及場景,以及對應的解決方案。 目前覆蓋的面可能不太全,後面會持續更新.....
一、監聽UITextField 內容變化
已知三種方式 :
- 代理:delegate
- 通知:NSNotification
- 目標動作:addTarget:action:
1. 代理
代理方式只能監聽設置了代理的文本框。沒有設置代理的文本框不能進行監聽。
設置代理
self.textField.delegate = self;
實現協議及協議方法 <UITextFieldDelegate>
@interface MyController:UIViewController <UITextFieldDelegate>
@end
@implementation MyController
//是否可以編輯yes可以 no不可以
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
return YES;
}
//開始編輯的時候調用
- (void)textFieldDidBeginEditing:(UITextField *)textField{
NSLog(@"開始編輯");
}
//是否允許結束編輯(當用戶結束一個文本框的時候,首先會調用這個)
//如果是NO 意思就是,這個文本框回一直處於編輯狀態(也叫第一響應者),就算你再點擊其他文本框,是沒有任何效果的
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField{
return YES;
}
//結束編輯的時候調用
- (void)textFieldDidEndEditing:(UITextField *)textField{
NSLog(@"結束編輯");
}
//是否允許用戶輸入文件
//用戶每次輸入一個字元的時候就會調用一次。然後判斷是否顯示在文本框里
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
//列印
NSString *text=[NSString stringWithFormat:@"%@%@",textField.text,string];
NSLog(@"------%@",text);
return YES;
}
//是否允許清除當前文本框中所輸入的內容
- (BOOL)textFieldShouldClear:(UITextField *)textField{
return YES;
}
@end
2. 通知
可以監聽所有文本框的內容變化
添加通知監聽 UITextFieldTextDidChangeNotification
[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textChange:)
name:UITextFieldTextDidChangeNotification object:nil];
-(void)textChange: (NSNotification *)notif {
NSLog(@“-----Change-----");
}
使用完成後,一定要銷毀
//當前對像要銷毀的時候,創建的通知要進行移除:(否則可能報錯,壞記憶體訪問)
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
3. 目標動作事件
多個控制項,可以使用同一個消息處理。也可以是多個不同的消息處理。
添加目標動作 events: UIControlEventEditingChanged
[self.textField1 addTarget:self action:@selector(textChange:) forControlEvents:UIControlEventEditingChanged];
[self.textField2 addTarget:self action:@selector(textChange:) forControlEvents:UIControlEventEditingChanged];
內容改變時觸發
//我把2個文本框的監聽觸發方法都設置為textChange: 目的是判斷登錄按鈕是否可以點擊
-(void)textChange:(UITextField *)tf {
if(tf == self.textField1){
NSLog(@"第一個文本控制項的內容發生變化");
}else if (tf == self.textField2){
NSLog(@"第二個文本控制項的內容發生變化");
}
}
二、監聽UITextView文本內容高度變化
遇到的需求或問題:
做聊天鍵盤時,在文字錄入區域,如果用單行文本展示,則會出現當文本內容過多時內容展示不全的情況,同時修改與預覽文本也比較費勁。 針對這種情況 像微信、QQ等的做法是 : 根據文本內容動態調整文本框控制項的高度, 並設置一個最大可顯示的高度,超過這個高度不再調整。
有了思路,那麼接下來要解決的就是如何知道文本高度發生了變化? 您可能想到的是 :如果當文本改變時,實時計算錄入文本的高度與原有高度進行比較, 如果與原高度不同,則觸發。這樣做的話,只要有字元變化就會調用一次計算,效率不可能會高,所以,這種方式顯然不是最優解。
解決方法:
其實,UITextView
控制項是繼承自UIScrollView
的。 當我們需要知道UIScrollView內容是否變化時,監聽的是它的contentSize
屬性。 那麼對於UITextView
控制項同樣適用。所以如果想要知道UITextView內容的高度,也可以通過contentSize
來拿到。
CGFloat height = self.textView.contentSize.height;
三、cell中的文本框,在reloadData or reloadRow後失去焦點
遇到的需求或問題:
接上面的場景。 當文本框處於UITableViewCell or UICollectionViewCell中時,會碰到如下情況: 文本框處於獲取焦點狀態, 監聽文本內容高度的變化同步更改Cell的高度。 通常在獲取到新的高度後,我們會使用reloadRow
or reloadData
來重新佈局與載入數據。 但此時你們發現調用完後,文本框失去了焦點。我們期望的是:在監聽到文本內容高度發生變化時,同步更改cell的高度,並且文本框不會失去焦點。 這該怎麼解決呢 ?
解決方法:
UICollectionView
和UITableView
都提供了這樣一個方法: performBatchUpdates:completion:
// allows multiple insert/delete/reload/move calls to be animated simultaneously. Nestable.
- (void)performBatchUpdates:(void (NS_NOESCAPE ^ _Nullable)(void))updates
completion:(void (^ _Nullable)(BOOL finished))completion;
使用這個方法讓UICollectionView
進行重新佈局,相當於調用了[collectionView reloadData]
方法,但是UITextField
控制項不會失去焦點仍然是第一響應者,從而解決了重新佈局導致鍵盤收起的問題。
使用:
//類似像調用 reloadData一樣使用
[self.tableView performBatchUpdates:^{
} completion:^(BOOL finished) {
}];
四、手機號碼、銀行卡號格式化
查看更多內容: https://blog.csdn.net/zhanglei5415/article/details/132743478
本文來自博客園,作者:reyzhang,轉載請註明原文鏈接:https://www.cnblogs.com/reyzhang/p/17705423.html