2012-07-30 123 views
1

我知道這個問題已被問了幾次。我明白如何在鍵盤出現時向上移動視圖或文本框,但是我遇到了一個我似乎無法弄清楚的小故障。鍵盤隱藏UIView iOS

我試圖向上移動的視圖是一個UIViewController,它充當兩個視圖的容器。這個容器本身就是一個滑動視圖控制器內的視圖(類似於Facebook實現的那種)。

當您第一次加載視圖時,文本字段向上移動,但如果您轉到其他視圖並返回,則鍵盤會導致視圖消失。

這裏是我使用的移動視圖了代碼:

- (void) animateTextField:(BOOL)up { 

    const int movementDistance = 350; // tweak as needed 
    const float movementDuration = 0; // tweak as needed 

    int movement = (up ? -movementDistance : movementDistance); 

    [UIView beginAnimations: @"anim" context: nil]; 
    [UIView setAnimationBeginsFromCurrentState: YES]; 
    [UIView setAnimationDuration: movementDuration]; 

    self.sendingToolbar.frame = CGRectOffset(self.sendingToolbar.frame, 0, movement); 
    self.messagesTable.frame = CGRectOffset(self.messagesTable.frame, 0, movement); 
    //[splitController moveViewUp:up]; 
    [UIView commitAnimations]; 

} 

- (void)registerForKeyboardNotifications 
{ 
    NSLog(@"was this method called"); 

    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(keyboardWasShown:) 
               name:UIKeyboardDidShowNotification object:nil]; 

    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(keyboardWillBeHidden:) 
               name:UIKeyboardWillHideNotification object:nil]; 

} 

// Called when the UIKeyboardDidShowNotification is sent. 
- (void)keyboardWasShown:(NSNotification*)aNotification 
{ 
    [self animateTextField:YES]; 
} 
// Called when the UIKeyboardWillHideNotification is sent 
- (void)keyboardWillBeHidden:(NSNotification*)aNotification 
{ 
    [self animateTextField:NO]; 
} 

任何想法,爲什麼這種故障可能發生的?謝謝

在爲布爾值添加建議以檢查文本字段是否已經啓動之後,視圖會一直顯示鍵盤時消失,而不僅僅是當您離開視圖並返回時。下面是修改後的方法:

- (void) animateTextField:(BOOL)up { 

    const int movementDistance = 350; // tweak as needed 
    const float movementDuration = 0; // tweak as needed 

    int movement = movementDistance; 

    [UIView beginAnimations: @"anim" context: nil]; 
    [UIView setAnimationBeginsFromCurrentState: YES]; 
    [UIView setAnimationDuration: movementDuration]; 

    if(textFieldIsUp && (up == YES)) { 
     NSLog(@"Case 1"); 
     // Do nothing since text field is already up 
    } 
    else if(textFieldIsUp && (up == NO)) { 
     NSLog(@"Case 2"); 
     // Move the text field down 
     self.sendingToolbar.frame = CGRectOffset(self.sendingToolbar.frame, 0, -movement); 
     self.messagesTable.frame = CGRectOffset(self.messagesTable.frame, 0, -movement); 

     textFieldIsUp = NO; 
    } 
    else if((textFieldIsUp == NO) && (up == YES)) { 
     NSLog(@"Case 3"); 
     // Move the text field up 
     self.sendingToolbar.frame = CGRectOffset(self.sendingToolbar.frame, 0, movement); 
     self.messagesTable.frame = CGRectOffset(self.messagesTable.frame, 0, movement); 

     textFieldIsUp = YES; 
    } 
    else if((textFieldIsUp == NO) && (up == NO)) { 
     NSLog(@"Case 4"); 
     // Do nothing since the text field is already down 
    } 
    else { 
     NSLog(@"Default"); 
     // Default catch all case. Does nothing 
    } 

    [UIView commitAnimations]; 

} 

這裏有一些關於我的設置一些細節:

視圖控制器是應用程序消息收發中心。視圖控制器包含兩個子視圖,左側的子視圖是用於選擇對話的菜單,右側的菜單是包含該對話內的消息的子視圖。由於我想從下往上加載消息,因此表視圖旋轉了180度,單元格也旋轉了180度,方向相反。此外,表格視圖使用NSTimer每5秒重新加載一次,以便可以使用任何新消息更新消息。

+0

不用「NSTimer」,你應該看看鍵值觀察。在後臺使用計時器自動檢查更新通常是不好的做法(相當低效)。 – Dustin 2012-07-30 15:07:23

+0

我會研究一下。這對於使用REST服務檢查新消息是否合適?我認爲包含消息的數組必須不斷從服務器進行更新。我也想找到一種方法來更新消息表,而不必重繪整個表。如果我做了這個鍵值觀察,我想這會起作用。 – 2012-07-30 15:28:12

+0

如果您使用的是服務器,您應該讓用戶決定何時更新他們的消息。從服務器中繪製消耗了不少數量的開銷。我不知道如何在不重繪表格的情況下更新表格。 KVO用於查看對象的屬性並在屬性更改時調用某種方法,因此我不確定它是否會按照您的要求進行操作。如果你需要幫助,試着看看你可以用它做什麼,並在SO上發佈另一個問題。 – Dustin 2012-07-30 15:43:57

回答

1

當您離開視圖時,textfield已被移動但未移回。當你重新審視視圖時,它會再次移動 - 並離開屏幕。

我以前有過這個問題;通過保持一個布爾變量來解決它,表明文本字段是處於向上還是向下的位置。檢查變量以確保文本字段在您再次移動之前尚未啓動。

我是如何做到的。我在我的視圖中使用NSNumber屬性來存儲視圖是否已被推高,以便其他視圖可以傳遞是否已將視圖向上或向下推送。一幀的

//In viewDidLoad 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardWillShowNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardWillHideNotification object:nil]; 

//Pushes the view up if one of the table forms is selected for editing 
- (void) keyboardDidShow:(NSNotification *)aNotification 
{ 
    if ([isRaised boolValue] == NO) 
    { 
     [UIView beginAnimations:nil context:NULL]; 
     [UIView setAnimationDuration:0.25]; 
     self.view.center = CGPointMake(self.view.center.x, self.view.center.y-moveAmount); 
     [UIView commitAnimations]; 
     isRaised = [NSNumber numberWithBool:YES]; 
    } 
} 

//Push view back down 
- (void) keyboardDidHide:(NSNotification *)aNotification 
{ 
    if ([isRaised boolValue]) 
    { 
     [UIView beginAnimations:nil context:NULL]; 
     [UIView setAnimationDuration:0.25]; 
     self.view.center = CGPointMake(self.view.center.x, self.view.center.y+moveAmount); 
     [UIView commitAnimations]; 
     isRaised = [NSNumber numberWithBool:NO]; 
    } 
} 

CNC中

你的代碼看,似乎你從減去y座標移動框架下來。 CGRect的iOS座標系與正常座標系不同 - y軸被翻轉(這對於圖形系統而言是相對常見的)。你會想做與你正在做的事情相反的事情。

+0

當我離開視圖時,鍵盤變得隱藏。不應該稱爲keyboardWillBeHidden方法,因此animateTextField?我記錄了該方法是否被調用,並且我注意到每次註冊鍵盤事件時都會調用兩次animateTextField方法。 – 2012-07-30 14:05:37

+0

只有在發生隱藏時仍處於相同視圖中時,纔會調用「keyboardWillBeHidden」通知。 – Dustin 2012-07-30 14:09:03

+0

我將爲布爾值添加條件並讓您知道發生了什麼,感謝迄今爲止的詳細答案。 – 2012-07-30 14:14:47