Ios 徽章视图如何使用全自动布局方法创建
我已经有一段时间没有尝试创建在右上角有一个简单徽章的自定义视图了。Ios 徽章视图如何使用全自动布局方法创建,ios,autolayout,nslayoutconstraint,Ios,Autolayout,Nslayoutconstraint,我已经有一段时间没有尝试创建在右上角有一个简单徽章的自定义视图了。 自定义视图由3部分组成 红色为自定义视图本身,其中包含: 以蓝色显示容器视图 在绿色徽标视图中,显示一个简单的ui标签 容器视图和徽章视图是同级视图。 此时,容器视图包含一个UIImageView 该视图必须符合这些要求: 全自动布局方法 以编程方式制作 必须仅考虑蓝色框架(容器视图) 为什么?想象一下,您需要通过将上边缘与另一个视图或按钮的上边缘对齐来定位该视图,如果只考虑容器中显示的内容,那就不好了? 在这里,您可以看到我
自定义视图由3部分组成
ui标签
此时,容器视图包含一个
UIImageView
该视图必须符合这些要求:在这里,您可以看到我是如何设置约束的。标签放置在容器视图的右上角。
容器视图还具有纵横比约束,以保持正方形大小。
正如您从图片中看到的,一切似乎都很好,只是当我试图将自定义视图约束到其superview的中心时,它似乎没有对齐,因为我希望视图相对于容器视图(带有图像的视图)居中。徽章是一种装饰,比如影子,我不想让它被考虑。
为了正确对齐它,我试图通过添加一个将标签大小“剪切”一半的插入来覆盖对齐矩形。
override func alignmentRectInsets() -> UIEdgeInsets {
let badgeSize = badge.bounds.size
return UIEdgeInsets(top: badgeSize.height / 2, left: 0, bottom: 0, right: badgeSize.width / 2)
}
我也尝试了不同的配置,但我始终无法适应想要的位置
如果我尝试使用其他两种方法
alignmentRectForFrame
和frameForAlignmentRect
(删除alignmentrectinests
),则永远不会调用它们。以下是我想要得到的:
我创建了一个
如果问题是您希望另一个视图(显示图像的“内容视图”)在最终超级视图中居中,那么只需在超级视图和内容视图之间设置居中约束(中心x到中心x,中心y到中心y)。没有法律规定必须在视图与其直接超视图之间设置约束;您可以在任意一对视图之间进行约束(这是约束的一个奇妙之处) 我制作了一个很像你的“这是我想要得到的”图片的快速模型:
正如你所看到的,Moe(中间的PEP男孩,在图像的中间)正好位于超视界(绿色线所示)。
为了简单起见,整个接口都是用代码创建的,因此我可以向您展示整个过程。这是:// create the custom view
let customView = UIView()
customView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(customView)
customView.backgroundColor = UIColor.redColor()
NSLayoutConstraint.activateConstraints([
customView.widthAnchor.constraintEqualToConstant(100),
customView.heightAnchor.constraintEqualToConstant(100),
])
// add the content view (image) to the custom view
let contentView = UIImageView(image: UIImage(named:"pep.jpg")!)
contentView.translatesAutoresizingMaskIntoConstraints = false
customView.addSubview(contentView)
NSLayoutConstraint.activateConstraints([
contentView.leadingAnchor.constraintEqualToAnchor(customView.leadingAnchor),
contentView.bottomAnchor.constraintEqualToAnchor(customView.bottomAnchor),
contentView.heightAnchor.constraintEqualToAnchor(customView.heightAnchor, constant: -10),
contentView.widthAnchor.constraintEqualToAnchor(customView.widthAnchor, constant: -10)
])
// add the badge (label) to the custom view
let badge = UILabel()
badge.translatesAutoresizingMaskIntoConstraints = false
customView.addSubview(badge)
badge.backgroundColor = UIColor.greenColor().colorWithAlphaComponent(0.5)
badge.font = UIFont(name: "GillSans", size: 14)
badge.textAlignment = .Center
badge.text = "567"
NSLayoutConstraint.activateConstraints([
badge.centerXAnchor.constraintEqualToAnchor(contentView.trailingAnchor),
badge.centerYAnchor.constraintEqualToAnchor(contentView.topAnchor),
])
// position the whole thing with respect to the content view
NSLayoutConstraint.activateConstraints([
contentView.centerXAnchor.constraintEqualToAnchor(self.view.centerXAnchor),
contentView.centerYAnchor.constraintEqualToAnchor(self.view.centerYAnchor),
])
但这并不是你问题的完整答案。您现在应该会问:是的,但是当我尝试使用
对齐矩形插入时出现了什么问题?答案是:您忘记了,alignmentRectInsets
影响与内部视图和外部视图的对齐。换言之,您当然可以使用这种方法,但是您必须相应地调整内容视图的位置
因此,这里有一个重写,我使用了alignmentrectinests
。首先,我将为自定义视图定义一个自定义视图子类:
class AlignedView : UIView {
override func alignmentRectInsets() -> UIEdgeInsets {
return UIEdgeInsetsMake(10, 0, 0, 10)
}
}
现在是重写。我在与上一个示例不同的所有行旁边放了一个星号(*
):
// create the custom view
let customView = AlignedView() // *
customView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(customView)
customView.backgroundColor = UIColor.redColor()
NSLayoutConstraint.activateConstraints([
customView.widthAnchor.constraintEqualToConstant(100),
customView.heightAnchor.constraintEqualToConstant(100),
])
// add the content view (image) to the custom view
let contentView = UIImageView(image: UIImage(named:"pep.jpg")!)
contentView.translatesAutoresizingMaskIntoConstraints = false
customView.addSubview(contentView)
NSLayoutConstraint.activateConstraints([
contentView.leadingAnchor.constraintEqualToAnchor(customView.leadingAnchor),
contentView.bottomAnchor.constraintEqualToAnchor(customView.bottomAnchor),
contentView.heightAnchor.constraintEqualToAnchor(customView.heightAnchor), // *
contentView.widthAnchor.constraintEqualToAnchor(customView.widthAnchor) // *
])
// add the badge (label) to the custom view
let badge = UILabel()
badge.translatesAutoresizingMaskIntoConstraints = false
customView.addSubview(badge)
badge.backgroundColor = UIColor.greenColor().colorWithAlphaComponent(0.5)
badge.font = UIFont(name: "GillSans", size: 14)
badge.textAlignment = .Center
badge.text = "567"
NSLayoutConstraint.activateConstraints([
badge.centerXAnchor.constraintEqualToAnchor(contentView.trailingAnchor),
badge.centerYAnchor.constraintEqualToAnchor(contentView.topAnchor),
])
// position the whole thing with respect to the custom view
NSLayoutConstraint.activateConstraints([
customView.centerXAnchor.constraintEqualToAnchor(self.view.centerXAnchor), // *
customView.centerYAnchor.constraintEqualToAnchor(self.view.centerYAnchor), // *
])
这会产生与以前完全相同的视觉效果。但我必须承认我真的不明白你在追求什么。如果你画了一张你想要的图片,而不是展示你得到的图片,这可能会有所帮助。你好,谢谢你的建议,我已经编辑了这个问题。即使我尝试反转插图,它似乎也不起作用。对齐ReCt仍然考虑标签。实际上,除了自定义视图的框架之外,它似乎什么都没有改变。我已经创建了一个示例代码,也许我只是异常密集,但我仍然不明白问题是什么。当我想我可能明白你想做什么的时候,我不明白为什么这么难。我不明白你用这些名字指的是什么观点。如果您能将整个问题简化为一个非常简单的最小项目,将其发布到github上,并弄清楚生成的接口有什么问题,也许会对我有所帮助。这样,我就可以试着编辑项目本身。谢谢,如果我不清楚这个问题,我很抱歉。事实上,这对我自己来说也很容易,我不明白我对对齐矩形有什么遗漏或误解。我已经按照您的建议创建了一个github项目,尝试清理所有不必要的代码,并全面审查了问题。谢谢您,但我的帮助很有趣——很抱歉,我花了这么长时间才理解问题所在。
// create the custom view
let customView = AlignedView() // *
customView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(customView)
customView.backgroundColor = UIColor.redColor()
NSLayoutConstraint.activateConstraints([
customView.widthAnchor.constraintEqualToConstant(100),
customView.heightAnchor.constraintEqualToConstant(100),
])
// add the content view (image) to the custom view
let contentView = UIImageView(image: UIImage(named:"pep.jpg")!)
contentView.translatesAutoresizingMaskIntoConstraints = false
customView.addSubview(contentView)
NSLayoutConstraint.activateConstraints([
contentView.leadingAnchor.constraintEqualToAnchor(customView.leadingAnchor),
contentView.bottomAnchor.constraintEqualToAnchor(customView.bottomAnchor),
contentView.heightAnchor.constraintEqualToAnchor(customView.heightAnchor), // *
contentView.widthAnchor.constraintEqualToAnchor(customView.widthAnchor) // *
])
// add the badge (label) to the custom view
let badge = UILabel()
badge.translatesAutoresizingMaskIntoConstraints = false
customView.addSubview(badge)
badge.backgroundColor = UIColor.greenColor().colorWithAlphaComponent(0.5)
badge.font = UIFont(name: "GillSans", size: 14)
badge.textAlignment = .Center
badge.text = "567"
NSLayoutConstraint.activateConstraints([
badge.centerXAnchor.constraintEqualToAnchor(contentView.trailingAnchor),
badge.centerYAnchor.constraintEqualToAnchor(contentView.topAnchor),
])
// position the whole thing with respect to the custom view
NSLayoutConstraint.activateConstraints([
customView.centerXAnchor.constraintEqualToAnchor(self.view.centerXAnchor), // *
customView.centerYAnchor.constraintEqualToAnchor(self.view.centerYAnchor), // *
])