Как изменить размер tableHeaderView UITableView? - PullRequest
98 голосов
/ 04 декабря 2008

У меня проблемы с изменением размера tableHeaderView. Это просто не работает.

1) Создание UITableView и UIView (100 x 320 px);

2) Установить UIView в качестве tableHeaderView UITableView;

3) Build and Go. Все в порядке.

Теперь я хочу изменить размер tableHeaderView, поэтому я добавляю этот код в viewDidLoad:

self.tableView.autoresizesSubviews = YES;

self.tableView.tableHeaderView = myHeaderView;
self.tableView.tableFooterView = myFooterView;

CGRect newFrame = self.tableView.tableHeaderView.frame;
newFrame.size.height = newFrame.size.height + 100;
self.tableView.tableHeaderView.frame = newFrame;

Высота tableHeaderView должна отображаться с 200, но отображается с 100.

Если я напишу:

self.tableView.autoresizesSubviews = YES;


CGRect newFrame = myHeaderView.frame;
newFrame.size.height = newFrame.size.height + 100;
myHeaderView.frame = newFrame;


self.tableView.tableHeaderView = myHeaderView;
self.tableView.tableFooterView = myFooterView;

Тогда начинается с 200, как я хочу. Но я хочу иметь возможность изменять его во время выполнения.

Я тоже пытался, но безуспешно:

self.tableView.autoresizesSubviews = YES;

self.tableView.tableHeaderView = myHeaderView;
self.tableView.tableFooterView = myFooterView;

CGRect newFrame = self.tableView.tableHeaderView.frame;
newFrame.size.height = newFrame.size.height + 100;
self.tableView.tableHeaderView.frame = newFrame;

[self.tableView.tableHeaderView setNeedsLayout];
[self.tableView.tableHeaderView setNeedsDisplay];
[self.tableView setNeedsLayout];
[self.tableView setNeedsDisplay];

Суть в следующем: Как мы изменяем размер tableHeaderView во время выполнения ???

Кто-нибудь мог это сделать?

Спасибо

IME

Ответы [ 18 ]

180 голосов
/ 09 февраля 2009

К вашему сведению: я заставил это работать, изменив tableHeaderView и заново установив его. В этом случае я настраиваю размер tableHeaderView после завершения загрузки подпредставления UIWebView.

[webView sizeToFit];
CGRect newFrame = headerView.frame;
newFrame.size.height = newFrame.size.height + webView.frame.size.height;
headerView.frame = newFrame;
[self.tableView setTableHeaderView:headerView];
12 голосов
/ 01 февраля 2010

Этот ответ старый и, по-видимому, не работает на iOS 7 и выше.

Я столкнулся с той же проблемой, и я также хотел, чтобы изменения были анимированы, поэтому я создал подкласс UIView для представления заголовка и добавил следующие методы:

- (void)adjustTableHeaderHeight:(NSUInteger)newHeight{
    NSUInteger oldHeight = self.frame.size.height;
    NSInteger originChange = oldHeight - newHeight;

    [UIView beginAnimations:nil context:nil];

    [UIView setAnimationDuration:1.0f];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];

    self.frame = CGRectMake(self.frame.origin.x, 
                        self.frame.origin.y, 
                        self.frame.size.width, 
                        newHeight);

    for (UIView *view in [(UITableView *)self.superview subviews]) {
        if ([view isKindOfClass:[self class]]) {
            continue;
        }
        view.frame = CGRectMake(view.frame.origin.x, 
                            view.frame.origin.y - originChange, 
                            view.frame.size.width, 
                            view.frame.size.height);
    }

    [UIView commitAnimations];
}

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{
    [(UITableView *)self.superview setTableHeaderView:self];
}

По сути, это анимирует все подпредставления UITableView, которые не относятся к тому же типу класса, что и вызывающий класс. В конце анимации он вызывает setTableHeaderView для суперпредставления (UITableView) - без этого содержимое UITableView будет возвращаться назад при следующей прокрутке пользователя. Единственное ограничение, которое я обнаружил на данный момент, заключается в том, что если пользователь пытается прокрутить UITableView во время анимации, прокрутка будет анимирована, как если бы размер заголовка не был изменен (не имеет значения, если анимация быстро).

10 голосов
/ 14 марта 2013

Если вы хотите условно анимировать изменения, вы можете сделать следующее:

- (void) showHeader:(BOOL)show animated:(BOOL)animated{

    CGRect closedFrame = CGRectMake(0, 0, self.view.frame.size.width, 0);
    CGRect newFrame = show?self.initialFrame:closedFrame;

    if(animated){
        // The UIView animation block handles the animation of our header view
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:0.3];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];

        // beginUpdates and endUpdates trigger the animation of our cells
        [self.tableView beginUpdates];
    }

    self.headerView.frame = newFrame;
    [self.tableView setTableHeaderView:self.headerView];

    if(animated){
        [self.tableView endUpdates];
        [UIView commitAnimations];
    }
}

Обратите внимание, что анимация состоит из двух частей:

  1. Анимация клеток под tableHeaderView. Это делается с использованием beginUpdates и endUpdates
  2. Анимация фактического представления заголовка. Это делается с помощью UIView анимационного блока.

Чтобы синхронизировать эти две анимации, animationCurve должен быть установлен в UIViewAnimationCurveEaseInOut, а продолжительность - в 0.3, что, по-видимому, и используется UITableView для анимации.

Обновление

Я создал проект XCode на gihub, который делает это. Проверьте проект ResizeTableHeaderViewAnimated в besi / ios-quickies

screenshot

8 голосов
/ 07 января 2009

Я думаю, что это должно работать, если вы просто установите высоту myHeaderView следующим образом:

CGRect newFrame = myHeaderView.frame;
newFrame.size.height = newFrame.size.height + 100;
myHeaderView.frame = newFrame;

self.tableView.tableHeaderView = myHeaderView;
6 голосов
/ 24 сентября 2013

Использовал решение @garrettmoon выше до iOS 7.
Вот обновленное решение, основанное на @ garrettmoon's:

- (void)adjustTableHeaderHeight:(NSUInteger)newHeight animated:(BOOL)animated {

    [UIView beginAnimations:nil context:nil];

    [UIView setAnimationDuration:[CATransaction animationDuration]];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];

    self.frame = CGRectMake(self.frame.origin.x,
                        self.frame.origin.y,
                        self.frame.size.width,
                        newHeight);

    [(UITableView *)self.superview setTableHeaderView:self];

    [UIView commitAnimations];
}

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{
    [(UITableView *)self.superview setTableHeaderView:self];
}
5 голосов
/ 27 ноября 2014

Это работало для меня на iOS 7 и 8. Этот код работает на контроллере табличного представления.

[UIView animateWithDuration:0.3 animations:^{
    CGRect oldFrame = self.headerView.frame;
    self.headerView.frame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y, oldFrame.size.width, newHeight);
    [self.tableView setTableHeaderView:self.headerView];
}];
4 голосов
/ 20 сентября 2010

Это потому, что установщик tableHeaderView.

Вы должны установить высоту UIView перед установкой tableHeaderView. (Было бы намного проще, если бы Apple открывала исходные тексты этой платформы ...)

3 голосов
/ 23 января 2017

На iOS 9 и ниже, tableHeaderView не будет изменять макет после изменения размера. Эта проблема решена в iOS 10.

Чтобы решить эту проблему, просто сделайте это с помощью следующего кода:

self.tableView.tableHeaderView = self.tableView.tableHeaderView;
2 голосов
/ 06 июня 2016

В iOS 9.x выполнение этого на viewDidLoad работает просто отлично:

var frame = headerView.frame
frame.size.height = 11  // New size
headerView.frame = frame

headerView объявлен как @IBOutlet var headerView: UIView! и подключен к раскадровке, где он находится в верхней части tableView, чтобы функционировать как tableHeaderView.

1 голос
/ 20 января 2017

Установка высоты для свойства представления заголовка tableView.tableHeaderView в viewDidLoad, кажется, не работает, высота представления заголовка все еще не изменяется, как ожидалось.

После борьбы с этим вопросом много попыток. Я обнаружил, что вы можете изменить высоту, вызвав логику представления заголовка внутри - (void)didMoveToParentViewController:(UIViewController *)parent метод.

Таким образом, пример кода будет выглядеть так:

- (void)didMoveToParentViewController:(UIViewController *)parent {
    [super didMoveToParentViewController:parent];

    if ( _tableView.tableHeaderView == nil ) {
        UIView *header = [[[UINib nibWithNibName:@"your header view" bundle:nil] instantiateWithOwner:self options:nil] firstObject];

        header.frame = CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), HeaderViewHeight);

        [_tableView setTableHeaderView:header];
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...