4

I have a view with a lot of labels being populated with parsed XML. That view is within a UIScrollView. Some of the XML is too long for the labels. I'm resizing the labels based on the XML content. When the labels are re sized, they overlap the subsequent labels because my UIView (that is within the UIScrollView) isn't being re sized. I've been scouring the internet for hours trying to find an answer to this, but everything that I've tried hasn't achieved what I'm looking for. Any help would be greatly appreciated.

This is my populateLabels method.

-(void) populateLabels {

NSString *noInfo = (@"No Information Available");
lblCgName.text = _Campground.campground;
NSString *cgLoc = _Campground.street1; 
NSString *cgCity = _Campground.city;
NSString *cgState = _Campground.state1;
NSString *cgCountry = _Campground.country;
NSString *cgZipPostal = _Campground.zipPostal;
cgLoc = [[cgLoc stringByAppendingString:@", "] stringByAppendingString:cgCity];
cgLoc = [[cgLoc stringByAppendingString:@", "] stringByAppendingString:cgState];
cgLoc = [[cgLoc stringByAppendingString:@", "] stringByAppendingString:cgCountry];
cgLoc = [[cgLoc stringByAppendingString:@" "] stringByAppendingString:cgZipPostal];
lblCgLoc.text = cgLoc;
double dRate = [_Campground.regRate1 doubleValue];
double dRate2 = [_Campground.regRate2 doubleValue];
NSString *rate = [[NSString alloc] initWithFormat:@"$%0.2f",dRate];
NSString *rate2 = [[NSString alloc] initWithFormat:@"$%0.2f",dRate2];
if ([rate2 isEqualToString:@"$0.00"]) {
    lblRate.text = rate;
} else {
    rate = [[rate stringByAppendingString:@" - "] stringByAppendingString:rate2];
    lblRate.text = rate;
}
double dPaRate = [_Campground.paRate1 doubleValue];
double dPaRate2 = [_Campground.paRate2 doubleValue];
NSString *paRate = [[NSString alloc] initWithFormat:@"$%0.2f",dPaRate];
NSString *paRate2 = [[NSString alloc] initWithFormat:@"$%0.2f",dPaRate2];
if ([paRate2 isEqualToString:@"$0.00"]) {
    lblPaRate.text = paRate;
} else {
    paRate = [[paRate stringByAppendingString:@" - "] stringByAppendingString:paRate2];
    lblPaRate.text = paRate;
}
lblLocal1.text = _Campground.localPhone1;
lblLocal2.text = _Campground.localPhone2;
lblTollFree.text = _Campground.tollFree;
lblFax.text = _Campground.fax;
lblEmail.text = _Campground.email;
lblWebsite.text = _Campground.website;
NSString *gps = _Campground.latitude;
NSString *longitude = _Campground.longitude;
gps = [[gps stringByAppendingString:@", "] stringByAppendingString:longitude];
lblGps.text = gps;
lblHighlights.text = _Campground.highlights;
lblHighlights.lineBreakMode = UILineBreakModeWordWrap;
lblHighlights.numberOfLines = 0;

//label resizing

CGSize maximumLabelSize = CGSizeMake(296,9999);

CGSize expectedLabelSize = [_Campground.highlights sizeWithFont:lblHighlights.font 
                                  constrainedToSize:maximumLabelSize 
                                                  lineBreakMode:lblHighlights.lineBreakMode]; 

//adjust the label the the new height.
CGRect newFrame = lblHighlights.frame;
newFrame.size.height = expectedLabelSize.height;
lblHighlights.frame = newFrame;

lblTents.text = _Campground.tents;
lblNotes.text = _Campground.notes;
lblDirections.text = _Campground.directions;
lblRentals.text = _Campground.rentals;

}
tallybear
  • 417
  • 3
  • 17
  • I appreciate the input, but that's not really what I'm looking for. They are creating the scroll view with code and resizing it. I'm looking to re size the view that I already have within the scroll view that I already have. Everything works and it scrolls all the way down. I just need to expand the view that the labels are on. – tallybear Jan 13 '12 at 17:39
  • i can suggest you to first create all the labels, now after this u can calculate the view height dyanamically - label_height + offset_height_between_label + header_footer_offset. Now with this mch height you can create your view and then u can add label there. – rishi Jan 13 '12 at 19:52

3 Answers3

3

Where is the - (void) populateLabels method located? If it's in a view controller, you should have easy access to the view that needs to be resized. Alternatively, if the labels (which look to already be created) have been added to the view that needs to be resized, then you can access their superview. You've already got size you need, just set set the superview's frame size at the end of the method.

If you're trying to find the size of each label first based on the string content, you'll want to use the NSString method: -sizeWithFont. There are several variations of this that allow you to specify constraints:

Computing Metrics for a Single Line of Text – sizeWithFont: – sizeWithFont:forWidth:lineBreakMode: – sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode: Computing Metrics for Multiple Lines of Text – sizeWithFont:constrainedToSize: – sizeWithFont:constrainedToSize:lineBreakMode:

Remember that UILables only show 1 line of text. Also keep in mind that this will return the size that the string will take up. Views like UILabels and UITextViews tend to add padding, so you may need to account for that when calculating the height. After you've calculated the height and placed each label, you should then know the size the superView will need to be and set it appropriately. Also, if you don't know which label will be last/lowest/furthest down in the view (the size of the superView should be the origin.y + the size.height of the last view) you can do something like this:

CGFloat totalHeight = 0.0f;
for (UIView *view in superView.subviews)
    if (totalHeight < view.frame.origin.y + view.frame.size.height) totalHeight = view.frame.origin.y + view.frame.size.height;

This will give you the height of the superview if you don't already know it (and you can do the same thing for width if need be).

Aaron Hayman
  • 8,492
  • 2
  • 36
  • 63
  • The populateLabels method is located in my CampgroundDetailsViewController.m file. In the nib for that file, I have all my objects (labels, text views, buttons, etc) inside of a view. Then that view is inside of a scroll view. Is there something I'm doing wrong? – tallybear Jan 13 '12 at 23:24
  • Not that I can see, at the end of that method just resize the view that holds the labels/text/views/buttons/etc, and I'd also set the contentSize of the scroll view to accommodate. You should have access to both views through the class instance variables of the CampgroundDetailsViewController. – Aaron Hayman Jan 13 '12 at 23:45
  • Do you know how to dynamically set the view based on the content? I've heard that I need to use sizeToFit, but what should I pass in? – tallybear Jan 16 '12 at 16:10
  • You mean the size of the labels? You can find the size of the rect that a string will take by using the sizeWithFont: method available on every NSString instance. There are several variations to this method that allow you constrain the size. I'll update my response. – Aaron Hayman Jan 16 '12 at 17:12
1

Do you really need to use a bunch of labels?
It seems you need to use UITextView or UIScrollView.

Valeriy Van
  • 1,851
  • 16
  • 19
  • I've considered using a UITextView, but the problem with that lies with my target demographic. The app I'm building is designed for RVers. We currently have an iPhone app and we've gotten more complaints than praise. It uses a UITextView for the "Directions", "Highlights", and "Notes" sections. They complain that they can't get the view to scroll once they get to the TextView. 99% of our complaints are because our members don't know how to use their devices. – tallybear Jan 13 '12 at 17:46
  • If content in UITextView is less then UITextView itself, it will not be scrollable. I don't see reasons not to use UITextView here. But it's up to you. – Valeriy Van Jan 13 '12 at 17:56
  • I'm to the point where I'm just gonna tell the old folks to deal with it and use a UITextView. I just replaced the "Highlights" label with a TextView and it works fabulously. Then I won't have to resize the view. I can make it static, load up a bunch of TextViews, and not worry with it. – tallybear Jan 13 '12 at 17:56
  • bunch of UITextViews??? Interesting. You need one UITextView for everything for all text stuff. – Valeriy Van Jan 13 '12 at 17:59
  • May be I don't understand your problem. If you need to enforce your view to relayout subviews, call [self layoutSubviews]. Unfortunately for you, default implementation of this method does nothing, you will need to implement it yourself. – Valeriy Van Jan 13 '12 at 18:03
  • Well, there are different sections. The application I'm building lists campground amenities and such for RVers. Directions to the park, park highlights, additional notes about the part, etc. I'm using a different UITextView for each of those sections as they are longer than one line. At first I was using the labels and expanding them based on the content. Then in turn I wanted to expand (or contract) the view based on the total content of all of the labels (now TextViews). I'm still having an issue resizing everything based on it's content, but I'm not in as bad a pickle as I was. – tallybear Jan 13 '12 at 20:11
1

The general method to resize a UIView based on its subviews is sizeToFit This method resizes your UIView automatically.

If you wanted to constrain the size, you'll need to use sizeThatFits: This method does not resize your UIView automatically, rather it returns the size.

Just a side note: These two methods only factor in subviews so not drawings nor Core Text.

Kevin Low
  • 2,672
  • 16
  • 17
  • I tried using sizeToFit on my scrollView but it isn't doing anything. I have a View inside my scrollView and everything is on the View. Should I be doing it another way? – tallybear Jan 13 '12 at 23:23