Closed 168-7cm closed 1 year ago
I want use my own custom header view which change height by content. (variable height)
I wrote code below but something went long.
here is my movie.
https://user-images.githubusercontent.com/71382628/150822800-9af6d6ed-0d3b-4314-bc16-0ac3844decad.MP4
class HeaderPagingView: PagingView { var headerHeightConstraint: NSLayoutConstraint? private lazy var headerView: UIView = { let view = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 200)) view.backgroundColor = .red return view }() override func setupConstraints() { addSubview(headerView) pageView.translatesAutoresizingMaskIntoConstraints = false collectionView.translatesAutoresizingMaskIntoConstraints = false headerView.translatesAutoresizingMaskIntoConstraints = false headerHeightConstraint = headerView.heightAnchor.constraint(equalToConstant: headerView.frame.height) headerHeightConstraint?.isActive = true NSLayoutConstraint.activate([ collectionView.leadingAnchor.constraint(equalTo: leadingAnchor), collectionView.trailingAnchor.constraint(equalTo: trailingAnchor), collectionView.heightAnchor.constraint(equalToConstant: options.menuHeight), collectionView.topAnchor.constraint(equalTo: headerView.bottomAnchor), headerView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor), headerView.leadingAnchor.constraint(equalTo: leadingAnchor), headerView.trailingAnchor.constraint(equalTo: trailingAnchor), pageView.leadingAnchor.constraint(equalTo: leadingAnchor), pageView.trailingAnchor.constraint(equalTo: trailingAnchor), pageView.bottomAnchor.constraint(equalTo: bottomAnchor), pageView.topAnchor.constraint(equalTo: topAnchor), ]) } }
class HeaderPagingViewController: PagingViewController { override func loadView() { view = HeaderPagingView(options: options, collectionView: collectionView, pageView: pageViewController.view) } }
HeaderViewController
class HeaderViewController: UIViewController { private let viewControllers = [ UserPostsViewController.configure(), UserPostsViewController.configure(), UserPostsViewController.configure() ] private let pagingViewController = HeaderPagingViewController() private var headerConstraint: NSLayoutConstraint { let pagingView = pagingViewController.view as! HeaderPagingView return pagingView.headerHeightConstraint! } private var headerHeight: CGFloat { let pagingView = pagingViewController.view as! HeaderPagingView return pagingView.headerHeightConstraint!.constant } override func viewDidLoad() { super.viewDidLoad() addChild(pagingViewController) view.addSubview(pagingViewController.view) pagingViewController.didMove(toParent: self) pagingViewController.selectedTextColor = .black pagingViewController.indicatorColor = .black pagingViewController.indicatorOptions = .visible(height: 1, zIndex: Int.max, spacing: .zero, insets: .zero) pagingViewController.view.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ pagingViewController.view.topAnchor.constraint(equalTo: view.topAnchor), pagingViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), pagingViewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), pagingViewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), ]) pagingViewController.dataSource = self pagingViewController.delegate = self viewControllers.first?.collectionView.delegate = self } }
extension HeaderViewController: PagingViewControllerDataSource {
func pagingViewController(_: PagingViewController, viewControllerAt index: Int) -> UIViewController { let viewController = viewControllers[index] viewController.title = "View \(index)" let height = pagingViewController.options.menuHeight + headerHeight let insets = UIEdgeInsets(top: height, left: 0, bottom: 0, right: 0) viewController.collectionView.contentInset = insets viewController.collectionView.scrollIndicatorInsets = insets return viewController } func pagingViewController(_: PagingViewController, pagingItemAt index: Int) -> PagingItem { return PagingIndexItem(index: index, title: "View \(index)") } func numberOfViewControllers(in _: PagingViewController) -> Int { return viewControllers.count }
}
extension HeaderViewController: PagingViewControllerDelegate {
func pagingViewController(_: PagingViewController, didScrollToItem _: PagingItem, startingViewController: UIViewController?, destinationViewController: UIViewController, transitionSuccessful: Bool) { guard let startingViewController = startingViewController as? UserPostsViewController else { return } guard let destinationViewController = destinationViewController as? UserPostsViewController else { return } if transitionSuccessful { startingViewController.collectionView.delegate = nil destinationViewController.collectionView.delegate = self } } func pagingViewController(_: PagingViewController, willScrollToItem _: PagingItem, startingViewController _: UIViewController, destinationViewController: UIViewController) { guard let destinationViewController = destinationViewController as? UserPostsViewController else { return } if let scrollView = destinationViewController.collectionView { let offset = headerConstraint.constant + pagingViewController.options.menuHeight scrollView.contentOffset = CGPoint(x: 0, y: -offset) updateScrollIndicatorInsets(in: scrollView) } }
extension HeaderViewController: UICollectionViewDelegate {
func updateScrollIndicatorInsets(in scrollView: UIScrollView) { let offset = min(0, scrollView.contentOffset.y) * -1 let insetTop = max(pagingViewController.options.menuHeight, offset) let insets = UIEdgeInsets(top: insetTop, left: 0, bottom: 0, right: 0) scrollView.scrollIndicatorInsets = insets } func scrollViewDidScroll(_ scrollView: UIScrollView) { guard scrollView.contentOffset.y < 0 else { if headerConstraint.constant > 0 { headerConstraint.constant = 0 } return } updateScrollIndicatorInsets(in: scrollView) let height = max(0, abs(scrollView.contentOffset.y) - pagingViewController.options.menuHeight) headerConstraint.constant = height }
Hi @168-7cm! Sorry for the late response. I hope you managed to find a solution for this, if not, you can check out the examples project to see how I would solve this.
I want use my own custom header view which change height by content. (variable height)
I wrote code below but something went long.
here is my movie.
https://user-images.githubusercontent.com/71382628/150822800-9af6d6ed-0d3b-4314-bc16-0ac3844decad.MP4
HeaderViewController
extension HeaderViewController: PagingViewControllerDataSource {
}
extension HeaderViewController: PagingViewControllerDelegate {
}
extension HeaderViewController: UICollectionViewDelegate {
}