Iphone 关键值观察在UITextView';s文本属性?

Iphone 关键值观察在UITextView';s文本属性?,iphone,objective-c,ios,Iphone,Objective C,Ios,在使用UITextView的文本属性时,我最难获得键值。我可以成功地添加观察者,甚至可以删除同一个观察者。我有一个带有多个单元格的tableview—一些单元格有UITextFields,一些单元格有UISegmentSelector,还有一个单元格有UITextView。除UITextView外,我的核心数据对象(NSMangeObject的子类)成功观察到了所有其他字段。如果需要,我可以发布代码 张贴代码: - (UITableViewCell *)tableView:(UITableVie

在使用UITextView的文本属性时,我最难获得键值。我可以成功地添加观察者,甚至可以删除同一个观察者。我有一个带有多个单元格的tableview—一些单元格有UITextFields,一些单元格有UISegmentSelector,还有一个单元格有UITextView。除UITextView外,我的核心数据对象(NSMangeObject的子类)成功观察到了所有其他字段。如果需要,我可以发布代码

张贴代码:

- (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外,所有单元都使用键值观察。如果需要任何其他信息,请告诉我。

您是否尝试实现UITextViewDelegate并将thisIsYourTextView.delegate分配给它


好吧,我发现了这个,也许它会让事情变得更清楚。

好吧,所以我没有找到任何解释来解释这种行为,除非有人告诉我,否则我相信这是IOS中的一个bug

我能够让它与这个黑客一起工作:

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

添加代码后,瞧,observeValueForKeyPath启动了

UIKit不保证:

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


它可能在某些类+键上工作,但不可靠,并且可能在不同的iOS版本中发生变化。看见Dave在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对象中的文本发生更改时,就会调用
textdichange:
方法。

是的,我会在interface builder中执行此操作(或调用任何4.0 xCode版本),那么您可以为控制器发布一些代码吗?使用视觉辅助可能更容易。我很想知道是否有其他人遇到过这个问题。我的代码似乎没有什么特别之处。我创建了另一个测试应用程序,它有一个UITextView,问题也是一样的。感谢您的教程,但它没有讨论键值观察,也没有阐明我的特定问题。我如何在自定义视图中实现这一点?我将重写什么方法来更改此行为?@jjm您只能对自定义键实现此操作-例如,如果您声明一个新属性。如果您有一个从UIKit类继承的自定义视图,KVO不一定适用于该UIKit类中已经存在的键。这不是一个bug。由于UITextView不保证KVO,可能它们使用iVar在内部设置值。而是使用属性设置器显式设置变量值,此“是”保证触发KVO事件。您甚至可以检查该文本视图是否为您的文本视图:
UITextViewTextDidChangeNotification通知观察者文本视图中的文本已更改。受影响的视图存储在通知的对象参数中。未使用userInfo字典。