无法使用 PureLayout 将标签定位到视图的右边缘

Can't position label to right edge of view using PureLayout

我找到了一个很好的教程,它很好地解释了如何使用 PureLayout 来做一些很酷且简单的布局工作。我在让我的标签与我试图放入的视图的右侧对齐时遇到了一些问题

我在 class

的顶部有这个
var cardView: UIView!
var clipView: UIView!
var scrollView: UIScrollView!

...

然后我在 viewDidLoad()

中有这个
var openNowLabelView: UIView!
var openNowLabel: UILabel!

cardView = UIView(frame: CGRect.zero)
cardView.layer.shadowColor = UIColor.black.cgColor
cardView.layer.shadowOffset = CGSize(width: 0, height: 12)
cardView.layer.shadowOpacity = 0.33
cardView.layer.shadowRadius = 8
cardView.layer.shadowPath = UIBezierPath(roundedRect: cardView.bounds, cornerRadius: 12).cgPath

self.addSubview(cardView)

clipView = UIView(frame: CGRect.zero)
clipView.backgroundColor = UIColor(red: 42/255, green: 46/255, blue: 61/255, alpha: 1)
clipView.layer.cornerRadius = 12.0
clipView.clipsToBounds = true

cardView.addSubview(clipView)

scrollView = UIScrollView(frame: CGRect.zero)

clipView.addSubview(scrollView)

...

openNowLabelView = UIView(frame: CGRect.zero)
openNowLabel = UILabel(frame: CGRect.zero)
openNowLabel.textColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.5)
openNowLabel.font = UIFont(name: "Gibson-Regular", size: 18)
openNowLabel.text = "Open Now"
openNowLabelView.layer.borderWidth = 1
openNowLabelView.layer.borderColor = UIColor.red.cgColor
openNowLabel.textAlignment = .right

openNowLabelView.addSubview(openNowLabel)
scrollView.addSubview(openNowLabelView)

我有一个override func updateConstraints()函数

if(shouldSetupConstraints) {
  cardView.autoPinEdge(toSuperviewEdge: .bottom, withInset: edgesInset)
  cardView.autoPinEdge(toSuperviewEdge: .left, withInset: edgesInset)
  cardView.autoPinEdge(toSuperviewEdge: .right, withInset: edgesInset)
  cardView.autoSetDimension(.height, toSize: UIScreen.main.bounds.height - 32)

  clipView.autoPinEdge(.top, to: .top, of: cardView)
  clipView.autoPinEdge(.left, to: .left, of: cardView)
  clipView.autoPinEdge(.right, to: .right, of: cardView)
  clipView.autoPinEdge(.bottom, to: .bottom, of: cardView)

  scrollView.autoPinEdge(.top, to: .top, of: clipView, withOffset: 161)
  scrollView.autoPinEdge(.bottom, to: .bottom, of: clipView)
  scrollView.autoPinEdge(.left, to: .left, of: clipView)
  scrollView.autoPinEdge(.right, to: .right, of: clipView)

  ...

  openNowLabel.sizeToFit()
  openNowLabelView.autoSetDimension(.height, toSize: openNowLabel.bounds.height)
  openNowLabelView.autoSetDimension(.width, toSize: openNowLabel.bounds.width)
  openNowLabelView.autoPinEdge(.right, to: .right, of: scrollView, withOffset: edgesInset)
  openNowLabelView.autoPinEdge(.top, to: .top, of: placeDistanceLabelView)
  shouldSetupConstraints = false
}
super.updateConstraints()

这是我得到的结果,看起来像这样...

我不明白为什么会这样

更新

我已经稍微清理了视图和标签以使其更清晰,我能够解决我遇到的问题,我需要在视图中嵌入标签以使 PureLayout 库工作,希望这可以更好地说明我的代码对我在屏幕上看到的内容的说明

// setup views and labels
...
var scrollView: UIScrollView = {
    let view = UIScrollView.newAutoLayout()
    view?.translatesAutoresizingMaskIntoConstraints = false
    return view!
}()
...
var placeTitleLabel: UILabel = {
    let label = UILabel.newAutoLayout()
    label?.numberOfLines = 1
    label?.lineBreakMode = .byClipping
    label?.textColor = .white
    label?.font = UIFont(name: "Gibson-Semibold", size: 25)
    return label!
}()
var placeDistanceLabel: UILabel = {
    let label = UILabel.newAutoLayout()
    label?.numberOfLines = 1
    label?.lineBreakMode = .byClipping
    label?.textColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.5)
    label?.font = UIFont(name: "Gibson-Regular", size: 18)
    return label!
}()
var placeNumReviewsLabel: UILabel = {
    let label = UILabel.newAutoLayout()
    label?.numberOfLines = 1
    label?.lineBreakMode = .byClipping
    label?.textColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.5)
    label?.font = UIFont(name: "Gibson-Regular", size: 12)
    return label!
}()
var openNowLabel: UILabel = {
    let label = UILabel.newAutoLayout()
    label?.numberOfLines = 1
    label?.lineBreakMode = .byClipping
    label?.textColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.5)
    label?.font = UIFont(name: "Gibson-Regular", size: 18)
    label?.text = "Open Now"
    label?.textAlignment = .right
    return label!
}()

// constraints
placeTitleLabel.setContentCompressionResistancePriority(UILayoutPriority.required, for: .vertical)
placeTitleLabel.autoPinEdge(.top, to: .top, of: scrollView, withOffset: edgesInset)
placeTitleLabel.autoPinEdge(.left, to: .left, of: scrollView, withOffset: edgesInset)

placeDistanceLabel.setContentCompressionResistancePriority(UILayoutPriority.required, for: .vertical)
placeDistanceLabel.autoPinEdge(.left, to: .left, of: scrollView, withOffset: edgesInset)
placeDistanceLabel.autoPinEdge(.top, to: .bottom, of: placeTitleLabel, withOffset: edgesInset / 2)

placeNumReviewsLabel.setContentCompressionResistancePriority(UILayoutPriority.required, for: .vertical)
placeNumReviewsLabel.autoPinEdge(.left, to: .right, of: ratingView, withOffset: edgesInset)
placeNumReviewsLabel.autoPinEdge(.top, to: .top, of: ratingView, withOffset: -2)

openNowLabel.setContentCompressionResistancePriority(UILayoutPriority.required, for: .vertical)
openNowLabel.autoPinEdge(.trailing, to: .trailing, of: scrollView, withOffset: edgesInset)
openNowLabel.autoPinEdge(.top, to: .top, of: placeDistanceLabel)

据我在检查员中所说,当我突出显示 scrollView 时,嵌入其中的标签具有我的容器的整个宽度,并且标签本身似乎具有宽度等,就是不知道为什么右边缘对齐不了,左边缘没有问题

当我检查模拟器时,我在 openNowLabel 旁边看到了这个图标,但我不确定它是什么意思,也不知道如何获取相关信息,这是否与我的问题有关?

这是我上传的 link 回购协议,其中包含 运行 所需的所有 pods,看看我看到的内容是否有助于理解原始上下文

https://github.com/Jordan4jc/place-app-test

从您分享的代码示例来看,您似乎将 openNowLabel 添加为 openNowLabelView 的子视图,但您从未设置其约束。

如果我正确理解您要实现的目标,您需要将 openNowLabel 的边缘固定到其父视图(在 openNowLabelView 的情况下)。

更新

根据您共享的项目,您的滚动视图及其子视图似乎没有获得所有需要的约束,因此系统知道如何计算内容大小。看看这篇来自 Apple (Technical Note TN2154) 的文章:

Use constraints to lay out the subviews within the scroll view, being sure that the constraints tie to all four edges of the scroll view and do not rely on the scroll view to get their size.

尝试添加这些约束并查看是否获得所需的布局:

openNowLabel.autoPinEdge(.left, to: .right, of: placeDistanceLabel, withOffset: edgesInset)
ratingView.autoPinEdge(.bottom, to: .bottom, of: scrollView, withOffset: edgesInset)

注意:如果你只添加第一个约束,你的布局看起来是一样的,但是滚动视图会有一个模糊的布局,因为它无法计算内容大小的高度。