mamaral / Neon

A powerful Swift programmatic UI layout framework.
MIT License
4.58k stars 389 forks source link

Dynamic UIlabel #12

Closed wieseljonas closed 9 years ago

wieseljonas commented 9 years ago

It's not a issue just a suggestion. at the moment I have UILabels that can have 1 to 2 lines depending and text size.

at the moment I do this like this but I'm sure there is a better way

let nameLabelHeight = nameLabel.text?.heightWithConstrainedWidth(self.width - 24 - profilePictureImageView.width, font: nameLabel.font)
    if let n = nameLabelHeight where n > 60 {
        nameLabel.alignAndFillWidth(align: .ToTheRightMatchingTop, relativeTo: profilePictureImageView, padding: 8, height: 60)
    } else if let n = nameLabelHeight {
        nameLabel.alignAndFillWidth(align: .ToTheRightMatchingTop, relativeTo: profilePictureImageView, padding: 8, height: n)
    }
mamaral commented 9 years ago

That is the number 1 thing I plan to add and have a pretty good idea how I would handle it. Ultimately what I envision is you'll do something like this:

nameLabel.alignAndFillWidth(align: .ToTheRightMatchingTop, relativeTo: profilePictureImageView, padding: 8, height: LabelAutoHeight)

LabelAutoHeight (or something similar) will be a Neon-defined constant you can just throw in there, telling the function itself to size automatically and then re-align. Under the covers that will essentially do the following (which is what I currently do myself)

nameLabel.alignAndFillWidth(align: .ToTheRightMatchingTop, relativeTo: profilePictureImageView, padding: 8, height: 0)
nameLabel.sizeToFit()
nameLabel.alignAndFillWidth(align: .ToTheRightMatchingTop, relativeTo: profilePictureImageView, padding: 8, height: nameLabel.height)

The reason you need to do something like that, it seems to me, is that the first pass through alignAndFillWidth() sets the width, but doesn't know the correct height yet and needs to set the y offset based on that. So then when you sizeToFit() it uses that same width but dynamically sets the height based on that width, and then adjusts the y value so that it matches the intended alignment specified. This should work with any number of lines.

Does that make sense and/or do you think the first bit of code that's a one-liner would suit your needs?

wieseljonas commented 9 years ago

@mamaral Thanks for the quick reply I will give it a spin and get back to you

mamaral commented 9 years ago

In case it wasn't clear, that first chunk of code with LabelAutoHeight has not been implemented yet, but in the meantime using those three lines with the sizeToFit() in the middle should auto-size and align the label correctly with any number of lines.

wieseljonas commented 9 years ago

@mamaral Ok got it. Thanks for the great work

mamaral commented 9 years ago

Implemented the first crack at it. Check this out and let me know if this is what you were thinking:

https://github.com/mamaral/Neon#what-about-labels

mamaral commented 9 years ago

You should be good to go, let me know if you have issues.

wieseljonas commented 9 years ago

I will give it a spin. If I can give a quick feedback. In my case a need to make sure the UILabel doesn't exceed a certain height. I think a maxHeight or maxWidth option could really be useful.

wieseljonas commented 9 years ago

Another 2 cents worth. In my case I'm not between 2 views but I need the label to fill the width from a view and the border of the superview. Maybe I didn't get fully and it's already possible.

mamaral commented 9 years ago

I don't have the max/min height capability, but you're able to pass in AutoHeight to any method that accepts a height param and the label will auto size and align appropriately.