ios - 使用视觉格式化语言计算不需要的按钮高度

标签 ios swift autolayout visual-format-language

我有一个 UIViewController ,上面有四个 UIButtons (2 x 2),我在界面生成器中布局,效果非常好。我的应用程序将有一个免费且支持广告的版本,因此我需要根据应用程序是付费版本还是支持广告的版本来重新加载该场景。基于此,我尝试使用视觉格式化语言来布局 View 。尽管在计算时考虑了 UIButton 高度,但我得到的值不正确。我无法弄清楚我的错误(或遗漏?)。

这是我的界面生成器的屏幕截图。 enter image description here

我对界面生成器中的按钮没有限制,但我确实将 IBOutlets 连接到 MyViewControllerMyViewController 位于导航 Controller 中,底部有一个标签栏。

我创建了一个名为 layoutButtons 的方法,在 super.viewDidLoad() 之后的 viewDidLoad 中调用该方法。这是:

func layoutButtons() {
    // Configure layout constraints

    // Remove interface builder constraints from storyboard
    view.removeConstraints(view.constraints)

    // create array to dump constraints into
    var allConstraints = [NSLayoutConstraint]()

    // determine screen size
    let screenSize: CGRect = UIScreen.mainScreen().bounds

    let navBarRect = navigationController!.navigationBar.frame
    let navBarHeight = navBarRect.height

    let tabBarRect = tabBarController!.tabBar.frame
    let tabBarHeight: CGFloat = tabBarRect.height

    // calculate button width based on screen size

    // padding for left + middle + right = 8.0 + 8.0 + 8.0 = 24.0
    let buttonWidth = (screenSize.width - 24.0) / 2

    /*
    My buttons are extending under the top & bottom layout guides despite accounting
    for them when I set the buttonHeight.
    */

    // padding for top + middle + bottom = 8.0 + 8.0 + 8.0 = 24.0
    let buttonHeight = (screenSize.height - topLayoutGuide.length - bottomLayoutGuide.length - 24.0) / 2

    // create dictionary of metrics
    let metrics = ["buttonWidth": buttonWidth,
        "buttonHeight": buttonHeight,
        "navBarHeight": navBarHeight,
        "tabBarHeight": tabBarHeight,
        "bannerAdWidth": bannerAdWidth,
        "bannerAdHeight": bannerAdHeight]

    // create dictionary of views
    var views: [String : AnyObject] = ["firstButton": firstButton,
        "secondButton": secondButton,
        "thirdButton": thirdButton,
        "fourthButton": fourthButton,
        "topLayoutGuide": topLayoutGuide,
        "bottomLayoutGuide": bottomLayoutGuide]

    let topRowHorizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat(
        "H:|-[firstButton(buttonWidth)]-[secondButton(buttonWidth)]-|",
        options: [.AlignAllCenterY],
        metrics: metrics,
        views: views)
    allConstraints += topRowHorizontalConstraints

    let bottomRowHorizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat(
        "H:|-[thirdButton(buttonWidth)]-[fourthButton(buttonWidth)]-|",
        options: [.AlignAllCenterY],
        metrics: metrics,
        views: views)
    allConstraints += bottomRowHorizontalConstraints

    let leftColumnVerticalConstraints = NSLayoutConstraint.constraintsWithVisualFormat(
        "V:|[topLayoutGuide]-[firstButton(buttonHeight)]-[thirdButton(buttonHeight)]-[bottomLayoutGuide]|",
        options: [],
        metrics: metrics,
        views: views)
    allConstraints += leftColumnVerticalConstraints

    let rightColumnVerticalConstraints = NSLayoutConstraint.constraintsWithVisualFormat(
        "V:|[topLayoutGuide]-[secondButton(buttonHeight)]-[fourthButton(buttonHeight)]-[bottomLayoutGuide]|",
        options: [],
        metrics: metrics,
        views: views)
    allConstraints += rightColumnVerticalConstraints

    NSLayoutConstraint.activateConstraints(allConstraints)
}

我摆弄了 buttonHeight 变量,但我尝试的每次迭代都会导致按钮在 topLayoutGuidebottomLayoutGuide 下扩展。这是运行时的样子:

enter image description here

我欢迎任何在哪里查找我的错误的建议。感谢您的阅读。

最佳答案

我最初关注的是 Ray Wenderlich's Visual Format Language tutorial本教程的设置与我的类似,因为 subViews 位于 Storyboard 上,并通过 IBOutlets 连接到 MyViewController

出于绝望,我取消了 Storyboard并在代码中创建了 UIButtons。一路上,我发现我的问题是我在按钮上放置图像之前就将其设置了。 这个故事的寓意是,在 UIButtons 上放置图像之前,不要在它们布置好之前将其设置!

下面是从我的 viewDidLoad 中的一个方法调用的代码,它布置了 2 x 2 的按钮网格:

    // Configure Buttons
    firstButton.translatesAutoresizingMaskIntoConstraints = false
    // code to customize button

    secondButton.translatesAutoresizingMaskIntoConstraints = false
    // code to customize button

    thirdButton.translatesAutoresizingMaskIntoConstraints = false
    // code to customize button

    fourthButton.translatesAutoresizingMaskIntoConstraints = false
    // code to customize button

    // Add buttons to the subview
    view.addSubview(firstButton)
    view.addSubview(secondButton)
    view.addSubview(thirdButton)
    view.addSubview(fourthButton)

    // create views dictionary
    var allConstraints = [NSLayoutConstraint]()

    let views: [String : AnyObject] = ["firstButton": firstButton,
        "secondButton": secondButton,
        "thirdButton": thirdButton,
        "fourthButton": fourthButton,
        "topLayoutGuide": topLayoutGuide,
        "bottomLayoutGuide": bottomLayoutGuide]

    // Calculate width and height of buttons
    // 24.0 = left padding + middle padding + right padding
    let buttonWidth = (screenSize.width - 24.0) / 2
    let buttonHeight = (screenSize.height - topLayoutGuide.length - bottomLayoutGuide.length - 24.0) / 2

    // Create a dictionary of metrics
    let metrics = ["buttonWidth": buttonWidth,
    "buttonHeight" : buttonHeight]

    let topVerticalConstraints = NSLayoutConstraint.constraintsWithVisualFormat(
        "V:|[topLayoutGuide]-[firstButton(buttonHeight)]",
        options: [],
        metrics: metrics,
        views: views)
    allConstraints += topVerticalConstraints

    let topRowHorizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat(
        "H:|-[firstButton(buttonWidth)]-[secondButton(==firstButton)]-|",
        options: NSLayoutFormatOptions.AlignAllCenterY,
        metrics: metrics,
        views: views)
    allConstraints += topRowHorizontalConstraints

    let bottomRowHorizontalContraints = NSLayoutConstraint.constraintsWithVisualFormat(
        "H:|-[thirdButton(buttonWidth)]-[fourthButton(==thirdButton)]-|",
        options: NSLayoutFormatOptions.AlignAllCenterY,
        metrics: metrics,
        views: views)
    allConstraints += bottomRowHorizontalContraints

    let leftColumnVerticalConstraints = NSLayoutConstraint.constraintsWithVisualFormat(
        "V:[firstButton]-[thirdButton(==firstButton)]-[bottomLayoutGuide]-|",
        options: [],
        metrics: metrics,
        views: views)
    allConstraints += leftColumnVerticalConstraints

    let rightColumnVerticalConstriants = NSLayoutConstraint.constraintsWithVisualFormat(
        "V:[secondButton(buttonHeight)]-[fourthButton(==secondButton)]-[bottomLayoutGuide]-|",
        options: [],
        metrics: metrics,
        views: views)
    allConstraints += rightColumnVerticalConstriants

    NSLayoutConstraint.activateConstraints(allConstraints)

    // ** DON'T SET IMAGES ON THE BUTTONS UNTIL THE BUTTONS ARE LAID OUT!!!**
    firstButton.imageView?.contentMode = UIViewContentMode.ScaleAspectFit
    firstButton.setImage(UIImage(named: "first.png"), forState: .Normal)

    secondButton.imageView?.contentMode = UIViewContentMode.ScaleAspectFit
    secondButton.setImage(UIImage(named: "second.png"), forState: .Normal)

    thirdButton.imageView?.contentMode = UIViewContentMode.ScaleAspectFit
    thirdButton.setImage(UIImage(named: "third.png"), forState: .Normal)

    fourthButton.imageView?.contentMode = UIViewContentMode.ScaleAspectFit
    fourthButton.setImage(UIImage(named: "fourth.png"), forState: .Normal)

关于ios - 使用视觉格式化语言计算不需要的按钮高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34996942/

相关文章:

javascript - Phonegap(Cordova)图片上传到服务器太大

ios - 更换相机 iOS 后相机帧丢失

objective-c - UIScrollView 旋转后仅显示部分 UIView

ios - 在今日扩展中使用自动布局的动态高度

横向定位错误中的 iOS 模式弹出窗口?

ios - Swift 1.2 - Xcode 6.4 - 如何使用 Parse.com 发送短信 (sms) 类似于发生了什么?

ios - 单元格一开始不出现,但如果我向下滚动并返回,则会显示

ios - 两个带有搜索栏的自定义单元格

ios - 离开并返回 View Controller 后 UIInputViewController 被解雇

swift - 添加导航项会缩小 View 中的所有内容