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

IOS: растяжка/изменение размера заголовка UITableView, когда пользователь перетаскивает вниз?

Используя раскадровку, я разместил imageView как мой tableView's headerView внутри ViewController.

Так создается моя раскадровка:

enter image description here

В зависимости от данных, которые пользователь просматривает, ViewController будет показывать или скрывать headerView. Мой вопрос заключается в том, что, когда отображается headerView, и пользователь перетаскивает его на tableView, , как я могу привязать imageView к navigationBar и tableView по мере изменения размера покрыть пространство между ними?

Это то, что он сейчас делает:

enter image description here

Но для этого я и собираюсь:

enter image description here

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

UPDATE:

Я следил за советом, опубликованным Дани ниже, и сделал следующее:

-(void)scrollViewDidScroll:(UIScrollView*)scrollView {

CGRect initialFrame = CGRectMake(0, 0, 320, 160);

if (scrollView.contentOffset.y < 0) {

    initialFrame.size.height =! scrollView.contentOffset.y;
    childHeaderView.frame = initialFrame;
} }

childHeaderView - это изображение и по какой-то причине, когда я перетаскиваю его, изображение движется вверх (например, половина его за navBar) и не возвращается. Любой совет будет очень оценили!! Спасибо!

4b9b3361

Ответ 2

Прежде всего, вы должны удалить UIImageView из заголовка и добавить его как простой UIImageView поверх UITableView, а затем, поскольку протокол UITableViewDelegate соответствует протоколу UIScrollViewDelegate, вы можете реализовать scrollViewDidScroll:, чтобы проверить, когда tableView прокручивается вниз и имеет эффект bouncing. что-то вроде этого:

-(void)someInitMethod {
   initialFrame = yourHeaderView.frame;
}
-(void)scrollViewDidScroll:(UIScrollView*)scrollView {
    if(scrollView.contentOffset.y < 0) {
       initialFrame.size.height -= scrollView.contentOffset.y;
       yourHeaderView.frame = initialFrame;
    }
}

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

Ответ 3

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

  • Создайте контроллер просмотра в раскадровке.
  • Добавить представление таблицы и установить ограничения на 0 со всех сторон.
  • Добавить представление карты (или любой вид) под табличным представлением, чтобы он отображался поверх. Это будет похоже на перекрытие.
  • Добавьте ограничения в верхний левый и правый.
  • В контроллере представления viewDidLoad добавьте следующее: tableView.contentInset = UIEdgeInsetsMake(200, 0, 0, 0) где 200 - высота представления. Это приведет к уменьшению содержимого таблицы вниз.
  • В контроллере представления добавьте следующий код, который изменяет размер представления на основе прокрутки:

    func scrollViewDidScroll(scrollView: UIScrollView) {
        var scrollOffset = scrollView.contentOffset.y
        var headerFrame = mapView.frame
        if (scrollOffset < 0) {
            // Adjust map
            headerFrame = CGRect(x: mapView.frame.origin.x,
                y: mapView.frame.origin.y,
                width: mapView.frame.size.width,
                height: -scrollOffset)
        } else {
            // Adjust map
            headerFrame = CGRect(x: mapView.frame.origin.x,
                y: mapView.frame.origin.y,
                width: mapView.frame.size.width,
                height: 0)
        }
        mapView.frame = headerFrame
    }
    

Если бы я мог установить contentInset из раскадровки, это было бы еще более красивым

Ответ 5

Более ранние решения на этой странице вызвали у меня определенные проблемы, когда мне это нужно, чтобы работать вместе с заголовками разделов и индексной панелью, поэтому я придумал следующую альтернативу. Пожалуйста, обратите внимание; Я не использую autolayout в моем проекте, и я тестировал это только на iOS9 +;

В раскадровке вашего проекта:

  • Создайте UITableView в UIViewController (или попробуйте его с помощью UITableViewController).
  • Отбросьте UIView вверху (но внутри) UITableView, так что он станет заголовком таблицы над первой ячейкой.
  • Дайте этому заголовку нужную высоту (например, 200px) и установите цвет фона на "Очистить цвет". Четкий цвет имеет важное значение, представление должно быть прозрачным.
  • Отбросить второй UIView в заголовке таблицы UIView и сделать его тем же размером, что и родительский. Это будет фактический заголовок, поэтому не стесняйтесь давать ему любой цвет, настраивать изображение или другой контент.
  • Подключите этот второй UIView к вашему UIViewController IBOutlet, я назвал его "headerView" в моем случае.

Затем перейдите в свой UIViewController.m:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Remove view from table header and place it in the background instead.
    [self.headerView removeFromSuperview];
    UIView *backgroundView = [UIView new];
    [backgroundView addSubview:self.headerView];
    self.tableView.backgroundView = backgroundView;
}

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

    /* Set initialScrollOffset ivar to start offset, because in my case
       the scroll offset was affected by the statusbar + navigation bar heights
       and the view controller "extend edges under top bars" option. */
    initialScrollOffset = self.tableView.contentOffset.y;
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    /* Modify headerView height only if the table content gets pulled
       beyond initial offset. */
    if (scrollView.contentOffset.y < initialScrollOffset) {
        CGRect frame = self.headerView.frame;
        frame.size.height = self.tableView.tableHeaderView.frame.size.height + -scrollView.contentOffset.y;
        self.headerView.frame = frame;
    }
}

Мне нужна эта реализация только для растягивающего заголовка с цветом фона и ярлыками. Это должно быть легко добавить UIImageView в этот заголовок, хотя.

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

EDIT:

Я нашел еще более чистый способ выполнить это;

  • Создайте заголовок таблицы в построителе интерфейса, как описано выше: 1 UIView в качестве контейнера со встроенным встроенным UIView.
  • Пропустите код viewDidLoad выше, нет необходимости вытаскивать UIView из контейнера, и нам не нужно будет устанавливать его в качестве фона таблицы.
  • Измените метод scrollViewDidScroll: следующим образом:

UIViewController.m:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
      if (scrollView.contentOffset.y < initialScrollOffset) {
           CGRect frame = self.headerView.frame;
           frame.size.height = self.tableView.tableHeaderView.frame.size.height - scrollView.contentOffset.y;
           frame.origin.y = self.tableView.tableHeaderView.frame.origin.y + scrollView.contentOffset.y;
           self.headerView.frame = frame;
    }
}

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

Ответ 6

Я не знаю, если это поможет вам или нет.

Задайте делегат прокрутки для себя.

а затем выполните следующее:

-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    float scrollViewHeight = scrollView.frame.size.height;
    float scrollContentSizeHeight = scrollView.contentSize.height;
    float scrollOffset = scrollView.contentOffset.y;

    if (scrollOffset == 0)
    {
        // then we are at the top
    }
    else if (scrollOffset + scrollViewHeight == scrollContentSizeHeight)
    {
        // then we are at the end
        // Do what you need here 
    }
}