如何使用自动布局创建总宽度的百分比?

我需要创建三个动态列,每个动态列占总宽度的固定百分比。不是三分之一,而是不同的价值。例如,下图显示了三列: 第一列宽42% ,第二列宽25% ,第三列宽33% 。

For a 600 pixel across viewcontroller, that would be 252, 150, and 198 pixels respectively.

然而,对于任何后续的显示屏尺寸(如 iPhone 4横屏(960宽)或 iPad 2纵屏(768宽) ,我希望相对百分比是相同的(而不是上面引用的像素宽度)。

有没有一种方法可以使用情节串连图板(即没有代码)做到这一点?我可以在代码中轻松地做到这一点,但我的目标是将尽可能多的显示逻辑放入故事板中。

enter image description here

65138 次浏览

If, as you say, you know how to do it in code, then you already know how to do it in the storyboard. It's exactly the same constraints, but you are creating them visually rather than in code.

  1. 同时选择视图及其超视图。

  2. 选择 Editor-> Pin-> Widths Equally 来约束宽度等于 Superview 的宽度(实际上在画布底部的“ Pin”弹出对话框在这里效果最好)。

  3. 编辑约束并将乘法器设置为所需的分数,例如0.42,其他视图也是如此。

I think this can be explained in more detail so it can be more easily applied to any number of views requiring fixed percentage layouts within a superview.

最左边的视图

  • 锚定在 SuperView.Leading
  • 将其固定百分比定义为 SuperView.Height上的乘数

中间观点

  • 将其固定百分比定义为 SuperView.Height上的乘数
  • 把它的 left固定在邻居的右边

右边-大部分景色

  • 不定义固定百分比(它是可用视图的其余部分)
  • 把它的 left固定在邻居的右边
  • 把它的 right固定到 SuperView.Trailing

所有意见

  • 通过锚定到 Top Layout Guide.TopTop Layout Guide.bottom来定义它们的非固定高度。在上面的答案中,我们注意到这也可以通过设置相邻视图的等高来实现。

随着苹果引入 UIStackView,工作变得容易多了。

方法1: 使用 Nib/StoryBoard:

你只需要在 Interface Builder 中添加三个 view 并将它们嵌入到 stackview 中

例如编辑器嵌入在 StackView 中

enter image description here

选择 stackView 并限制前导、后导、顶部和安全区域的高度相等

点击属性检查器区域 & 设置 StackView 水平和分布以按比例填充

[ < img src = “ https://i.stack.imgur.com/GXpnv.png”alt = “ enter image description here”> 3

给出了前、后、上、下三个视角各自侧面的约束。 enter image description here

方法2: 程序设计:

import UIKit
class StackViewProgramatically: UIViewController {
var propotionalStackView: UIStackView!
///Initially defining three views
let redView: UIView = {
let view = UIView()//taking 42 % initially
view.frame = CGRect(x: 0, y: 0, width: 42 * UIScreen.main.bounds.width/100, height: UIScreen.main.bounds.height)
view.backgroundColor = .red
return view
}()


let greenView: UIView = {
let view = UIView()//taking 42* initially
view.frame = CGRect(x: 42 * UIScreen.main.bounds.width/100, y: 0, width: 25 * UIScreen.main.bounds.width/100, height: UIScreen.main.bounds.height)
view.backgroundColor = .green
return view
}()
let blueView: UIView = {
let view = UIView()//taking 33*initially
view.frame = CGRect(x: 67 * UIScreen.main.bounds.width/100, y: 0, width: 33 * UIScreen.main.bounds.width/100, height: UIScreen.main.bounds.height)
view.backgroundColor = .blue
return view
}()


///Changing UIView frame to supports landscape mode.
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
DispatchQueue.main.async {
self.redView.frame = CGRect(x: 0, y: 0, width: 42 * self.widthPercent, height: self.screenHeight)
self.greenView.frame = CGRect(x: 42 * self.widthPercent, y: 0, width: 25 * self.widthPercent, height: self.screenHeight)
self.blueView.frame = CGRect(x: 67 * self.widthPercent, y: 0, width: 33 * self.widthPercent, height: self.screenHeight)
}
}


override func viewDidLoad() {
super.viewDidLoad()
//Adding subViews to the stackView
propotionalStackView = UIStackView()
propotionalStackView.addSubview(redView)
propotionalStackView.addSubview(greenView)
propotionalStackView.addSubview(blueView)
propotionalStackView.spacing = 0
///setting up stackView
propotionalStackView.axis = .horizontal
propotionalStackView.distribution = .fillProportionally
propotionalStackView.alignment = .fill
view.addSubview(propotionalStackView)
}
}
//MARK: UIscreen helper extension
extension NSObject {


var widthPercent: CGFloat {
return UIScreen.main.bounds.width/100
}


var screenHeight: CGFloat {
return UIScreen.main.bounds.height
}
}

产出:

与风景和肖像作品

enter image description here enter image description here

示范项目 -https://github.com/janeshsutharios/UIStackView-with-constraints

Https://developer.apple.com/videos/play/wwdc2015/218/