ios - UIImageView 上的 directionalLayoutMargins 在水平堆栈视图中不起作用
问题描述
我正在创建一个水平堆栈视图:
let hs = UIStackView(forAutoLayout: ());
hs.axis = .horizontal
hs.spacing = 0
hs.alignment = .top
hs.distribution = .fill
hs.layoutMargins = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
hs.isLayoutMarginsRelativeArrangement = true
hs.translatesAutoresizingMaskIntoConstraints = false
然后放置几个孩子:
let label = UILabel(forAutoLayout: ());
hs.addArrangedSubview(label)
let image = UIImageView(frame: CGRect(x: 0, y: 0, width: 32, height: 32))
image.directionalLayoutMargins = NSDirectionalEdgeInsets(top: 64, leading: 0, bottom: 16, trailing: 16)
hs.addArrangedSubview(image)
水平堆栈视图布局看起来不错,但是我在图像中添加了似乎被忽略的布局边距。有没有办法在水平堆栈视图中围绕特定子项设置边距?
编辑:
我知道我可以将 UIImageView 扔到另一个视图中并设置约束。或者更简单,只需使用 EdgeInsets 将其放入另一个堆栈视图中:
let imageStack = UIStackView(forAutoLayout: ());
imageStack.axis = .vertical
imageStack.alignment = .fill
imageStack.distribution = .fill
imageStack.directionalLayoutMargins = NSDirectionalEdgeInsets(top: 64, leading: 0, bottom: 16, trailing: 16)
imageStack.isLayoutMarginsRelativeArrangement = true
imageStack.translatesAutoresizingMaskIntoConstraints = false
imageStack.addArrangedSubview(image)
// add imageStack to horizontal stack view, instead of image
hs.addArrangedSubview(imageStack)
添加到另一个视图或在 UIImageView 中使用图像矩形插入似乎只是为了在视图周围添加边距或填充。来自 Android,我可以在任何视图(包括图像视图)上设置填充和边距,而无需包装在另一个元素中,这对于如此简单的事情来说似乎是一项疯狂的工作。
解决方案
不完全确定你要做什么,但听起来你想要:
- 水平堆栈视图
- 左边的标签
- 右侧的图像视图
- 图像视图 32x32 其
- image view top 64-pts from label top
所以,它看起来像这样:
绿色轮廓显示元素框架(包括堆栈视图)。
如果这是正确的,您可以通过.withAlignmentRectInsets()
在运行时修改图像来做到这一点。
这是一个例子:
class StackTestViewController: UIViewController {
let hs = UIStackView()
let label = UILabel()
let imageView = UIImageView()
override func viewDidLoad() {
super.viewDidLoad()
hs.axis = .horizontal
hs.spacing = 0
hs.alignment = .top
hs.distribution = .fill
hs.isLayoutMarginsRelativeArrangement = true
hs.translatesAutoresizingMaskIntoConstraints = false
label.text = "Test Label"
hs.addArrangedSubview(label)
hs.addArrangedSubview(imageView)
view.addSubview(hs)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
hs.topAnchor.constraint(equalTo: g.topAnchor, constant: 80.0),
hs.centerXAnchor.constraint(equalTo: g.centerXAnchor),
imageView.widthAnchor.constraint(equalToConstant: 32.0),
// we want the imageView to be 64-pts taller than its width
imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor, constant: 64)
])
if let img = UIImage(named: "swiftBlue64x64") {
// use withAlignmentRectInsets to create a new image with 64-pts "empty space" on top
imageView.image = img.withAlignmentRectInsets(UIEdgeInsets(top: -64, left: 0, bottom: 0, right: 0))
}
// so we can see the label frame
label.backgroundColor = .yellow
}
}
我使用了这个 64x64 像素的图像:
编辑
来自 Apple 的文档:
讨论
使用此属性可指定此视图的边缘与其子视图之间的所需空间量(以磅为单位)。
因此,您可以将其应用于UIStackView
整体或具有子视图的视图。这应该解释为什么它不能应用于UIImageView
(无子视图)。
推荐阅读
- javascript - Angularjs在页面刷新时收到错误404
- java - Java中的数组继承
- android - 无法解决:com.android.support:appcompat-v7:27.1.1
- javascript - 无法在 ag-grid 组件中加载数据
- google-maps - Google Api 不会每次都返回给定城市、州、国家/地区的邮政编码 | 反向地理编码
- android - 在 ExpandableListView 中添加 GridView
- ios - 占位符在构建时删除约束
- python - Azure Linux Python Webapp ImportError:libodbc.so.2 无法打开共享对象文件
- ios - Unity Codeless IAP IOS 构建被拒绝
- php - 具有不同金额的条纹的定期付款