Search code examples
iosobjective-cnsattributedstring

Resize an image that is used in NSAttributedString


Possible duplicate but the accepted answer below is a simple one-function solution.

I'm trying to make a news article details view controller to display the article's image at the top then date then a long description.

I learned that i have to use NSAttributedString and only one UITextView in order to do that. Now everything works fine but i have only one issue now: the image width is not fitting the screen width (or the TextView width), please see this image below:

App Screenshot

I tried everything, nothing works.

How can i make the image fit screen width ?

Thanks in advance.

EDITED AGAIN This is the code that is involved:

#import "SingleNewsViewController.h"

@interface SingleNewsViewController ()

@end

@implementation SingleNewsViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSAttributedString *image = [self imageString];
    NSAttributedString *date = [self dateString];
    NSAttributedString *body = [self bodyString];

    NSMutableAttributedString *wholeStory = [NSMutableAttributedString new];

    // TODO: can you be sure image, date and body are all non-nil?
    NSArray *allComponents = @[image, date, body];
    for(NSAttributedString *component in allComponents)
    {
        [wholeStory appendAttributedString:component];
        if(component != [allComponents lastObject])
            [[wholeStory mutableString] appendString:@"\n\n"];
    }

    self.tv.attributedText = wholeStory;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (UIImage *)image
{
    return [UIImage imageNamed:@"latest_news_img.jpg"];
}

- (NSString *)dateText
{
    return @"Hi There, this is date!";
}

- (NSString *)bodyText
{
    return @"Hi There, this is body text!Hi There, .....";
}

- (NSAttributedString *)imageString
{
    NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
    textAttachment.image = [self image];
    return [NSAttributedString attributedStringWithAttachment:textAttachment];
}

- (NSAttributedString *)dateString
{
    return [[NSAttributedString alloc]
            initWithString:[self dateText]
            /*attributes:
             @{
             NSFontAttributeName: [UIFont preferredFontForTextStyle: UIFontTextStyleSubheadline],
             ... etc ...
             }*/];
}

- (NSAttributedString *)bodyString
{
    return [[NSAttributedString alloc]
            initWithString:[self bodyText]
            /*attributes:
             @{
             NSFontAttributeName: [UIFont preferredFontForTextStyle: UIFontTextStyleBody],
             ... etc ...
             }*/];
}



@end

Solution

  • Oh right, so NSTextAttachment doesn't have image views... ah... Right well then another idea comes to mind. How about reszing the UIImage data and then passing that image to the NSTextAttachment, like in this post:

    https://stackoverflow.com/a/2658801/4657588

    Make use of this method to resize the image accordingly:

    + (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
        //UIGraphicsBeginImageContext(newSize);
        // In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
        // Pass 1.0 to force exact pixel size.
        UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
        [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
        UIGraphicsEndImageContext();
        return newImage;
    }