在UITextView的文本属性上观察关键值?

我有最糟糕的时间获取关键值观察与UITextView的文本属性工作。 我可以成功地添加观察者,我甚至可以删除同一个观察者。 我有一个tableview与几个单元格 – 一些有UITextFields,一些有UISegmentSelectors和一个有一个UITextView。 除了UITextView之外,所有其余的字段都被我的核心数据对象(NSMangedObject的子类)成功地观察到了。 如果需要,我可以发布代码。

发布代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *UserProfileCellIdentifier = @"UserProfileCellIdentifier"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: UserProfileCellIdentifier]; if (cell == nil) { [_tableCellsNib instantiateWithOwner:self options:nil]; switch (indexPath.row) { // UserName Row case UserNameRowIndex: _textFieldCell.cellLabel.text = NSLocalizedString(@"UserNameLabel", @"User Profile TableView"); _textFieldCell.cellType = CellTypeNormal; _textFieldCell.boundProperty = @"UserName"; _textFieldCell.tag = indexPath.row; _textFieldCell.errorHandler = self; _textFieldCell.boundControl = _textFieldCell.cellTextField; [_textFieldCell addObserver:[MBUtilities getAppDelegate].userProfile forKeyPath:@"cellTextField.text" options:NSKeyValueObservingOptionNew context:NULL]; cell = _textFieldCell; self.textFieldCell = nil; break; case PasswordRowIndex: _textFieldCell.cellLabel.text = NSLocalizedString(@"PasswordLabel", @"User Profile TableView"); _textFieldCell.cellType = CellTypeNormal; _textFieldCell.cellTextField.secureTextEntry = YES; _textFieldCell.boundProperty = @"Password"; _textFieldCell.tag = indexPath.row; _textFieldCell.errorHandler = self; _textFieldCell.boundControl = _textFieldCell.cellTextField; [_textFieldCell addObserver:[MBUtilities getAppDelegate].userProfile forKeyPath:@"cellTextField.text" options:NSKeyValueObservingOptionNew context:NULL]; cell = _textFieldCell; self.textFieldCell = nil; break; case PasswordConfirmRowIndex: _textFieldCell.cellLabel.text = NSLocalizedString(@"PasswordConfirmLabel", @"User Profile TableView"); _textFieldCell.cellType = CellTypeNormal; _textFieldCell.cellTextField.secureTextEntry = YES; _textFieldCell.tag = indexPath.row; cell = _textFieldCell; self.textFieldCell = nil; break; case FirstNameRowIndex: _textFieldCell.cellLabel.text = NSLocalizedString(@"FirstNameLabel", @"User Profile TableView"); _textFieldCell.cellType = CellTypeNormal; _textFieldCell.boundProperty = @"FirstName"; _textFieldCell.tag = indexPath.row; _textFieldCell.errorHandler = self; _textFieldCell.boundControl = _textFieldCell.cellTextField; [_textFieldCell addObserver:[MBUtilities getAppDelegate].userProfile forKeyPath:@"cellTextField.text" options:NSKeyValueObservingOptionNew context:NULL]; cell = _textFieldCell; self.textFieldCell = nil; break; case LastNameRowIndex: _textFieldCell.cellLabel.text = NSLocalizedString(@"LastNameLabel", @"User Profile TableView"); _textFieldCell.cellType = CellTypeNormal; _textFieldCell.boundProperty = @"LastName"; _textFieldCell.tag = indexPath.row; _textFieldCell.errorHandler = self; _textFieldCell.boundControl = _textFieldCell.cellTextField; [_textFieldCell addObserver:[MBUtilities getAppDelegate].userProfile forKeyPath:@"cellTextField.text" options:NSKeyValueObservingOptionNew context:NULL]; cell = _textFieldCell; self.textFieldCell = nil; break; case DateOfBirthRowIndex: _textFieldCell.cellLabel.text = NSLocalizedString(@"BirthDateLabel", @"User Profile TableView"); _textFieldCell.cellType = CellTypeDatePicker; _textFieldCell.boundProperty = @"DateOfBirth"; _textFieldCell.tag = indexPath.row; _textFieldCell.errorHandler = self; _textFieldCell.boundControl = _textFieldCell.cellTextField; [_textFieldCell addObserver:[MBUtilities getAppDelegate].userProfile forKeyPath:@"cellTextField.text" options:NSKeyValueObservingOptionNew context:NULL]; cell = _textFieldCell; self.textFieldCell = nil; break; case GenderSelfRowIndex: _genderSelectCell.cellLabel.text = NSLocalizedString(@"UserSexLabel", @"User Profile TableView"); _genderSelectCell.boundProperty = @"GenderSelf"; _genderSelectCell.errorHandler = self; _genderSelectCell.boundControl = _genderSelectCell.cellGenderSegment; _genderSelectCell.tag = indexPath.row; [_genderSelectCell addObserver:[MBUtilities getAppDelegate].userProfile forKeyPath:@"cellGenderSegment.selectedSegmentIndex" options:NSKeyValueObservingOptionNew context:NULL]; cell = _genderSelectCell; self.genderSelectCell = nil; break; case GenderInterestedInRowIndex: _genderSelectCell.cellLabel.text = NSLocalizedString(@"UserInterestedInLabel", @"User Profile TableView"); _genderSelectCell.boundProperty = @"GenderInterestedIn"; _genderSelectCell.errorHandler = self; _genderSelectCell.boundControl = _genderSelectCell.cellGenderSegment; _genderSelectCell.tag = indexPath.row; [_genderSelectCell addObserver:[MBUtilities getAppDelegate].userProfile forKeyPath:@"cellGenderSegment.selectedSegmentIndex" options:NSKeyValueObservingOptionNew context:NULL]; cell = _genderSelectCell; self.genderSelectCell = nil; break; case IntroductionRowIndex: _textViewCell.cellLabel.text = NSLocalizedString(@"IntroductionLabel", @"User Profile TableView"); _textViewCell.boundControl = _textViewCell.cellTextView; _textViewCell.errorHandler = self; _textViewCell.boundProperty = @"Introduction"; _textViewCell.tag = indexPath.row; [_textViewCell addObserver:[MBUtilities getAppDelegate].userProfile forKeyPath:@"cellTextView.text" options:NSKeyValueObservingOptionNew context:NULL]; cell = _textViewCell; self.textViewCell = nil; break; }; } return cell; } 

讨论:每个单元格都从外部的NIB文件加载,然后用不同的属性进行初始化。 除了最后一个UITextView以外,所有单元格都使用键值观察。 让我知道是否需要任何额外的信息。

UIKit不保证符合KVO标准 :

注意:尽pipeUIKit框架的类通常不支持KVO,但您仍然可以在应用程序的自定义对象(包括自定义视图)中实现它。

它可能在一些类+键上工作,但这不可靠,并可能在不同的iOS版本中改变。 见戴夫对这个问题的回答 ; 戴夫在UIKit上工作。

使用UITextViewTextDidChangeNotification更好。

我做了以下几点:

首先注册NSNotificationCenter:

 - (id)init { [super init]; if (self) { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(textDidChange:) name:UITextViewTextDidChangeNotification object:nil]; } return self; } - (void)dealloc { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc removeObserver:self]; } 

然后定义一个通知处理器:

 - (void)textDidChange:(NSNotification *)note { NSLog(@"Observation..."); } 

现在只要UITextView对象中的文本发生更改,就会调用textDidChange:方法。

好吧,所以我没有find任何解释这种行为的运气,除非有人能告诉我,否则我相信这是一个IOS的错误。

我能够得到它与这个黑客工作:

 - (void)textViewDidEndEditing:(UITextView *)textView { NSLog(@"Editing Ended"); textView.text = textView.text; } 

一旦代码被添加,瞧,observeValueForKeyPath会触发!

你有没有尝试实现UITextViewDelegate并将thisIsYourTextView.delegate分配给它?

那么,我发现这个教程 ,也许会让事情更清楚一点。