我创建了一个像imessage的视图,只需在底部文本视图中输入文本。我使用表视图来执行此操作,并使用最后一个单元格中的文本视图。当我输入多行的长文本时,我需要文本视图,单元格变成了尾部。所以我需要刷新单元格的高度。但如果我使用表视图的重新加载或重新加载行,文本视图中的内容将消失,键盘也将消失。有没有更好的方法来解决它?
可能我应该使用工具栏轻松完成吗?但我仍然怀疑桌面视图可以做到。
答案 0 :(得分:67)
当您致电beginUpdates
和endUpdates
时,小组会顺利调整大小。在这些调用之后,tableView将为表中的所有单元格发送tableView:heightForRowAtIndexPath:
,当tableView获得所有单元格的所有高度时,它将为调整大小设置动画。
您可以通过直接设置单元格的属性来更新单元格而无需重新加载它们。无需涉及tableView和tableView:cellForRowAtIndexPath:
要调整单元格的大小,您可以使用与此类似的代码
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
NSString *newText = [textView.text stringByReplacingCharactersInRange:range withString:text];
CGSize size = // calculate size of new text
if ((NSInteger)size.height != (NSInteger)[self tableView:nil heightForRowAtIndexPath:nil]) {
// if new size is different to old size resize cells.
// since beginUpdate/endUpdates calls tableView:heightForRowAtIndexPath: for all cells in the table this should only be done when really necessary.
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
return YES;
}
在不重新加载的情况下更改单元格的内容我使用以下内容:
- (void)configureCell:(FancyCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
MyFancyObject *object = ...
cell.textView.text = object.text;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FancyCell *cell = (FancyCell *)[tableView dequeueReusableCellWithIdentifier:@"CellWithTextView"];
[self configureCell:cell forRowAtIndexPath:indexPath];
return cell;
}
// whenever you want to change the cell content use something like this:
NSIndexPath *indexPath = ...
FancyCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
[self configureCell:cell forRowAtIndexPath:indexPath];
答案 1 :(得分:2)
我编写了一个UITableViewCell的子类来处理这个功能。
.h文件:
#import <UIKit/UIKit.h>
@protocol AECELLSizeableDelegate;
@interface AECELLSizeable : UITableViewCell
@property (weak, nonatomic) id <AECELLSizeableDelegate> delegate;
@property IBOutlet UIView *viewMinimized;
@property IBOutlet UIView *viewMaximized;
@property BOOL maximized;
@property CGFloat height;
- (IBAction)clickedConfirm:(id)sender;
- (IBAction)clickedCancel:(id)sender;
- (void)minimizeForTableview: (UITableView*)tableView;
- (void)maximizeForTableview: (UITableView*)tableView;
- (void)toggleForTableview: (UITableView*)tableView;
@end
@protocol AECELLSizeableDelegate <NSObject>
- (void)sizeableCellConfirmedForCell: (AECELLSizeable*)cell;
- (void)sizeableCellCancelledForCell: (AECELLSizeable*)cell;
@end
.m文件:
#import "AECELLSizeable.h"
@implementation AECELLSizeable
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)minimizeForTableview: (UITableView*)tableView
{
self.maximized = NO;
[self.viewMinimized setHidden:NO];
[self.viewMaximized setHidden:YES];
self.height = self.viewMinimized.frame.size.height;
[tableView beginUpdates];
[tableView endUpdates];
}
- (void)maximizeForTableview: (UITableView*)tableView
{
self.maximized = YES;
[self.viewMinimized setHidden:YES];
[self.viewMaximized setHidden:NO];
self.height = self.viewMaximized.frame.size.height;
[tableView beginUpdates];
[tableView endUpdates];
}
- (void)toggleForTableview:(UITableView *)tableView
{
if (self.maximized) {
[self minimizeForTableview:tableView];
} else {
[self maximizeForTableview:tableView];
}
}
- (void)clickedConfirm:(id)sender
{
[self.delegate sizeableCellConfirmedForCell:self];
}
- (void)clickedCancel:(id)sender
{
[self.delegate sizeableCellCancelledForCell:self];
}
@end
示例用法:
在tableview控制器的实现文件中定义tableview的heightForRowAtIndexPath回调方法,如下所示:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
//Sizeable Cell
return self.cellSizeable.height;
} else {
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
}
在tableview控制器的viewDidLoad方法中,调用单元格中的minimizeForTableview以确保它从最小化开始。
答案 2 :(得分:-1)
结帐this library。这是使用UITableView
的消息气泡的实现。请记住,每次显示一个单元格时,都会调用cellForRow:atIndexPath
并绘制单元格。
修改强>
您可以使用heightForRowAtIndexPath
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
Messages *message = [self.messageList objectAtIndex:[indexPath row]];
CGSize stringSize = [message.text sizeWithFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:13]
constrainedToSize:CGSizeMake(320, 9999) lineBreakMode:UILineBreakModeWordWrap];
return stringSize.height + 78;
}
答案 3 :(得分:-3)
表视图单元格不会平滑调整大小。点。
但是,由于您的文本视图位于最后一个单元格中,因此您很幸运,因为您可以轻松地模拟行调整大小。在表格中间有一个文本视图将会困难得多。
我将如何操作:将文本视图放在表格视图的顶部。将其位置与scrollViewDidScroll:中tableView的contentOffset同步。并使用tableView的动画contentInset,以便为用户输入textView留出空间。您可能必须确保textView不可滚动。