在一些情况下,我想添加一个工具栏到iPhone键盘的顶部(例如在iPhone Safari中导航表单元素时)。
目前,我正在使用常量指定工具栏的矩形框架,但由于界面的其他元素处于不稳定状态 - 例如屏幕顶部的工具栏和导航栏 - 每当我们进行轻微的界面更改时,工具栏就会失去对齐。
有没有办法通过编程确定键盘与当前视图的位置关系?
在一些情况下,我想添加一个工具栏到iPhone键盘的顶部(例如在iPhone Safari中导航表单元素时)。
目前,我正在使用常量指定工具栏的矩形框架,但由于界面的其他元素处于不稳定状态 - 例如屏幕顶部的工具栏和导航栏 - 每当我们进行轻微的界面更改时,工具栏就会失去对齐。
有没有办法通过编程确定键盘与当前视图的位置关系?
从iOS 3.2开始,有一种新的实现方式:
UITextFields
和 UITextViews
有一个名为 inputAccessoryView
的属性,您可以将其设置为任何视图,该视图会自动显示在键盘上方,并随键盘动画而移动。
请注意,您使用的视图既不应该在其他地方的视图层次结构中,也不应该将其添加到某个父视图,因为这些都已经由系统为您处理好了。
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];
UIKeyboardFrameBeginUserInfoKey
,可以提供相同的信息。 - Stephen DarlingtonUIKeyboardFrameEndUserInfoKey
来获取键盘的最终框架(以屏幕坐标为单位)。您还可以使用 UIKeyboardAnimationDurationUserInfoKey
和 UIKeyboardAnimationCurveUserInfoKey
来获取其余参数,以完全匹配键盘的行为。 - Dave Peck这是基于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];
}
UIKeyboardWillShowNotification
和UIKeyboardWillHideNotification
,您将收到包含键盘边界的通知,它位于userInfo
字典中 (UIKeyboardBoundsUserInfoKey
)。UIWindow
类参考。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
进行类似的动画。
- (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;
}
}
据我所知,没有办法获取键盘视图的尺寸。但是,至少在迄今为止的每个 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
函数来返回基于键盘是否正在显示的大小,而不是使用define,并将此工具栏定位移动到单独的函数中以重新组织布局。
此外,它可能取决于您执行此定位的位置,因为根据您的导航栏设置,您的视图的大小可能会在加载和显示之间发生变化。我认为最好的地方是在viewWillAppear中执行。