Как я могу изменить размер UIView на прокрутке с задержкой - PullRequest
0 голосов
/ 17 мая 2019

У меня есть UIView, который привязан к якорям top, leading и trailing. Он имеет начальную высоту 138 и должен уменьшиться до не менее 88.

У меня есть UITableView закрепленная вершина к нижней части этого представления, она также привязана к leading, trailing и нижней части суперпредставления.

Это не представление заголовка для табличного представления, а отдельное представление.

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

  • Прокрутка вверх = сокращение до не менее 88
  • Прокрутка вниз = увеличение до не более 138

В настоящее время я могу достичь этого с помощью

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    onUserScroll?(scrollView)
}

который через привязку запускает приведенный ниже код

class FeedView: UIView {
    private(set) var brandedHeader: UIView!
    private(set) var brandedHeaderHeight: NSLayoutConstraint!
    private(set) var tableView: UITableView!

    private lazy var maxHeaderHeight: CGFloat = 138
    private lazy var minHeaderHeight: CGFloat = 88
    private var previousScrollOffset: CGFloat = 0

    ...............

}
    extension FeedView {
        func setTableViewDelegate(_ delegate: TableViewDelegate) {
            tableView.delegate = delegate
            tableView.dataSource = delegate
        }

        func onUserScroll(_ scrollView: UIScrollView) {

            let scrollDiff = scrollView.contentOffset.y - self.previousScrollOffset

            let absoluteTop: CGFloat = 0
            let absoluteBottom: CGFloat = scrollView.contentSize.height - scrollView.frame.size.height

            let isScrollingDown = scrollDiff > 0 && scrollView.contentOffset.y > absoluteTop
            let isScrollingUp = scrollDiff < 0 && scrollView.contentOffset.y < absoluteBottom

            guard canAnimateHeader(scrollView) else { return }

            // Calculate new header height
            var newHeight = self.brandedHeaderHeight.constant
            if isScrollingDown {
                newHeight = max(self.minHeaderHeight, self.brandedHeaderHeight.constant - abs(scrollDiff))
            } else if isScrollingUp {
                newHeight = min(self.maxHeaderHeight, self.brandedHeaderHeight.constant + abs(scrollDiff))
            }

            // Header needs to animate
            if newHeight != self.brandedHeaderHeight.constant {
                self.brandedHeaderHeight.constant = newHeight
                self.setScrollPosition(self.previousScrollOffset)
            }

            self.previousScrollOffset = scrollView.contentOffset.y
        }

        private func canAnimateHeader(_ scrollView: UIScrollView) -> Bool {
            // Calculate the size of the scrollView when header is collapsed
            let scrollViewMaxHeight = scrollView.frame.height + self.brandedHeaderHeight.constant - minHeaderHeight

            // Make sure that when header is collapsed, there is still room to scroll
            return scrollView.contentSize.height > scrollViewMaxHeight
        }

        private func setScrollPosition(_ position: CGFloat) {
            self.tableView.contentOffset = CGPoint(x: self.tableView.contentOffset.x, y: position)
        }
    }

Однако я бы хотел задержать событие изменения размера.

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

Я обновил свой код следующим образом

private var previousScrollOffset: CGFloat = 100 // offset the initial scroll so the header does not shrink immediately on scroll

, а затем также

    func onUserScroll(_ scrollView: UIScrollView) {

        guard scrollView.contentOffset.y < 200 else { return }
        ..........
}

Но это не сработало, как ожидалось.

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

Ответы [ 2 ]

1 голос
/ 17 мая 2019

Обновите функцию onUserScroll с помощью

    let isScrollingDown = scrollDiff > 0 && scrollView.contentOffset.y > absoluteTop && scrollView.contentOffset.y > 300
    let isScrollingUp = scrollDiff < 0 && scrollView.contentOffset.y < absoluteBottom && scrollView.contentOffset.y < 300

Вы должны получить желаемый эффект, я верю.

0 голосов
/ 17 мая 2019

Используйте несколько y-констант, чтобы начать сжимать / раскрывать верхнюю полосу.

Например Если прокрутка вниз и полоса обнаружена и contentOffset.y больше 500 - уменьшите ее.

Если прокрутка вверх, а полоса сужена и contentOffset.y меньше 300 - покажите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...