UIImageView 上的 directionalLayoutMargins 在水平堆栈视图中不起作用
Posted
技术标签:
【中文标题】UIImageView 上的 directionalLayoutMargins 在水平堆栈视图中不起作用【英文标题】:directionalLayoutMargins on UIImageView not working inside horizontal stack view 【发布时间】:2020-08-24 21:45:42 【问题描述】:我正在创建一个水平堆栈视图:
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,我可以在任何视图(包括图像视图)上设置填充和边距,而无需包装在另一个元素中,这对于如此简单的事情来说似乎是一项疯狂的工作。
【问题讨论】:
您是否要向图像视图“添加顶部填充”?如果是这样,那么这种方法是不正确的。见:***.com/questions/32551890/… 因此,要向图像视图添加插图或边距,您必须将其放在另一个视图中。看起来很荒谬,感谢 ios。 【参考方案1】:不完全确定你想要什么,但听起来你想要:
水平堆栈视图 左侧标签 右侧的图像视图 图像视图 32x32 其 图像视图顶部距离标签顶部 64 分所以,它看起来像这样:
绿色轮廓显示元素框架(包括堆栈视图)。
如果正确,您可以使用.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
(无子视图)。
【讨论】:
谢谢。我更新了这个问题,我想它真的是关于我认为我对 directionalLayoutMargins 的误解。似乎我应该能够在 ImageView 上设置边距。我知道我可以将 UIIImageView 包装在另一个视图中,或者弄乱 ImageView 中的图像插图。但这似乎是一种解决方法,因为人们不能简单地在 ImageView 周围添加边距。以上是关于UIImageView 上的 directionalLayoutMargins 在水平堆栈视图中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 中检测 UIImageView 上的 UIImageView 更改或 KVO 炒锅