phi*_*reo 1674 objective-c uiscrollview uitextfield uikeyboard ios
使用iOS SDK:
我有一个UIView
带有UITextField
键盘的s.我需要它能够:
UIScrollView
一旦键盘出现,允许滚动内容以查看其他文本字段
自动"跳跃"(通过向上滚动)或缩短
我知道我需要一个UIScrollView
.我已经尝试将我的类更改UIView
为a UIScrollView
但我仍然无法向上或向下滚动文本框.
我需要a UIView
和a UIScrollView
吗?一个进去另一个吗?
需要实现什么才能自动滚动到活动文本字段?
理想情况下,尽可能多的组件设置将在Interface Builder中完成.我只想编写需要它的代码.
注意:我正在使用的UIView
(或UIScrollView
)是由tabbar(UITabBar
)启动的,它需要正常运行.
编辑:我正在添加滚动条,仅用于键盘出现时.即使它不需要,我觉得它提供了更好的界面,因为用户可以滚动和更改文本框.
我已经让它工作,我改变UIScrollView
了键盘上下的框架大小.我只是使用:
-(void)textFieldDidBeginEditing:(UITextField *)textField {
//Keyboard becomes visible
scrollView.frame = CGRectMake(scrollView.frame.origin.x,
scrollView.frame.origin.y,
scrollView.frame.size.width,
scrollView.frame.size.height - 215 + 50); //resize
}
-(void)textFieldDidEndEditing:(UITextField *)textField {
//keyboard will hide
scrollView.frame = CGRectMake(scrollView.frame.origin.x,
scrollView.frame.origin.y,
scrollView.frame.size.width,
scrollView.frame.size.height + 215 - 50); //resize
}
Run Code Online (Sandbox Code Playgroud)
但是,这不会自动"向上移动"或将可见区域中的下部文本字段居中,这是我真正想要的.
小智 1029
ScrollView
如果您现在拥有的内容不适合iPhone屏幕,则只需要一个.(如果要添加ScrollView
组件的超级视图.只是TextField
在键盘出现时向上滚动,则不需要.)
为了显示textfields
没有被键盘隐藏,标准方法是在显示键盘时向上/向下移动具有文本字段的视图.
以下是一些示例代码:
#define kOFFSET_FOR_KEYBOARD 80.0
-(void)keyboardWillShow {
// Animate the current view out of the way
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
else if (self.view.frame.origin.y < 0)
{
[self setViewMovedUp:NO];
}
}
-(void)keyboardWillHide {
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
else if (self.view.frame.origin.y < 0)
{
[self setViewMovedUp:NO];
}
}
-(void)textFieldDidBeginEditing:(UITextField *)sender
{
if ([sender isEqual:mailTf])
{
//move the main view, so that the keyboard does not hide it.
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
}
}
//method to move the view up/down whenever the keyboard is shown/dismissed
-(void)setViewMovedUp:(BOOL)movedUp
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3]; // if you want to slide up the view
CGRect rect = self.view.frame;
if (movedUp)
{
// 1. move the view's origin up so that the text field that will be hidden come above the keyboard
// 2. increase the size of the view so that the area behind the keyboard is covered up.
rect.origin.y -= kOFFSET_FOR_KEYBOARD;
rect.size.height += kOFFSET_FOR_KEYBOARD;
}
else
{
// revert back to the normal state.
rect.origin.y += kOFFSET_FOR_KEYBOARD;
rect.size.height -= kOFFSET_FOR_KEYBOARD;
}
self.view.frame = rect;
[UIView commitAnimations];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
Run Code Online (Sandbox Code Playgroud)
Shi*_*iun 445
我在UIScrollView
组合多个时遇到了很多问题UITextFields
,其中一个或多个在编辑时会被键盘遮挡.
如果您UIScrollView
没有正确滚动,请考虑以下事项.
1)确保您的contentSize大于UIScrollView
帧大小.理解的方式UIScrollViews
是,UIScrollView
它就像是在contentSize中定义的内容上的查看窗口.所以当为了在UIScrollview
任何地方滚动时,contentSize必须大于UIScrollView
.否则,不需要滚动,因为contentSize中定义的所有内容都已可见.BTW,默认contentSize = CGSizeZero
.
2)现在您已经明白这UIScrollView
是一个真正进入"内容"的窗口,确保键盘不会遮挡您的UIScrollView's
"窗口"的方法就是调整大小,UIScrollView
以便在键盘存在时,您有UIScrollView
窗口大小只是原始的UIScrollView
frame.size.height减去键盘的高度.这将确保您的窗口只是那个小的可视区域.
3)这里有一个问题:当我第一次实现这个时,我想我必须得到CGRect
已编辑的文本字段并调用UIScrollView's
scrollRecToVisible方法.我通过调用UITextFieldDelegate
方法实现了textFieldDidBeginEditing
该scrollRecToVisible
方法.这实际上与一个奇怪的副作用是滚动将工作卡的UITextField
到位.在最长的时间里,我无法弄清楚它是什么.然后我注释掉了textFieldDidBeginEditing
Delegate方法,一切正常!!(???).事实证明,我认为UIScrollView
实际上隐含地将当前编辑的内容隐式地带UITextField
入可查看窗口.我对该UITextFieldDelegate
方法的实现和后续调用scrollRecToVisible
是多余的,是造成奇怪副作用的原因.
因此,这里是正常滚动的步骤UITextField
在UIScrollView
到位键盘出现时.
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:self.view.window];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:self.view.window];
keyboardIsShown = NO;
//make contentSize bigger than your scrollSize (you will need to figure out for your own use case)
CGSize scrollContentSize = CGSizeMake(320, 345);
self.scrollView.contentSize = scrollContentSize;
}
- (void)keyboardWillHide:(NSNotification *)n
{
NSDictionary* userInfo = [n userInfo];
// get the size of the keyboard
CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
// resize the scrollview
CGRect viewFrame = self.scrollView.frame;
// I'm also subtracting a constant kTabBarHeight because my UIScrollView was offset by the UITabBar so really only the portion of the keyboard that is leftover pass the UITabBar is obscuring my UIScrollView.
viewFrame.size.height += (keyboardSize.height - kTabBarHeight);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[self.scrollView setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = NO;
}
- (void)keyboardWillShow:(NSNotification *)n
{
// This is an ivar I'm using to ensure that we do not do the frame size adjustment on the `UIScrollView` if the keyboard is already shown. This can happen if the user, after fixing editing a `UITextField`, scrolls the resized `UIScrollView` to another `UITextField` and attempts to edit the next `UITextField`. If we were to resize the `UIScrollView` again, it would be disastrous. NOTE: The keyboard notification will fire even when the keyboard is already shown.
if (keyboardIsShown) {
return;
}
NSDictionary* userInfo = [n userInfo];
// get the size of the keyboard
CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
// resize the noteView
CGRect viewFrame = self.scrollView.frame;
// I'm also subtracting a constant kTabBarHeight because my UIScrollView was offset by the UITabBar so really only the portion of the keyboard that is leftover pass the UITabBar is obscuring my UIScrollView.
viewFrame.size.height -= (keyboardSize.height - kTabBarHeight);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[self.scrollView setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = YES;
}
Run Code Online (Sandbox Code Playgroud)
viewDidLoad
viewDidUnload
contentSize
设置且大于UIScrollView
atviewDidLoad
UIScrollView
当键盘存在UIScrollView
时候键盘消失.UITextField
的标签即使键盘已经存在,以避免缩水的UIScrollView
时候,它已经缩水有一点需要注意的是,UIKeyboardWillShowNotification
即使键盘已经在屏幕上,当你在另一个键盘上时,它也会触发UITextField
.我通过使用ivar来解决这个问题,以避免UIScrollView
在键盘已经在屏幕上时调整大小.无意中调整UIScrollView
键盘已经存在的时候会有灾难性的!
希望这段代码可以让你们中的一些人头疼.
DK_*_*DK_ 270
实际上,最好只使用Apple的实现,如文档中所提供的那样.但是,他们提供的代码是错误的.将keyboardWasShown:
评论下方的部分替换为以下内容:
NSDictionary* info = [aNotification userInfo];
CGRect keyPadFrame=[[UIApplication sharedApplication].keyWindow convertRect:[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue] fromView:self.view];
CGSize kbSize =keyPadFrame.size;
CGRect activeRect=[self.view convertRect:activeField.frame fromView:activeField.superview];
CGRect aRect = self.view.bounds;
aRect.size.height -= (kbSize.height);
CGPoint origin = activeRect.origin;
origin.y -= backScrollView.contentOffset.y;
if (!CGRectContainsPoint(aRect, origin)) {
CGPoint scrollPoint = CGPointMake(0.0,CGRectGetMaxY(activeRect)-(aRect.size.height));
[backScrollView setContentOffset:scrollPoint animated:YES];
}
Run Code Online (Sandbox Code Playgroud)
Apple代码的问题是这些:(1)它们总是计算点是否在视图的框架内,但它是a ScrollView
,所以它可能已经滚动,你需要考虑该偏移:
origin.y -= scrollView.contentOffset.y
Run Code Online (Sandbox Code Playgroud)
(2)他们将contentOffset移动键盘的高度,但我们想要相反(我们想要移动contentOffset
屏幕上可见的高度,而不是不是):
activeField.frame.origin.y-(aRect.size.height)
Run Code Online (Sandbox Code Playgroud)
sum*_*odi 245
在textFieldDidBeginEditting
和textFieldDidEndEditing
通话功能[self animateTextField:textField up:YES]
,如下所示:
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
[self animateTextField:textField up:YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[self animateTextField:textField up:NO];
}
-(void)animateTextField:(UITextField*)textField up:(BOOL)up
{
const int movementDistance = -130; // tweak as needed
const float movementDuration = 0.3f; // tweak as needed
int movement = (up ? movementDistance : -movementDistance);
[UIView beginAnimations: @"animateTextField" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
}
Run Code Online (Sandbox Code Playgroud)
我希望这段代码可以帮到你.
在Swift 2中
func animateTextField(textField: UITextField, up: Bool)
{
let movementDistance:CGFloat = -130
let movementDuration: Double = 0.3
var movement:CGFloat = 0
if up
{
movement = movementDistance
}
else
{
movement = -movementDistance
}
UIView.beginAnimations("animateTextField", context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(movementDuration)
self.view.frame = CGRectOffset(self.view.frame, 0, movement)
UIView.commitAnimations()
}
func textFieldDidBeginEditing(textField: UITextField)
{
self.animateTextField(textField, up:true)
}
func textFieldDidEndEditing(textField: UITextField)
{
self.animateTextField(textField, up:false)
}
Run Code Online (Sandbox Code Playgroud)
SWIFT 3
func animateTextField(textField: UITextField, up: Bool)
{
let movementDistance:CGFloat = -130
let movementDuration: Double = 0.3
var movement:CGFloat = 0
if up
{
movement = movementDistance
}
else
{
movement = -movementDistance
}
UIView.beginAnimations("animateTextField", context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(movementDuration)
self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
UIView.commitAnimations()
}
func textFieldDidBeginEditing(textField: UITextField)
{
self.animateTextField(textField: textField, up:true)
}
func textFieldDidEndEditing(textField: UITextField)
{
self.animateTextField(textField: textField, up:false)
}
Run Code Online (Sandbox Code Playgroud)
DAS*_*DAS 135
只需使用TextFields:
1a)使用Interface Builder
:选择所有TextFields => Edit => Embed In => ScrollView
1b)在UIScrollView中手动嵌入名为scrollView的TextFields
2)设置 UITextFieldDelegate
3)设置每个textField.delegate = self;
(或连接Interface Builder
)
4)复制/粘贴:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
CGPoint scrollPoint = CGPointMake(0, textField.frame.origin.y);
[scrollView setContentOffset:scrollPoint animated:YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
[scrollView setContentOffset:CGPointZero animated:YES];
}
Run Code Online (Sandbox Code Playgroud)
Moh*_*shi 114
对于Universal Solution,这是我实现IQKeyboardManager的方法.
第一步: -我加的全球性的通知UITextField
,UITextView
和UIKeyboard
在一个单独的类.我称之为IQKeyboardManager.
第二步: -如果找到UIKeyboardWillShowNotification
,UITextFieldTextDidBeginEditingNotification
或UITextViewTextDidBeginEditingNotification
通知,我试图让topMostViewController
从实例UIWindow.rootViewController
层次结构.为了正确地揭开它UITextField
/ UITextView
它,topMostViewController.view
需要调整框架.
步骤3: -我计算topMostViewController.view
了相对于第一个响应的预期移动距离UITextField
/ UITextView
.
Step4: -我topMostViewController.view.frame
根据预期的移动距离向上/向下移动.
第五步: -如果找到UIKeyboardWillHideNotification
,UITextFieldTextDidEndEditingNotification
或UITextViewTextDidEndEditingNotification
通知,我再次试图让topMostViewController
从实例UIWindow.rootViewController
层次结构.
步骤6: -我计算出topMostViewController.view
需要恢复到其原始位置的干扰距离.
Step7: -我topMostViewController.view.frame
根据不安的距离恢复了下来.
Step8: -我在app load上实例化了单例IQKeyboardManager类实例,因此应用程序中的每个UITextField
/ UITextView
都会根据预期的移动距离自动调整.
这就是IQKeyboardManager为你做的所有没有代码行!只需要将相关的源文件拖放到项目中.IQKeyboardManager还支持设备方向,自动UIToolbar管理,KeybkeyboardDistanceFromTextField以及比您想象的更多.
Mic*_*son 101
我已经整理了一个通用的,插入式的UIScrollView
,UITableView
甚至是UICollectionView
子类,它负责将其中的所有文本字段移出键盘.
当键盘即将出现时,子类将找到即将被编辑的子视图,并调整其帧和内容偏移以确保视图可见,并使用与键盘弹出窗口匹配的动画.当键盘消失时,它会恢复其先前的大小.
它应该基本上适用于任何设置,UITableView
基于a 的接口,或者由手动放置的视图组成的接口.
Sat*_*ync 88
对于Swift程序员:
这将为您完成所有工作,只需将它们放在视图控制器类中并实现UITextFieldDelegate
视图控制器并将textField的委托设置为self
textField.delegate = self // Setting delegate of your UITextField to self
Run Code Online (Sandbox Code Playgroud)
实现委托回调方法:
func textFieldDidBeginEditing(textField: UITextField) {
animateViewMoving(true, moveValue: 100)
}
func textFieldDidEndEditing(textField: UITextField) {
animateViewMoving(false, moveValue: 100)
}
// Lifting the view up
func animateViewMoving (up:Bool, moveValue :CGFloat){
let movementDuration:NSTimeInterval = 0.3
let movement:CGFloat = ( up ? -moveValue : moveValue)
UIView.beginAnimations( "animateView", context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(movementDuration )
self.view.frame = CGRectOffset(self.view.frame, 0, movement)
UIView.commitAnimations()
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*ich 64
已经有很多答案,但仍然没有上述解决方案具有"完美"无错误,向后兼容和无闪烁动画所需的所有花哨的定位功能.(动画帧/边界和contentOffset在一起时的错误,不同的界面方向,iPad分离键盘,...)
让我分享我的解决方案:(
假设你已经设置UIKeyboardWill(Show|Hide)Notification
)
// Called when UIKeyboardWillShowNotification is sent
- (void)keyboardWillShow:(NSNotification*)notification
{
// if we have no view or are not visible in any window, we don't care
if (!self.isViewLoaded || !self.view.window) {
return;
}
NSDictionary *userInfo = [notification userInfo];
CGRect keyboardFrameInWindow;
[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrameInWindow];
// the keyboard frame is specified in window-level coordinates. this calculates the frame as if it were a subview of our view, making it a sibling of the scroll view
CGRect keyboardFrameInView = [self.view convertRect:keyboardFrameInWindow fromView:nil];
CGRect scrollViewKeyboardIntersection = CGRectIntersection(_scrollView.frame, keyboardFrameInView);
UIEdgeInsets newContentInsets = UIEdgeInsetsMake(0, 0, scrollViewKeyboardIntersection.size.height, 0);
// this is an old animation method, but the only one that retains compaitiblity between parameters (duration, curve) and the values contained in the userInfo-Dictionary.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
[UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
_scrollView.contentInset = newContentInsets;
_scrollView.scrollIndicatorInsets = newContentInsets;
/*
* Depending on visual layout, _focusedControl should either be the input field (UITextField,..) or another element
* that should be visible, e.g. a purchase button below an amount text field
* it makes sense to set _focusedControl in delegates like -textFieldShouldBeginEditing: if you have multiple input fields
*/
if (_focusedControl) {
CGRect controlFrameInScrollView = [_scrollView convertRect:_focusedControl.bounds fromView:_focusedControl]; // if the control is a deep in the hierarchy below the scroll view, this will calculate the frame as if it were a direct subview
controlFrameInScrollView = CGRectInset(controlFrameInScrollView, 0, -10); // replace 10 with any nice visual offset between control and keyboard or control and top of the scroll view.
CGFloat controlVisualOffsetToTopOfScrollview = controlFrameInScrollView.origin.y - _scrollView.contentOffset.y;
CGFloat controlVisualBottom = controlVisualOffsetToTopOfScrollview + controlFrameInScrollView.size.height;
// this is the visible part of the scroll view that is not hidden by the keyboard
CGFloat scrollViewVisibleHeight = _scrollView.frame.size.height - scrollViewKeyboardIntersection.size.height;
if (controlVisualBottom > scrollViewVisibleHeight) { // check if the keyboard will hide the control in question
// scroll up until the control is in place
CGPoint newContentOffset = _scrollView.contentOffset;
newContentOffset.y += (controlVisualBottom - scrollViewVisibleHeight);
// make sure we don't set an impossible offset caused by the "nice visual offset"
// if a control is at the bottom of the scroll view, it will end up just above the keyboard to eliminate scrolling inconsistencies
newContentOffset.y = MIN(newContentOffset.y, _scrollView.contentSize.height - scrollViewVisibleHeight);
[_scrollView setContentOffset:newContentOffset animated:NO]; // animated:NO because we have created our own animation context around this code
} else if (controlFrameInScrollView.origin.y < _scrollView.contentOffset.y) {
// if the control is not fully visible, make it so (useful if the user taps on a partially visible input field
CGPoint newContentOffset = _scrollView.contentOffset;
newContentOffset.y = controlFrameInScrollView.origin.y;
[_scrollView setContentOffset:newContentOffset animated:NO]; // animated:NO because we have created our own animation context around this code
}
}
[UIView commitAnimations];
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillHide:(NSNotification*)notification
{
// if we have no view or are not visible in any window, we don't care
if (!self.isViewLoaded || !self.view.window) {
return;
}
NSDictionary *userInfo = notification.userInfo;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[[userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
[UIView setAnimationCurve:[[userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
// undo all that keyboardWillShow-magic
// the scroll view will adjust its contentOffset apropriately
_scrollView.contentInset = UIEdgeInsetsZero;
_scrollView.scrollIndicatorInsets = UIEdgeInsetsZero;
[UIView commitAnimations];
}
Run Code Online (Sandbox Code Playgroud)
cbr*_*nch 62
Shiun说:"事实证明,我认为UIScrollView实际上隐含地将当前编辑的UITextField隐含地带入可视窗口"这似乎适用于iOS 3.1.3,但不适用于3.2,4.0或4.1.我必须添加一个显式的scrollRectToVisible,以使UITextField在iOS> = 3.2上可见.
Jon*_*ing 47
需要考虑的一件事是你是否想要自己使用a UITextField
.我没有遇到任何精心设计的iPhone应用程序,实际上UITextFields
在外面使用UITableViewCells
.
这将是一些额外的工作,但我建议您实现表视图的所有数据输入视图.添加UITextView
到您的UITableViewCells
.
Xar*_*mer 32
找到最简单的解决方案
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self animateTextField: textField up: YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[self animateTextField: textField up: NO];
}
- (void) animateTextField: (UITextField*) textField up: (BOOL) up
{
const int movementDistance = 80; // tweak as needed
const float movementDuration = 0.3f; // tweak as needed
int movement = (up ? -movementDistance : movementDistance);
[UIView beginAnimations: @"anim" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
}
Run Code Online (Sandbox Code Playgroud)
tt.*_*lew 31
适用于许多UITextField的小修复
#pragma mark UIKeyboard handling
#define kMin 150
-(void)textFieldDidBeginEditing:(UITextField *)sender
{
if (currTextField) {
[currTextField release];
}
currTextField = [sender retain];
//move the main view, so that the keyboard does not hide it.
if (self.view.frame.origin.y + currTextField.frame.origin. y >= kMin) {
[self setViewMovedUp:YES];
}
}
//method to move the view up/down whenever the keyboard is shown/dismissed
-(void)setViewMovedUp:(BOOL)movedUp
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3]; // if you want to slide up the view
CGRect rect = self.view.frame;
if (movedUp)
{
// 1. move the view's origin up so that the text field that will be hidden come above the keyboard
// 2. increase the size of the view so that the area behind the keyboard is covered up.
rect.origin.y = kMin - currTextField.frame.origin.y ;
}
else
{
// revert back to the normal state.
rect.origin.y = 0;
}
self.view.frame = rect;
[UIView commitAnimations];
}
- (void)keyboardWillShow:(NSNotification *)notif
{
//keyboard will be shown now. depending for which textfield is active, move up or move down the view appropriately
if ([currTextField isFirstResponder] && currTextField.frame.origin.y + self.view.frame.origin.y >= kMin)
{
[self setViewMovedUp:YES];
}
else if (![currTextField isFirstResponder] && currTextField.frame.origin.y + self.view.frame.origin.y < kMin)
{
[self setViewMovedUp:NO];
}
}
- (void)keyboardWillHide:(NSNotification *)notif
{
//keyboard will be shown now. depending for which textfield is active, move up or move down the view appropriately
if (self.view.frame.origin.y < 0 ) {
[self setViewMovedUp:NO];
}
}
- (void)viewWillAppear:(BOOL)animated
{
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification object:self.view.window];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification object:self.view.window];
}
- (void)viewWillDisappear:(BOOL)animated
{
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*eve 30
RPDP的代码成功地将文本字段移出键盘.但是当您在使用和关闭键盘后滚动到顶部时,顶部已向上滚动到视图之外.这对于模拟器和设备来说都是如此.要阅读该视图顶部的内容,必须重新加载视图.
是不是他的下面的代码应该让视图回落?
else
{
// revert back to the normal state.
rect.origin.y += kOFFSET_FOR_KEYBOARD;
rect.size.height -= kOFFSET_FOR_KEYBOARD;
}
Run Code Online (Sandbox Code Playgroud)
小智 22
要恢复原始视图状态,请添加:
-(void)textFieldDidEndEditing:(UITextField *)sender
{
//move the main view, so that the keyboard does not hide it.
if (self.view.frame.origin.y < 0)
{
[self setViewMovedUp:NO];
}
}
Run Code Online (Sandbox Code Playgroud)
Sou*_*rma 20
尝试这个简短的技巧.
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self animateTextField: textField up: YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[self animateTextField: textField up: NO];
}
- (void) animateTextField: (UITextField*) textField up: (BOOL) up
{
const int movementDistance = textField.frame.origin.y / 2; // tweak as needed
const float movementDuration = 0.3f; // tweak as needed
int movement = (up ? -movementDistance : movementDistance);
[UIView beginAnimations: @"anim" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
}
Run Code Online (Sandbox Code Playgroud)
Hot*_*ard 19
有这么多解决方案,但我花了几个小时才开始工作.所以,我把这段代码放在这里(只需粘贴到项目中,任何修改都不需要):
@interface RegistrationViewController : UIViewController <UITextFieldDelegate>{
UITextField* activeField;
UIScrollView *scrollView;
}
@end
- (void)viewDidLoad
{
[super viewDidLoad];
scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];
//scrool view must be under main view - swap it
UIView* natView = self.view;
[self setView:scrollView];
[self.view addSubview:natView];
CGSize scrollViewContentSize = self.view.frame.size;
[scrollView setContentSize:scrollViewContentSize];
[self registerForKeyboardNotifications];
}
- (void)viewDidUnload {
activeField = nil;
scrollView = nil;
[self unregisterForKeyboardNotifications];
[super viewDidUnload];
}
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShown:)
name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
-(void)unregisterForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)keyboardWillShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect frame = self.view.frame;
frame.size.height -= kbSize.height;
CGPoint fOrigin = activeField.frame.origin;
fOrigin.y -= scrollView.contentOffset.y;
fOrigin.y += activeField.frame.size.height;
if (!CGRectContainsPoint(frame, fOrigin) ) {
CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y + activeField.frame.size.height - frame.size.height);
[scrollView setContentOffset:scrollPoint animated:YES];
}
}
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
[scrollView setContentOffset:CGPointZero animated:YES];
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
activeField = textField;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
activeField = nil;
}
-(BOOL) textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
Run Code Online (Sandbox Code Playgroud)
PS:我希望代码可以帮助人们快速达到预期的效果.(Xcode 4.5)
小智 18
@ user271753
要将您的视图恢复为原始添加:
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
[self setViewMovedUp:NO];
return YES;
}
Run Code Online (Sandbox Code Playgroud)
pro*_*rmr 16
它不需要滚动视图就可以移动视图框.您可以更改viewcontroller's
视图的框架,以便整个视图向上移动到足以将第一个响应文本字段放在键盘上方.当我遇到这个问题时,我创建了一个子类UIViewController
来做到这一点.它观察到键盘将出现通知并找到第一响应者子视图并且(如果需要)它向上动画主视图足够使得第一响应者在键盘上方.当键盘隐藏时,它会将视图设置回原位.
要使用此子类,请将自定义视图控制器作为GMKeyboardVC的子类,并继承此功能(只需确保实现viewWillAppear
,viewWillDisappear
并且必须调用super).该课程在github上.
ZAF*_*007 14
斯威夫特4.
您可以轻松地上下移动,UITextField
或者UIView
用UIKeyBoard
带Animation
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet var textField: UITextField!
@IBOutlet var chatView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange), name: .UIKeyboardWillChangeFrame, object: nil)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
textField.resignFirstResponder()
}
@objc func keyboardWillChange(notification: NSNotification) {
let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
let curve = notification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as! UInt
let curFrame = (notification.userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let targetFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let deltaY = targetFrame.origin.y - curFrame.origin.y
print("deltaY",deltaY)
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: curve), animations: {
self.chatView.frame.origin.y+=deltaY // Here You Can Change UIView To UITextField
},completion: nil)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*lin 12
这是我为特定布局提出的黑客解决方案.该解决方案类似于Matt Gallagher解决方案,即将一个部分滚动到视图中.我还是iPhone开发的新手,我不熟悉布局的工作方式.因此,这个黑客.
我的实现需要支持在单击字段时滚动,并在用户选择键盘上的下一个时滚动.
我有一个高度为775的UIView.控件基本上以3个为一组在大空间内展开.我最终得到了以下IB布局.
UIView -> UIScrollView -> [UI Components]
Run Code Online (Sandbox Code Playgroud)
黑客来了
我将UIScrollView高度设置为比实际布局大12个单位(1250).然后我创建了一个数组,其中包含我需要滚动到的绝对位置,以及一个基于IB标签号来获取它们的简单函数.
static NSInteger stepRange[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 140, 140, 140, 140, 410
};
NSInteger getScrollPos(NSInteger i) {
if (i < TXT_FIELD_INDEX_MIN || i > TXT_FIELD_INDEX_MAX) {
return 0 ;
return stepRange[i] ;
}
Run Code Online (Sandbox Code Playgroud)
现在您需要做的就是在textFieldDidBeginEditing和textFieldShouldReturn中使用以下两行代码(如果您要创建下一个字段导航,则使用后一行代码)
CGPoint point = CGPointMake(0, getScrollPos(textField.tag)) ;
[self.scrollView setContentOffset:point animated:YES] ;
Run Code Online (Sandbox Code Playgroud)
一个例子.
- (void) textFieldDidBeginEditing:(UITextField *)textField
{
CGPoint point = CGPointMake(0, getScrollPos(textField.tag)) ;
[self.scrollView setContentOffset:point animated:YES] ;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
NSInteger nextTag = textField.tag + 1;
UIResponder* nextResponder = [textField.superview viewWithTag:nextTag];
if (nextResponder) {
[nextResponder becomeFirstResponder];
CGPoint point = CGPointMake(0, getScrollPos(nextTag)) ;
[self.scrollView setContentOffset:point animated:YES] ;
}
else{
[textField resignFirstResponder];
}
return YES ;
}
Run Code Online (Sandbox Code Playgroud)
此方法不像其他方法那样"向后滚动".这不是必要条件.再次,这是一个相当"高"的UIView,我没有几天学习内部布局引擎.
swi*_*Boy 11
在这里,我找到了处理键盘的最简单的解决方案.
您只需复制粘贴下面的示例代码并更改文本字段或任何您想要移动的视图.
步骤1
只需在控制器中复制粘贴两个方法即可
- (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)deregisterFromKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidHideNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
Run Code Online (Sandbox Code Playgroud)
第2步
分别在viewWillAppear和 viewWillDisappear方法中注册和取消注册键盘通知.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self registerForKeyboardNotifications];
}
- (void)viewWillDisappear:(BOOL)animated
{
[self deregisterFromKeyboardNotifications];
[super viewWillDisappear:animated];
}
Run Code Online (Sandbox Code Playgroud)
步骤3
灵魂部分来了,只需替换你的文本域,并改变你想要向上移动的高度.
- (void)keyboardWasShown:(NSNotification *)notification
{
NSDictionary* info = [notification userInfo];
CGSize currentKeyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
//you need replace your textfield instance here
CGPoint textFieldOrigin = self.tokenForPlaceField.frame.origin;
CGFloat textFieldHeight = self.tokenForPlaceField.frame.size.height;
CGRect visibleRect = self.view.frame;
visibleRect.size.height -= currentKeyboardSize.height;
if (!CGRectContainsPoint(visibleRect, textFieldOrigin))
{
//you can add yor desired height how much you want move keypad up, by replacing "textFieldHeight" below
CGPoint scrollPoint = CGPointMake(0.0, textFieldOrigin.y - visibleRect.size.height + textFieldHeight); //replace textFieldHeight to currentKeyboardSize.height, if you want to move up with more height
[self.scrollView setContentOffset:scrollPoint animated:YES];
}
}
- (void)keyboardWillBeHidden:(NSNotification *)notification
{
[self.scrollView setContentOffset:CGPointZero animated:YES];
}
Run Code Online (Sandbox Code Playgroud)
参考:嗯,请欣赏这个人,谁分享了这个美丽的代码剪辑,干净的解决方案.
希望这对那里的某人非常有帮助.
小智 10
当UITextField
处于UITableViewCell
滚动应自动进行设置.
如果不是,可能是因为tableview的代码/设置不正确.
例如,当我重新加载我的长桌,UITextField
底部有一个如下,
-(void) viewWillAppear:(BOOL)animated
{
[self.tableview reloadData];
}
Run Code Online (Sandbox Code Playgroud)
然后我在底部的文本字段被键盘遮挡了,当我在文本区域内单击时出现了键盘.
为了解决这个问题,我必须这样做 -
-(void) viewWillAppear:(BOOL)animated
{
//add the following line to fix issue
[super viewWillAppear:animated];
[self.tableview reloadData];
}
Run Code Online (Sandbox Code Playgroud)
sav*_*oob 10
一直在寻找关于这个主题的初学者的好教程,在这里找到了最好的教程.
在本MIScrollView.h
教程底部的示例中,请务必留出空格
@property (nonatomic, retain) id backgroundTapDelegate;
Run Code Online (Sandbox Code Playgroud)
正如你看到的.
使用此第三方,您甚至不需要写一行
https://github.com/hackiftekhar/IQKeyboardManager
下载项目并在项目中拖放IQKeyboardManager.如果您发现任何问题,请阅读README文档.
真的是它消除了管理键盘的麻烦..
感谢和好运!
注意:此答案假定您的textField位于scrollView中.
我更喜欢使用scrollContentInset和scrollContentOffset来处理它,而不是弄乱我的视图的帧.
首先让我们听一下键盘通知
//call this from viewWillAppear
-(void)addKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
}
//call this from viewWillDisappear
-(void)removeKeyboardNotifications{
[[NSNotificationCenter default
Center] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
Run Code Online (Sandbox Code Playgroud)
下一步是保留一个表示当前第一响应者的属性(当前具有键盘的UITextfield/UITextVIew).
我们使用委托方法来设置此属性.如果您正在使用其他组件,则需要类似的东西.
请注意,对于textfield,我们在didBeginEditing中设置它,在shouldBeginEditing中设置textView.这是因为textViewDidBeginEditing由于某种原因在UIKeyboardWillShowNotification之后被调用.
-(BOOL)textViewShouldBeginEditing:(UITextView * )textView{
self.currentFirstResponder = textView;
return YES;
}
-(void)textFieldDidBeginEditing:(UITextField *)textField{
self.currentFirstResponder = textField;
}
Run Code Online (Sandbox Code Playgroud)
最后,这是魔术
- (void)keyboardWillShow:(NSNotification*)aNotification{
NSDictionary* info = [aNotification userInfo];
CGRect kbFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
/*if currentFirstResponder is overlayed by the keyboard, move it so it bottom ends where the keyboard begins*/
if(self.currentFirstResponder){
//keyboard origin in currentFirstResponderFrame
CGPoint keyboardOrigin = [self.currentFirstResponder convertPoint:kbFrame.origin fromView:nil];
float spaceBetweenFirstResponderAndKeyboard = abs(self.currentFirstResponder.frame.size.height-keyboardOrigin.y);
//only scroll the scrollview if keyboard overlays the first responder
if(spaceBetweenFirstResponderAndKeyboard>0){
//if i call setContentOffset:animate:YES it behaves differently, not sure why
[UIView animateWithDuration:0.25 animations:^{
[self.scrollView setContentOffset:CGPointMake(0,self.scrollView.contentOffset.y+spaceBetweenFirstResponderAndKeyboard)];
}];
}
}
//set bottom inset to the keyboard height so you can still scroll the whole content
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbFrame.size.height, 0.0);
_scrollView.contentInset = contentInsets;
_scrollView.scrollIndicatorInsets = contentInsets;
}
- (void)keyboardWillHide:(NSNotification*)aNotification{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
_scrollView.contentInset = contentInsets;
_scrollView.scrollIndicatorInsets = contentInsets;
}
Run Code Online (Sandbox Code Playgroud)
这是使用Swift的解决方案.
import UIKit
class ExampleViewController: UIViewController, UITextFieldDelegate {
@IBOutlet var scrollView: UIScrollView!
@IBOutlet var textField1: UITextField!
@IBOutlet var textField2: UITextField!
@IBOutlet var textField3: UITextField!
@IBOutlet var textField4: UITextField!
@IBOutlet var textField5: UITextField!
var activeTextField: UITextField!
// MARK: - View
override func viewDidLoad() {
super.viewDidLoad()
self.textField1.delegate = self
self.textField2.delegate = self
self.textField3.delegate = self
self.textField4.delegate = self
self.textField5.delegate = self
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.registerForKeyboardNotifications()
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
self.unregisterFromKeyboardNotifications()
}
// MARK: - Keyboard
// Call this method somewhere in your view controller setup code.
func registerForKeyboardNotifications() {
let center: NSNotificationCenter = NSNotificationCenter.defaultCenter()
center.addObserver(self, selector: "keyboardWasShown:", name: UIKeyboardDidShowNotification, object: nil)
center.addObserver(self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil)
}
func unregisterFromKeyboardNotifications () {
let center: NSNotificationCenter = NSNotificationCenter.defaultCenter()
center.removeObserver(self, name: UIKeyboardDidShowNotification, object: nil)
center.removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}
// Called when the UIKeyboardDidShowNotification is sent.
func keyboardWasShown (notification: NSNotification) {
let info : NSDictionary = notification.userInfo!
let kbSize = (info.objectForKey(UIKeyboardFrameBeginUserInfoKey)?.CGRectValue() as CGRect!).size
let contentInsets: UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your app might not need or want this behavior.
var aRect = self.view.frame
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, self.activeTextField.frame.origin) ) {
self.scrollView.scrollRectToVisible(self.activeTextField.frame, animated: true)
}
}
// Called when the UIKeyboardWillHideNotification is sent
func keyboardWillBeHidden (notification: NSNotification) {
let contentInsets = UIEdgeInsetsZero;
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
}
// MARK: - Text Field
func textFieldDidBeginEditing(textField: UITextField) {
self.activeTextField = textField
}
func textFieldDidEndEditing(textField: UITextField) {
self.activeTextField = nil
}
}
Run Code Online (Sandbox Code Playgroud)
您需要以特定的帧大小以编程方式添加scrollview.您必须在.h文件中添加UIScrollViewDelegate.您必须在viewDidLoad()中为您需要编写以下内容启用scrollview.
scrollview.scrollEnabled=YES;
scrollview.delegate=self;
scrollview.frame = CGRectMake(x,y,width,height);
//---set the content size of the scroll view---
[scrollview setContentSize:CGSizeMake(height,width)];
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以添加x,y,width和height值.我想这会对你有所帮助.
小智 7
试试这个:
-(void)textFieldDidBeginEditing:(UITextField *)sender
{
if ([sender isEqual:self.m_Sp_Contact])
{
[self.m_Scroller setContentOffset:CGPointMake(0, 105)animated:YES];
}
}
Run Code Online (Sandbox Code Playgroud)
Swift 2.0:
添加UIScrollView并在其顶部添加textFields.制作故事板引用VC.
@IBOutlet weak var username: UITextField!
@IBOutlet weak var password: UITextField!
@IBOutlet weak var scrollView: UIScrollView!
Run Code Online (Sandbox Code Playgroud)
添加以下方法:UITextFieldDelegate和UIScrollViewDelegate.
//MARK:- TEXTFIELD METHODS
func textFieldShouldReturn(textField: UITextField) -> Bool {
if(username.returnKeyType == UIReturnKeyType.Default) {
password.becomeFirstResponder()
}
textField.resignFirstResponder()
return true
}
func textFieldDidBeginEditing(textField: UITextField) {
dispatch_async(dispatch_get_main_queue()) {
let scrollPoint:CGPoint = CGPointMake(0,textField.frame.origin.y/4)
self.scrollView!.setContentOffset(scrollPoint, animated: true);
}
}
func textFieldShouldEndEditing(textField: UITextField) -> Bool {
dispatch_async(dispatch_get_main_queue()) {
UIView.animateWithDuration(0, animations: { self.scrollView!.setContentOffset(CGPointZero,animated: true) })
}
return true
}
override func touchesBegan(touches: Set<UITouch>,
withEvent event: UIEvent?) {
self.view.endEditing(true)
}
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
self.scrollView.scrollEnabled = true
dispatch_async(dispatch_get_main_queue()) {
UIView.animateWithDuration(0, animations: { self.scrollView!.setContentOffset(CGPointZero,animated: true)
})
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
这是一个免费的键盘处理键盘处理iPhone应用程序库.您只需编写一行代码:
[AutoScroller addAutoScrollTo:scrollView];
Run Code Online (Sandbox Code Playgroud)
这对于处理表单中的键盘非常棒
我认为如果您使用Swift,最好的方法是使用面向协议的编程.
首先,您必须创建一个KeyboardCapable
协议,该协议为任何符合它的UIViewController提供注册和取消注册键盘观察器的能力:
import Foundation
import UIKit
protocol KeyboardCapable: KeyboardAnimatable {
func keyboardWillShow(notification: NSNotification)
func keyboardWillHide(notification: NSNotification)
}
extension KeyboardCapable where Self: UIViewController {
func registerKeyboardNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil)
}
func unregisterKeyboardNotifications() {
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}
}
Run Code Online (Sandbox Code Playgroud)
您已经注意到KeyboardAnimatable
上面一段代码中的无关关键字.它只是我们需要创建的下一个协议的名称:
import Foundation
import UIKit
protocol KeyboardAnimatable {
}
extension KeyboardAnimatable where Self: UIViewController {
func performKeyboardShowFullViewAnimation(withKeyboardHeight height: CGFloat, andDuration duration: NSTimeInterval) {
UIView.animateWithDuration(duration, animations: { () -> Void in
self.view.frame = CGRectMake(view.frame.origin.x, -height, view.bounds.width, view.bounds.height)
}, completion: nil)
}
func performKeyboardHideFullViewAnimation(withDuration duration: NSTimeInterval) {
UIView.animateWithDuration(duration, animations: { () -> Void in
self.view.frame = CGRectMake(view.frame.origin.x, 0.0, view.bounds.width, view.bounds.height)
}, completion: nil)
}
}
Run Code Online (Sandbox Code Playgroud)
该KeyboardAnimatable
协议使所有UIViewController都符合两种方法,分别对上下整个视图进行动画制作.
好的,如果KeyboardCapable
符合KeyboardAnimatable
,所有UIViewController符合KeyboardCapable
,也符合KeyboardAnimatable
.这很酷.
让我们看一下UIViewController
符合条件KeyboardCapable
,并对键盘事件作出反应:
import Foundation
import UIKit
class TransferConfirmViewController: UIViewController, KeyboardCapable {
//MARK: - LIFE CYCLE
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
registerKeyboardNotifications()
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
unregisterKeyboardNotifications()
}
//MARK: - NOTIFICATIONS
//MARK: Keyboard
func keyboardWillShow(notification: NSNotification) {
let keyboardHeight = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue().height
let animationDuration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
performKeyboardShowFullViewAnimation(withKeyboardHeight: keyboardHeight, andDuration: animationDuration)
}
func keyboardWillHide(notification: NSNotification) {
let animationDuration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
performKeyboardHideFullViewAnimation(withDuration: animationDuration)
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您的UIViewController
意志将响应键盘事件并因此产生动画效果.
注意:如果您想要自定义动画而不是推或拉视图,则必须在KeyboardAnimatable
协议上定义自定义方法或在KeyboardCapable
函数上执行它们.由你决定.
只需将其添加到您的pod文件-> pod 'IQKeyboardManager'
就是这样,可以处理所有键盘,scrollviews和所有内容!
您不需要编写任何代码,找不到更好的解决方案!
它具有扩展名,如果有多个文本字段,则可以处理文本字段的显示,屏幕移动,下一个和上一个箭头。
它还具有一个自定义完成按钮,可以将其删除。
链接-> https://github.com/hackiftekhar/IQKeyboardManager
小智 5
一个更,更优雅的解决方案是使用一个UIView
子类(虽然这并不总是合适),然后重新上父母的框架变化的所有子视图(并且是聪明的:只有重新计算他们,如果新的帧的大小发生了变化,即使用CGRectEqualToRect
到在覆盖时setFrame
和在调用之前比较新帧[super setFrame:frame_]
.唯一能抓到的就是UIViewController
你打算使用它应该听一下键盘事件(或者,你可以自己动手做UIView
,用于方便的封装).但只有UIKeyboardWillShowNotification
和UIKeyboardWillHideNotification
.这只是看起来很顺利(如果你等待CG调用它,你会得到一个不稳定的时刻).
UIView
无论如何,这有利于构建一个做正确事情的子类.
天真的实现将是覆盖drawRect:
(不),一个更好的将是只使用layoutSubviews
(然后在UIViewController
,或者你可以setNeedsLayout
在一个被调用show或hide的SINGLE方法中调用[view ]).
这个解决方案远离硬编码键盘偏移(如果它们没有分开会改变,等等),也意味着你的视图可能是许多其他视图的子视图,仍然可以正常响应.
除非没有其他解决方案,否则不要硬编码.操作系统为您提供了足够的信息,如果您做得对,您只需要智能地重绘(根据您的新frame
尺寸).这更清洁,你应该做的事情.(但可能会有更好的方法.)
干杯.
这是我使用autolayout的版本:
这个想法只是将包含文本字段/文本视图的视图嵌入到UIScrollView中,从底部对其超级视图设置约束,创建出口,并使用通知根据键盘高度更新其常量。这是基于苹果的例子在这里,并使用自动版式上的UIScrollView苹果技术说明这里。
1)将View V嵌入到UIScrollView S中:如果已经设置了常量和子视图,则可以在ViewController的视图中复制/粘贴视图和子视图,然后使用Editor-> embed菜单将其嵌入,最后删除复制的视图)
2)设置以下约束:
S尾随superview:0
V观看超级空间:0
V超视空间:0
V等于S的宽度
最新的下V子视图到Superview:20
3)创建一个从最新约束到视图控制器的出口
4)使用以下代码:
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomSpaceToContentView;
// ...
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// ...
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Handle keyboard
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
self.bottomSpaceToContentView.constant = kBottomMargin + kbSize.height;
[self.view layoutIfNeeded];
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
self.bottomSpaceToContentView.constant = kBottomMargin;
[self.view layoutIfNeeded];
}
Run Code Online (Sandbox Code Playgroud)
和tadaaaaa,它有效!
小智 5
只需在您的类中放入以下代码并根据需要进行自定义即可.
-(void)textFieldDidBeginEditing:(UITextField *)textField {
//Show Keyboard
self.view.frame = CGRectMake(self.view.frame.origin.x,
self.view.frame.origin.y-50,
self.view.frame.size.width,
self.view.frame.size.height);
}
-(void)textFieldDidEndEditing:(UITextField *)textField {
// Hide keyboard
self.view.frame = CGRectMake(self.view.frame.origin.x,
self.view.frame.origin.y+50,
self.view.frame.size.width,
self.view.frame.size.height);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
614343 次 |
最近记录: |