具有定义的框架约束的自定义 Xib 在运行时发生变化

Custom Xib With Defined Frame Constraints Is Changing At Runtime

我花了几个小时在谷歌搜索和调试器中,我无法弄清楚为什么我在这个 xib 中的父视图在 运行 时间发生变化。

我创建了一个简单的 Xib:

在容器中我设置了宽度和高度限制(我尝试在顶部父项中设置限制但我似乎无法做到):

在 运行 时,我以编程方式加载 Xib,并将其添加到视图中。但是我把它添加到视图中并设置位置后,父级的框架变小了,位置不对。

这里我明确地将 x 设置为 16,将 y 设置为 400。但是,当我在 inspector 调试工具中查看它时,我得到的结果与我想要的不同,因为父框架已经改变并且 Container 位置结果是错误的。我将检查器转到一边,这样您就可以看到父容器(蓝色)和子容器(白色),以及父容器如何小于子容器:

父级(根 xib 视图 'Item Detail Size Widget')的详细信息如下。注意高度现在是 32 而不是 76:

顶级子(Container)的详细信息如下:

因此,我为容器设置的约束得到遵守,但父级正在调整大小(我假设因为我无法设置约束,所以它会使用我设置的框架)。

我尝试关闭和打开 translatesAutoResizingMaskIntoConstraints 和其他一些东西,但我似乎无法让父级与容器的大小完全相同。

对于根项目详细信息大小小部件为何与容器的大小不匹配并且在 运行 时间发生变化,您有什么建议吗?

更新

这里是我添加小部件的代码供参考:

    let sizer: ItemDetailSizeWidget = .fromNib() 
    sizer.x = 16
    sizer.y = 400
    contentView.addSubview(sizer)

我有如下设置 x 和 y 的 UIView 扩展:

var x: CGFloat {
    set { self.frame = CGRect(x: newValue,
                              y: self.y,
                              width: self.width,
                              height: self.height)
        }
    get { return self.frame.origin.x }
}

var y: CGFloat {
    set { self.frame = CGRect(x: self.x,
                              y: newValue,
                              width: self.width,
                              height: self.height)
        }
    get { return self.frame.origin.y }
}

这里是 fromNib 扩展

class func fromNib<T: UIView>() -> T {
    return Bundle.main.loadNibNamed(String(describing: T.self), owner: nil, options: nil)![0] as! T
}
  • Xcode 始终对 xib 中的顶级视图使用自动调整大小掩码。您可以看到您的第一个屏幕截图:它显示了自动调整大小控件。

  • 您的顶级视图的 autoresizingMask 设置为灵活的宽度和高度。

  • 您没有在顶级视图和“容器”子视图之间设置任何宽度或高度限制。

您还有这个代码:

contentView.addSubview(sizer)

我怀疑(因为你提到了 contentView)你正在将 sizer 添加到 table 视图单元格或集合视图单元格的视图层次结构中。首次创建单元格时,它可能尚未达到最终大小。集合视图(或 table 视图)可能会在您从 collectionView:cellForRowAtIndexPath:.

return 后调整单元格的大小

由于您的 sizer 视图在从 nib 加载时将 translatesAutoresizingMaskIntoConstraints 设置为 true,并且由于其 autoresizingMask[.flexibleWidth, .flexibleHeight],这意味着它将增长或在它的父视图增长或收缩时收缩。

要修复,请尝试以下步骤:

  1. 将自动调整掩码更改为:

  2. 约束“Item Size Detail Widget”的宽度等于“Container”的宽度,约束高度也等于: