具有定义的框架约束的自定义 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]
,这意味着它将增长或在它的父视图增长或收缩时收缩。
要修复,请尝试以下步骤:
将自动调整掩码更改为:
约束“Item Size Detail Widget”的宽度等于“Container”的宽度,约束高度也等于:
我花了几个小时在谷歌搜索和调试器中,我无法弄清楚为什么我在这个 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:
.
由于您的 sizer
视图在从 nib 加载时将 translatesAutoresizingMaskIntoConstraints
设置为 true,并且由于其 autoresizingMask
为 [.flexibleWidth, .flexibleHeight]
,这意味着它将增长或在它的父视图增长或收缩时收缩。
要修复,请尝试以下步骤:
将自动调整掩码更改为:
约束“Item Size Detail Widget”的宽度等于“Container”的宽度,约束高度也等于: