boost la altura de la celda de visualización adecuada aumentando simultáneamente la UITextView interna

Creo un UITableView con diferentes types de UITableViewCell según el tipo de contenido que se muestre. Una de estas es una UITableViewCell con dentro de un UITextView programáticamente creado de esta manera:

  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ... if([current_field.tipo_campo isEqualToString:@"text_area"]) { NSString *string = current_field.valore; CGSize stringSize = [string sizeWithFont:[UIFont boldSystemFontOfSize:15] constrainedToSize:CGSizeMake(320, 9999) lineBreakMode:UILineBreakModeWordWrap]; CGFloat height = ([string isEqualToString:@""]) ? 30.0f : stringSize.height+10; UITextView *textV=[[UITextView alloc] initWithFrame:CGRectMake(5, 5, 290, height)]; textV.font = [UIFont systemFontOfSize:15.0]; textV.text = string; textV.autoresizingMask = UIViewAutoresizingFlexibleWidth; textV.textColor=[UIColor blackColor]; textV.delegate = self; textV.tag = indexPath.section; [cell.contentView addSubview:textV]; [textV release]; return cell; } ... } 

Esta vista de text se puede editar para que la celda que lo contiene y el mismo TextView se networkingimensionen. Inicialmente hago esto TextView el tamaño del TextView en el método textViewDidChange :, de esta manera:

 - (void)textViewDidChange:(UITextView *)textView { NSInteger index = textView.tag; Field* field = (Field*)[[self sortFields] objectAtIndex:index]; field.valore = textView.text; [self.tableView beginUpdates]; CGRect frame = textView.frame; frame.size.height = textView.contentSize.height; textView.frame = frame; newHeight = textView.contentSize.height; [self.tableView endUpdates]; } 

tableView:heightForRowAtIndexPath la nueva altura de la vista de text en una variable y cuando tableView:heightForRowAtIndexPath : method is call, cambie el tamaño de la celda de esta manera:

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { ... if ([current_field.tipo_campo isEqualToString:@"text_area"]) { return newHeight +10.0f; } else return 44.0f; ... } 

De esta manera, ambos se cambian de tamaño, pero no se realiza en synchronization, es decir, primero se cambia el tamaño de TextView y luego se cambia el tamaño de la altura de la celda, lo que hace que un instante vea que la vista de text es más grande que la celda. ¿Cómo puedo arreglar esto?

He creado una demostración para su problema, la esperanza lo ayudará.

Mi idea de solución es usar AutoResizingMask de UITextView .

Mi file .h

 #import <UIKit/UIKit.h> @interface ViewController : UIViewController<UITabBarDelegate, UITableViewDataSource, UITextViewDelegate>{ IBOutlet UITableView *tlbView; float height; } @end 

Y mi file .m (Incluye solo los methods requeridos)

 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. height = 44.0; } - (void)textViewDidChange:(UITextView *)textView{ [tlbView beginUpdates]; height = textView.contentSize.height; [tlbView endUpdates]; } #pragma mark - TableView datasource & delegates - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return 1; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ if (indexPath.row==0) { if (height>44.0) { return height + 4.0; } } return 44.0; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CellIdentifier"]; UITextView *txtView = [[UITextView alloc] initWithFrame:CGRectMake(0.0, 2.0, 320.0, 40.0)]; [txtView setDelegate:self]; [txtView setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight]; // It will automatically resize TextView as cell resizes. txtView.backgroundColor = [UIColor yellowColor]; // Just because it is my favourite [cell.contentView addSubview:txtView]; return cell; } 

Espero que te ayude.

Para cambiar el tamaño de las celdas, usaría un código similar a este

 - (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 CGRect frame = textView.frame; frame.size.height = textView.contentSize.height; textView.frame = frame; if ((NSInteger)size.height != (NSInteger)[self tableView:nil heightForRowAtIndexPath:nil]) { // if new size is different to old size resize cells. [self.tableView beginUpdates]; [self.tableView endUpdates]; } return YES; } 

Establezca el marco TextView con una animation … así que se sincroniza con la animation de la celda de la altura de expansión

Comtesting esto: UIView Contentmode – juega con los valores como:

 cell.contentMode = //...// 
 - (void)textViewDidChange:(UITextView *)textView { UITableViewCell *cell = (UITableViewCell*)textView.superview.superview; if (cell.frame.size.height < textView.contentSize.height) { [self.tableView beginUpdates]; CGRect frame = textView.frame; frame.size.height = textView.contentSize.height; textView.frame = frame; CGRect cellFrame = cell.frame; cellFrame.size.height = textView.frame.size.height; cell.frame = cellFrame; [self.tableView endUpdates]; } } 

El código de Siba Prasad Hota probablemente hará el truco (necesita reference a la vista de tabla desde el nivel de celda), pero tengo otro enfoque más largo. Siempre hago este tipo de cosas de esta manera, porque me gusta tener todas las cosas separadas (patrón MVC). Si yo fuera usted, haría esto así (código de la cabeza):

Protocolo padre celular:

 @protocol CellParent <NSObject> @requinetworking @property (nonatomic, strong) UITableView *tableView; @end 

Modelo celular:

 @interface CellModel @property (nonatomic, assign) BOOL hasTextView; @property (nonatomic, strong) NSString *textViewContent; -(float)getCurrentHeightForCell;//implement calculating current height of cell. probably 2 * SOME_MARGIN + height of temporary textView with textViewContent variable 

Celda

 @interface MyCell @property (nonatomic, strong) CellModel *dataModel; @property (nonatomic, weak) id<CellParent> parent; @property (nonatomic, strong) UITextView *textView; - (id)initWithStyle:(UITableViewCellStyle)style andModel:(CellModel*) model; 

con implementaciones como esta:

 (id)initWithStyle:(UITableViewCellStyle)style andModel:(CellModel*) model { self = [super initWithStyle:style reuseIdentifier:@"MyCell"]; if (self) { [[NSBundle mainBundle] loadNibNamed:@"MyCell" owner:self options:nil]; self.dataModel = model; } return self; } -(void) setDataModel:(CellModel *)dataModel { _dataModel = dataModel; if(_dataModel.hasTextView) { //show text view } else { //hide text view } //do other cell modifications } -(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { self.dataModel.textViewContent = textView.text; [self.parent.tableView beginUpdates]; [self.parent.tableView endUpdates]; return YES; } 

Controlador con vista de tabla

 -(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { MyCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"]; if (cell == nil) { cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault andModel: [self.cellsModels objectAtIndex:indexPath.row]]; } cell.dataModel = [self.cellsModels objectAtIndex:indexPath.row]; cell.parent = self; return cell; } -(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return [((CellModel*)[self.tableContentArray objectAtIndex:indexPath.row]) getCurrentHeightForCell]; } 

Debe calcular newHeight para la celda antes de cargar la celda. En lugar de calcular newHeight en textViewDidChange, cómprelo en heightForRowAtIndexPath y devuelva lo mismo que

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if ([current_field.tipo_campo isEqualToString:@"text_area"]) { NSString *string = current_field.valore; CGSize stringSize = [string sizeWithFont:[UIFont boldSystemFontOfSize:15] constrainedToSize:CGSizeMake(320, 9999) lineBreakMode:UILineBreakModeWordWrap]; CGFloat height = ([string isEqualToString:@""]) ? 30.0f : stringSize.height+10; return height + 10.0f; } else { return 44.0f; } } 

No me molestaría con la altura de las celdas usando el método

 (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 

y más bien hizo su delegado de campo de text de vista y gestiona el siguiente evento de la manera que se muestra a continuación:

 - (void) textFieldDidResize:(id)sender { [self.tableView beginUpdates]; [self.tableView endUpdates]; } 

También asegúrese de que hizo lo siguiente:

 yourInputField.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 

Entonces, lo único que necesita es cambiar el tamaño del campo de text. Sus celdas en tableview adoptarán el tamaño del campo de text interno. Simplemente agréguelo como subview a cell.contentView.