以编程方式将iPhone键盘顶部的工具栏对齐


94

在某些情况下,我想在iPhone键盘的顶部添加一个工具栏(例如,在导航表单元素时,例如在iPhone Safari中)。

目前,我正在使用常量指定工具栏的矩形,但是由于界面的其他元素在变动中-屏幕顶部的工具栏和导航栏-每次我们进行较小的界面更改时,工具栏都会偏离对齐状态。

有没有办法以编程方式确定键盘相对于当前视图的位置?

Answers:


142

从iOS 3.2开始,有一种新方法可以实现此效果:

UITextFieldsUITextViews具有一个inputAccessoryView可以设置为任意视图的属性,该属性会自动显示在上方并使用键盘进行动画处理。

请注意,您使用的视图既不应位于其他视图层次中,也不应将其添加到某些超级视图中,这是为您完成的。


让我尝试 。虽然它看起来是最好的方法。
harshalb

哇。真是个发现!谢谢(我做得很辛苦,很乱)
征收

1
我有一个带有UITextField的UIToolbar,该UIToolbar的其中一个按钮按钮项位于其中,但尽管我在第一次按下时将textFields inputAccessoryView设置为该工具栏,但该工具栏却上升了,但是没有键盘出现。在第二次按下键盘时,对工具栏有什么了解吗?
Ugur Kumru '02

但是如何在UIWebView上添加工具栏?:(
Dmitry

我已经通过替换标准UIWebView工具栏上的按钮(与删除它的代码相同)来完成此操作。
德米特里(Dmitry)

72

所以基本上:

在init方法中:

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil];
[nc addObserver:self selector:@selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object:nil];

然后使用上面提到的方法来调整条的位置:

-(void) keyboardWillShow:(NSNotification *) note
{
    CGRect r  = bar.frame, t;
    [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &t];
    r.origin.y -=  t.size.height;
    bar.frame = r;
}

通过将位置变化动画化,可以使其变得漂亮

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];
//...
    [UIView commitAnimations];

今天早上在闲逛我的旧东西,发现这是一个更好,最全面的答案。谢谢!
罗布·德里米

一年后,这个答案仍然很有意义。在开发与此相关的东西时,它帮助我克服了困难。
james_womack 2010年

2
现在只是警告人们,在此问题上绊脚石:iPhone OS 3.2中已弃用UIKeyboardBoundsUserInfoKey。还有其他类似的UIKeyboardFrameBeginUserInfoKey信息提供相同的信息。
斯蒂芬·达灵顿,2010年

9
在iOS3.2中,甚至还有更好的新方法可以实现UITextField和UITextView的inputAccessoryView属性。
tonklon

6
这个答案帮助了很多,但有点过时了。您应该UIKeyboardFrameEndUserInfoKey用来获取键盘的最后一帧(以屏幕坐标为准)。您还可以使用UIKeyboardAnimationDurationUserInfoKeyUIKeyboardAnimationCurveUserInfoKey获取与键盘行为完全匹配所需的其余参数。
戴夫·派克

60

这是基于tonklon现有答案 -我只是添加一个代码段,该代码段在键盘顶部显示一个半透明的黑色工具栏,并在右侧显示一个“完成”按钮:

UIToolbar *toolbar = [[[UIToolbar alloc] init] autorelease];
[toolbar setBarStyle:UIBarStyleBlackTranslucent];
[toolbar sizeToFit];

UIBarButtonItem *flexButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *doneButton =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(resignKeyboard)];

NSArray *itemsArray = [NSArray arrayWithObjects:flexButton, doneButton, nil];

[flexButton release];
[doneButton release];
[toolbar setItems:itemsArray];

[aTextField setInputAccessoryView:toolbar];

-resignKeyboard看起来像:

-(void)resignKeyboard {
  [aTextField resignFirstResponder];
}

希望能对某人有所帮助。


2
只是添加一些评论,以使下一个到位。UISegmentedControl * segmentControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@“ Previous”,@“ Next”,nil]]; [segmentControl setSegmentedControlStyle:UISegmentedControlStyleBar]; [segmentControl addTarget:self操作:@selector(nextPrevious :) forControlEvents:UIControlEventValueChanged];
Trausti Thor

1
@TraustiThor注释的补充:您必须将分段控件包装在UIBarButtonItem中,才能将其添加到工具栏。
蒂姆·布斯(TimBüthe)2012年

太好了-这就是我需要的所有代码。感谢您的发布:)
2012年

但是UIWebView呢?如何添加工具栏?
德米特里(Dmitry)

24

如果您注册了键盘通知,例如UIKeyboardWillShowNotification UIKeyboardWillHideNotification,则您收到的通知将在userInfodict(UIKeyboardBoundsUserInfoKey)中包含键盘的边界。

请参阅UIWindow课程参考。


16

在3.0及更高版本中,您可以从userInfo通知字典中获取动画持续时间和曲线。

例如,要动画化视图的大小以为键盘腾出空间,请注册UIKeyboardWillShowNotification并执行以下操作:

- (void)keyboardWillShow:(NSNotification *)notification
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];

    CGRect frame = self.view.frame;
    frame.size.height -= [[[notification userInfo] objectForKey:UIKeyboardBoundsUserInfoKey] CGRectValue].size.height;
    self.view.frame = frame;

    [UIView commitAnimations];
}

为制作类似的动画UIKeyboardWillHideNotification


似乎是在3.0 SDK上执行此操作的更好方法,谢谢!
华英

感谢您的代码。这很有帮助。但是,当我将UITextView设置为viewDidLoad中的第一响应者时,UIToolBar不会随着self.view的大小而移动。你知道为什么吗
RyanJM 2010年

1
@RyanJM:当视图不在屏幕上时,beginFirstResponder和resignFirstResponder行为异常。您应该改为从viewWillAppear方法调用成为firstFirstResponder。
大卫·贝克

0

创建此方法并在ViewWillLoad上调用它:

        - (void) keyboardToolbarSetup
{
    if(self.keyboardToolbar==nil)
        {
        self.keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];

        UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStylePlain target:self action:@selector(anyAction)];

        UIBarButtonItem *extraSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

        UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(anyOtherAction)];


        NSArray *toolbarButtons = [[NSArray alloc]initWithObjects:cancelButton,extraSpace,doneButton, nil];

        [self.keyboardToolbar setItems:toolbarButtons];

        self.myTextView.inputAccessoryView=self.keyboardToolbar;
        }
}

-3

无法(AFAIK)获取键盘视图的尺寸。但是,至少在到目前为止的每个iPhone版本中,它都是恒定的。

如果将工具栏位置计算为相对于视图底部的偏移量,并且考虑了视图的大小,则不必担心导航栏是否存在。

例如

#define KEYBOARD_HEIGHT 240 // example - can't remember the exact size
#define TOOLBAR_HEIGHT 30

toolBarRect.origin.y = viewRect.size.height - KEYBOARD_HEIGHT - TOOLBAR_HEIGHT;

// move toolbar either directly or with an animation

代替定义,您可以轻松创建一个keyboardHeight根据是否显示键盘返回大小的函数,并将此工具栏位置移动到一个单独的函数中,以重新组织您的布局。

而且,这可能取决于您在何处进行定位,因为根据导航栏的设置,视图的大小可能会在加载和显示之间发生变化。我相信最好的方法是在viewWillAppear中。


这很好,谢谢!到目前为止,我一直在UIKeyboardDidShowNotification触发的选择器中进行此计算。我只在几个地方进行过测试,但是看起来不错。
罗布·德里米

从5.0开始,键盘大小不再是静态的。
Alastair Stuart
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.