【问题标题】:Adjust View For Keyboard When Switching UITextField?切换 UITextField 时调整键盘视图?
【发布时间】:2013-02-09 18:28:44
【问题描述】:

当键盘出现在我的应用程序中时,我的视图可以向上滑动,以便可以看到文本字段并且效果很好。但是,由于它基于键盘通知,因此它仅在键盘出现时才起作用。

意思是,我选择一个文本字段,键盘出现,视图相应地向上滑动,但如果我直接点击另一个文本字段,视图不会调整,因为键盘已经存在。

这是我正在使用的代码,非常感谢任何帮助使其适应上述情况的帮助。

-(void)registerForKeyboardNotifications
{
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
    [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

    // add a tap gesture to drop first responder
    UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapToHideKeyboard:)];
    [self.view addGestureRecognizer:tapGR];
}

-(void)keyboardDidShow:(NSNotification *)notification
{
    CGRect keyboardFrameW = [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    UIWindow *window = [[UIApplication sharedApplication] keyWindow];
    CGRect keyboardFrame = [window convertRect:keyboardFrameW toView:self.view];

    //Have a minimum space between the keyboard and textfield
    CGFloat textFieldBuffer = 40;
    CGFloat textFieldKeyboardDifference = 0;

    if (activeTextField.frame.origin.y + activeTextField.frame.size.height > keyboardFrame.origin.y) textFieldKeyboardDifference = (activeTextField.frame.origin.y + activeTextField.frame.size.height + textFieldBuffer) - keyboardFrame.origin.y;
    else if (activeTextField.frame.origin.y + activeTextField.frame.size.height < keyboardFrame.origin.y) textFieldKeyboardDifference = 0;

    [self translateView:self.view toRect:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y - textFieldKeyboardDifference, self.view.frame.size.width, self.view.frame.size.height) withDuration:0.3];
}

-(void)keyboardWillHide:(NSNotification *)notification
{
    //Revert to y origin 0
    [self translateView:self.view toRect:CGRectMake(self.view.frame.origin.x, 0, self.view.frame.size.width, self.view.frame.size.height) withDuration:0.3];
}

编辑:

textFieldDidBeginEditing 被这样调用时,我尝试手动调用键盘通知:

[self keyboardDidShow:[NSNotification notificationWithName:UIKeyboardDidShowNotification object:nil]]; 没有运气。该方法被调用,但由于我无法解决的原因未进行任何调整。

【问题讨论】:

  • (void)textFieldDidBeginEditing:(UITextField *)textField 使用了这个委托方法它会解决你的问题。

标签: iphone objective-c ipad uitextfield uikeyboard


【解决方案1】:

您可能想要在这里做的是为您的所有UITextFields 提供一个委托,并在该委托上实现- (void)textFieldDidBeginEditing:(UITextField *)textField 以触发您的滚动操作。这将在有人开始编辑文本字段时调用,并且文本字段作为参数传递给方法。

编辑:以您的代码为起点,这就是我想出的。每次更改文本字段时都会调用它:

@interface SOViewController () <UITextFieldDelegate>
@property (nonatomic, readwrite, assign) UITextField* activeTextField;
@property (nonatomic, readwrite, assign) CGRect keyboardFrame;
@end

@implementation SOViewController

@synthesize activeTextField;
@synthesize keyboardFrame;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self registerForKeyboardNotifications];
    self.keyboardFrame = CGRectNull;
}

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    self.activeTextField = textField;
    [self updatePosition];
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    self.activeTextField = nil;
}

-(void)registerForKeyboardNotifications
{
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
    [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

    //    // add a tap gesture to drop first responder
    //    UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapToHideKeyboard:)];
    //    [self.view addGestureRecognizer:tapGR];
}

- (void)translateView: (UIView*)view toRect: (CGRect)rect withDuration: (NSTimeInterval)duration
{
    NSLog(@"Translating view to rect: %@ overDuration: %g", NSStringFromCGRect(rect), duration);
}

- (void)updatePosition
{
    if (self.activeTextField && !CGRectIsNull(self.keyboardFrame))
    {
        UIWindow *window = [[UIApplication sharedApplication] keyWindow];
        CGRect localKeyboardFrame = [window convertRect: self.keyboardFrame toView:self.view];

        //Have a minimum space between the keyboard and textfield
        CGFloat textFieldBuffer = 40;

        CGRect textFieldFrame = self.activeTextField.frame;

        CGRect viewFrame = self.view.frame;
        viewFrame.origin.y = 0;

        if (CGRectGetMaxY(textFieldFrame) + textFieldBuffer > CGRectGetMinY(localKeyboardFrame))
        {
            viewFrame.origin.y = -1.0 * (CGRectGetMaxY(textFieldFrame) + textFieldBuffer - CGRectGetMinY(localKeyboardFrame));
        }

        [self translateView: self.view toRect: viewFrame withDuration: 0.3];

    }
    else
    {
        CGRect viewFrame = self.view.frame;
        viewFrame.origin.y = 0;
        [self translateView: self.view toRect: viewFrame withDuration: 0.3];
    }
}

-(void)keyboardDidShow:(NSNotification *)notification
{
    self.keyboardFrame = [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    [self updatePosition];
}

-(void)keyboardWillHide:(NSNotification *)notification
{
    self.keyboardFrame = CGRectNull;
    [self updatePosition];
}

@end

【讨论】:

  • 我已经尝试过但没有运气,请检查我的问题,我已经进行了编辑以解释我尝试过的内容。
  • 对于初学者来说,您不想发送通知,您想将滚动逻辑移出通知处理程序并移到通知处理程序和textFieldDidBeginEditing 都调用的方法中。您发送的通知(而不是 UIKit 发送的通知)将没有正确的 userInfo 或源对象,并且您专门使用 userInfo 来确定您的滚动操作。)您可能需要在第一次将键盘框架存储在 ivar 中出现(并在它消失时将其清除)。
  • 成功了!除了存储键盘框架外,我还必须存储视图偏移量,所以如果我在键盘仍然存在的情况下点击第二个文本字段,我可以扣除旧的偏移量。
【解决方案2】:

我喜欢在像你这样的情况下使用UITableViewController 子类。只需使用UITableView 页眉页脚和单元格构建您的视图。当您需要在UITextView 或字段UITableViewController 中进行文本编辑时,将自动布局所有内容。

即使您将scrollEnabled 属性设置为 NO,它也会起作用;

【讨论】:

    猜你喜欢
    • 2015-02-28
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-02
    相关资源
    最近更新 更多