【问题标题】:Xcode/iOS5: Move UIView up, when keyboard appearsXcode/iOS5:当键盘出现时,向上移动 UIView
【发布时间】:2011-12-18 15:51:34
【问题描述】:

我想在显示键盘时向上移动视图。键盘(高度:216)应该用它的高度推高我的视野。这可以通过简单的代码实现吗?

【问题讨论】:

  • 无需更改您的标题以包含 SOLVED,接受的答案表明这一点。

标签: iphone ios uiviewcontroller keyboard ios5


【解决方案1】:

要移动视图up,只需更改其center。首先,将原始的保留在 CGPoint 属性中。

- (void)viewDidLoad 
{
    ...
    self.originalCenter = self.view.center;
    ...
}

然后,当键盘出现时根据需要进行更改:

self.view.center = CGPointMake(self.originalCenter.x, /* new calculated y */);

最后,在键盘隐藏时恢复:

self.view.center = self.originalCenter;

随意添加动画糖

知道键盘何时出现的方法不止一种。

观察 UIKeyboardDidShowNotification 通知。

/* register notification in any of your initWithNibName:bundle:, viewDidLoad, awakeFromNib, etc. */
{
    ...
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];     
    ...
}

- (void)keyboardDidShow:(NSNotification *)note 
{
    /* move your views here */
}

UIKeyboardDidHideNotification做相反的事情。

-或-

实现 UITextFieldDelegate

在编辑开始/结束时检测以移动视图。

- (void)textFieldDidBeginEditing:(UITextField *)textField 
{
    /* keyboard is visible, move views */
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    /* resign first responder, hide keyboard, move views */
}

根据您可能需要跟踪用户正在编辑哪个字段的实际文本字段,添加一个计时器以避免过多地移动视图。

【讨论】:

  • 谢谢你,madmw,这是完美的:)
  • @AlexisW 您是在 六个月 后改变主意接受一个不太完整的答案,还是 SO 出现故障?很奇怪。
  • 我无意降低您的声誉,甚至无视您的详细回答。因为我在堆栈上,所以我学到了很多关于编程的知识。所以当我需要一个函数时,我只是搜索它来学习。我还了解到,有时简单的答案或示例对“新手”来说更有帮助。无论如何,谢谢你的帮助 madmw。
  • 我不太关心 SO 的声誉,只是想了解您为什么选择了不正确的(当然是恕我直言)答案。感谢您的澄清。
  • 我只是尝试将此解决方案用于类似的问题。此解决方案存在一个问题:您应该在 viewDidAppear 而不是 viewDidLoad 中设置 originalCenter 参数。这是因为 UI 元素在循环中此时尚未放置在它们的位置,而是由 viewDidAppear 放置。 viewDidLoad 中的 originalCenter 给了我 x=0, y=0。
【解决方案2】:

这样做。 键盘可见后使用此代码

- (void)textFieldDidBeginEditing:(UITextField *)textField 
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.25];
    self.view.frame = CGRectMake(0,-10,320,480);
    [UIView commitAnimations];

}

【讨论】:

  • 这太好了,谢谢!改变框架虽然有些变形,所以我改变了 self.view 的中心,动画用键盘平滑地移动了视图:)
【解决方案3】:

我以与 djromero 类似的方式执行此操作,只是我调整了视图的框架原点而不是其中心。

我要移动的视图是 UIScrollView,我希望它相对于 UITextField 元素移动,以便始终显示文本字段。此文本字段的位置可能会根据滚动视图的偏移量而有所不同。

所以我的代码如下所示:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    dispatch_async(dispatch_get_main_queue(), ^{
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:0.2];
        [UIView setAnimationCurve:UIViewAnimationCurveLinear];
        self.scrollView.frame = CGRectMake(0,0,self.scrollView.frame.size.width,self.scrollView.frame.size.height);
        [UIView commitAnimations];
    });
    return YES;
}

- (NSInteger)getKeyBoardHeight:(NSNotification *)notification
{
    NSDictionary* keyboardInfo = [notification userInfo];
    NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey];
    CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue];
    NSInteger keyboardHeight = keyboardFrameBeginRect.size.height;
    return keyboardHeight;
}

-(void) keyboardDidShow:(NSNotification*) notification
{
    NSInteger keyboardHeight;
    keyboardHeight = [self getKeyBoardHeight:notification];
    NSInteger scrollViewFrameHeight = self.scrollView.frame.size.height;
    NSInteger textFieldRelativePosition = self.tableView.frame.origin.y - self.scrollView.contentOffset.y;
    NSInteger textFieldFrameOffset = scrollViewFrameHeight - textFieldRelativePosition;
    NSInteger movement = MAX(0,keyboardHeight-textFieldFrameOffset); // Offset from where the keyboard will appear.
    dispatch_async(dispatch_get_main_queue(), ^{
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:0.2];
        [UIView setAnimationCurve:UIViewAnimationCurveLinear];
        self.scrollView.frame = CGRectMake(0,-movement,
                                           self.scrollView.frame.size.width,
                                           self.scrollView.frame.size.height);
        [UIView commitAnimations];
    });
}

视图控制器是一个 UITextFieldDelegate 并且还订阅了 UIKeyboardDidShowNotification 以便我们能够访问键盘的大小。

当键盘显示时,我们计算 UITextField 的相对偏移量(调整滚动偏移量)和键盘,它们改变 UIScrollView 的原点,使其移动刚好足以让 UITextField 仍然显示。

如果即使出现键盘,UITextField 仍会显示,则原点不会改变。

【讨论】:

  • 您推送视图的方法有效,而移动中心无效。 (移动中心向上推,但是当我把它移回来时,它向下推得太远了)。
【解决方案4】:

这是实现这一目标的最简单有效的方法:

添加以下常量:

static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
static const CGFloat LANDSCAPE_KEYBOARD_HEIGHT = 162;    

将此添加到您的视图控制器:

CGFloat animatedDistance;

并将这些方法添加到您的代码中:

- (void)textFieldDidBeginEditing:(UITextField *)textField{
CGRect textFieldRect =
[self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect =
[self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
CGFloat numerator =
midline - viewRect.origin.y
- MINIMUM_SCROLL_FRACTION * viewRect.size.height;
CGFloat denominator =
(MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION)
* viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0)
{
    heightFraction = 0.0;
}
else if (heightFraction > 1.0)
{
    heightFraction = 1.0;
}
UIInterfaceOrientation orientation =
[[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait ||
    orientation == UIInterfaceOrientationPortraitUpsideDown)
{
    animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
}
else
{
    animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
}
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= animatedDistance;

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

[self.view setFrame:viewFrame];

[UIView commitAnimations];
}

- (void)textFieldDidEndEditing:(UITextField *)textfield{

CGRect viewFrame = self.view.frame;
viewFrame.origin.y += animatedDistance;

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

[self.view setFrame:viewFrame];

[UIView commitAnimations];
}

【讨论】:

  • 对我很有帮助,谢谢,我只是把它放进去,设置我的 UITextField 代表,剩下的就交给它了。谢谢!
  • 效果很好,不过有一个建议,使用基于块的动画来代替 begin/commitAnimation ...
  • 完美!并且它非常容易和快速地集成到您现有的代码中。
  • 我同意。这是地球上最好和最整洁的解决方案。我什至不必考虑其他任何事情,它甚至可以很好地与我的 textFieldShouldReturn 集成(使用标签设置 becomeFirstResponder 的下一个链)。即使在原始发布日期起 2 年后,您的解决方案仍然有效。谢谢!
  • 当键盘已经隐藏时,它会产生一个黑色区域,但视图仍然有动画。
【解决方案5】:
【解决方案6】:

大概你有一些代码调用[myTextField becomeFirstResponder];。你应该在这个调用之后移动你的视图。

【讨论】:

  • myView.center = //whatever your center was before + (CGPointMake(0, 216))
【解决方案7】:
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
    CGFloat y = textField.frame.origin.y;
    if (y >= 350) //not 380
   {
        CGRect frame = self.view.frame;
        frame.origin.y = 320 - textField.frame.origin.y;
        [UIView animateWithDuration:0.3 animations:^{self.view.frame = frame;}];
    }
}

-(void)textFieldDidEndEditing:(UITextField *)textField
{
CGRect returnframe =self.view.frame;
returnframe.origin.y = 0;
[UIView animateWithDuration:0.3 animations:^{self.view.frame = frame;}];
}

只需编辑这两个方法。
所有 d 代码的简单答案。在 if 语句中根据 iphone 更改值,即,如果 iphone 4S 将其更改为 265,并且在 didbeginediting 中将 320 更改为 240,如果 iphone 5 将其更改为 350,并且在 didbeginediting 方法中将其保留为 320,因为这是逻辑如果你明白

【讨论】:

【解决方案8】:

这是 Tendulkar 解决方案,但请记住原始框架尺寸并移除键盘。此解决方案适用于所有设备。

-(BOOL) textFieldShouldReturn:(UITextField *)textField{

[textField resignFirstResponder];

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.25];
self.view.frame = CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height);
[UIView commitAnimations];
return YES;
 }


- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.25];
    self.view.frame = CGRectMake(0,-50,self.view.frame.size.width,self.view.frame.size.height);
    [UIView commitAnimations];

}

不要忘记设置 UITextField 委托!

【讨论】:

    【解决方案9】:

    Sample project Based on 苹果参考Keyboard Documentation

    H 文件:(不要忘记 UITextFieldDelegate

    @property (weak, nonatomic) IBOutlet UIScrollView *scrollview;
    
    @property (weak, nonatomic) IBOutlet UIView *myView;
    
    
        //items on view
    @property (weak, nonatomic) IBOutlet UISwitch *partySwitch;
    @property (weak, nonatomic) IBOutlet UILabel *partyLabel;
    @property (weak, nonatomic) IBOutlet UITextField *partyNameTextfield;
    

    M文件:

        //MARK: View Loading
    - (void)viewDidLoad
    {
        [super viewDidLoad];
            // Do any additional setup after loading the view.
    }//eom
    
    -(void)viewDidAppear:(BOOL)animated
    {
        [self registerForKeyboardNotifications];
    }//eom
    
        //MARK: textfield delegates
    -(bool)textFieldShouldReturn:(UITextField *)textField
    {
        [textField resignFirstResponder];
        return true;
    }//eom
    
        //MARK: - Keyboard Observers
        // Call this method somewhere in your view controller setup code.
    - (void)registerForKeyboardNotifications
    {
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardWasShown:)
                                                     name:UIKeyboardDidShowNotification object:nil];
    
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardWillBeHidden:)
                                                     name:UIKeyboardWillHideNotification object:nil];
    
    }
    
    
    - (void)keyboardWasShown:(NSNotification*)aNotification
    {
        NSDictionary* info      = [aNotification userInfo];
        CGSize kbSize           = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
        CGRect bkgndRect        = myView.superview.frame;
        bkgndRect.size.height += kbSize.height;
    
        [myView.superview setFrame:bkgndRect];
        [scrollview setContentOffset:CGPointMake(0.0, myView.frame.origin.y-kbSize.height) animated:YES];
    }//eom
    
        // Called when the UIKeyboardWillHideNotification is sent
    - (void)keyboardWillBeHidden:(NSNotification*)aNotification
    {
        UIEdgeInsets contentInsets          = UIEdgeInsetsZero;
        scrollview.contentInset             = contentInsets;
        scrollview.scrollIndicatorInsets    = contentInsets;
    }//eom
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-07
      • 2013-05-21
      • 2014-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-02
      相关资源
      最近更新 更多