使用视觉格式化语言计算不需要的按钮高度
Undesired button height being calculated using Visual Formatting Language
我有一个 UIViewController
,上面有四个 UIButtons
(2 x 2),我在界面生成器中布置得很好。我将拥有一个免费且支持广告的应用程序版本,因此我需要根据应用程序是付费版本还是广告支持版本重做该场景以进行加载。基于此,我正在尝试使用可视格式语言来布置视图。我的 UIButton
身高值不正确,尽管我在计算它们时考虑了它们。我想不通我的错误(或遗漏?)。
这是我的界面生成器的屏幕截图。
我对界面生成器中的按钮没有限制,但我确实有 IBOutlets
连接到 MyViewController
。 MyViewController
在导航控制器中,底部有一个标签栏。
我创建了一个名为 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
变量,但我尝试的每次迭代都会导致按钮在 topLayoutGuide
和 bottomLayoutGuide
下扩展。这是它在运行时的样子:
我欢迎任何关于在哪里查找我的错误的建议。感谢阅读。
我最初遵循 Ray Wenderlich's Visual Format Language tutorial 教程的设置与我的相似,因为 subViews
在故事板上并通过 IBOutlets
连接到 MyViewController
。
出于绝望,我修改了情节提要并在代码中创建了 UIButtons
。一路上,我发现我的问题是我在布局之前在按钮上设置图像。 这个故事的寓意是,在 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)
我有一个 UIViewController
,上面有四个 UIButtons
(2 x 2),我在界面生成器中布置得很好。我将拥有一个免费且支持广告的应用程序版本,因此我需要根据应用程序是付费版本还是广告支持版本重做该场景以进行加载。基于此,我正在尝试使用可视格式语言来布置视图。我的 UIButton
身高值不正确,尽管我在计算它们时考虑了它们。我想不通我的错误(或遗漏?)。
这是我的界面生成器的屏幕截图。
我对界面生成器中的按钮没有限制,但我确实有 IBOutlets
连接到 MyViewController
。 MyViewController
在导航控制器中,底部有一个标签栏。
我创建了一个名为 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
变量,但我尝试的每次迭代都会导致按钮在 topLayoutGuide
和 bottomLayoutGuide
下扩展。这是它在运行时的样子:
我欢迎任何关于在哪里查找我的错误的建议。感谢阅读。
我最初遵循 Ray Wenderlich's Visual Format Language tutorial 教程的设置与我的相似,因为 subViews
在故事板上并通过 IBOutlets
连接到 MyViewController
。
出于绝望,我修改了情节提要并在代码中创建了 UIButtons
。一路上,我发现我的问题是我在布局之前在按钮上设置图像。 这个故事的寓意是,在 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)