在视图弹出之前存储 UITextField 内容

发布于 2024-09-29 22:56:26 字数 2797 浏览 7 评论 0原文

我确信这在苹果文档中或者一定在这个论坛的某个地方得到了回答,因为它看起来很基本,但我自己找不到它也不是一个特别优雅的解决方案。

我拥有的是一个 UIViewController,它将编辑视图推送到其导航堆栈上。编辑视图中有一堆 UITextFields。如果在触摸后退按钮时正在编辑其中一个视图,则在 textFieldShouldEndEditingtextFieldDidEndEditing 的 UITextField 委托方法或链接的 IB 之前调用原始视图的 ViewWillAppear 方法调用 textFieldEditingEnded 方法。

下面是一些我希望能够使其更清楚的代码:

在 UIViewController 中:

- (void) viewWillAppear: (BOOL) animated {
    [super viewWillAppear: animated];
    NSLog( @"Entering view will appear for master view" );
    nameLabelField.text = objectToEdit.name;
}
- (IBAction) editMyObject: (id) sender {
    NSLog( @"Editing the object" );
    EditViewController *evc = [[EditViewController alloc] initWithNibName: @"EditTableView" bundle: nil];
    evc.editedObject = objectToEdit;
    [self.navigationController pushViewController: evc animated: YES];
    [evc release];
}

在 EditViewController中:

- (void) viewWillAppear: (BOOL) animated {
    [super viewWillAppear: animated];
    nameField.text = editedObject.name;
}
- (void) viewWillDisappear: (BOOL) animated {
    [super viewWillDisappear: animated];
    NSLog( @"In viewWillDisappear" );
    if( [self.navigationController.viewControllers indexOfObject: self] == NSNotFound ) {
        NSLog( @"-- We are not in controller stack... the back button has been pushed" );
    }
}
- (BOOL) textFieldShouldEndEditing: (UITextField *) textField {
    NSLog( @"In textFieldShouldEndEditing" );
    // Store text field value here???
    // editedObject.name = nameField.text;
    return YES;
}
- (void) textFieldDidEndEditing: (UITextField *) textField {
    NSLog( @"In textFieldDidEndEditing" );
    // Store text field value here???
    // editedObject.name = nameField.text;
}
- (IBAction) textFieldEditingEnded: (id) sender {
    NSLog( @"In textFieldEditingEnded" );
    // Store text field value here???
    // editedObject.name = nameField.text;
}

日志最终为:

[...]进入视图将显示主视图
[...] 编辑对象
[...] 在 vi​​ewWillDisappear
[...] -- 我们不在控制器堆栈中...后退按钮已被按下
[...]进入视图将出现主视图
[...] 在 textFieldShouldEndEditing
[...] 在 textFieldEditingEnded
[...] 在 textFieldDidEndEditing

我想在 UIViewController 的 viewWillAppear 中设置标签之前设置 self.editedObject.name = nameField.text

我考虑过在 EditViewController 的 viewWillDisappear 方法中检查我的任何文本字段当前是否是第一响应者,如果是的话,获取它们的文本并存储它,但这似乎是一个混杂,如果我维护起来会很痛苦添加或更改文本字段。

我还可以实现 textFieldEditingChanged IB 链接操作,以便在每次击键后设置编辑对象中的文本,但这也是相当大的开销,因为我必须弄清楚每次击键时我在哪个文本字段中(记住我只显示了name,但有一大堆)。

我所需要的只是在 UIViewController 中调用 viewWillAppear 之前结束编辑或知道编辑将结束,以便正确设置 nameFieldLabel 。

I am sure this is in the Apple documentation or must have been answered somewhere on this forum, since it seems so basic, but I could not find it nor a particularly elegant solution myself.

What I have is a UIViewController that pushes an editing view on its navigation stack. The editing view has a bunch of UITextFields in it. If one of them is being editing when the back button is touched, the original view's ViewWillAppear method is called before either the UITextField delegate methods of textFieldShouldEndEditing or textFieldDidEndEditing, or the IB linked action textFieldEditingEnded method are called.

Here is some code that I hope will make it clearer:

In the UIViewController:

- (void) viewWillAppear: (BOOL) animated {
    [super viewWillAppear: animated];
    NSLog( @"Entering view will appear for master view" );
    nameLabelField.text = objectToEdit.name;
}
- (IBAction) editMyObject: (id) sender {
    NSLog( @"Editing the object" );
    EditViewController *evc = [[EditViewController alloc] initWithNibName: @"EditTableView" bundle: nil];
    evc.editedObject = objectToEdit;
    [self.navigationController pushViewController: evc animated: YES];
    [evc release];
}

In the EditViewController <UITextFieldDelegate>:

- (void) viewWillAppear: (BOOL) animated {
    [super viewWillAppear: animated];
    nameField.text = editedObject.name;
}
- (void) viewWillDisappear: (BOOL) animated {
    [super viewWillDisappear: animated];
    NSLog( @"In viewWillDisappear" );
    if( [self.navigationController.viewControllers indexOfObject: self] == NSNotFound ) {
        NSLog( @"-- We are not in controller stack... the back button has been pushed" );
    }
}
- (BOOL) textFieldShouldEndEditing: (UITextField *) textField {
    NSLog( @"In textFieldShouldEndEditing" );
    // Store text field value here???
    // editedObject.name = nameField.text;
    return YES;
}
- (void) textFieldDidEndEditing: (UITextField *) textField {
    NSLog( @"In textFieldDidEndEditing" );
    // Store text field value here???
    // editedObject.name = nameField.text;
}
- (IBAction) textFieldEditingEnded: (id) sender {
    NSLog( @"In textFieldEditingEnded" );
    // Store text field value here???
    // editedObject.name = nameField.text;
}

The log ends up with:

[...] Entering view will appear for master view
[...] Editing the object
[...] In viewWillDisappear
[...] -- We are not in controller stack... the back button has been pushed
[...] Entering view will appear for master view
[...] In textFieldShouldEndEditing
[...] In textFieldEditingEnded
[...] In textFieldDidEndEditing

I want to set self.editedObject.name = nameField.text before the label gets set in viewWillAppear for the UIViewController.

I thought about in the viewWillDisappear method for the EditViewController checking to see if any of my text fields are currently the first responder and if so getting their text and storing it, but this seems like such a kludge that will be a pain to maintain if I add or change text fields.

I can also implement the textFieldEditingChanged IB linked action to set the text in the edited object after every keystroke but this is also quite a bit of overhead since I have to figure out which text field I am in every keystroke (remember I only showed name but there are a whole bunch of them).

All I need is for the editing to be ended or to know the editing will be ended before viewWillAppear is called in the UIViewController so the nameFieldLabel is properly set.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

塔塔猫 2024-10-06 22:56:26

好吧,经过大量的网上冲浪、论坛阅读和手册阅读后,我找到了一个简单的解决方案。正如我所怀疑的,它非常简单,只添加了一行代码。在 EditViewContorller 的 viewWillDisappear 方法中,我简单地添加了:

    [self.view.window endEditing: YES];

现在,textFieldShouldEndEditingtextFieldEditingEndedtextFieldDidEndEditing 全部被触发在主视图的 viewWillAppear 之前。

现在,viewWillDisappear 方法如下所示:

- (void) viewWillDisappear: (BOOL) animated {
    [super viewWillDisappear: animated];
    NSLog( @"In viewWillDisappear" );
    // Force any text fields that might be being edited to end so the text is stored
    [self.view.window endEditing: YES];
}

处理键盘上“返回”按钮的方法也可以处理导航控制器上的“返回”按钮。

感谢亚伦和杰夫的帮助并帮助我思考这个问题。

OK, I figured out a simple solution after a lot of web-surfing, forum reading, and manual reading. It was, as I suspected, very simple, only one line of code added. In the viewWillDisappear method of the EditViewContorller I simply added:

    [self.view.window endEditing: YES];

Now textFieldShouldEndEditing, textFieldEditingEnded, and textFieldDidEndEditing all get fired off before the viewWillAppear of the master view does.

So now the viewWillDisappear method looks like:

- (void) viewWillDisappear: (BOOL) animated {
    [super viewWillDisappear: animated];
    NSLog( @"In viewWillDisappear" );
    // Force any text fields that might be being edited to end so the text is stored
    [self.view.window endEditing: YES];
}

And the methods already in place to handle the 'Return' on the keyboard also handle the 'Back' button on the Navigation controller.

Thank you Aaron and Jeff for your assistance and helping me think this through.

笛声青案梦长安 2024-10-06 22:56:26

为什么不在其操作方法中使用该逻辑创建您自己的后退按钮呢?

Why not just create your own Back button with that logic in its action method?

殊姿 2024-10-06 22:56:26

我认为从用户体验的角度来看,您应该显示一个警报,以确定用户是否想要在退出当前视图之前取消他们正在进行的编辑操作。

通过提醒用户,您可以了解他们是否意外按下了按钮,或者他们是否确实决定离开视图,并采取适当的操作。

// add this to the field(s) to be edited, selector will be called as the changes
// are being made... still difficult to handle a cancel, but should work
[objectToEdit addTarget:self action:@selector(updateNameField:) 
                         forControlEvents:UIControlEventEditingChanged];

此处附加代码...

// the method called to update object from parent view
- (void)updateNameField:(id)sender {
    <OBJECT TO UPDATE>.text = ((UITextField *)sender).text;
}

I would think that from a UX perspective, you should display an alert to determine if the user wants to cancel the edit action they were in the middle of before exiting the current view.

By alerting the user, you can see if they hit the button by accident or if they did decide to leave the view, take the appropriate action.

// add this to the field(s) to be edited, selector will be called as the changes
// are being made... still difficult to handle a cancel, but should work
[objectToEdit addTarget:self action:@selector(updateNameField:) 
                         forControlEvents:UIControlEventEditingChanged];

additional code here...

// the method called to update object from parent view
- (void)updateNameField:(id)sender {
    <OBJECT TO UPDATE>.text = ((UITextField *)sender).text;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文