it-swarm.com.ru

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

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

Вот как настроена моя раскадровка:

enter image description here

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

Вот что он делает в данный момент:

enter image description here

Но вот к чему я иду:

enter image description here

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

Обновление:

Я последовал совету Дэни, приведенному ниже, и сделал следующий:

-(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 - это imageView и по какой-то причине, когда я перетаскиваю вниз, изображение перемещается вверх (как половина за навигационной панелью) и не возвращается. Любой совет будет высоко ценится !! Спасибо!

27
KingPolygon

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

Вот ссылка: Создание эффекта параллакса на UIScrollView с использованием ограничений

7
petehare

Прежде всего вы должны удалить 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. Также я думаю, что эта реализация создаст эффект отскакивания, но я не уверен, потому что я не могу проверить это прямо сейчас, но я думаю, что это хорошая отправная точка для вас.

5
danypata

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

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

    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 из раскадровки, это было бы еще более красиво

2
geometrikal

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

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

  1. Создайте UITableView в UIViewController (или попробуйте его с UITableViewController).
  2. Удалите UIView сверху (но внутри) UITableView, чтобы он стал заголовком таблицы над первой ячейкой.
  3. Дайте этому виду заголовка желаемую высоту (например, 200 пикселей) и установите цвет фона на «Очистить цвет». Чистый цвет важен, вид должен быть прозрачным.
  4. Перетащите 2-й UIView в заголовок таблицы UIView и сделайте его равным размеру родительского. Это будет фактический заголовок, поэтому не стесняйтесь придавать ему любой цвет, настраивать вид изображения или другой контент.
  5. Подключите этот второй 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's "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. До тех пор, пока вы убедитесь, что таблица имеет вид заголовка «Прозрачный цвет», установленный с той же высотой, что и желаемый заголовок, потому что он служит в качестве разделителя, чтобы держать ваши ячейки и заголовки разделов в строке.

Правка:

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

  1. Создайте свой заголовок таблицы в конструкторе интерфейса, как описано выше: 1 UIView как контейнер со вторым UIView, встроенным в него.
  2. Пропустите код viewDidLoad, приведенный выше, нет необходимости извлекать UIView из его контейнера, и нам не нужно будет устанавливать его в качестве фона таблицы.
  3. Измените метод 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;
    }
}

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

1
Tonnie

Пожалуйста, посмотрите на это https://github.com/matteogobbi/MGSpotyViewController , которое реализует тот же эффект, что и в соответствии с вашими требованиями.

1
Prabhu

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

Установите свой делегат свитка на себя.

а затем реализовать это:

-(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 
    }
}
0
Islam Adel