Довольно часто нужно знать и контролировать те данные, что пользователь вводит в текстовые поля. Причем контролировать непосредственно в процессе ввода. Это вполне возможно.
И UITextView и UITextField шлют системе уведомления о изменении своего состояния (UITextViewTextDidChangeNotification и UITextFieldTextDidChangeNotification ). Шлют они их, используя NSNotificationCenter. Все что нам нужно, это слушать этот NotificationCenter и реагировать на нужные нам уведомления.
Пара слов о работе с NSNotificationCenter
NSNotificationCenter *notCenter = [NSNotificationCenter defaultCenter];
Это ссылка на NotificationCenter, через который по умолчанию ходят все системные сообщения (в том числе и нужные нам)
[[NSNotificationCenter defaultCenter]postNotificationName: @"NAME_OF_NOTIFICATION" object: self];
Так можно отправлять уведомления. Как видно, уведомление имеет имя и ссылку на объект (обычно это объект отправивший уведомлене). То есть мы можем видеть кто и какое уведомление отправил. В нашем случае мы будем только ловить уведомления, отправленные текстовыми полями
[[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(meth:) name:@"UITextViewTextDidChangeNotification" object: nil];
Регистрируем слушателя уведомлений. Рассмотрим все 4 параметра
addObserver: Объект, который будет реагировать на уведомления
selector: селектор (метод) объекта, который будет вызван при приходе уведомления
name: строка-имя уведомления, которое мы ждем
object: объект, уведомления от которого мы ждем. Если nil, то принимаем уведомления от любого объекта.
- (void)meth:(NSNotification*)notification;
Так выглядит метод(selector:), который будет вызван при приходе уведомления
Ну и наконец-то возвращаемся к теме статьи. Небольшой пример. Класс, который будет менять буквы, вводимые в любом текстовом поле приложения на ПРОПИСНЫЕ
-(id) init {
if(self = [super init]) {
[[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(capitalizeText:) name:@"UITextFieldTextDidChangeNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(capitalizeText:) name:@"UITextViewTextDidChangeNotification" object:nil];
}
return self;
}
-(void) capitalizeText: (NSNotification*)notification{
[[NSNotificationCenter defaultCenter]removeObserver: self name: [notification name] object: nil];
UIView *textItem = [notification object]; // textField or textView
NSString *text = [textItem text];
text = [text uppercaseString];
[textItem setText: text];
[[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(capitalizeText:) name:[notification name] object:nil];
}
- (void) dealloc
{
[[NSNotificationCenter defaultCenter]removeObserver: self name: @"UITextFieldTextDidChangeNotification" object: nil];
[[NSNotificationCenter defaultCenter]removeObserver: self name: @"UITextViewTextDidChangeNotification" object: nil];
[super dealloc];
}
Обратите внимание на то, что уведомление xxxTextDidChangeNotification будет слаться и при программном изменении текста в текстовом поле. поэтому мы в методе capitalizeText: временно отключаам наблюдение.
Все. Будут вопросы-предложения-комментарии - пишите ))
Вопрос может не совсем в тему, я изучаю Objective-C и в процессе изучения наткнулся на необходимость отслеживать изменение файла. На предмет записи в этот файл либо создания нового файла с таким же именем и в том же месте. Мне кажется надо работать с NSNotification, но я не уверен что это так.
ОтветитьУдалитьЕсли не затруднит не могли бы вы посоветовать материал к изучению или дать пример кода для моей задачи?
ALiEN, Не совсем понятно, как во время работы Вашего приложения кто-то, кроме этого приложения может изменить файл?
ОтветитьУдалитьОднако проверить, будет ли нотификация на изменение файла просто. Зарегистрируйте в NotificationCentr-е наблюдателя, который будет ловить ВСЕ нотификации и посмотрите, поймает ли он что-то при изменении файла.
[[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(your_meth_name:) name: nil object:nil];
З.Ы. Сам проверить не могу, так-как iPhone больше не занимаюсь.
С делегатами не проще?
ОтветитьУдалить– textField:shouldChangeCharactersInRange:replacementString:
– textView:shouldChangeTextInRange:replacementText:
С делегатами не проще, с делегатами по другому )
ОтветитьУдалитьДелегата Вы должны зарегистрировать для КАЖДОГО текстфилда, который вы хотите обрабат
А удобство работы с нотификациями в том, что Вы написали этот код один раз и он сразу стал работать для всех текстфилдов, которые уже есть в программе или появятся в будующем.
Так что тут немного разная область применения.