Specifying CocoaTouch control coordinates and sizes without using Interface Builder
I'm getting started with iOS development, but am unable to use a mouse, as I'm blind and use Voiceover on both the Mac and iOS devices. In this particular case I'm unable to get someone to design the UI for me, so wish to lay out 9 controls on a view myself - nothing complex, just in 3 rows.
I can't do this myself in Interface Builder as it requires the use of the mouse to create connections, and for dragging controls from the library to the view. So I've created the UI in code, and this works.
But I now wish to lay out the controls:
- a UILabel with a UITextField next to it
- Underneath that, two UILabels and two UIButtons.
- there's a couple more controls - my intension is merely to indicate this is a simple UI.
Does anyone have any tips or rules-of-thumb that one could use to arrange these controls on the view. Each control is initialized with syntax similar to the below:
inputField = [[UITextField alloc] initWithFrame:CGRectMake(x, y, width, height)];
I've spent hours doing the maths in my head and trying to get a reasonable set of values for x/y/width/height with medioca results. Tips from anyone else who's done this before would be much appreciated.
I usually get the exact coords using a blank IB view, just to get the right #'s, then plug them in code.
Eventually, after talking to various people and researching further, I've come up with a better, but still suboptimal solution. the key piece of information I lacked was the SizeToFit message on UILabel objects.
Now, I create all labels first, set their text, and use SizeToFit to have the width/height automatically calculated. In the case of buttons, I also create labels and set the label as the button's title.
Next, I programatically calculate the width for all TextFields based on the labels and values for margin/padding:
- Suppose I want a label with a text field next to it.
- I create the label, and use SizeToFit.
- I define variables margin=10 and padding=5 (will investigate what these ought to be)
- then the text field's width is totalWidth-2*margin-myLabel.frame.size.width-padding
- the x value for the label is simly margin, and the x value for the text field is margin+myLabel.frame.size.width+padding
- For now I'm hard-coding the height of text fields at 20 - but again this will be refined.
I've made this a community wiki if others have improvements to this approach.