【问题标题】:How to create percentage of total width using autolayout?如何使用自动布局创建总宽度的百分比?
【发布时间】:2014-12-10 00:02:38
【问题描述】:

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

对于跨视图控制器的 600 像素,分别为 252、150 和 198 像素。

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

有没有办法使用情节提要(即没有代码)来做到这一点?我可以在代码中轻松做到这一点,但我的目标是将尽可能多的显示逻辑放入 Storyboard。

【问题讨论】:

    标签: ios xcode autolayout


    【解决方案1】:

    如您所说,如果您知道如何在代码中执行此操作,那么您已经知道如何在情节提要中执行此操作。这是完全相同的约束,但您是在视觉上而不是在代码中创建它们。

    1. 同时选择一个视图及其父视图。

    2. 选择 Editor -> Pin -> Widths Equally 将宽度限制为等于父视图的宽度(实际上,画布底部的“pin”弹出对话框在这里效果最好)。

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

    【讨论】:

    • 确保您要约束的视图出现在 Equal Widths Constraint 的“第一项”而不是父视图的宽度中,否则您的子视图宽度是父视图宽度的倍数。当从子视图控制拖动到父视图以应用等宽约束时,这些总是相反的,这对我来说似乎违反直觉。
    • 啊——“在代码中做”我的意思更像是“手动,没有约束或自动布局”。
    • 不错的答案。我很惊讶 IB 没有提供一种无需编辑约束的方法。
    • 我试图在我的 UITableViewCell 中应用它,但一切都是灰色的。我必须将我所有的视图嵌入到一个新视图中,并从我的标签中选择 Width Equally 到这个新视图。希望对您有所帮助。
    • Xcode7 中的新功能:如果您想同样对齐视图,请使用新的“堆栈视图”。
    【解决方案2】:

    随着 Apple 推出 UIStackView,这让工作变得轻松多了。

    方法一:使用笔尖/StoryBoard:

    您只需在界面生成器中添加三个视图并将它们嵌入到堆栈视图中

    Xcode ► 编辑器 ► 嵌入 ► StackView

    选择 stackView 并通过 safeArea 提供前导、尾随、顶部和相等高度的约束

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

    [3

    给出三个视图的约束,分别是前导、尾随、顶部和底部。

    方法 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
        }
    }
    

    输出:

    适用于横向和纵向

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

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

    【讨论】:

      【解决方案3】:

      我认为这可以更详细地解释,因此它可以更容易地应用于在超级视图中需要固定百分比布局的任意数量的视图。

      最左侧视图

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

      中间视图

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

      最右侧视图

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

      所有视图

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-06
        • 2013-09-23
        • 2012-06-05
        • 2013-07-04
        • 2015-09-11
        • 1970-01-01
        • 2011-09-06
        • 2019-10-26
        相关资源
        最近更新 更多