【问题标题】:Aligning the bounds of a UILabel proportionally to a sister UIView in the same subview将 UILabel 的边界与同一子视图中的姐妹 UIView 按比例对齐
【发布时间】:2016-01-10 16:40:53
【问题描述】:

我有一个静态图像,上面有一个区域,用于显示一些多行文本。就像电子游戏中角色的讲话泡泡。我抓住了一张看起来像这样的库存图片:

我有一个 UIImageView 设置为在主视图的子视图内适合宽高比(参见question)。我还在子视图中设置了一个 UILabel,它将保存多行文本。我希望能够在屏幕上移动子视图并使其具有任何大小,并且 UIImageView 仍然保持相同的方面,并且 UILabel 适合图像的气泡。

我创建了一个sample project,它已经设置好了。

我打算将 UILabel 的边界保持在对话气泡区域内的方法是设置与 UIImageView 的中心 x 和 y 成比例的约束。对于我的图像,左边的乘数是 0.65,右边是 1.8,顶部是 0.19,底部是 0.63。

我编写了几个从 UIView 扩展的函数来确认这一点:

/**
Draws a vertical line proportional to the center x of the view.

A `proportional` value of 0 is the left edge, while 2 is the right edge.

:param: proportion The value from the left edge (0.0) to the right edge (2.0)
:param: inColor The color to draw the line in (red by default)
*/
func drawVertLineAtProportion(proportion: CGFloat, inColor: UIColor = UIColor.redColor()) {
  let size = self.frame.size
  
  UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
  let context = UIGraphicsGetCurrentContext()
  
  let x = self.bounds.origin.x + proportion*self.frame.size.width/2
  
  var vertPath = UIBezierPath()
  vertPath.lineWidth = size.height/150.0
  vertPath.moveToPoint(CGPointMake(x, 0))
  vertPath.addLineToPoint(CGPointMake(x, self.frame.size.height))
  inColor.setStroke()
  vertPath.stroke()
  
  let image = UIGraphicsGetImageFromCurrentImageContext()
  UIGraphicsEndImageContext()
  
  self.addSubview(UIImageView(image: image))
}

drawHorizLineAtProportion 类似,但用于水平线。

我可以通过在viewDidAppear 中运行这 4 行来确认我的乘数值是正确的:

imageView.drawVertLineAtProportion(0.65)
imageView.drawVertLineAtProportion(1.8)
imageView.drawHorizLineAtProportion(0.19)
imageView.drawHorizLineAtProportion(0.63)

然后imageView看起来是这样的:

我可以将包含 imageView 的 subView 的大小更改为我想要的任何大小,并且 imageView 保持宽高比,并且这些红线交叉处的红色框始终正是我想要的。

那么,当我设置 UILabel 边缘的约束以遵循相同的公式时,为什么边缘不对齐?

似乎当imageView的宽度最大化时左右边缘是正确的但顶部和底部是错误的:

而如果高度达到最大值,则上下是正确的,但左右是错误的:

那么为什么 UILabel 边界不与红线对齐?

编辑指定我知道有一个运行时修复,但我想知道为什么故事板不起作用。

如果我在viewDidAppear 中添加这些行来修复 UILabel 的框架,它会起作用:

let upperLeft: CGPoint = CGPointMake(imageView.frame.origin.x + 0.65*imageView.frame.size.width/2, imageView.frame.origin.y + 0.19*imageView.frame.size.height/2)
let lowerRight: CGPoint = CGPointMake(imageView.frame.origin.x + 1.8*imageView.frame.size.width/2, imageView.frame.origin.y + 0.63*imageView.frame.size.height/2)
let size: CGSize = CGSizeMake(lowerRight.x - upperLeft.x, lowerRight.y - upperLeft.y)

speechLabel.frame = CGRectMake(upperLeft.x, upperLeft.y, size.width, size.height)

但我仍然想知道为什么我在故事板中设置的内容不起作用。

【问题讨论】:

    标签: ios storyboard autolayout alignment


    【解决方案1】:

    我想出了一个完全在故事板中的解决方案,它得到了我想要的,尽管我相信我最初的问题表明 Xcode 中存在错误。

    我注意到,由于 Xcode 似乎不尊重我想将 speechLabel 与姐妹 UI 元素 imageView 对齐,所以我只是将我正在对齐的 UIView 不再是 imageView

    我实施的解决方案是将imageViewspeechLabel 放入一个新的父视图中,我称之为aspectFitView。我对imageView 施加的所有约束以使其适合方面,我改为使用aspectFitView

    然后我设置imageView的约束,使其大小为aspectFitView:对齐中心x和y,宽度和高度相等。

    既然speechLabel 的父级是imageView 的确切大小、位置和纵横比,我将speechLabelaspectFitView 设置为比例约束,然后瞧。这一切都很漂亮。它在我的故事板上看起来是正确的,我不需要添加任何 post-viewDidAppear 帧校正代码,它在我运行它的任何设备上都能完美运行。

    我更新了sample project (Xcode 6.4) 为任何感兴趣的人提供解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-08
      • 2020-06-03
      • 2014-02-02
      • 2022-11-03
      • 1970-01-01
      相关资源
      最近更新 更多