自定义 UITableViewCell + UITextField 问题

发布于 2024-12-22 08:34:11 字数 2146 浏览 3 评论 0原文

我遇到了一个我似乎无法弄清楚的问题。

我所设置的:

  1. 一个自定义 UITableViewCell,其中有多个文本字段。类似于 Apple 在为联系人中的某人添加新地址时的设置方式。
  2. 带有自定义单元格的表格显示为模式视图。该表视图还具有其他通用单元格(即不是 1. 中所述的自定义单元格)。
  3. 呈现的模式视图顶部有一个工具栏,其中包含一个完成按钮。当按下完成后,模态视图将回调发送回其委托并关闭。

我遇到的问题: 当用户选择 UITextField 并开始编辑时,将显示 UIKeyboard(显然是对的?)。如果键盘打开,并且用户在工具栏上选择“完成”(如 3. 中所述),则应用程序会崩溃,因为在键盘打开时父视图试图关闭模态视图(包含键盘的模态视图) 。

从高层次来看,它应该像这样工作:

用户单击工具栏中的“完成” - >检查 UIKeyboard 是否打开 ->如果打开,则关闭,否则关闭模态视图

但这并不那么容易。

我一直在绞尽脑汁试图找到一个可行的解决办法,但似乎没有任何效果。

任何建议将不胜感激。

编辑

以下是崩溃日志:

2011-12-22 16:03:09.021 Renshaw[2308:5f43] bool _WebTryThreadLock(bool), 0xad7a9e0: Tried     to obtain the web lock from a thread other than the main thread or the web thread. This may be     a result of calling to UIKit from a secondary thread. Crashing now...
1   _ZL17_WebTryThreadLockb
2   WebThreadLock
3   -[UITextRangeImpl isEmpty]
4   -[UITextRange(UITextSelectionAdditions) _isCaret]
5   -[UITextSelectionView setCaretBlinks:]
6   -[UIKeyboardImpl setCaretBlinks:]
7   -[UIKeyboardImpl setDelegate:force:]
8   -[UIPeripheralHost(UIKitInternal) _reloadInputViewsForResponder:]
9   -[UIResponder _finishResignFirstResponder]
10  -[UIResponder resignFirstResponder]
11  -[UITextField resignFirstResponder]
12  -[UIView(UITextField) endEditing:]
13  -[UIWindowController _prepareKeyboardForTransition:fromView:]
14  -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:]
15  -[UIViewController _dismissViewControllerWithTransition:from:completion:]
16  -[UIViewController dismissViewControllerWithTransition:completion:]
17  -[UIViewController dismissViewControllerWithTransition:completion:]
18  -[ListingsViewController postSearch:allObjects:constrainedList:]
19  -[FilterViewController searchObjects]
20  -[NSObject performSelector:withObject:]
21  -[MBProgressHUD launchExecution]
22  -[NSThread main]
23  __NSThread__main__
24  _pthread_start
25  thread_start
[Switching to process 10499 thread 0x2903]
[Switching to process 10499 thread 0x2903]

I am having a problem that I can't seem to figure out.

What I have setup:

  1. A custom UITableViewCell that has multiple textfields in it. Similar to how Apple has it setup when adding a new address for someone in contacts.
  2. The table with the custom cell is being presented as a modal view. This table view also has other cells that are generic (i.e. not the custom cell stated in 1. ).
  3. The presented modal view has a toolbar at the top, which contains a done button. When done is pressed the modal view sends a call back to its delegate and dismisses.

The problem that I am having:
When the user selects a UITextField and starts to edit the UIKeyboard is presented (obviously right?). If the keyboard is open, and the user selects "done" on the toolbar (as stated in 3. ), the app crashes because the parent view is trying to dismiss the modal view (modal view containing the keyboard) while the keyboard is open.

High level it seems like it should work like this:

User clicks "done" in toolbar -> check if UIKeyboard is open -> if open, close else dismiss modal view

But it hasn't been that easy.

I have been pulling my hair out trying to find a viable work around for this and nothings seems to work.

Any suggestions would be very appreciated.

Edit

Here is the crash log:

2011-12-22 16:03:09.021 Renshaw[2308:5f43] bool _WebTryThreadLock(bool), 0xad7a9e0: Tried     to obtain the web lock from a thread other than the main thread or the web thread. This may be     a result of calling to UIKit from a secondary thread. Crashing now...
1   _ZL17_WebTryThreadLockb
2   WebThreadLock
3   -[UITextRangeImpl isEmpty]
4   -[UITextRange(UITextSelectionAdditions) _isCaret]
5   -[UITextSelectionView setCaretBlinks:]
6   -[UIKeyboardImpl setCaretBlinks:]
7   -[UIKeyboardImpl setDelegate:force:]
8   -[UIPeripheralHost(UIKitInternal) _reloadInputViewsForResponder:]
9   -[UIResponder _finishResignFirstResponder]
10  -[UIResponder resignFirstResponder]
11  -[UITextField resignFirstResponder]
12  -[UIView(UITextField) endEditing:]
13  -[UIWindowController _prepareKeyboardForTransition:fromView:]
14  -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:]
15  -[UIViewController _dismissViewControllerWithTransition:from:completion:]
16  -[UIViewController dismissViewControllerWithTransition:completion:]
17  -[UIViewController dismissViewControllerWithTransition:completion:]
18  -[ListingsViewController postSearch:allObjects:constrainedList:]
19  -[FilterViewController searchObjects]
20  -[NSObject performSelector:withObject:]
21  -[MBProgressHUD launchExecution]
22  -[NSThread main]
23  __NSThread__main__
24  _pthread_start
25  thread_start
[Switching to process 10499 thread 0x2903]
[Switching to process 10499 thread 0x2903]

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

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

发布评论

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

评论(5

挽袖吟 2024-12-29 08:34:11

线索就在堆栈跟踪中:

Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...

您正在从辅助线程调用 UIKit 方法。您必须在非主线程上执行某些操作,例如调用 resignFirstResponder。有关详细信息,请参阅此处:

更新:事实

证明,解决方案是使用以下内容:

dispatch_async(dispatch_get_main_queue(), ^{ <code_here> });

包装调用以关闭视图,以便 UIKit 方法在主线程上运行。

The clue is in the stack trace:

Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...

You're calling a UIKit method from a secondary thread. You must be doing something on not-the-main-thread such as calling resignFirstResponder. See here for more information on that:

Update:

It turns out the solution was to use something along the lines of:

dispatch_async(dispatch_get_main_queue(), ^{ <code_here> });

to wrap the call to dismiss the view so that the UIKit methods were being run on the main thread.

梦冥 2024-12-29 08:34:11

将其放在您的 @implementation 之上

static UITextField *currentlySelectedTextField = nil;

并覆盖这些方法,

- (void)viewWillDisappear {
  [super viewWillDisappear];
  [currentlySelectedTextField resignFirstResponder];
}

- (void)textFieldDidBeginEditing:(UITextField *)textField {
  currentlySelectedTextField = textField;
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
  currentlySelectedTextField = nil;
}

当然这假设您将自己注册为自定义单元格内使用的每个 UITextField 的委托

Put this above your @implementation

static UITextField *currentlySelectedTextField = nil;

And override those methods

- (void)viewWillDisappear {
  [super viewWillDisappear];
  [currentlySelectedTextField resignFirstResponder];
}

- (void)textFieldDidBeginEditing:(UITextField *)textField {
  currentlySelectedTextField = textField;
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
  currentlySelectedTextField = nil;
}

of course this assumes that you are registering yourself as a delegate for each of the UITextFields that are being used inside your custom cells

心作怪 2024-12-29 08:34:11

每当文本字段处于活动状态时禁用“完成”按钮怎么样?

只需执行以下操作:doneButton.enabled = NO;,当文本字段成为FirstResponder时,然后在键盘关闭时启用完成按钮(在textFieldShouldReturn:(UITextField*)中)文本字段)。

How about disabling the done button whenever a textfield is made active?

Just do: doneButton.enabled = NO;, when a textfield becomesFirstResponder, then enable the done button when the keyboard is dismissed (in textFieldShouldReturn:(UITextField*)textField).

吻风 2024-12-29 08:34:11

我遇到了类似的问题,但不是在 textFieldShouldReturn 上,而是在 textFieldDidBeginEditing 上。

问题是文本字段是在模式视图中添加的,但基础视图上也有一个文本字段。底层文本字段是在 Interface Builder 中创建的,因此在模式视图出现在屏幕上之前就已分配并设置为第一响应者。
这导致了与上面相同的错误。

通过不在 IB 中添加底层文本字段,可以轻松解决此问题。当底层视图需要它时,我稍后以编程方式添加它。

容易修复,很难发现问题;-)

干杯
缺口

I had a similar issue but not on the textFieldShouldReturn but rather on the textFieldDidBeginEditing.

The issue was that the textField was added in a modal view but there was also a textField on the underlying view. The underlying textField was created in Interface Builder and was therefor allocated and set to First Responder before the modal view was even on screen.
This resulted in the same error as above.

This was easily fixed by NOT adding the underlying textField in IB. I added it programmatically later, once it was needed in the underlying view.

Easy fix, hard to find issue ;-)

Cheers
Nick

呆萌少年 2024-12-29 08:34:11

在检查 textFieldShouldReturn 中的某些值后需要推送 UIViewController 时,我看到 _webthreadlockfromanythread 崩溃。

如果您需要使用 textFieldShouldReturn,则工作原理如下:

  1. 如果 textFieldShouldReturn 返回 YES,您还需要调用 resignFirstRespondertextfield 上,
  2. 这将依次调用 textFieldDidEndEditing:,并启动动画以关闭键盘。

调用 _webthreadlockfromanythread 异常是因为我的应用程序在键盘完全关闭之前推送了视图控制器。

解决方案是为 UIKeyboardDidHideNotification 添加一个观察者和一个接收通知以推送视图控制器的方法。祝你好运!

I was seeing _webthreadlockfromanythread crashes when needing to push a UIViewController after checking some values in textFieldShouldReturn.

If you need to use textFieldShouldReturn, here's what works:

  1. If textFieldShouldReturn returns YES you will also need to call resignFirstResponder on the textfield
  2. This will in turn call textFieldDidEndEditing:, and will start an animation to dismiss the keyboard.

The _webthreadlockfromanythread exception was being called because my App was pushing a view controller before the keyboard had fully been dismissed.

The solution is to add an observer for the UIKeyboardDidHideNotification and a method that receives the notification to push your view controller. Good luck!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文