2012-08-13 55 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 
相关问题