【问题标题】:Keyboard hiding UIView iOS键盘隐藏 UIView iOS
【发布时间】:2012-07-30 13:38:02
【问题描述】:

我知道这个问题已经被问过几次了。我知道当键盘出现时如何向上移动视图或文本字段,但是我遇到了一个我似乎无法弄清楚的故障。

我试图向上移动的视图位于 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 秒重新加载一次,以便可以使用任何新消息更新消息。

【问题讨论】:

  • 您应该研究键值观察,而不是使用NSTimer。在后台使用计时器自动检查更新通常是不好的做法(效率很低)。
  • 我会调查的。这对于使用 REST 服务检查新消息是否有效?我假设包含消息的数组必须从服务器不断更新。我还想找到一种方法来更新消息表,而不必重新绘制整个表。我想如果我进行这个键值观察,这会起作用。
  • 如果您使用服务器,您应该让用户决定何时更新他们的消息。从服务器提取会消耗大量开销。我不知道在不重绘表格的情况下更新表格的方法。 KVO 用于查看对象的属性并在属性更改时调用某些方法,所以我不确定它是否会做你想要的。试着看看你能用它做什么,如果你需要帮助,可以在 SO 上发布另一个问题。

标签: objective-c ios5


【解决方案1】:

文本字段已经向上移动,但在您离开视图时没有向下移动。当您重新访问视图时,它会再次向上移动 - 并离开屏幕。

我以前遇到过这个问题;通过保持布尔变量指示文本字段是处于向上还是向下位置来解决它。在再次向上移动之前检查变量以确保文本字段尚未向上。

我是怎么做到的。我在我的视图上使用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];
    }
}

-编辑-

查看您的代码,您似乎正在从框架的 y 坐标中减去框架以向下移动框架。 CGRect 的 iOS 坐标系与普通坐标系不同 - y 轴是翻转的(这在图形系统中比较常见)。你会想做与你正在做的事情相反的事情。

【讨论】:

  • 当我离开视图时,键盘被隐藏了。那不应该调用keyboardWillBeHidden方法并因此调用animateTextField吗?我记录了该方法是否被调用,并且我注意到每次注册键盘事件时都会调用 animateTextField 方法两次。
  • keyboardWillBeHidden 通知只有在发生隐藏时您仍在同一视图中时才会被调用。
  • 我将为布尔值添加条件并让您知道会发生什么,感谢到目前为止的详细回答。
  • 现在只要显示键盘,视图就会消失。我记录了检查我的案例是否正确的方法,并且它们似乎是正确的。我用更新的方法编辑了我的问题。
  • 抱歉,如何记录可见性状态?记录位置是指只记录框架的 CGRect 吗?
猜你喜欢
  • 1970-01-01
  • 2013-01-12
  • 1970-01-01
  • 2016-05-30
  • 2012-05-10
  • 1970-01-01
  • 1970-01-01
  • 2015-01-17
  • 1970-01-01
相关资源
最近更新 更多