【发布时间】:2011-12-18 15:51:34
【问题描述】:
我想在显示键盘时向上移动视图。键盘(高度:216)应该用它的高度推高我的视野。这可以通过简单的代码实现吗?
【问题讨论】:
-
无需更改您的标题以包含 SOLVED,接受的答案表明这一点。
标签: iphone ios uiviewcontroller keyboard ios5
我想在显示键盘时向上移动视图。键盘(高度:216)应该用它的高度推高我的视野。这可以通过简单的代码实现吗?
【问题讨论】:
标签: iphone ios uiviewcontroller keyboard ios5
要移动视图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 */
}
根据您可能需要跟踪用户正在编辑哪个字段的实际文本字段,添加一个计时器以避免过多地移动视图。
【讨论】:
这样做。 键盘可见后使用此代码
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.25];
self.view.frame = CGRectMake(0,-10,320,480);
[UIView commitAnimations];
}
【讨论】:
我以与 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 仍会显示,则原点不会改变。
【讨论】:
这是实现这一目标的最简单有效的方法:
添加以下常量:
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];
}
【讨论】:
大概你有一些代码调用[myTextField becomeFirstResponder];。你应该在这个调用之后移动你的视图。
【讨论】:
myView.center = //whatever your center was before + (CGPointMake(0, 216))
-(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,因为这是逻辑如果你明白
【讨论】:
这是 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 委托!
【讨论】:
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
【讨论】: