Изменение размера пользовательского UITableViewCell и его подвидов

Я создал Custom UITableViewCell с использованием файла XIB и заставил его работать в UITableView. Я разработал пользовательскую ячейку и ее подвиды в портретных размерах, но когда я поворачиваю устройство в ландшафтном режиме, я хочу изменить размер ячейки и ее подвидов. Я написал для этого следующий код, но не уверен, почему только одна ячейка в видимых ячейках изменяется, а остальные остаются прежними! Может ли кто-нибудь помочь мне со стандартной практикой изменения размера пользовательской ячейки и их подвидов? Спасибо.

#pragma mark - UITableView delegate methods

- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"CustomTableViewCellIdentifier";
    CustomTableViewCell *cell = (CustomTableViewCell*)[tv dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        // Load custom cell from NIB
        self.customTableViewCell = [[[NSBundle mainBundle] loadNibNamed:@"CustomTableViewCell" owner:self options:nil] objectAtIndex:0];
        cell = _customTableViewCell;
    }
    // Use cell
    ...
}

#pragma mark - Layout views

- (void)layoutForOrientation:(UIInterfaceOrientation)orientation {
    if (UIInterfaceOrientationIsPortrait(orientation))
        [self layoutPortraitViews];
    else
        [self layoutLandscapViews];
}

- (void)layoutLandscapViews {
    self.customTableViewCell.frame = CGRectMake(0, 0, 1024, 40);
    self.customTableViewCell.contentSize = CGSizeMake(1024, 40);
    self.customTableViewCell.cellBackgroundImageView.frame = CGRectMake(0, 0, 1024, 40);
    self.customTableViewCell.assetNameLabel.frame = CGRectMake(15, 0, 245, 20);
    self.customTableViewCell.assetTypeLabel.frame = CGRectMake(15, 20, 245, 20);
    self.customTableViewCell.assetImageView.frame = CGRectMake(265, 20, 120, 20);
    self.customTableViewCell.assetValueLabel.frame = CGRectMake(265, 20, 120, 20);

    [self.tableView reloadData];
}

- (void)layoutPortraitViews {
    self.customTableViewCell.frame = CGRectMake(0, 0, 768, 40);
    self.customTableViewCell.contentSize = CGSizeMake(768, 40);
    self.customTableViewCell.cellBackgroundImageView.frame = CGRectMake(0, 0, 768, 40);
    self.customTableViewCell.assetNameLabel.frame = CGRectMake(15, 0, 180, 20);
    self.customTableViewCell.assetTypeLabel.frame = CGRectMake(15, 20, 180, 20);
    self.customTableViewCell.assetImageView.frame = CGRectMake(200, 20, 90, 20);
    self.customTableViewCell.assetValueLabel.frame = CGRectMake(200, 20, 90, 20);

    [self.tableView reloadData];
}

[РЕШЕНИЕ]

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

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

Я создал два вида ячеек в NIB, один для портрета, а другой для ландшафта.

Используются две переменные;

BOOL refreshing;
UIInterfaceOrientation currentOrientation;

Из поля зрения появится;

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    currentOrientation = [UIApplication sharedApplication].statusBarOrientation;
    [self layoutForOrientation:[UIApplication sharedApplication].statusBarOrientation];
}

От делегатов ротации;

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    refreshing = YES;
    currentOrientation = toInterfaceOrientation;
    [UIView animateWithDuration:duration animations:^{
        [self.tableView reloadData];
        [self layoutForOrientation:toInterfaceOrientation];
    }];
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    refreshing = NO;
}

От делегата tableview;

- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"CustomTableViewCellIdentifier";
    CustomTableViewCell *cell = (CustomTableViewCell*)[tv dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil || refreshing)
     {
        if (UIInterfaceOrientationIsPortrait(currentOrientation))
            cell = [[[NSBundle mainBundle] loadNibNamed:@"CustomTableViewCell" owner:self options:nil] objectAtIndex:0];
         else 
            cell = [[[NSBundle mainBundle] loadNibNamed:@"CustomTableViewCell" owner:self options:nil] objectAtIndex:1];
    }

    //Use cell
}

... поэтому это решение будет перезагружать ячейки только тогда, когда произойдет событие изменения ориентации. Удачного кодирования :-)


person AlienMonkeyCoder    schedule 02.11.2012    source источник


Ответы (3)


Изменение размера пользовательской ячейки xib NIB может обеспечить или не обеспечить желаемый пользовательский интерфейс при вращении. Чтобы упростить задачу. Создайте два наконечника UITableViewCell.

 if (!cell) {
            if(UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) {
                [[NSBundle mainBundle] loadNibNamed:@"CustomTableViewCell-Landscape" owner:self options:nil];
            }else {
                [[NSBundle mainBundle] loadNibNamed:@"CustomTableViewCell" owner:self options:nil];
     }
}

Дальнейший вызов [tableView reloadData]; при изменении ориентации

person AppleDelegate    schedule 02.11.2012
comment
Я думал об этом, но должен быть способ заставить мой код работать. Я думаю, что происходит после того, как вкладка с загруженным наконечником ячейки продолжает использовать то же самое, даже после того, как я программно изменил размеры. Если я назначу self. customTableViewCell непосредственно в ячейку без удаления из очереди, тогда у меня есть только одна ячейка в uitableview со странным миганием между другими ячейками .... так раздражает! - person AlienMonkeyCoder; 02.11.2012
comment
Кстати, reloadingData не перезагружает ячейки, просто изменяются данные, а не графический интерфейс! - person AlienMonkeyCoder; 02.11.2012
comment
Принятие вашего ответа, поскольку это было ближе всего к тому, что я сделал. Спасибо. :-) - person AlienMonkeyCoder; 02.11.2012

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

person quarac    schedule 02.11.2012
comment
Не может быть! Вы можете использовать автоматическую компоновку и автоматическое изменение размера только тогда, когда вам не нужен фиксированный размер и положение элементов управления, но я очень внимательно отношусь к этим значениям. - person AlienMonkeyCoder; 02.11.2012
comment
Хорошо, ребята, как насчет перезаписи layoutSubviews внутри вашего класса CustomTableViewCell? - person quarac; 02.11.2012

Потому что вы self.customTableViewCell мгновенно перезаписываете все время. поэтому он возвращает только последний объект.

вы должны написать ниже код, чтобы изменить размер всех UITableViewCells

for(UITableViewCell *cell in self.tableView.visibleCells)
{
     if([cell isKindOfClass:[UITableViewCell class]])
     {
          cell.frame = CGRectMake(0, 0, 1024, 40);
          cell.contentSize = CGSizeMake(1024, 40);
          cell.cellBackgroundImageView.frame = CGRectMake(0, 0, 1024, 40);
          cell.assetNameLabel.frame = CGRectMake(15, 0, 245, 20);
          cell.assetTypeLabel.frame = CGRectMake(15, 20, 245, 20);
          cell.assetImageView.frame = CGRectMake(265, 20, 120, 20);
          cell.assetValueLabel.frame = CGRectMake(265, 20, 120, 20);
     }
}
person Romit M.    schedule 02.11.2012
comment
Я надеюсь, что это так просто! Я меняю свойства self.customTableViewCell при изменении ориентации, что совершенно правильно, но UITableView не использует измененные свойства ячейки, это проблема. Если я попрошу tabview принудительно использовать измененную ячейку в cellForRowAtIndexPath - cell = _customTableViewCell; (без ячейки регистрации == ноль), то это создает странные проблемы! - person AlienMonkeyCoder; 02.11.2012
comment
вам не нужно создавать свойство для customTableViewCell. создать объект ячейки локально, что намного лучше реализовать. если вы не будете проверять (cell == nil), ваше приложение может выйти из строя через некоторое время. - person Romit M.; 02.11.2012
comment
Хм, это имеет смысл! Я внес эти изменения, но они не работают! Должно быть что-то делать с уже загруженной ячейкой NIB! Я должен выгрузить его и принудительно использовать модифицированную ячейку. - person AlienMonkeyCoder; 02.11.2012
comment
Привет, Ромит, кажется, это работает, но размер всех ячеек не изменяется! Я бы сказал, что он изменяет размер только половины ячеек! Любые идеи, почему это происходит? - person AlienMonkeyCoder; 02.11.2012