ios Xcode/iOS5:当键盘出现时向上移动 UIView

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7952762/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 22:08:05  来源:igfitidea点击:

Xcode/iOS5: Move UIView up, when keyboard appears

iphoneiosuiviewcontrollerkeyboardios5

提问by filou

I'd like to move up my view, when the keyboard is shown. The keyboard (height: 216) should push up my view with it's height. Is this possible with a simple code?

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

回答by djromero

To move the view up, just change its center. First, keep the original one in a CGPointproperty.

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

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

Then, change as needed when keyboard shows up:

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

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

Finally, restore it when keyboard is hidden:

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

self.view.center = self.originalCenter;

Add animation sugar as you wish

根据需要添加动画糖

You have more than one way to know when the keyboard appears.

您有不止一种方法可以知道键盘何时出现。

Observing UIKeyboardDidShowNotificationnotification.

观察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 */
}

Do the opposite with UIKeyboardDidHideNotification.

做相反的事情UIKeyboardDidHideNotification

-OR-

-或者-

Implement UITextFieldDelegate

实现UITextFieldDelegate

Detect when editing begin/end to move views around.

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

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

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

Depending on the actual text fields you may need to track in which field is the user editing, add a timer to avoid moving views too much.

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

回答by Tendulkar

do like this. after keyboard visible use this code

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

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

}

回答by Kishore Suthar

This is the most easiest and efficient way to achieve this:

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

Add the following constants:

添加以下常量:

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;    

Add this to your view controller:

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

CGFloat animatedDistance;

And add these methods to your code:

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

- (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];
}

回答by Michael

I did this in a similar fashion to djromero except that I adjusted the frame origin of the view rather than its centre.

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

The view that i'm moving is a UIScrollView, and I want it to move relative to a UITextField element, so that the text field always shows. The position of this text field can vary depending on the offset of the scroll view.

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

So my code looks like this:

所以我的代码是这样的:

- (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];
    });
}

The view controller is a UITextFieldDelegate and also subscribes to UIKeyboardDidShowNotification so that we are able to access the size of the keyboard.

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

When the keyboard shows, we calculate the relative offset of the UITextField (adjusted for scroll offset) and the keyboard and them change the origin of the UIScrollView so that it moves just enough for the UITextField still to be showing.

当键盘显示时,我们计算 UITextField(针对滚动偏移进行调整)和键盘的相对偏移量,然后它们更改 UIScrollView 的原点,使其移动到足以让 UITextField 仍然显示的位置。

If the UITextField will still show even if the keyboard appears, then the origin does not change.

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

回答by sreekanthk

-(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;}];
}

just edit these two methods.
simple answer to all d codes. In the if statement change the value according to the iphone i.e., if iphone 4S change it to 265 and in didbeginediting change the 320 to 240 and if iphone 5 change it to 350 and in didbeginediting method keep it as 320, because it is the logic if u understand

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

回答by James Webster

Presumably you have some code calling [myTextField becomeFirstResponder];. You should move your view just after this call.

大概你有一些代码调用[myTextField becomeFirstResponder];. 您应该在此调用后立即移动您的视图。

回答by Javier Calatrava Llavería

This is Tendulkar solution, but keeping in mind original frame size and removing keyboard. This solution works for all devices.

这是 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];

}

Do not forget set UITextField delegate!

不要忘记设置 UITextField 委托!

回答by LuAndre

Sample project Based on Apple Reference Keyboard Documentation

基于Apple 参考 键盘文档的示例项目

H File: (Don't Forget the UITextFieldDelegate)

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 file:

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