2012-08-13 62 views
0

我使用UITextView的一個子類UIViewController我已經命名爲FacebookPostViewController。因此,文本視圖的目的是允許用戶查看已準備好的帖子的內容,可能對其進行更改,然後確定文本視圖中的文本是否應發佈到Facebook。是否有可能使UITextView無效(可編輯=否)而不隱藏鍵盤?

我設置的UITextView的returnKeyType屬性UIReturnKeySend,因爲我想用它來實際發佈到Facebook。通過導航欄中的後退按鈕可以取消。

所以FacebookPostViewController是UITextView中的代表,並在的TextView:shouldChangeTextInRange:replacementText:委託方法,我查了換行插入,然後叫我sendTextToFacebook方法:

- (void)sendTextToFacebook; 
{ 
    // prepare sending 
    NSMutableDictionary* sendParameters = [NSMutableDictionary dictionaryWithObjectsAndKeys:self.textView.text, @"message", nil]; 

    // request sending to own feed 
    [[FacebookController sharedFacebookController].facebook requestWithGraphPath:@"me/feed" andParams:sendParameters andHttpMethod:@"POST" andDelegate:self]; 
} 

正如你所看到的,我指定自我作爲FBRequestDelegate,所以我也實現

- (void)request:(FBRequest *)request didFailWithError:(NSError *)error; 
- (void)request:(FBRequest *)request didLoad:(id)result; 

如果發佈成功或不成功,我會向用戶提供反饋。

但是,我發現在Facebook服務器回覆之前需要一些時間,所以我想讓完整的UI處於非活動狀態,直到調用兩個委託方法中的一個爲止。因此,我已經實現了以下方法:

- (void)disableUserInterface; 
{ 
    self.textView.editable = NO; 
    self.loginButton.enabled = NO; 
    self.logoutButton.enabled = NO; 
    [self.navigationItem setHidesBackButton:YES animated:YES]; 

    [self.spinner startAnimating]; 
    self.spinner.hidden = NO; 
} 

我的問題是,調用self.textView.editable = NO將隱藏鍵盤,看起來愚蠢。如果我刪除該行,鍵盤不會消失,但用戶可以在文本發送到Facebook時更改textView內容。但是,由於發佈已經啓動。這些變化實際上不會出現在Facebook中。

我想我可以簡單地實現另一個UITextViewDelegate方法:

- (BOOL)textViewShouldEndEditing:(UITextView *)textView 
{ 
    return NO; 
} 

的UI結果是那麼正是我想如何擁有它。但是,當我彈出FacebookPostViewController,然後將另一個視圖推送到UINavigationController時,這會導致EXC_BAD_ACCESS崩潰。那麼療法誤差

*** -[UITextView isKindOfClass:]: message sent to deallocated instance 0x20c650 

因此,任何人有一個想法,我怎麼能解決我的問題作出的UITextView不可編輯,但防止鍵盤消失?!?

+0

你讓我直到最後。你用textViewShouldEndEditing提出的解決方案是我所建議的。你的崩潰與這個禁止界面的問題無關。如果你有鍵盤,並以某種方式釋放其綁定的UITextView,當然它會崩潰。我懷疑你需要在彈出FacebookPostViewController之前發送textView resignFirstResponder。 – 2012-08-13 19:42:11

+0

嗯謝謝你的建議!我不知道在釋放_UITextView_時鍵盤已經打開會導致崩潰!但是,我已經嘗試在_viewWillDisappear:_中調用_ [self.textView resignFirstResponder] _,但這會導致另一個_textViewShouldEndEditing:_的調用,這將阻止鍵盤隱藏。但由於你的提示,我找到了解決問題的辦法。我會把它作爲一個單獨的答案發布。再次感謝! – Tafkadasoh 2012-08-14 11:39:38

+0

那麼,即使你得到了textViewShouldEndEditing,你也只是在那個時候返回YES - 你可以設置一個標誌來知道你必須這樣做。 – 2012-08-14 11:43:57

回答

0

好的,感謝上面David H的評論,我已經找到了一個解決方案。但這裏是最重要的觀點:

  1. 當我彈出我的FacebookPostViewControllerUINavigationController的,在UITextView的由系統自動要求辭職是第一個響應者。

  2. 你應該從未textViewShouldEndEditing:總是返回NO,因爲這將始終防止鍵盤隱藏,那麼這將導致上述崩潰,只要的UITextView被釋放。

解決方案是防止鍵盤在我們仍在等待Facebook服務器響應的情況下消失。這裏有幾行代碼,我已經添加,這是做到這一點:

@interface FacebookPostViewController() 
// ... 
@property (nonatomic, assign, getter = isWaitingForFBResponse) BOOL waitingForFBResponse; 
// ... 
@end 

@implementation FacebookPostViewController 
// ... 
@synthesize waitingForFBResponse = _waitingForFBResponse; 

- (id)init; 
{ 
    self = [super init]; 
    if (self) { 
     // set default values 
     self.waitingForFBResponse = NO; 

     // ... 
    } 

    return self; 
} 


#pragma mark - 
#pragma mark UITextViewDelegate methods 
- (BOOL)textViewShouldEndEditing:(UITextView *)textView 
{ 
    if ([self isWaitingForFBResponse]) { 
     return NO; 
    } else { 
     return YES; 
    } 
} 

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { 
    // Did user press 'return' (Send) key? 
    if([text isEqualToString:@"\n"]) { 
     // enter waiting state 
     self.waitingForFBResponse = YES; 

     // disable the user interface 
     [self disableUserInterface]; 

     FacebookController *fbController = [FacebookController sharedFacebookController]; 
     if ([fbController.facebook isSessionValid] == YES) { 
      // Post to Facebook! 
      [self sendTextToFacebook]; 
     } else { 
      // we need to login first 
      [self loginToFacebook]; 

      // remember that user wants to post to Facebook 
      self.sendTextAfterFBLogin = YES; 
     } 

     // Don't allow textView to insert a LF into the text property 
     return NO; 
    } 

    // allow all other edits 
    return YES; 
} 


#pragma mark - 
#pragma mark FBRequestDelegate methods 
- (void)request:(FBRequest *)request didFailWithError:(NSError *)error; 
{ 
    // request failed, so display error status overlay. 
    [[FeedbackController sharedFeedbackController] displayStatusOverlayWithString:NSLocalizedString(@"StatusMessage_Failure", nil)]; 

    // leave waiting state 
    self.waitingForFBResponse = NO; 

    // enable UI again 
    [self enableUserInterface]; 
} 

- (void)request:(FBRequest *)request didLoad:(id)result; 
{ 
    // request succeeded, give user appropriate feedback. 
    [[FeedbackController sharedFeedbackController] displayStatusOverlayWithString:NSLocalizedString(@"StatusMessage_Sent", nil)]; 

    // leave waiting state 
    self.waitingForFBResponse = NO; 

    // pop the view, as the user accomplished his goal. 
    [self.navigationController popViewControllerAnimated:YES]; 
} 

@end 
相關問題