2011-06-13 39 views
13

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

发布代码:

- (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的最后一个外,所有单元格都可以使用键值观察。让我知道是否需要任何额外的信息。

回答

15

UIKit的是不能保证KVO compliant

注:虽然UIKit框架中的类一般不支持志愿,你仍然可以实现它在你的应用程序的自定义对象,包括自定义观点。

它可能适用于某些类+键,但这不可靠,并可能在不同的iOS版本中更改。见Dave’s answer to this question; Dave在UIKit上工作。

+0

我该如何在自定义视图中实现这一点?我会重写什么方法来改变这种行为? – jjm340 2011-06-15 16:52:40

+0

@jjm你只能实现这个自定义键 - 例如,如果你声明一个新的属性。如果您有从UIKit类继承的自定义视图,则KVO不一定适用于该UIKit类中已存在的键。 – 2011-06-15 21:49:37

0

您是否尝试过实现UITextViewDelegate并将thisIsYourTextView.delegate赋值给它?

嗯,我发现这tutorial,也许它会让事情更清楚一点。

+0

是的,我这样做的界面生成器(或任何4.0 xCode版本被称为) – jjm340 2011-06-13 17:22:28

+0

你可以发布一些代码为您的控制器呢?帮助视觉辅助可能更容易。 – 2011-06-13 17:29:22

+0

会做。谢谢。 – jjm340 2011-06-13 17:44:41

3

好的,所以我没有找到任何解释此行为的运气,除非有人能告诉我,否则我相信它是IOS中的一个错误。

我能得到它与这个技巧的工作:

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

一旦加入该代码,瞧,在observeValueForKeyPath火灾!

+0

这不是一个错误。作为UITextView而不是KVO保证,可能他们使用iVar在内部设置了该值。你改为使用属性设置器明确地设置变量值,并且这肯定会触发KVO事件。 – SalvoC 2015-11-27 13:56:51

14

使用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:方法将被调用。

+0

您甚至可以检查该文本视图是否为文本视图:UITextViewTextDidChangeNotification 通知观察者文本视图中的文本已更改。受影响的视图存储在通知的对象参数中。 userInfo字典未使用 – 2017-09-25 10:36:46