自定义 UITableViewCell + UITextField 问题
我遇到了一个我似乎无法弄清楚的问题。
我所设置的:
- 一个自定义 UITableViewCell,其中有多个文本字段。类似于 Apple 在为联系人中的某人添加新地址时的设置方式。
- 带有自定义单元格的表格显示为模式视图。该表视图还具有其他通用单元格(即不是 1. 中所述的自定义单元格)。
- 呈现的模式视图顶部有一个工具栏,其中包含一个完成按钮。当按下完成后,模态视图将回调发送回其委托并关闭。
我遇到的问题: 当用户选择 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:
- 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.
- 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. ).
- 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
线索就在堆栈跟踪中:
您正在从辅助线程调用 UIKit 方法。您必须在非主线程上执行某些操作,例如调用
resignFirstResponder
。有关详细信息,请参阅此处:更新:事实
证明,解决方案是使用以下内容:
包装调用以关闭视图,以便 UIKit 方法在主线程上运行。
The clue is in the stack trace:
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:
to wrap the call to dismiss the view so that the UIKit methods were being run on the main thread.
将其放在您的 @
implementation
之上并覆盖这些方法,
当然这假设您将自己注册为自定义单元格内使用的每个 UITextField 的委托
Put this above your @
implementation
And override those methods
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
每当文本字段处于活动状态时禁用“完成”按钮怎么样?
只需执行以下操作:
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 textfieldbecomesFirstResponder
, then enable the done button when the keyboard is dismissed (intextFieldShouldReturn:(UITextField*)textField
).我遇到了类似的问题,但不是在 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
在检查
textFieldShouldReturn
中的某些值后需要推送UIViewController
时,我看到_webthreadlockfromanythread
崩溃。如果您需要使用
textFieldShouldReturn
,则工作原理如下:textFieldShouldReturn
返回YES
,您还需要调用resignFirstResponder
在textfield
上,textFieldDidEndEditing:
,并启动动画以关闭键盘。调用
_webthreadlockfromanythread
异常是因为我的应用程序在键盘完全关闭之前推送了视图控制器。解决方案是为
UIKeyboardDidHideNotification
添加一个观察者和一个接收通知以推送视图控制器的方法。祝你好运!I was seeing
_webthreadlockfromanythread
crashes when needing to push aUIViewController
after checking some values intextFieldShouldReturn
.If you need to use
textFieldShouldReturn
, here's what works:textFieldShouldReturn
returnsYES
you will also need to callresignFirstResponder
on thetextfield
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!