另一个 xib 中的自定义 xib 大小不正确

Posted

技术标签:

【中文标题】另一个 xib 中的自定义 xib 大小不正确【英文标题】:Custom xib inside another xib not being sized properly 【发布时间】:2020-02-16 23:19:38 【问题描述】:

首先,这是我的视图层次结构:

- Table view
-- Table view cell (loaded from custom xib)
--- Collection view
---- Collection view cell (loaded from custom xib)
----- Custom view (loaded from custom xib)

我遇到的问题是最后一个视图,即自定义视图,我将其作为自定义 xib 加载到集合视图单元格中。由于某种原因,它的大小不合适:

如您所见,视图上方有一个巨大的空白区域,而不是正确填充单元格。有趣的是,如果我向下滚动表格视图,然后再向上滚动,它会显示在它应该:

这是我的收藏视图代码的一部分:

// I use this to size the collection view cells to be of 16:9 ratio, nothing crazy
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    // Get the width of the screen
    let width = UIScreen.main.bounds.width

    let imageWidth = width
    let imageHeight = imageWidth / (16 / 9)

    self.postMediaHeight = imageHeight

    return CGSize(width: imageWidth, height: imageHeight)


// Here I initialize the cell
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PostMediaCollectionViewCell", for: indexPath as IndexPath) as? PostMediaCollectionViewCell else 
        fatalError("The dequeued cell is not an instance of PostMediaCollectionViewCell.")
    

    let media = post.images[indexPath.row]

    cell.initialize()

    return cell

这是我的集合视图单元格类,PostMediaCollectionViewCell。没什么特别的:

class PostMediaCollectionViewCell: UICollectionViewCell 

    @IBOutlet weak var container: UIView!
    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var moreView: UIView!
    @IBOutlet weak var moreViewLabel: UILabel!
    @IBOutlet weak var myCustomView: MyCustomView!

    override func awakeFromNib() 
        super.awakeFromNib()
    

    func initialize() 
        //
    

最后,这是我的MyCustomView 课程:

class MyCustomView: UIView 
    @IBOutlet var rootView: UIView!
    @IBOutlet weak var videoView: VideoView!

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

    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
        initialize()
    

    func initialize() 
        Bundle.main.loadNibNamed("MyCustomView", owner: self, options: nil)
        addSubview(rootView)
        rootView.frame = self.bounds
        rootView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
    

我已确保我的 xib 中的约束设置正确,因此自动布局应该可以工作,但显然不是:

PostMediaCollectionViewCell xib: https://i.stack.imgur.com/GQLpj.png

MyCustomView xib: https://i.stack.imgur.com/jpSi0.png

那么我在这里做错了什么?

【问题讨论】:

【参考方案1】:

rootView.frame = self.bounds 行添加断点并检查self.bounds 值。如果值与滚动后的值不同,则应更改 awakeFromNib 方法。

类 PostMediaCollectionViewCell: UICollectionViewCell

@IBOutlet weak var container: UIView!
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var moreView: UIView!
@IBOutlet weak var moreViewLabel: UILabel!
@IBOutlet weak var myCustomView: MyCustomView!

override func awakeFromNib() 
    super.awakeFromNib()

    self.myCustomView.frame = self.bounds 
    self.myCustomView.autoresizingMask = [.flexibleWidth, .flexibleHeight]



func initialize() 
    //

【讨论】:

您说得对,当我向下和向上滚动时,bounds 的值是不同的,但是您的解决方案似乎对我没有任何改变。 ://【参考方案2】:

所以我找到了一个解决方案,但我不知道它为什么会起作用以及它是否是解决它的最佳方法,所以我正在寻找输入。

如果我修改我的PostMediaCollectionViewCell 类以在初始化函数中包含layoutIfNeeded(),它会起作用:

class PostMediaCollectionViewCell: UICollectionViewCell 

    @IBOutlet weak var container: UIView!
    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var moreView: UIView!
    @IBOutlet weak var moreViewLabel: UILabel!
    @IBOutlet weak var myCustomView: MyCustomView!

    override func awakeFromNib() 
        super.awakeFromNib()
    

    func initialize() 
        layoutIfNeeded()
    

但我不明白为什么。谁能解释一下?

【讨论】:

以上是关于另一个 xib 中的自定义 xib 大小不正确的主要内容,如果未能解决你的问题,请参考以下文章

显示来自 Xib 的自定义视图

从 .xib 加载自定义视图不适合 iPhone 6+

用作自定义 UITableViewCell 的 XIB 中的自定义按钮不响应点击(ios7)

使用 xib 和自动布局的自定义 UITableViewCell 无法在顶部的多个单元格中正确显示

iOS正确的自定义View方式

我有一个使用 XIB 文件创建的自定义 UICollectionViewCell。如何让这个单元格在点击时将另一个控制器推入堆栈