自定义UITableViewCell + UITextField问题

时间:2011-12-22 21:24:22

标签: objective-c ios uitextfield modalviewcontroller uikeyboard

我遇到了一个我无法理解的问题。

我的设置:

  1. 自定义UITableViewCell,其中包含多个文本字段。类似于Apple为联系人中的某人添加新地址时的设置方式。
  2. 具有自定义单元格的表格将显示为模态视图。该表视图还具有通用的其他单元(即,不是1中所述的自定义单元)。
  3. 呈现的模态视图顶部有一个工具栏,其中包含一个完成按钮。按下完成后,模态视图会将回调发送回其委托并解除。
  4. 我遇到的问题: 当用户选择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]
    

5 个答案:

答案 0 :(得分:5)

线索在堆栈跟踪中:

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方法。

答案 1 :(得分:1)

将其置于@ implementation

之上
static UITextField *currentlySelectedTextField = nil;

并覆盖这些方法

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

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

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

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

答案 2 :(得分:0)

如果文本字段处于活动状态,禁用“完成”按钮怎么样?

只需执行:doneButton.enabled = NO;,当文本字段为becomesFirstResponder时,然后在解除键盘时启用完成按钮(在textFieldShouldReturn:(UITextField*)textField中)。

答案 3 :(得分:0)

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

如果您需要使用textFieldShouldReturn,这里有效:

  1. 如果textFieldShouldReturn返回YES,您还需要致电resignFirstResponder
  2. 上的textfield
  3. 这将依次调用textFieldDidEndEditing:,并将启动动画以关闭键盘。
  4. 正在调用_webthreadlockfromanythread异常,因为我的应用程序在键盘完全被解除之前推送了一个视图控制器

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

答案 4 :(得分:0)

我有一个类似的问题,但没有关于textFieldShouldReturn,而是关于textFieldDidBeginEditing。

问题是textField是在模态视图中添加的,但底层视图上还有一个textField。底层textField是在Interface Builder中创建的,因此在模态视图甚至在屏幕上之前分配并设置为First Responder。 这导致了与上述相同的错误。

通过在IB中添加底层textField可以很容易地解决这个问题。在底层视图中需要它之后,我稍后以编程方式添加它。

轻松修复,很难找到问题; - )

干杯 尼克