我有一个带有自定义单元格的UITableView,一开始都是空的。
我的UITableViewCell有一个UITextView,当我点击屏幕时,我创建了一个新的单元格,然后点亮它:
#import "MemoViewController.h"
#import "MemoViewCell.h"
#import "MemoModel.h"
static NSString *CellIdentifier = @"MemoCell";
@interface MemoViewController () <UITextViewDelegate>
@property (nonatomic, strong) MemoModel *model;
@property (nonatomic, strong) NSMutableDictionary *offscreenCells;
@end
@implementation MemoViewController
{
NSIndexPath *currentIndexPath;
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
self.model = [[MemoModel alloc] init];
//[self.model populateDataSource];
self.offscreenCells = [NSMutableDictionary dictionary];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[MemoViewCell class] forCellReuseIdentifier:CellIdentifier];
self.tableView.rowHeight = UITableViewAutomaticDimension;
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(insertNewRow:)];
gestureRecognizer.cancelsTouchesInView = NO;
[self.tableView addGestureRecognizer:gestureRecognizer];
currentIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
UIBarButtonItem *editButton = [[UIBarButtonItem alloc]
initWithTitle:@"Modifica"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(editButtonPressed:)];
self.navigationItem.rightBarButtonItem = editButton;
}
-(IBAction)editButtonPressed:(UIBarButtonItem *)sender
{
if ([sender.title isEqualToString:@"Fine"]) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[self.model.dataSource count] - 1 inSection:0];
MemoViewCell *cell = (MemoViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
[cell.bodyLabel resignFirstResponder];
}
}
-(void)insertNewRow:(UIGestureRecognizer *)gestureRecognizer
{
CGPoint point = [gestureRecognizer locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:point];
if (indexPath == nil) {
[self.model addObject];
[self.tableView reloadData];
indexPath = [NSIndexPath indexPathForRow:[self.model rowsCount] - 1 inSection:0];
}
[self.navigationItem.rightBarButtonItem setTitle:@"Fine"];
MemoViewCell *cell = (MemoViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
[cell.bodyLabel becomeFirstResponder];
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contentSizeCategoryChanged:) name:UIContentSizeCategoryDidChangeNotification object:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(void)contentSizeCategoryChanged:(NSNotification *)notification
{
[self.tableView reloadData];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.model.dataSource count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MemoViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if ([self.model.dataSource count] > 0) {
NSDictionary *dataSourceItem = [self.model.dataSource objectAtIndex:indexPath.row];
cell.bodyLabel.text = [dataSourceItem valueForKey:@"body"];
}
cell.bodyLabel.delegate = self;
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *reuserIdentifier = CellIdentifier;
if ([self.model.dataSource count] > 0) {
MemoViewCell *cell = [self.offscreenCells objectForKey:reuserIdentifier];
if (!cell) {
cell = [[MemoViewCell alloc] init];
[self.offscreenCells setObject:cell forKeyedSubscript:reuserIdentifier];
}
[cell updateFonts];
NSDictionary *dataSourceItem = [self.model.dataSource objectAtIndex:indexPath.row];
cell.bodyLabel.text = [dataSourceItem valueForKey:@"body"];
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(tableView.bounds), CGRectGetHeight(cell.bounds));
[cell setNeedsLayout];
[cell layoutIfNeeded];
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
height += 1;
CGFloat toReturn = height + [self measureHeightOfUITextView:cell.bodyLabel] - 30;
NSLog(@"Height for Row %li is %f", (long)indexPath.row, toReturn);
return toReturn;
} else {
return 44.0;
}
}
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 44.0;
}
/*
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MemoViewCell *cell = (MemoViewCell *)[tableView cellForRowAtIndexPath:indexPath];
cell.bodyLabel.userInteractionEnabled = YES;
[cell.bodyLabel becomeFirstResponder];
}
*/
#pragma mark - Text View Delegate
- (void)textViewDidBeginEditing:(UITextView*)textView
{
MemoViewCell* cell = (MemoViewCell *)[self parentCellFor:textView];
if (cell)
{
NSIndexPath* indexPath = [self.tableView indexPathForCell:cell];
currentIndexPath = indexPath;
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
}
/*
-(BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
MemoViewCell *cell = (MemoViewCell *)[self.tableView cellForRowAtIndexPath:currentIndexPath];
[cell.bodyLabel becomeFirstResponder];
[self.tableView selectRowAtIndexPath:currentIndexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
return YES;
}
*/
- (UITableViewCell*)parentCellFor:(UIView*)view
{
if (!view)
return nil;
if ([view isMemberOfClass:[MemoViewCell class]])
return (UITableViewCell*)view;
return [self parentCellFor:view.superview];
}
-(void)textViewDidChange:(UITextView *)textView
{
NSMutableDictionary *dataSourceItem = [self.model.dataSource objectAtIndex:currentIndexPath.row];
[dataSourceItem setObject:textView.text forKey:@"body"];
[self.model.dataSource replaceObjectAtIndex:currentIndexPath.row withObject:dataSourceItem];
if ([textView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height != textView.frame.size.height) {
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
}
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
return YES;
}
- (CGFloat)measureHeightOfUITextView:(UITextView *)textView
{
if ([textView respondsToSelector:@selector(snapshotViewAfterScreenUpdates:)])
{
CGRect frame = textView.bounds;
UIEdgeInsets textContainerInsets = textView.textContainerInset;
UIEdgeInsets contentInsets = textView.contentInset;
CGFloat leftRightPadding = textContainerInsets.left + textContainerInsets.right + textView.textContainer.lineFragmentPadding * 2 + contentInsets.left + contentInsets.right;
CGFloat topBottomPadding = textContainerInsets.top + textContainerInsets.bottom + contentInsets.top + contentInsets.bottom;
frame.size.width -= leftRightPadding;
frame.size.height -= topBottomPadding;
NSString *textToMeasure = textView.text;
if ([textToMeasure hasSuffix:@"\n"])
{
textToMeasure = [NSString stringWithFormat:@"%@-", textView.text];
}
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping];
NSDictionary *attributes = @{ NSFontAttributeName: textView.font, NSParagraphStyleAttributeName : paragraphStyle };
CGRect size = [textToMeasure boundingRectWithSize:CGSizeMake(CGRectGetWidth(frame), MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil];
CGFloat measuredHeight = ceilf(CGRectGetHeight(size) + topBottomPadding);
return measuredHeight;
}
else
{
return textView.contentSize.height;
}
}
@end
使用此代码(insertNewRow :)我首先在dataModel上创建一个新对象,我重新加载数据以设置所有表,然后我将第一个响应者设置为我最后添加的UITextView。
在textViewDidChange上:委托我更新表以将行展开到UITextViewContent。
如果我至少有2行,那么一切正常。如果我只有一行,则所有行都采用相同的宽度。
答案 0 :(得分:0)
如果你的细胞高度是固定的,那么只需使用此方法返回。
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
但是如果您的单元格的高度是动态的,那么您需要进行一些计算,然后返回单元格的正确高度。