2011-06-13 60 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