Я ищу способ реализовать представление заголовка, которое автоматически скрывается, как только вы начинаете прокручивать вниз, и сразу же показывает себя, как только пользователь начинает прокручивать вверх. Обычно я всегда публикую какой-то код, но теперь я немного не понимаю, как реализовать такое поведение.
Мой макет просмотра:
UICollectionViewController
с включенным листанием по горизонтали
прокрутка (имеет два элемента)UICollectionViewCell
заполняет все вертикальное пространство. Каждая UICollectionViewCell содержит UITableView для вертикальной прокрутки. Я предполагаю, что мне нужно использовать положение вертикальной прокрутки UITableView для настройки рамки строки меню.Видео: https://imgur.com/a/Rdu3wko
Что было бы лучшим способом реализовать такое поведение?
Я думаю, что это UICollectionView с тремя элементами и включенным пейджингом. Я не знаю, как иначе можно было бы создать представление заголовка.
Может быть, это поможет вам github.com/cillyfly/MXScroll
Эта функциональность возможна в UITableView
установленном заголовке параллакса, иначе UIScrollView
анимации параллакса.
Здравствуйте, у вас есть пример? Может быть, вы пришлете мне ссылку?
Проверьте это [medium.com/if-let-swift-programming/… [github.com/romansorochak/ParallaxHeader] [github.com/maxep/MXParallaxHeader]] Вы можете ссылаться на [cococontrols.com/search?q=parallax] также вы ищете на [cocopods.org] и многие другие .
Я думаю, что это намного усложняет тот факт, что у меня есть UICollectionView с горизонтальной прокруткой. В ваших примерах используется только один UITableView.
Если вы хотите использовать UICollectionView
набор UIScrollView
для установки параллаксной анимации.
@J.Doe все ссылки работают отлично, когда вы открываете ссылку, проверьте, что ULRLink открыт с ], поэтому, пожалуйста, удалите, это сработало, и теперь я не могу редактировать свой ответ, поэтому я не мог обновить свой ответ.
Если вы хотите использовать UICollectionView
, просто возьмите делегата, посмотрите, в каком направлении прокручивается пользователь, и скройте/покажите заголовок по мере необходимости. Вот пример для начала:
class ViewController: UIViewController {
// Variable to save the last scroll offset.
private var lastContentOffset: CGFloat = 0
private lazy var header: UIView = {
let header = UIView()
header.translatesAutoresizingMaskIntoConstraints = false
header.backgroundColor = .red
header.widthAnchor.constraint(equalToConstant: self.view.frame.width).isActive = true
header.heightAnchor.constraint(equalToConstant: 80.0).isActive = true
return header
}()
private lazy var collectionView: UICollectionView = {
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewLayout())
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.delegate = self
collectionView.backgroundColor = .white
collectionView.contentSize = CGSize(width: UIScreen.main.bounds.width, height: 2000.0)
// Setting bounces to false - otherwise the header will disappear when we go past the top and are sprung back.
collectionView.bounces = false
return collectionView
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(collectionView)
collectionView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
collectionView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
collectionView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
collectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
collectionView.contentSize = CGSize(width: UIScreen.main.bounds.width, height: 2000.0)
// Make sure you either add the header subview last, or call self.view.bringSubviewToFront(header)
self.view.addSubview(header)
// Constrain the header so it's just sitting on top of the view. To make it visible, we'll use a transform.
header.bottomAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
header.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
// Header starts visible.
header.layoutIfNeeded()
self.header.transform = CGAffineTransform(translationX: 0.0, y: header.frame.height)
}
func revealHeader() {
// Set the duration below to how quickly you want header to appear/disappear.
UIView.animate(withDuration: 0.3) {
self.header.transform = CGAffineTransform(translationX: 0.0, y: self.header.frame.height)
}
}
func hideHeader() {
UIView.animate(withDuration: 0.3) {
self.header.transform = .identity
}
}
}
extension ViewController: UICollectionViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if (lastContentOffset > scrollView.contentOffset.y) {
// Scrolled up: reveal header.
revealHeader()
}
else if (lastContentOffset < scrollView.contentOffset.y) {
// Scrolled down: reveal header.
hideHeader()
}
lastContentOffset = scrollView.contentOffset.y
}
}
Обновлено: Заметил, что функциональность заголовка Reddit немного отличается. Если вы хотите, чтобы вещь прокручивалась динамически (т. е. на количество, которое вы прокрутили вниз, а не отображалось сразу), замените эту функцию делегата на это:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if (lastContentOffset > scrollView.contentOffset.y) {
// Scrolled up: reveal header.
let difference = lastContentOffset - scrollView.contentOffset.y
if header.transform.ty < (header.frame.height - difference) {
// Header hasn't been fully revealed yet, bring it down by the amount we've scrolled up.
self.header.transform = CGAffineTransform(translationX: 0.0, y: header.transform.ty + difference)
} else {
self.header.transform = CGAffineTransform(translationX: 0.0, y: header.frame.height)
}
}
else if (lastContentOffset < scrollView.contentOffset.y) {
// Scrolled down: reveal header.
let difference = scrollView.contentOffset.y - lastContentOffset
if header.transform.ty > difference {
self.header.transform = CGAffineTransform(translationX: 0.0, y: header.transform.ty - difference)
} else {
self.header.transform = CGAffineTransform(translationX: 0.0, y: 0.0)
}
}
lastContentOffset = scrollView.contentOffset.y
}
Спасибо, я постараюсь внедрить это решение в свое приложение.
Без проблем! Добавлена альтернатива выше, если вам это нужно.
Привет, у меня есть еще один вопрос: теперь заголовок отображается и прокручивается очень плавно, это выглядит очень красиво, еще раз спасибо. Однако представление покрывает первую ячейку. Как я могу изменить поведение, чтобы ячейка начиналась прямо под меню заголовка? Я видел свойство contentInset, но программное изменение contentInset сделало UIScrollView «дерганым». Есть ли лучшее решение?
Замените строку header.bottomAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
на header.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
. Затем удалите эту строку: collectionView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
и добавьте ее после того, как вы добавите заголовок в качестве подпредставления: `collectionView.topAnchor.constraint(equalTo: header.bottomAnchor).isActive = true
Поскольку я больше не использую UIViewConroller (а вместо этого использую UICollectionViewController), мне пришлось немного подправить некоторые вещи, но ваш код мне очень помог, так что большое вам спасибо, теперь он наконец работает и выглядит очень хорошо.
Я думаю, что это UITableview, а не представление коллекции