在子子视图中获取视图的框架

时间:2017-09-23 14:58:15

标签: ios swift cocoa-touch

所以,让我试着解释一下会发生什么。所以,我有这个视图结构:

ViewController
HeaderView -> Subview of ViewController
MenuView -> Subview of HeaderView

我在每个视图中使用自动布局。

我的问题是,在MenuView中,当我尝试使用帧大小来锚定一些视图时,帧仍然是0.0,因此,它没有布局任何东西,我想这可能是因为它仍然没有从ViewController获得它,因为当我在HeaderView中布局MenuView时,我也使用了帧大小。

任何帮助?

编辑: 顺便说一下,边界也是0.0

代码:

HeaderController

lazy var headerView: HeaderView = {
       let hv = HeaderView(maxHeight: self.maxHeight, medHeight: self.medHeight, minHeight: self.minHeight, paddingBetween: 10)
        return hv
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupViews()
        tableView.delegate = self
        tableView.dataSource = self

        headerView.headerControllerDelegate = self
    }

    func setupViews() {
        addSubview(collectionView)
        addSubview(lineView)
        bringSubview(toFront: lineView)

        _ = collectionView.anchor(top: topAnchor, bottom: bottomAnchor, right: rightAnchor, left: leftAnchor)

        lineViewLeftAnchor = lineView.anchor(top: nil, bottom: bottomAnchor, right: nil, left: leftAnchor, topConstant: 0, bottomConstant: 0, rightConstant: 0, leftConstant: 0, widthConstant: frame.size.width / 4, heightConstant: 1.5)[1]


    }
}

HeaderView

 let menuView: MenuView = {
        let mv = MenuView()
        return mv
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = Theme.PRIMARY_DARK_COLOR
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    convenience init(maxHeight: CGFloat, medHeight: CGFloat, minHeight: CGFloat, paddingBetween containerPadding: CGFloat) {
        self.init(frame: CGRect.zero)
        self.maxHeight = maxHeight
        self.medHeight = medHeight
        self.minHeight = minHeight
        self.containerPadding = containerPadding

        collapseBtn.addTarget(self, action: #selector(handleCollapse), for: .touchUpInside)
        setupViews()
    }

    func setupViews() {
        addSubview(menuView)
        _ = menuView.anchor(top: menuContainer.topAnchor, bottom: menuContainer.bottomAnchor, right: menuContainer.rightAnchor, left: menuContainer.leftAnchor)
    }

MenuView

extension MenuView: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as? MenuCell {
            cell.menuLabel.text = menuItems[indexPath.row]
            cell.menuLabel.textColor = fontColor
            return cell
        }
        return UICollectionViewCell()
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return menuItems.count
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: frame.size.width / 4, height: frame.size.height)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }

这不是整个代码,但我认为这是重要的部分。

2 个答案:

答案 0 :(得分:0)

这个问题需要更多的上下文,但是你是想在代码中抓取框架大小,还是说你的视图没有根据它们的约束进行布局。

如果它在代码中,则需要注意frame.size在调用viewDidAppear之前无法使用。

答案 1 :(得分:0)

最明显的解决方案是在HeaderView的{​​{1}} func中获取MenuView的框架。

但你为什么要达到layoutSubviews的大小?在自动布局中,您可以使用UI元素之间的关系来安排应用程序的UI,因此您不应该关心框架的具体值。

<强>更新

当集合视图的边界发生变化时,正确的解决方案会使布局无效。

您必须覆盖HeaderView并返回shouldInvalidateLayout(forBoundsChange:)

  

https://developer.apple.com/documentation/uikit/uicollectionviewlayout/1617781-shouldinvalidatelayoutforboundsc

并致电true collectionView中的invalidateLayoutlayoutSubviews