Подтвердить что ты не робот

Есть ли способ обновить высоту ячейки без перезагрузки/перезагрузки?

Я делаю вид как imessage, просто ввод текста в нижний текстовый вид. Для этого я использую представление таблицы и текстовое представление в последней ячейке. когда я вводя длинный текст, который содержит более одной строки, мне нужен текстовый вид, а ячейка станет портной. поэтому мне нужно обновить высоту ячейки. но если я использую перезагрузку или перезагрузку таблицы, содержимое в текстовом представлении исчезнет, ​​и клавиатура тоже исчезнет. Есть ли способ лучше исправить это?

Может быть, я должен использовать панель инструментов, чтобы сделать это легко? но я все еще сомневаюсь, что это может сделать табличный вид.

4b9b3361

Ответ 1

Ячейки будут плавно изменяться, когда вы вызываете 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];

Ответ 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 file:

#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

Пример использования:

  • Создайте UITableViewController со статическим UITableView в IB
  • Добавить ячейку в представление таблицы, которое является AECELLSizeable (или подклассом)
  • Создайте два UIView в этой ячейке. Один UIView будет использоваться для видимого содержимого, если он сведен к минимуму, другой будет использоваться для видимого контента, пока он будет максимальным. Убедитесь, что эти ячейки начинаются с 0 по оси y и что их высота равна высоте, которую вы хотите иметь ячейку для каждого состояния.
  • Добавьте любые подзаголовки в эти два вида, которые вы хотели. При необходимости добавьте подтверждение и отмените UIButtons на максимальный UIView и подключите предоставленные IBActions для приема обратных вызовов делегатов в этих событиях.
  • Установите контроллер табличного представления в соответствие с AECELLSizeableDelegate и установите свойство делегата ячейки контроллеру таблицы.
  • Создайте IBOutlet в файле интерфейса UIViewController для ячейки AECELLSizeable.
  • Вернитесь в IB, убедитесь, что начальная высота ячейки соответствует минимальной версии и подключается только что созданный IBOutlet.
  • Определите метод обратного вызова heightForRowAtIndexPath tableview в файле реализации контроллера tableview как таковой:

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
      {
          if (indexPath.row == 0) {
              //Sizeable Cell
              return self.cellSizeable.height;
          } else {
              return [super tableView:tableView heightForRowAtIndexPath:indexPath];
          }
      }
    
  • В вашем методе viewDidLoad контроллера табличного вызова вызовите в своей ячейке minimForTableview, чтобы убедиться, что он начинает сбрасываться.

  • Затем вызовите функцию maximizeForTableview: в ячейке, когда она выбрана с помощью обратного вызова didSelectRowAtIndexPath из tableview (или, как бы то ни было, вы бы хотели его обработать), и вызовите метод minimForTableview: в ячейке, когда вы получите отмененный/подтвержденный делегат обратные вызовы из ячейки (или, опять же, как бы вы хотели ее обрабатывать).

Ответ 3

Отметьте эту библиотеку. Это реализация сообщений с использованием 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;
}

Ответ 4

Ячейки просмотра таблицы не будут плавно изменять размер. Dot.

Однако, поскольку ваше текстовое представление находится в последней ячейке, вам повезло, потому что вы можете легко имитировать изменение размера строки. Наличие текстового представления в середине таблицы было бы намного сложнее.

Вот как я это сделаю: поставьте свой текстовый вид поверх представления таблицы. Синхронизируйте свою позицию с содержимымОфис таблицы TableView в scrollViewDidScroll:. И используйте animatable contentInset таблицыView, чтобы оставить место для textView, поскольку пользователь вводит в него. Возможно, вам придется убедиться, что ваш текст не прокручивается.