【问题标题】:Why Xcode simulator view is different from view-hierarchy view为什么 Xcode 模拟器视图与视图层次结构视图不同
【发布时间】:2019-01-20 02:10:57
【问题描述】:

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

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

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

查看层次结构调试器

iPhone 8 Plus 模拟器

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]))
        }




    }

【问题讨论】:

  • 首先,确保在界面生成器和模拟器上使用相同的屏幕尺寸。其次,您在运行时添加了约束,因此显然您期望有一些不同。我还会在控制台中检查约束错误。

标签: ios swift xcode uicollectionview


【解决方案1】:

我找到了原因,这是由于我的ViewController中子视图的堆叠顺序。 photoView 被添加到 collectionView 之上,它阻止了 collectionView 的一部分。

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

 // stack views
        view.addSubview(photoView)

        // little trick to bring inherent collectionView to front
        view.bringSubviewToFront(self.collectionView)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-11
    • 2018-09-14
    • 2016-08-03
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    • 2018-03-02
    • 1970-01-01
    相关资源
    最近更新 更多