代码之家  ›  专栏  ›  技术社区  ›  Alk

弹性布局不使用子视图控制器

  •  0
  • Alk  · 技术社区  · 6 年前

    我试图按照这里描述的示例来制作一个弹性布局,其中包括 UIImageView UIScrollView . https://github.com/TwoLivesLeft/StretchyLayout/tree/Step-6

    唯一不同的是我把 UILabel UIViewController 它本身包含一个 UICollectionView UICollectionViewCell . enter image description here

    import UIKit
    import SnapKit
    
    class HomeController: UIViewController, UIScrollViewDelegate {
    
    private let scrollView = UIScrollView()
    private let imageView = UIImageView()
    private let contentContainer = UIView()
    private let collectionViewController = CollectionViewController()
    
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
    
        scrollView.contentInsetAdjustmentBehavior = .never
        scrollView.delegate = self
    
        imageView.image = UIImage(named: "burger")
        imageView.contentMode = .scaleAspectFill
        imageView.clipsToBounds = true
    
        let imageContainer = UIView()
        imageContainer.backgroundColor = .darkGray
    
        contentContainer.backgroundColor = .clear
    
        let textBacking = UIView()
        textBacking.backgroundColor = #colorLiteral(red: 0.7450980544, green: 0.1235740449, blue: 0.2699040081, alpha: 1)
    
        view.addSubview(scrollView)
    
        scrollView.addSubview(imageContainer)
        scrollView.addSubview(textBacking)
        scrollView.addSubview(contentContainer)
        scrollView.addSubview(imageView)
    
        self.addChild(collectionViewController)
        contentContainer.addSubview(collectionViewController.view)
        collectionViewController.didMove(toParent: self)
    
    
        scrollView.snp.makeConstraints {
            make in
    
            make.edges.equalTo(view)
        }
    
        imageContainer.snp.makeConstraints {
            make in
    
            make.top.equalTo(scrollView)
            make.left.right.equalTo(view)
            make.height.equalTo(imageContainer.snp.width).multipliedBy(0.7)
        }
    
        imageView.snp.makeConstraints {
            make in
    
            make.left.right.equalTo(imageContainer)
    
            //** Note the priorities
            make.top.equalTo(view).priority(.high)
    
            //** We add a height constraint too
            make.height.greaterThanOrEqualTo(imageContainer.snp.height).priority(.required)
    
            //** And keep the bottom constraint
            make.bottom.equalTo(imageContainer.snp.bottom)
        }
    
        contentContainer.snp.makeConstraints {
            make in
    
            make.top.equalTo(imageContainer.snp.bottom)
            make.left.right.equalTo(view)
            make.bottom.equalTo(scrollView)
        }
    
        textBacking.snp.makeConstraints {
            make in
    
            make.left.right.equalTo(view)
            make.top.equalTo(contentContainer)
            make.bottom.equalTo(view)
        }
    
        collectionViewController.view.snp.makeConstraints {
            make in
    
            make.left.right.equalTo(view)
            make.top.equalTo(contentContainer)
            make.bottom.equalTo(view)
        }
    
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
    
        scrollView.scrollIndicatorInsets = view.safeAreaInsets
        scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: view.safeAreaInsets.bottom, right: 0)
    }
    
    //MARK: - Scroll View Delegate
    
    private var previousStatusBarHidden = false
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if previousStatusBarHidden != shouldHideStatusBar {
    
            UIView.animate(withDuration: 0.2, animations: {
                self.setNeedsStatusBarAppearanceUpdate()
            })
    
            previousStatusBarHidden = shouldHideStatusBar
        }
    }
    
    //MARK: - Status Bar Appearance
    
    override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
        return .slide
    }
    
    override var prefersStatusBarHidden: Bool {
        return shouldHideStatusBar
    }
    
    private var shouldHideStatusBar: Bool {
        let frame = contentContainer.convert(contentContainer.bounds, to: nil)
        return frame.minY < view.safeAreaInsets.top
    }
    
    }
    

    所有内容都与此文件中的相同: https://github.com/TwoLivesLeft/StretchyLayout/blob/Step-6/StretchyLayouts/StretchyViewController.swift 除了 innerText CollectionViewController .

    ui集合视图 显示正确-但是我无法再向上或向下滚动。我不知道我的错误在哪里。

    0 回复  |  直到 6 年前
        1
  •  1
  •   BHendricks    6 年前

    看起来您正在将集合视图的大小限制在包含集合视图的容器视图和图像视图的父视图的范围内。因此,容器 scrollView 没有 contentSize

    在您给出的示例中,此行为是通过标签的长度实现的,标签要求的高度大于图像视图和视图其余部分之间的高度。在您的情况下,集合视图容器的行为需要像它大于该区域一样。

    更准确地说你需要通过 collectionView.contentSize scrollView.contentSize . 滚动视图 内容大小 是可设置的,所以你只需要增加 集合视图.contentSize collectionView.height (因为你的滚动视图是当前的 当前包括collectionView的高度)。我不确定您是如何添加子视图控制器的,但是在您这样做的时候,我会相应地增加scrollView的contentSize。但是,如果在那之后collectionView的大小发生了变化,则还需要确保将该变化委托给 . 这可以通过制定如下协议来实现:

    protocol InnerCollectionViewHeightUpdated {
      func collectionViewContentHeightChanged(newSize: CGSize)
    }
    

    滚动视图 滚动视图 内容大小 collectionView 儿童管理员,你会有一个 delegate 此协议的属性(在创建子视图控制器时设置此属性,将委托设置为 self ,包含子VC和 滚动视图 ). 无论何时 集合视图 高度更改(例如,如果添加单元格)可以执行 delegate.collectionViewContentHeightChanged(...