How to arrange labels in a flowlayout manner?
How do I arrange some UILabels and/or UIButtons of a variable length? I just want to add them to a UITableViewCell and they should arrange in a left-to-right flow, much like lines of text in a paragraph.
I only found开发者_C百科 possibilities to create lables with a fixed size and position using "initWithFrame:...". Same seems to be true for Interface Builder, as far as I can tell. Any solution is appreciated no matter if it's done in code or using a custom cell XIB-file.
UITableViewCell
, UILabel
, and UIButton
are all subclasses of UIView
and the documentation for UIView
says:
Layout and subview management
- A view may contain zero or more subviews.
- Each view defines its own default resizing behavior in relation to its parent view.
- A view can manually change the size and position of its subviews as needed.
So, it is certainly possible to do.
You can create your labels and buttons using initWithFrame:
with the argument CGRectZero
and then resize them (based on the text or whatever) using setBounds:
or setFrame:
(because right now you're just going to set the size of the view). Then, add these views as subviews of the cell's contentView
.
Then, in a custom subclass of UITableViewCell
you can implement your solution by overriding the default behavior (which does nothing) of layoutSubviews:
to set the origin field of the subview's frames (i.e., CGRect) that will position the subviews in the cell's content view (the size has already been set). You may need to call setNeedsLayout:
or layoutIfNeeded:
.
This is really a rough outline of how it is possible to implement a solution because there are a lot of details left out. For example, if you resize a button based on the the text of the titleLabel
you'll probably want to pad some to the width and height otherwise the button will be the size of the label and will look odd. In the layoutSubviews:
method there could be a fair amount of logic to layout the labels and buttons the way you want (e.g., it would be simpler if all the subviews of a cell where of the same type such as all labels) esp. if the subviews could wrap to a new line.
For multiline UILabels to get the width and height you should use the NSString method sizeWithFont:constrainedToSize:lineBreakMode: you can then use the sizes you get to lay everything out where it needs to be.
I want to do the same thing to allow users to enter tags into a text field - a bit like how when you type in an email address, the address gets converted into a blue tag (the the users name in when that users email address is already in your contacts list). Haven't written it yet, but will be happy to share with you once I do. I can't commit to how long it I will take to write this unfortunately. However if no one else has code they can share and you need to get the job done quickly - Just as a tip, consider this:
Create tag view objects where each object knows the size of the parent text field/tag container view and where each tag object has a utility method which a further tag object can use to insert itself at the right position. This approach makes it easy to manage the view and relayout tags using a simple iteration flow.
Hi If you still need an answer... To get the size of text (and to then calculate the frame of the UILabel/UIButton etc) use the sizeWithFont: NSString function which will give you the width/height of a string of text using a specified font.
There is a little bit of maths that you'll need to do to work out the best fit, where to place the UILabels, and the spacing, but you will have the data that you need to do it.
Hope this helps!
精彩评论