Изменение высоты UITableView динамически

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

Add-на:

У меня в основном есть UserProfileViewController, который имеет скрытый вид на половине экрана. Там я добавляю другие другие контроллеры view:

enter image description here

enter image description here

В случае кнопки на стене это так, как я добавляю viewcontroller и последующее представление таблицы:

- (IBAction)wallButtonPressed:(id)sender
{
    //Check if there is an instance of the viewcontroller we want to display. If not make one and set it tableview frame to the container view bounds
    if(!_userWallViewController) {
        self.userWallViewController = [[WallViewController alloc] init];
//        self.userWallViewController.activityFeedTableView.frame = self.containerView.bounds;

    }

    [self.userWallViewController.containerView addSubview:self.userWallViewController.activityFeedTableView];
    //If the currentviewcontroller adn it view are already added to the hierarchy remove them
    [self.currentViewController.view removeFromSuperview];
    [self.currentViewController removeFromParentViewController];

    //Add the desired viewcontroller to the currentviewcontroller
    self.currentViewController = self.userWallViewController;

    //Pass the data needed for the desired viewcontroller to it instances
    self.userWallViewController.searchURLString = [NSString stringWithFormat:@"event/user/%@/", self.userID];
    self.userWallViewController.sendCommentURLString = [NSString stringWithFormat:@"event/message/%@", self.userID];

    [self.userWallViewController.activityFeedTableView reloadData];

    self.userWallViewController.totalCellHeight = ^(float totalCellHeight){

        self.scrollView.contentSize = CGSizeMake(320.0, totalCellHeight);
        CGRect newFrame = self.userWallViewController.containerView.frame;
        newFrame.size.height = totalCellHeight + 33.0;
        self.userWallViewController.containerView.frame = newFrame;

        self.userWallViewController.activityFeedTableView.frame = self.containerView.bounds;
    };

    //Add this containerview to the desired viewcontroller containerView
    self.userWallViewController.containerView = self.containerView;


    //Add the needed viewcontroller and view to the parent viewcontroller and the containerview
    [self addChildViewController:self.userWallViewController];
    [self.containerView addSubview:self.userWallViewController.view];

    //CLEAN UP THE CONTAINER VIEW BY REMOVING THE PREVIOUS ADDED TABLE VIEWS
    [self.userFansViewController.userSimpleTableView removeFromSuperview];
    [self.fanOfViewController.userSimpleTableView removeFromSuperview];
    [self.userPublishedMovellaListViewController.gridView removeFromSuperview];

    [self.userPublishedMovellaListViewController removeFromParentViewController];

    self.userPublishedMovellaListViewController = nil;
}

и в этом viewcontroller это где я инициализирую мой tableview:

-(UITableView *)activityFeedTableView
{
    if (!_activityFeedTableView) {
        _activityFeedTableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 850.0) style:UITableViewStylePlain];
    }
    return _activityFeedTableView;
}

Я вычисляю его общую сумму высоты ячейки, проблема заключается в том, что метод высоты ячейки называется способом после вызова getthe te tableview. Поэтому мне понадобится какой-то способ узнать, когда метод высоты ячеек выполняется для всех ячеек, а затем я могу изменить размер таблицы. Благодаря

Ответ 1

Нет системной функции для изменения высоты таблицы на основе содержимого таблицы. Сказав это, можно программно изменить высоту табличного представления на основе содержимого, в частности, на основе contentSize таблицы (что проще, чем вручную вычислять высоту самостоятельно). Некоторые из деталей различаются в зависимости от того, используете ли вы новую автозапуск этой части iOS 6 или нет.

Но если вы хотите настроить базовую модель табличного представления в viewDidLoad, если вы хотите затем отрегулировать высоту таблицы, вы можете сделать это в viewDidAppear:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [self adjustHeightOfTableview];
}

Аналогично, если вы когда-либо выполняете reloadData (или иначе добавляете или удаляете строки) для представления таблицы, вы должны также убедиться, что вы также вручную вызываете adjustHeightOfTableView, например:

- (IBAction)onPressButton:(id)sender
{
    [self buildModel];
    [self.tableView reloadData];

    [self adjustHeightOfTableview];
}

Итак, вопрос заключается в том, что должны делать наши adjustHeightOfTableView. К сожалению, это зависит от того, используете ли вы автозапуск iOS 6 или нет. Вы можете определить, включен ли автозапуск, открыв раскадровку или NIB и перейдите в "Инспектор файлов" (например, нажмите option + command + 1 или щелкните по этой первой вкладке на панели справа)

enter image description here

Предположим на секунду, что автозапуск отключен. В этом случае это довольно просто, и adjustHeightOfTableView просто отрегулирует frame таблицы:

- (void)adjustHeightOfTableview
{
    CGFloat height = self.tableView.contentSize.height;
    CGFloat maxHeight = self.tableView.superview.frame.size.height - self.tableView.frame.origin.y;

    // if the height of the content is greater than the maxHeight of
    // total space on the screen, limit the height to the size of the
    // superview.

    if (height > maxHeight)
        height = maxHeight;

    // now set the frame accordingly

    [UIView animateWithDuration:0.25 animations:^{
        CGRect frame = self.tableView.frame;
        frame.size.height = height;
        self.tableView.frame = frame;

        // if you have other controls that should be resized/moved to accommodate
        // the resized tableview, do that here, too
    }];
}

Если ваш автозапуск был включен, adjustHeightOfTableView будет настраивать ограничение высоты для вашего табличного представления:

- (void)adjustHeightOfTableview
{
    CGFloat height = self.tableView.contentSize.height;
    CGFloat maxHeight = self.tableView.superview.frame.size.height - self.tableView.frame.origin.y;

    // if the height of the content is greater than the maxHeight of
    // total space on the screen, limit the height to the size of the
    // superview.

    if (height > maxHeight)
        height = maxHeight;

    // now set the height constraint accordingly

    [UIView animateWithDuration:0.25 animations:^{
        self.tableViewHeightConstraint.constant = height;
        [self.view setNeedsUpdateConstraints];
    }];
}

Для этого последнего решения на основе ограничений для работы с автозапуском мы должны сначала позаботиться о нескольких вещах:

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

    add height constraint

  • Затем добавьте IBOutlet для этого ограничения:

    add IBOutlet

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

    adjust other constraints

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

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

Ответ 2

создайте свою ячейку по xib или раскадровке. дайте ему содержимое на выходе. теперь вызовите его в CellForRowAtIndexPath.  например. если вы хотите установить высоту ячейки в соответствии с текстом метки комментария. enter image description here

поэтому установите для вас комментарииLbl.numberOfLine = 0; enter image description here

поэтому установите для вас комментарииLbl.numberOfLine = 0;

затем в ViewDidLoad

 self.table.estimatedRowHeight = 44.0 ;
self.table.rowHeight = UITableViewAutomaticDimension;

и теперь

-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewAutomaticDimension;}

Ответ 3

Это может быть упрощено с помощью всего лишь 1 строки кода в представленииDidAppear:

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        tableViewHeightConstraint.constant = tableView.contentSize.height
    }

Ответ 4

Решение Rob очень приятно, единственное, что в его методе -(void)adjustHeightOfTableview вызывает

[self.view needsUpdateConstraints]

ничего не делает, он просто возвращает флаг, вместо этого вызывающий

[self.view setNeedsUpdateConstraints]

сделает желаемый эффект.

Ответ 5

Используйте простой и удобный код

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        let myCell = tableView.dequeueReusableCellWithIdentifier("mannaCustumCell") as! CustomCell
        let heightForCell = myCell.bounds.size.height;

        return heightForCell;
    }

Ответ 6

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

class UIDynamicTableView: UITableView
{
    override var intrinsicContentSize: CGSize {
        self.layoutIfNeeded()
        return CGSize(width: UIViewNoIntrinsicMetric, height: self.contentSize.height)
    }

    override func reloadData() {
        super.reloadData()
        self.invalidateIntrinsicContentSize()
    }
} 

Установите класс TableView в UIDynamicTableView в построителе интерфейса и просмотрите волшебство, поскольку этот TableView изменит его размер после вызова reloadData().

Ответ 7

для изменения размера таблицы. Я пошел с этим решением в моем контроллере tableview. Это прекрасно.

[objectManager getObjectsAtPath:self.searchURLString
                         parameters:nil
                            success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
                                NSArray* results = [mappingResult array];
                                self.eventArray = results;
                                NSLog(@"Events number at first: %i", [self.eventArray count]);
                                CGRect newFrame = self.activityFeedTableView.frame;
                                newFrame.size.height = self.cellsHeight + 30.0;
                                self.activityFeedTableView.frame = newFrame;

                                self.cellsHeight = 0.0;

                            }
                            failure:^(RKObjectRequestOperation *operation, NSError *error) {
                                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
                                                                                message:[error localizedDescription]
                                                                               delegate:nil
                                                                      cancelButtonTitle:@"OK"
                                                                      otherButtonTitles:nil];
                                [alert show];
                                NSLog(@"Hit error: %@", error);
                            }];

Часть изменения размера находится в методе, но здесь вы просто видите это. Теперь единственная проблема, с которой я столкнулся, изменяет размер прокрутки в другом контроллере представления, поскольку я понятия не имею, когда tableview закончил изменение размера. На данный момент я делаю это с помощью performSelector: afterDelay: но это действительно не очень хороший способ сделать это. Любые идеи?

Ответ 8

Я обнаружил, что добавление ограничений программно намного проще, чем в раскадровке.

    var leadingMargin = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.LeadingMargin, relatedBy: NSLayoutRelation.Equal, toItem: self.mView, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1, constant: 0.0)

    var trailingMargin = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.TrailingMargin, relatedBy: NSLayoutRelation.Equal, toItem: mView, attribute: NSLayoutAttribute.TrailingMargin, multiplier: 1, constant: 0.0)

    var height = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: screenSize.height - 55)

    var bottom = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.BottomMargin, relatedBy: NSLayoutRelation.Equal, toItem: self.mView, attribute: NSLayoutAttribute.BottomMargin, multiplier: 1, constant: screenSize.height - 200)

    var top = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.TopMargin, relatedBy: NSLayoutRelation.Equal, toItem: self.mView, attribute: NSLayoutAttribute.TopMargin, multiplier: 1, constant: 250)

    self.view.addConstraint(leadingMargin)
    self.view.addConstraint(trailingMargin)
    self.view.addConstraint(height)
    self.view.addConstraint(bottom)
    self.view.addConstraint(top)