Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 点击时在键盘上方移动文本字段的逻辑_Objective C_Ios_Xcode_Uitextfield - Fatal编程技术网

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