CainaSouza
CainaSouza

Reputation: 1437

UILabel auto size error on iOS 7

I'm making my app transition to iOS 7 and have this method (already modified for iOS 7, using boundingRectWithSize...):

+ (CGSize)messageSize:(NSString*)message {

    NSDictionary *attributes = @{NSFontAttributeName : [UIFont fontWithName:@"Futura-Medium" size:13]};

    CGRect frame = [message boundingRectWithSize:CGSizeMake([PTSMessagingCell maxTextWidth], CGFLOAT_MAX) options:NSStringDrawingUsesFontLeading attributes:attributes context:nil];

    return frame.size;
}

I am getting this appearance:

bubble

The message UILabel is being cut. It feels like line spacing is too big. It tried many other answers I found but none of them work.

If someone knows how to help me, I appreciate! ;)

Thanks!

Upvotes: 0

Views: 2768

Answers (3)

Mr. T
Mr. T

Reputation: 13055

Try changing NSStringDrawingUsesFontLeading as your option to NSStringDrawingUsesLineFragmentOrigin.

If you were only supporting iOS 6 and iOS 7, then I would definitely change all of your NSString's sizeWithFont:... to the NSAttributeString's boundingRectWithSize. Starting in iOS 6, the NSAttributedString's NSStringDrawing functions were introduced and they're threadsafe unlike the old NSString+UIKit methods we're used to (eg. sizeWithFont:..., etc), which were UIStringDrawing functions (and act unpredictably when you use them from a non-main thread. It'll save you a lot of headache if you happen to have a weird multi-threading corner case! Here's how I converted NSString's sizeWithFont:constrainedToSize::

What used to be:

NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
CGSize size = [text sizeWithFont:font 
               constrainedToSize:(CGSize){width, CGFLOAT_MAX}];

Can be replaced with:

NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
NSAttributedString *attributedText =
    [[NSAttributedString alloc]
        initWithString:text
        attributes:@
        {
            NSFontAttributeName: font
        }];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX}
                                           options:NSStringDrawingUsesLineFragmentOrigin
                                           context:nil];
CGSize size = rect.size;

Please note the documentation mentions:

In iOS 7 and later, this method returns fractional sizes (in the size component of the returned CGRect); to use a returned size to size views, you must use raise its value to the nearest higher integer using the ceil function.

So to pull out the calculated height or width to be used for sizing views, I would use:

CGFloat height = ceilf(size.height);
CGFloat width  = ceilf(size.width);

Upvotes: 4

imDeveloper
imDeveloper

Reputation: 824

I think you are updating your label frame from either viewDidLoad or viewWillAppear, so it is not working.

if you will update frame of label from viewDidAppear method then you will get updated frame of label.

I am not sure why this is happened, I think it is iOS 7 bug.

Upvotes: 0

Hemant Singh Rathore
Hemant Singh Rathore

Reputation: 2139

Try this

+ (CGSize)messageSize:(NSString*)message {

CGSize nameSize = [message sizeWithFont:[UIFont fontWithName:@"Futura-Medium" size:13]
                      constrainedToSize:CGSizeMake(maxWidth, maxHeight) lineBreakMode:NSLineBreakByWordWrapping];


NSLog(@"width = %f, height = %f", nameSize.width, nameSize.height);

return nameSize;
}

Upvotes: -1

Related Questions