Objective c 点击时在键盘上方移动文本字段的逻辑
现在,我有一些基本代码,可以在开始编辑时将文本字段移到键盘上方。但是,文本字段的大小因设备和方向而异。所以,我写了一个粗略的方法,它不会一直保持在键盘的正上方,但是当你旋转它时,它会进一步上升,所以它看起来不像我想要的那么专业 我的问题的基本意思是,是否有逻辑根据设备和方向来获取键盘的大小,并自动使用该值,希望比这更快 如果这是最好的办法,请让我知道。否则,请提供输入。这是我的代码。 (这只是上移代码,不是下移代码,以防止占用太多空间)Objective c 点击时在键盘上方移动文本字段的逻辑,objective-c,ios,xcode,uitextfield,Objective C,Ios,Xcode,Uitextfield,现在,我有一些基本代码,可以在开始编辑时将文本字段移到键盘上方。但是,文本字段的大小因设备和方向而异。所以,我写了一个粗略的方法,它不会一直保持在键盘的正上方,但是当你旋转它时,它会进一步上升,所以它看起来不像我想要的那么专业 我的问题的基本意思是,是否有逻辑根据设备和方向来获取键盘的大小,并自动使用该值,希望比这更快 如果这是最好的办法,请让我知道。否则,请提供输入。这是我的代码。 (这只是上移代码,不是下移代码,以防止占用太多空间) UIViewController有一个名为interfac
UIViewController有一个名为interfaceOrientation的属性和功能UIInterfaceOrientationSportRait/横向,因此基本上可以执行以下操作:
if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation){
//portrait logic
}
else{
//landcapeLogic
}
在您的视图控制器中,为每个视图控制器安装iPhone和iPad。从那里你可以像以前一样进行像素测量,因为据我所知,这是最简单的方法
另外,还有一个功能可以检查横向检查器,但是如果第一个if语句为false,表示设备不是纵向的,那么它必须是横向的,因此是普通的。您真正想做的是观察UIKeyboard(Did | Will)(Show | Hide)通知。它们在用户信息字典中包含开始帧和结束帧,以及正确的动画曲线和持续时间 因此,在观察此通知后,当它发布时,根据提供的动画提示,根据通知中传递的帧的大小移动文本字段 您可以在UIWindow类参考的“通知”部分看到更多信息: 下面是视图控制器实现的示例。该视图控制器的nib只是一个文本字段,有一个出口连接到它,文本字段的委托设置为视图控制器
@interface ViewController ()
- (void)viewControllerInit;
@end
@implementation ViewController
@synthesize textField;
- (id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
[self viewControllerInit];
}
return self;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
{
[self viewControllerInit];
}
return self;
}
- (void)viewControllerInit
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark - Notification Handlers
- (void)keyboardWillShow:(NSNotification *)notification
{
// I'll try to make my text field 20 pixels above the top of the keyboard
// To do this first we need to find out where the keyboard will be.
NSValue *keyboardEndFrameValue = [[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardEndFrame = [keyboardEndFrameValue CGRectValue];
// When we move the textField up, we want to match the animation duration and curve that
// the keyboard displays. So we get those values out now
NSNumber *animationDurationNumber = [[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSTimeInterval animationDuration = [animationDurationNumber doubleValue];
NSNumber *animationCurveNumber = [[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey];
UIViewAnimationCurve animationCurve = [animationCurveNumber intValue];
// UIView's block-based animation methods anticipate not a UIVieAnimationCurve but a UIViewAnimationOptions.
// We shift it according to the docs to get this curve.
UIViewAnimationOptions animationOptions = animationCurve << 16;
// Now we set up our animation block.
[UIView animateWithDuration:animationDuration
delay:0.0
options:animationOptions
animations:^{
// Now we just animate the text field up an amount according to the keyboard's height,
// as we mentioned above.
CGRect textFieldFrame = self.textField.frame;
textFieldFrame.origin.y = keyboardEndFrame.origin.y - textFieldFrame.size.height - 40; //I don't think the keyboard takes into account the status bar
self.textField.frame = textFieldFrame;
}
completion:^(BOOL finished) {}];
}
- (void)keyboardWillHide:(NSNotification *)notification
{
NSNumber *animationDurationNumber = [[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSTimeInterval animationDuration = [animationDurationNumber doubleValue];
NSNumber *animationCurveNumber = [[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey];
UIViewAnimationCurve animationCurve = [animationCurveNumber intValue];
UIViewAnimationOptions animationOptions = animationCurve << 16;
[UIView animateWithDuration:animationDuration
delay:0.0
options:animationOptions
animations:^{
self.textField.frame = CGRectMake(20, 409, 280, 31); //just some hard coded value
}
completion:^(BOOL finished) {}];
}
#pragma mark - View lifecycle
- (void)viewDidUnload
{
[self setTextField:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
#pragma mark - UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[self.textField resignFirstResponder];
return YES;
}
@end
@界面视图控制器()
-(无效)viewControllerInit;
@结束
@实现视图控制器
@合成文本场;
-(id)initWithCoder:(NSCoder*)编码器{
self=[super initWithCoder:coder];
如果(自我){
[自视控制器];
}
回归自我;
}
-(id)initWithNibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil
{
if(self=[super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
{
[自视控制器];
}
回归自我;
}
-(void)viewControllerInit
{
[[NSNotificationCenter defaultCenter]添加观察者:自选择器:@selector(keyboardWillShow:)名称:UIKeyboardWillShowNotification对象:nil];
[[NSNotificationCenter defaultCenter]添加观察者:自选择器:@selector(keyboardWillHide:)名称:UIKeyboardWillHideNotification对象:nil];
}
-(无效)解除锁定{
[[NSNotificationCenter defaultCenter]移除观察者:self];
}
#pragma标记-通知处理程序
-(无效)键盘将显示:(NSNotification*)通知
{
//我将尝试使我的文本字段在键盘顶部上方20像素
//要做到这一点,首先我们需要找到键盘的位置。
NSValue*keyboardEndFrameValue=[[notification userInfo]objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardEndFrame=[keyboardEndFrameValue CGRectValue];
//当我们向上移动textField时,我们希望匹配动画的持续时间和曲线
//键盘会显示出来。所以我们现在就把这些值拿出来
NSNumber*animationDurationNumber=[[notification userInfo]objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSTimeInterval animationDuration=[animationDurationNumber doubleValue];
NSNumber*AnimationCurveEnumber=[[notification userInfo]objectForKey:UIKeyboardAnimationCurveUserInfo];
UIViewAnimationCurve animationCurve=[AnimationCurveEnumber intValue];
//UIView基于块的动画方法预期的不是UIVieAnimationCurve,而是UIViewAnimationOptions。
//我们根据文档移动它,得到这条曲线。
UIViewAnimationOptions animationOptions=animationCurve使用通知键盘寄存器,您可以将文本字段放置在滚动条中,并管理滚动条的内容偏移量,以便在必要时将实际的第一响应者转到键盘上方
所以,在“将控制器注册到键盘”出现后,必须获得键盘原点和相对于父项的滚动原点之间的间隙
您必须知道特定的第一响应者是否可以更改滚动的内容偏移量,因此有必要知道键盘原点和第一响应者之间的可能界限
顺便说一下,您需要知道滚动内容偏移量和第一响应者之间的间隙,以便将第一响应者放置在特定位置
@interface MainViewController : UIViewController
@property (strong, nonatomic) IBOutlet UIScrollView *scroll;
@end
@interface MainViewController ()
{
CGPoint scrollOffset;
}
@end
@implementation MainViewController
@synthesize scroll
-(void)viewWillAppear:(BOOL)animated
{
[[ NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillAppear:) name:UIKeyboardDidShowNotification object:nil];
[[ NSNotificationCenter defaultCenter ] addObserver:self selector:@selector(keyboardWillDisAppear:) name:UIKeyboardDidHideNotification object:nil];
}
-(void)viewWillDisappear:(BOOL)animated
{
[[ NSNotificationCenter defaultCenter ] removeObserver:self ];
}
-(void)keyboardWillAppear:(NSNotification*) note
{
const CGFloat default_gap = 25.0f;
NSValue *keyBoardEndFrameValue = [[ note userInfo ] objectForKey:UIKeyboardFrameEndUserInfoKey ];
CGRect keyBoardFrame = [ keyBoardEndFrameValue CGRectValue ];
offset = scroll.contentOffset;
UIWindow *window = [[ UIApplication sharedApplication ] keyWindow];
UITextField *textField = (UITextField*)[ window performSelector:@selector(firstResponder) ];
//Gap between keyboard origin and the scroll origin, relative to parent.
CGFloat distanceRelativeToParent = keyBoardFrame.origin.y - scroll.frame.origin.y;
//Distance between superview to textfield inside scroll. to determine if it's necesary to scroll.
CGFloat bound = (textField.frame.origin.y + textField.frame.size.height)+scroll.frame.origin.y;
CGFloat gapScroll = textField.frame.size.height+default_gap;
if( bound >= keyBoardFrame.origin.y )
{
[ UIView animateWithDuration:.3 delay:0.0 options:UIViewAnimationCurveEaseOut
animations:^{
[ scroll setContentOffset:CGPointMake(0, textField.frame.origin.y - distanceRelativeToParent + gapScroll ) animated:YES ];
}
completion:^(BOOL finished){
}];
}
}
-(void) keyboardWillDisAppear:(NSNotification*) note
{
[ scroll setContentOffset:offset animated:YES ];
}
@end
左边的风景线和倒过来的风景线怎么样?或者,portait和风景线属性是否包括倒过来和两个风景线选项?肖像线可以做任何右上或倒过来的事情,风景线可以覆盖左边和右边好的,我会试试看,如果行得通,我会给你打勾。请给我一分钟=)试试看。p问题是,如果在编辑设备时旋转设备,坐标不会发生变化,并且失败得很惨。对不起,我将不得不使用另一种方法。谢谢。对不起,我应该提到,您应该在视图控制器中的shouldRotateToInterfaceOrientation方法中添加代码,以便根据w将屏幕动画显示到新位置你正在从哪个方向切换。可能对你的情况来说太复杂了,如果你不想尝试,我不会责怪你。我可以这样做,我现在正在查看警报部分。但是,你如何从这些消息中获取实际坐标,以便将其实现到我发布的方法中。我在玩w请立即使用,但协助将非常好。更新:
@interface MainViewController : UIViewController
@property (strong, nonatomic) IBOutlet UIScrollView *scroll;
@end
@interface MainViewController ()
{
CGPoint scrollOffset;
}
@end
@implementation MainViewController
@synthesize scroll
-(void)viewWillAppear:(BOOL)animated
{
[[ NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillAppear:) name:UIKeyboardDidShowNotification object:nil];
[[ NSNotificationCenter defaultCenter ] addObserver:self selector:@selector(keyboardWillDisAppear:) name:UIKeyboardDidHideNotification object:nil];
}
-(void)viewWillDisappear:(BOOL)animated
{
[[ NSNotificationCenter defaultCenter ] removeObserver:self ];
}
-(void)keyboardWillAppear:(NSNotification*) note
{
const CGFloat default_gap = 25.0f;
NSValue *keyBoardEndFrameValue = [[ note userInfo ] objectForKey:UIKeyboardFrameEndUserInfoKey ];
CGRect keyBoardFrame = [ keyBoardEndFrameValue CGRectValue ];
offset = scroll.contentOffset;
UIWindow *window = [[ UIApplication sharedApplication ] keyWindow];
UITextField *textField = (UITextField*)[ window performSelector:@selector(firstResponder) ];
//Gap between keyboard origin and the scroll origin, relative to parent.
CGFloat distanceRelativeToParent = keyBoardFrame.origin.y - scroll.frame.origin.y;
//Distance between superview to textfield inside scroll. to determine if it's necesary to scroll.
CGFloat bound = (textField.frame.origin.y + textField.frame.size.height)+scroll.frame.origin.y;
CGFloat gapScroll = textField.frame.size.height+default_gap;
if( bound >= keyBoardFrame.origin.y )
{
[ UIView animateWithDuration:.3 delay:0.0 options:UIViewAnimationCurveEaseOut
animations:^{
[ scroll setContentOffset:CGPointMake(0, textField.frame.origin.y - distanceRelativeToParent + gapScroll ) animated:YES ];
}
completion:^(BOOL finished){
}];
}
}
-(void) keyboardWillDisAppear:(NSNotification*) note
{
[ scroll setContentOffset:offset animated:YES ];
}
@end