我已经实现了一个自定义的UITableViewCell,它包含一个可以随着用户输入自动调整大小的UITextView,类似于Contacts应用程序中的"Notes“字段。它在我的iPhone上工作正常,但当我在iPad中测试它时,我得到了一些非常奇怪的行为:当您到达一行的末尾时,键盘隐藏了一毫秒,然后立即再次显示。我会把它写成一个奇怪的bug,但它实际上会导致一些数据丢失,因为如果你在打字,它会丢失一两个字符。下面是我的代码:
《守则》
// returns the proper height/size for the UITextView based on the string it contains.
// If no string, it assumes a space so that it will always have one line.
- (CGSize)textViewSize:(UITextView*)textView {
float fudgeFactor = 16.0;
CGSize tallerSize = CGSizeMake(textView.frame.size.width-fudgeFactor, kMaxFieldHeight);
NSString *testString = @" ";
if ([textView.text length] > 0) {
testString = textView.text;
}
CGSize stringSize = [testString sizeWithFont:textView.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap];
return stringSize;
}
// based on the proper text view size, sets the UITextView's frame
- (void) setTextViewSize:(UITextView*)textView {
CGSize stringSize = [self textViewSize:textView];
if (stringSize.height != textView.frame.size.height) {
[textView setFrame:CGRectMake(textView.frame.origin.x,
textView.frame.origin.y,
textView.frame.size.width,
stringSize.height+10)]; // +10 to allow for the space above the text itself
}
}
// as per: https://stackoverflow.com/questions/3749746/uitextview-in-a-uitableviewcell-smooth-auto-resize
- (void)textViewDidChange:(UITextView *)textView {
[self setTextViewSize:textView]; // set proper text view size
UIView *contentView = textView.superview;
// (1) the padding above and below the UITextView should each be 6px, so UITextView's
// height + 12 should equal the height of the UITableViewCell
// (2) if they are not equal, then update the height of the UITableViewCell
if ((textView.frame.size.height + 12.0f) != contentView.frame.size.height) {
[myTableView beginUpdates];
[myTableView endUpdates];
[contentView setFrame:CGRectMake(0,
0,
contentView.frame.size.width,
(textView.frame.size.height+12.0f))];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
int height;
UITextView *textView = myTextView;
[self setTextViewSize:textView];
height = textView.frame.size.height + 12;
if (height < 44) { // minimum height of 44
height = 44;
[textView setFrame:CGRectMake(textView.frame.origin.x,
textView.frame.origin.y,
textView.frame.size.width,
44-12)];
}
return (CGFloat)height;
}
问题
所以,这是正在发生的事情
textViewDidChange:(UITextView *)textView
中删除行[myTableView beginUpdates]; [myTableView endUpdates];
会使UITextView正常增长,也不会显示和隐藏键盘,但不幸的是,然后,在these instructions之后,UITableViewCell不会增长到正确的height.
有没有人知道如何让键盘持续显示,而不是在到达iPad的行尾时隐藏和显示?
附言:我对使用ThreeTwenty不感兴趣。
发布于 2010-10-30 04:56:55
您应该在以下位置返回NO:
-(BOOL) textViewShouldEndEditing:(UITextView *)textView
如果您想要始终显示键盘。您应该通过将YES返回给这个委托函数来处理键盘应该隐藏的情况。
编辑:
我深入研究了一下,当tableView endUpdates调用时,它基本上做了3件事:
上启用用户交互
SDK(Platforms)之间的区别在于UIView setUserInteractionEnabled方法。由于UITableView不覆盖setUserInteractionEnabled方法,因此它是从超级(UIView)调用的。
当调用setUserInteractionEnabled时,iPhone查找私有字段_shouldResignFirstResponderWithInteractionDisabled,该字段默认返回NO,因此不会放弃第一个响应者(UITextView)
但在iPad上没有这样的检查AFAIK,所以它在step 1上辞去了UITextView,并在step 3上设置了焦点并使其成为第一响应者
基本上,textViewShouldEndEditing是你唯一的选择,根据SDK的文档,它可以让你保持专注。
当文本视图被要求放弃第一响应者状态时,调用此方法。当用户尝试将编辑焦点更改到另一个控件时,可能会发生这种情况。但是,在焦点实际更改之前,文本视图将调用此方法,以便让您的委托有机会决定是否应该这样做。
发布于 2011-01-30 20:18:56
我在一个iPad应用程序上也遇到了同样的问题,在没有计算文本高度的情况下,我想出了另一个解决方案。
首先,在IB中创建自定义UITableViewCell,并将UITextField放在单元格的contentView中。将文本视图的scrollEnabled设置为NO,将autoresizingMask设置为flexibleWidth和flexibleHeight,这一点很重要。
在ViewController中实现文本视图的委托方法-textViewDidChanged:,如下所示,其中-tableViewNeedsToUpdateHeight是一个类型为的实例变量,textHeight是一个我们将在下一步中定义的自定义方法。
- (void)textViewDidChange:(UITextView *)textView
{
CGFloat newTextHeight = [textView contentSize].height;
if (newTextHeight != textHeight)
{
textHeight = newTextHeight;
[self tableViewNeedsToUpdateHeight];
}
}
-tableViewNeedsToUpdateHeight方法调用表视图的beginUpdates和-tableView:heightForRowAtIndexPath:委托方法,因此表视图本身将调用endUpdates方法。
- (void)tableViewNeedsToUpdateHeight
{
BOOL animationsEnabled = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
[table beginUpdates];
[table endUpdates];
[UIView setAnimationsEnabled:animationsEnabled];
}
在表视图的-tableView:heightForRowAtIndexPath:委托方法中,我们需要根据textHeight计算文本视图的单元格的新高度。
首先,我们需要将文本视图单元格的高度调整为最大可用高度(减去表视图中所有其他单元格的高度)。然后我们检查textHeight是否大于计算的高度。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat heightForRow = 44.0;
if ([indexPath row] == kRowWithTextViewEmbedded)
{
CGFloat tableViewHeight = [tableView bounds].size.height;
heightForRow = tableViewHeight - ((kYourTableViewsNumberOfRows - 1) * heightForRow);
if (heightForRow < textHeight)
{
heightForRow = textHeight;
}
}
return heightForRow;
}
为了获得更好的用户体验,将表格视图的content insets For bottom设置为50.0。
我已经在使用iOS 4.2.1的iPad上进行了测试,并按预期工作。
弗洛里安
https://stackoverflow.com/questions/4015557
复制相似问题