我制作了一个类似 imessage 的视图,只需在底部文本视图中输入文本。我使用表格视图来执行此操作,并使用最后一个单元格中的文本视图。当我输入超过一行的长文本时,我需要文本视图并且单元格变得更细。所以我需要刷新单元格的高度。但是如果我使用表格视图的重新加载或重新加载行,文本视图中的内容会消失,键盘也会消失。有没有更好的方法来修复它?
可能我应该使用工具栏来简单吗?但我仍然怀疑表格视图可以做到这一点。
当您调用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];
我编写了 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 以确保它开始最小化。
看看这个库。这是使用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;
}
表格视图单元格不会平滑地调整大小。点。
但是,由于您的文本视图位于最后一个单元格中,因此您很幸运,因为您可以轻松模拟行大小调整。在表格中间有一个文本视图会困难得多。
我会这样做:将您的文本视图放在表格视图的顶部。将其位置与 scrollViewDidScroll: 中 tableView 的 contentOffset 同步。并使用 tableView 的动画 contentInset 以便为 textView 留出空间,因为用户在其中键入。您可能必须确保您的 textView 不可滚动。