为什么Xcode仿真器视图与视图层次结构视图不同

时间:2019-01-20 02:10:58

标签: ios swift xcode uicollectionview

我正在使用自动布局约束在UIImageView之上开发UICollectionView

我已经将UIImageView固定在屏幕的顶部,固定的H:W比例为4:3,然后让UICollectionView占据底部的任何空间。

奇怪的是,当我运行它时,xcode模拟器中的视图与视图层次调试器完全不同:

查看层次结构调试器
View Hierarchy Debugger

iPhone 8 Plus模拟器
iPhone 8 Plus simulator

UICollectionView中,每个单元格都将显示一张脸部照片,我已将UICollectionView的itemSize配置为一个正方形。然后应该显示整个脸部(因此调试器视图正确,模拟器不正确)。

// MARK: - UICollectionViewDelegateFlowLayout
extension ViewController : UICollectionViewDelegateFlowLayout {

    // set item size 
    func collectionView(_ collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                        sizeForItemAt indexPath: IndexPath) -> CGSize {



        // gw: to force one row, height need to be smaller than flow height
        return CGSize(width: collectionView.bounds.height, height: collectionView.bounds.height)
    }
}

造成这种差异的原因是什么
我正在使用xcode 10.1,ios 12.1 完整的代码在这里(不是很长):

import UIKit


class ViewController: UICollectionViewController{

    let collectionViewCellIdentifier = "MyCollectionViewCellIdentifier"
    let canvas:Canvas = {
        let canvas = Canvas()
        canvas.backgroundColor = UIColor.black
        canvas.translatesAutoresizingMaskIntoConstraints=false
        canvas.alpha = 0.2
        return canvas
    } ()

    let photoView: UIImageView = {
        let imageView = UIImageView()

        imageView.image = UIImage(imageLiteralResourceName: "hongjinbao")
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.contentMode = .scaleAspectFill
        return imageView
    } ()


     private let myArray: NSArray = ["First","Second","Third"]

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        // stack views
        view.addSubview(photoView)
        view.addSubview(canvas)

        collectionView?.backgroundColor = UIColor.white
        collectionView?.translatesAutoresizingMaskIntoConstraints = false

        collectionView?.register(PersonCollectionViewCell.self, forCellWithReuseIdentifier: collectionViewCellIdentifier)


        setupLayout()


    }

    private func setupLayout() {


        photoView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        photoView.heightAnchor.constraint(equalTo: view.widthAnchor,   multiplier: 1.333).isActive = true
        photoView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        photoView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true

        canvas.topAnchor.constraint(equalTo: photoView.topAnchor).isActive = true
        canvas.bottomAnchor.constraint(equalTo: photoView.bottomAnchor).isActive = true
        canvas.leadingAnchor.constraint(equalTo: photoView.leadingAnchor).isActive = true
        canvas.trailingAnchor.constraint(equalTo: photoView.trailingAnchor).isActive = true

        collectionView?.topAnchor.constraint(equalTo: photoView.bottomAnchor).isActive = true
        collectionView?.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        collectionView?.leadingAnchor.constraint(equalTo: photoView.leadingAnchor).isActive = true
        collectionView?.trailingAnchor.constraint(equalTo: photoView.trailingAnchor).isActive = true


    }

}


// MARK: - UICollectionViewDataSource
extension ViewController {

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: self.collectionViewCellIdentifier, for: indexPath)
        return cell
    }


    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 13
    }


}

// MARK: - UICollectionViewDelegateFlowLayout
extension ViewController : UICollectionViewDelegateFlowLayout {

    // set item size 
    func collectionView(_ collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                        sizeForItemAt indexPath: IndexPath) -> CGSize {



        // gw: to force one row, height need to be smaller than flow height
        return CGSize(width: collectionView.bounds.height, height: collectionView.bounds.height)
    }
}



    import UIKit

    class PersonCollectionViewCell: UICollectionViewCell {

        let face: UIImageView = {
            let imageView = UIImageView()
            imageView.image = UIImage(imageLiteralResourceName: "mary")
            imageView.translatesAutoresizingMaskIntoConstraints = false
            return imageView
        } ()

        let name: UILabel = {
            let textLabel = UILabel()
            textLabel.translatesAutoresizingMaskIntoConstraints = false
            return textLabel
        } ()

        let desc: UITextView = {
           let textView = UITextView()
            textView.translatesAutoresizingMaskIntoConstraints = false
            return textView
        } ()

        override init(frame: CGRect) {
            super.init(frame: frame)

            setupView()
        }


        // gw: needed by compiler
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }

        private func setupView() {
            addSubview(face)
            addSubview(name)
            addSubview(desc)

            backgroundColor = UIColor.red
            addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-16-[v0]|", options: NSLayoutConstraint.FormatOptions(), metrics: nil, views: ["v0":face]))
        }




    }

1 个答案:

答案 0 :(得分:0)

我找到了原因,这是由于我的ViewController中子视图的堆叠顺序所致。 photoView被添加到collectionView的顶部,并且阻塞了collectionView的一部分。

解决方案:在viewDidLoad中添加以下语句,将后面的语句放在前面:

 // stack views
        view.addSubview(photoView)

        // little trick to bring inherent collectionView to front
        view.bringSubviewToFront(self.collectionView)
相关问题