【发布时间】:2010-09-14 14:05:35
【问题描述】:
在某些情况下,我想在 iPhone 键盘的顶部添加一个工具栏(例如,当您在 iPhone Safari 中导航表单元素时)。
目前我正在用常量指定工具栏的矩形,但是因为界面的其他元素在不断变化 - 屏幕顶部的工具栏和导航栏 - 每次我们进行小的界面更改时,工具栏都会失去对齐。
有没有办法以编程方式确定键盘相对于当前视图的位置?
【问题讨论】:
标签: ios iphone cocoa-touch keyboard
在某些情况下,我想在 iPhone 键盘的顶部添加一个工具栏(例如,当您在 iPhone Safari 中导航表单元素时)。
目前我正在用常量指定工具栏的矩形,但是因为界面的其他元素在不断变化 - 屏幕顶部的工具栏和导航栏 - 每次我们进行小的界面更改时,工具栏都会失去对齐。
有没有办法以编程方式确定键盘相对于当前视图的位置?
【问题讨论】:
标签: ios iphone cocoa-touch keyboard
从 iOS 3.2 开始,有一种新方法可以实现此效果:
请注意,您使用的视图不应位于其他地方的视图层次结构中,也不应将其添加到某个超级视图中,这是为您完成的。
【讨论】:
所以基本上:
在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];
然后有上面提到的方法来调整bar的位置:
-(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 提供相同的信息。
UIKeyboardFrameEndUserInfoKey 来获取键盘的最后一帧(在屏幕坐标中)。您还可以使用UIKeyboardAnimationDurationUserInfoKey 和UIKeyboardAnimationCurveUserInfoKey 来获取完全匹配键盘行为所需的其余参数。
这是基于existing answer from tonklon - 我只是添加一个代码sn-p,它在键盘顶部显示一个半透明的黑色工具栏,以及右侧的“完成”按钮:
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];
}
希望对某人有所帮助。
【讨论】:
如果您注册键盘通知,即UIKeyboardWillShowNotificationUIKeyboardWillHideNotification等,您收到的通知将包含userInfo dict(UIKeyboardBoundsUserInfoKey)中的键盘边界。
请参阅UIWindow 类参考。
【讨论】:
在 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做一个类似的动画。
【讨论】:
创建此方法并在 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;
}
}
【讨论】:
没有办法 (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。
【讨论】: