让我的 UIPickerView 具有与键盘相同的行为
Posted
技术标签:
【中文标题】让我的 UIPickerView 具有与键盘相同的行为【英文标题】:Have my UIPickerView having the same behavior than the keyboard 【发布时间】:2010-05-27 16:14:50 【问题描述】:所以我有一个 UITableView,其中一行是 UITextView。
当用户正在向 UITextView 写入内容(使用键盘)时,用户可以滚动 tableview 并选择另一个单元格。一切正常。
当用户选择另一个单元格时,会出现一个 datePicker,用户可以选择一个给定的日期。我希望用户能够像键盘在屏幕上一样滚动 tableView。
这里的问题是,当我使用选择器滚动时,表格会弹回之前的位置(选择器隐藏了一些单元格)。
我认为发生这种情况是因为我将选择器作为子视图添加到主窗口...但老实说我不确定...
我应该在哪里(以及如何)添加我的选择器,以便它“出现”在键盘出现的地方?
不确定我是否清楚...
非常感谢。
【问题讨论】:
【参考方案1】:您应该使用 UIResponder 类(也是 UITextField 类)的 inputView 属性。 做吧:
UIPickerView *picker = [[UIPickerView alloc] initWithFrame:CGRectZero];
//picker.delegate = self;
//picker.dataSource = self;
//[picker setShowsSelectionIndicator:YES];
textField.inputView = picker;
[picker release];
UIPickerView 的行为类似于键盘视图。
有关更多详细信息和示例代码,请参阅我关于 working with pickers 的文章。
【讨论】:
【参考方案2】:我实际上是用 UIDatePicker 完成的,创建了我自己的 SlideUpDatePicker,它就像键盘一样从底部向上动画。我花了一两个星期才让它完美运行,让它在纵向和横向以及导航控制器及其动画中运行绝对不容易。
键盘创建一个新的***窗口来保存它的视图,并在它出现和消失之前和之后向通知中心发布通知,以便视图控制器可以调整其视图的大小以适应键盘。视图控制器需要处理这些通知并根据键盘的大小调整表格视图的大小。
我的 SlideUpDatePicker 发布了与键盘相同的通知,因此不必修改视图控制器,并且可以对键盘和上滑日期选择器做出相同的响应。
如果您使用dumpWindows() 函数,您可以在基于导航的应用程序中通过键盘和表格视图查看 UIWindow 和 UIView 层次结构:
dumpView: <UIWindow: 0x411fd50; frame = (0 0; 320 480); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x4120af0>>
dumpView: : <UILayoutContainerView: 0x4123310; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x411f800>>
dumpView: : | <UINavigationTransitionView: 0x4123500; frame = (0 0; 320 480); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x41232e0>>
dumpView: : | : <UIViewControllerWrapperView: 0x4519d30; frame = (0 64; 320 416); autoresize = W+H; layer = <CALayer: 0x4519a40>>
dumpView: : | : | <UITableView: 0x7808000; frame = (0 0; 320 416); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x45182a0>>
dumpView: : | : | : <DeleteCell: 0x45196e0; baseClass = UITableViewCell; frame = (0 507; 320 45); opaque = NO; autoresize = W; layer = <CALayer: 0x4519a80>>
dumpView: : | : | : <TextCell: 0x4523280; baseClass = UITableViewCell; frame = (0 442; 320 45); autoresize = W; layer = <CALayer: 0x4521ed0>>
dumpView: : | : | : <DatePickerCell: 0x45224b0; baseClass = UITableViewCell; frame = (0 398; 320 44); autoresize = W; layer = <CALayer: 0x451e170>>
dumpView: : | : | : <ButtonCell: 0x4521680; baseClass = UITableViewCell; frame = (0 354; 320 44); autoresize = W; layer = <CALayer: 0x4521750>>
dumpView: : | : | : <ButtonCell: 0x45209f0; baseClass = UITableViewCell; frame = (0 310; 320 44); autoresize = W; layer = <CALayer: 0x4520ac0>>
dumpView: : | : | : <ButtonCell: 0x4520100; baseClass = UITableViewCell; frame = (0 266; 320 44); autoresize = W; layer = <CALayer: 0x45201d0>>
dumpView: : | <UINavigationBar: 0x45018b0; frame = (0 20; 320 44); clipsToBounds = YES; autoresize = W; layer = <CALayer: 0x4500fe0>>
dumpView: : | : <UINavigationItemView: 0x4522a20; frame = (100 8; 160 27); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x4526310>>
dumpView: : | : <UINavigationItemButtonView: 0x45230a0; frame = (5 7; 87 30); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x4520260>>
dumpView: <UITextEffectsWindow: 0x4537080; frame = (0 0; 320 480); opaque = NO; layer = <CALayer: 0x45371c0>>
dumpView: : <UIKeyboard: 0x4536ce0; frame = (0 264; 320 216); opaque = NO; layer = <CALayer: 0x4536f60>>
dumpView: : | <UIKeyboardImpl: 0x4175b10; frame = (0 0; 320 216); opaque = NO; layer = <CALayer: 0x4173f90>>
dumpView: : | : <UIKeyboardLayoutStar: 0x4177d90; frame = (0 0; 320 216); layer = <CALayer: 0x4177610>>
dumpView: : | : | <UIKBKeyplaneView: 0x418a6a0; frame = (0 0; 320 216); userInteractionEnabled = NO; layer = <CALayer: 0x418a750>>
dumpView: : | : | : <UIKBKeyView: 0x41748e0; frame = (1 119; 40 42); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x41545c0>>
dumpView: : | : | : <UIKBKeyView: 0x417e2d0; frame = (279 119; 40 42); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x417df10>>
dumpView: : | : | : <UIKBKeyView: 0x418a780; frame = (1 173; 78 42); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x417f990>>
dumpView: : | : | : <UIKBKeyView: 0x418adf0; frame = (81 173; 158 42); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x4180120>>
dumpView: : | : | : <UIKBKeyView: 0x418cdb0; frame = (241 173; 78 42); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x418cf20>>
【讨论】:
按照它的逻辑,它可以工作。现在,我将使用通知快速尝试一下。主要问题是我没有两周的时间,所以……让我们看看会发生什么。无论如何,非常感谢。【参考方案3】:没那么优雅……
不是很专业...
我这样做了...
CGRect frame3 = self.tableView.frame;
frame3.size.height = frame3.size.height-216;
self.tableView.frame = frame3;
然后我让我的选择器出现了。瞧! ;)
【讨论】:
【参考方案4】:正如 lechec 指出的,只需将 UITextField 的 inputView 属性设置为 UIPickerView。这很容易做到。
这篇博文详细介绍了如何做到这一点:http://nomtek.com/tips-for-developers/working-with-pickers/ 并且包含一个项目供下载,其中包含示例代码。该项目在 XCode 4.2 中可以正常打开并针对 ios 5 进行编译。
此外,我不想添加一个按钮来隐藏它。以下代码允许用户点击视图中的任何位置,在 UITextField 之外并将其作为第一响应者退出,基本上使其“失去焦点”。实际上,处理点击手势的代码会导致任何 UITextField “失去焦点”,从而隐藏任何 inputView 或键盘。
-(void)handleViewTapGesture:(UITapGestureRecognizer *)gesture
[self endEditing:YES];
这是在 ViewController 中实现的。该处理程序作为手势识别器添加到 View 属性的 setter 中的适当 View:
-(void) setLoginView:(LoginView *)loginView
_loginView = loginView;
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self.loginView action:@selector(handleTapGesture:)];
[tapRecognizer setDelegate:self]; // self implements the UIGestureRecognizerDelegate protocol
[self.loginView addGestureRecognizer:tapRecognizer];
也可以在视图中定义处理程序。如果您不熟悉处理手势,请参阅 Apple 的文档和/或其他地方的大量示例。
我应该提到,您将需要一些额外的代码来确保其他控件被点击,您需要一个实现 UIGestureRecognizerDelegate 协议的委托和此方法:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
if ([touch.view isKindOfClass:[UIButton class]]) // Customize appropriately.
return NO; // Don't let the custom gestureRecognizer handle the touch
return YES;
【讨论】:
以上是关于让我的 UIPickerView 具有与键盘相同的行为的主要内容,如果未能解决你的问题,请参考以下文章
使用 UITextField + UIPickerview 时禁用键盘输入
无法在 SWIFT 中使用 UipickerView 委派文本字段