# Creating view rects in loop

I don't use constraints or IB to create views so it's easier to create rects this way. Does it wrong totaly?

@interface Client ()

@property (nonatomic, strong) UITextField *name;
@property (nonatomic, strong) UITextField *phoneNumber;
@property (nonatomic, strong) UIButton *submit;

@end

[self createSubviews];

}

- (void)createSubviews{

_name = [Utility textFieldWithPadding:@"Name" frame:[Utility rectForFormFields]];
_name.delegate = self;
_phoneNumber = [Utility textFieldWithPadding:@"Phone Number" frame:[Utility rectForFormFields]];
_phoneNumber.delegate = self;

_submit = [UIButton buttonWithType:UIButtonTypeCustom];
[_submit setTitle:@"Submit" forState:UIControlStateNormal];
_submit.backgroundColor = [[Cache sharedCache]blackColor];
_submit.frame = [Utility rectForFormFields];

}

- (void)saveClient{
}

- (void)textFieldDidBeginEditing:(UITextField *)textField{
_currentField = textField;
}

- (void)createViewsRects:(NSArray *)views{

for (UIView *view in views) {
CGRect viewRect = view.frame;
viewRect.origin.y = totalHeight;
view.frame = viewRect;
}
self.bgView.contentSize = CGSizeMake(self.view.frame.size.width, totalHeight);
}
@end

• Why aren't you using auto-layout? – nhgrif Nov 5 '14 at 21:17
• I don't like it. I know I write too much code here, but I feel more comfortable that way. – Pkwies Nov 5 '14 at 21:22

We should be using auto-layout. Not being as comfortable with auto-layout is not an excuse to not use it. Manually setting rects is not very good at all. Manually set rects don't play well with rotation. Manually set rects mean we probably need a special set of code for iPad versus iPhone. Manually set rects mean we probably need a special set of code for iPhone 4 vs iPhone 5 vs iPhone 6 vs iPhone 6+.

I'm not really going to touch the createSubviews method, which has some issues that should be address, but I do want to point out the problems with createViewRects: and how we can more easily write this code with auto-layout and using the Visual Format Language quite simply.

The method sets up the position for four views. The spacing follows two rules:

1. Each view has an X of 16 pixels from the left edge.
2. Each view has a Y that leaves a gap of 8 pixels between the other views (plus 8 pixels between the top of the super view and the top of the top view and 8 pixels between the bottom of the super view and the bottom of the bottom view).

For this, I'm going to assume that bgView is a scroll view. Scroll view's content doesn't really work particularly well with multiple top-level subviews. Instead, we give the bgView a single subview and add all of the subviews to that subview. This will allow auto-layout to work well.

Let's define a couple dictionaries to use with VFL.

For starters, so we can put them in a dictionary, let's use NSNumber objects rather than CGFloat for our metrics:

NSNumber *padding = @16.0;


We don't need a total height. Auto-layout will resolve this for us. Anyway, creating a dictionary is as simple as this:

NSDictionary *metrics = NSDictionaryOfVariableBindings(padding, rowPadding);


Now, using a mutable string, a mutable dictionary, let's set up these constraints:

int viewIndex = 0;
NSMutableDictionary *views = [NSMutableDictionary dictionary];

UIView *backgroundView = [[UIView alloc] init];

for (UIView *view in views) {
NSString *viewKey = [NSString stringWithFormat:@"view%i", viewIndex];
++viewIndex;

views[viewKey] = view;

NSString *horizConstraintStr =

NSArray *horizontalConstraints =
[NSLayoutConstraint constraintsWithVisualFormat:horizConstraintStr
options:0
metrics:metrics
views:views];

}

NSArray *verticalConstraints =
[NSLayoutConstraint constraintsWithVisualFormat:vertConstraintStr
options:0
metrics:metrics
views:views];


Consider what happens if we were to change the size of one of our subviews. With your code, we must be sure to call createViewsRect: each time any view changes sizes in order to ensure everything still looks right. With auto layout, the view will automatically adjust to the new size of one of the subviews. Plus, now you've got some experience working with auto layout so you'll be less intimidated and more comfortable with it in the future, particularly when you want to start doing more complicated layouts.