HiveBrain v1.2.0
Get Started
← Back to all entries
patternswiftMinor

Constraints for auto layout

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
autoconstraintsforlayout

Problem

I am adding some constraints for my auto layout.

My method calling the methods creating the constraints:

```
// all
if displayUnitConversion && displayCode {
if currency.isDefaultCurrency {
buildConstraintsForDefaultCurrency(view1: computedRateLabel, sizeView1: 37, view2: codeLabel, sizeView2: 27)
} else {
switch (rowDisplayType) {
case 0:
buildConstraintsFor(view1: computedRateLabel, sizeView1: 30, view2: codeLabel, sizeView2: 18, view3: rateLabel, sizeView3: 15)
case 1:
buildConstraintsFor(view1: rateLabel, sizeView1: 18, view2: computedRateLabel, sizeView2: 30, view3: codeLabel, sizeView3: 15)
case 2:
buildConstraintsFor(view1: computedRateLabel, sizeView1: 30, view2: rateLabel, sizeView2: 18, view3: codeLabel, sizeView3: 15)
default:
break
}
}
codeLabel.hidden = false
rateLabel.hidden = false

computedRateLabel.font = computedRateLabel.font.fontWithSize(CGFloat(25))
codeLabel.font = codeLabel.font.fontWithSize(CGFloat(16))
rateLabel.font = rateLabel.font.fontWithSize(CGFloat(12))
} // rate only
else if !displayUnitConversion && !displayCode {
buildConstraintsFor(view1: computedRateLabel, sizeView1: 45)
codeLabel.hidden = true
rateLabel.hidden = true

computedRateLabel.font = computedRateLabel.font.fontWithSize(CGFloat(30))
} // rate and code
else if !displayUnitConversion && displayCode {
buildConstraintsFor(view1: computedRateLabel, sizeView1: 35, view2: codeLabel, sizeView2: 25)
codeLabel.hidden = false
rateLabel.hidden = true
computedRateLabel.font = computedRateLabel.font.fontWithSize(CGFloat(30))
codeLabel.font = codeLabel.font.fontWithSize(CGFloat(15))
} // rate and unit conversion
else if displayUnitConversion && !displayCode {
if currency.isDefaultCurrency {
buildConstraintsForDefaultCurrency(view1: computedRateLabel, sizeView1: 61)
} else {
switch (rowDisplay

Solution

Use interface builder.

Use interface builder to set up your constraints. If they need to be altered at run time, connect IBOutlets for the constraints and alter them at run time.

You can look at this Stack Overflow answer for a simplified approach at changing constraints at run time based on something you set up in interface builder.

What's not immediately obvious but that you should certainly keep in mind is that this approach saves us some run-time CPU time because we don't have to programmatically create the constraints every single time. The constraints are encoded into the interface builder file and loaded into memory when the view is loaded. It still takes some processor time to swap out the constraints, but at the end of the day this is much more efficient (and significantly cleaner) than what you have.

No more magic numbers.

You've got magic numbers all over the place, and several of them are repeated. If you ever change your mind on what value to use, now you have to change it in several places and hope you don't make a typo.

You've got a lot here, so I'm not going to even attempt coming up with a constant name for all of them, but suffice to say, all of the stuff that shows up in red on this page (all of the literal numbers) should instead be a named constant.

This includes the values for the case statements in the switch. These should be an enum.

About these build methods...

// build constraints for rate and unit conversion or for rate and currency code
func buildConstraintsForDefaultCurrency(#view1: UILabel, sizeView1: CGFloat)


All of your "build" methods all have the same set of problems.

-
They're called "build", but they actually "add" constraints. These method names should more clearly indicate that they're actually adding constraints. Otherwise, if they're called build, they should return constraints.

-
They manage to all require a comment describing what they do... and the comment isn't even in the useful Appledoc style so that Xcode will help you out with it later on. These all need better names and Appledoc style comments.

-
When you're numbering variables, you need an array. So, why not let this method take a variable number of arguments?

func setupConstraints(views forViews:[UIView], sizes withSizes:[CGFloat])


This will require a bit of extra logic to validate inputs and to figure out exactly how to set up the constraints, but once that's done, it's much easier to call and use this method now.

Code Snippets

// build constraints for rate and unit conversion or for rate and currency code
func buildConstraintsForDefaultCurrency(#view1: UILabel, sizeView1: CGFloat)
func setupConstraints(views forViews:[UIView], sizes withSizes:[CGFloat])

Context

StackExchange Code Review Q#98561, answer score: 3

Revisions (0)

No revisions yet.