iOS 7 TextKit-텍스트와 함께 이미지를 인라인으로 삽입하는 방법은 무엇입니까?


109

UITextView를 사용하여 다음과 같은 효과를 얻으려고합니다.

여기에 이미지 설명 입력

기본적으로 텍스트 사이에 이미지를 삽입하고 싶습니다. 이미지는 단순히 한 줄의 공간 만 차지할 수 있으므로 줄 바꿈이 필요하지 않습니다.

하위보기에 UIView를 추가하려고했습니다.

UIView *pictureView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
[pictureView setBackgroundColor:[UIColor redColor]];
[self.textView addSubview:pictureView];

그러나 그것은 텍스트 위에 떠 있고 그것을 덮는 것처럼 보입니다.

나는 이것을 구현하는 한 가지 방법으로 보이는 제외 경로 에 대해 약간 읽었습니다 . 그러나 이미지의 위치를 ​​절대적으로 지정하고 싶지는 않습니다. 대신 텍스트와 함께 흐릅니다 ( <span>HTML에서 작동 하는 방식과 유사 ).


몇 가지 답변은 NSTextAttachment 및 NSTextField의 이미지 속성 사용에 대해 언급했지만 UIView를 추가 할 수있는 솔루션이 필요하다고 언급하고 싶습니다.
Andy Hin

5
오늘 아침에 WWE 네트워크를 통해 Royal Rumble 2011을 보았습니다 (당신의 이미지가 잡힌 곳). 그리고 여기서 저는이 질문에 대해 오늘 일어나고 있습니다.
bpapa

Heya, TextAttachment와 관련된 작업 코드의 예가 있습니까?
fatuhoku

답변:


180

속성이있는 문자열을 사용하고 이미지를의 인스턴스로 추가해야합니다 NSTextAttachment.

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"like after"];

NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
textAttachment.image = [UIImage imageNamed:@"whatever.png"];

NSAttributedString *attrStringWithImage = [NSAttributedString attributedStringWithAttachment:textAttachment];

[attributedString replaceCharactersInRange:NSMakeRange(4, 1) withAttributedString:attrStringWithImage];

4
지금까지 가장 가까운 대답이라고 생각합니다. UIImage 대신 UIView에서 이와 동일한 기술을 사용할 수 있습니까?
Andy Hin

4
UITextView에 결과 문자열을 사용할 때 이미지를 표시하지 않습니다
DeepK SOreadytohelp을

6
NSTextAttachment의 크기를 어떻게 조정합니까?
jsetting32

2
@bilobatum, textview에 이미지를 두 개 이상 추가하고 싶습니다. 그래서 어떻게 추가 할 수 있습니까?
Diken Shah 2015 년

3
`[attributedString insertAttributedString : textAttachment atIndex : 4]`가 다음보다 낫습니다.replaceCharactersInRange
DawnSong

26

@bilobatum의 코드는 필요한 사람들을 위해 Swift로 변환되었습니다.

let attributedString = NSMutableAttributedString(string: "like after")

let textAttachment = NSTextAttachment()

textAttachment.image = UIImage(named: "whatever.png")

let attrStringWithImage = NSAttributedString(attachment: textAttachment)

attributedString.replaceCharacters(in: NSMakeRange(4, 1), with: attrStringWithImage)

20

NSAttributedString 및 NSTextAttachment를 사용해 볼 수 있습니다. 이미지 크기를 조정하기 위해 NSTextAttachment를 사용자 지정하는 방법에 대한 자세한 내용은 다음 링크를 참조하십시오. http://ossh.com.au/design-and-technology/software-development/implementing-rich-text-with-images-on-os-x-and-ios/

내 예에서는 너비에 맞게 이미지 크기를 조정합니다. 귀하의 경우에는 선 높이와 일치하도록 이미지 크기를 조정할 수 있습니다.


지금까지 가장 가까운 대답이라고 생각합니다. UIImage 대신 UIView에서 이와 동일한 기술을 사용할 수 있습니까?
Andy Hin

사용자 정의 클래스에 대한 몇 가지 주요 작업을 수행 할 수 있습니다. NSTextAttachment에는 기본 이미지 속성이 있으며 첨부 파일은 NSAttributedString의 일부로 저장됩니다. 자신 만의 하위 클래스를 만들고 원하는 것을 저장할 수 있습니다. 디스플레이가 이미지를 표시하는 것으로 제한되어 있으므로 UIView가 유용할지 확신하지 못합니다. 내가 기억할 때 layoutManager는 이미지를 기대합니다.
Duncan Groenewald 2014 년

1
@AndyHin 나는 이것을 직접 테스트하지 않았지만 한 가지 옵션은 아마도 당신 UIView을 a 로 렌더링 UIImage한 다음 NSTextAttachment. 뷰를 이미지로 렌더링하려면 다음 질문을 확인 하십시오
Michael Gaylord

이것으로 새로운 발전이 있습니까?
fatuhoku 2014-06-24

5

@bilobatum의 답변을 확장하고 다른 질문 에서이 범주 를 사용 합니다 . 나는 이것을 요리했다 :

용법:

UILabel *labelWithImage = [UILabel new];
labelWithImage.text = @"Tap [new-button] to make a new thing!";
NSAttributedString *stringWithImage = [labelWithImage.attributedText attributedStringByReplacingOccurancesOfString:@"[new-button]" withImage:[UIImage imageNamed:@"MyNewThingButtonImage"] scale:0];
labelWithImage.attributedText = stringWithImage;

이행:

@interface NSMutableAttributedString (InlineImage)

- (void)replaceCharactersInRange:(NSRange)range withInlineImage:(UIImage *)inlineImage scale:(CGFloat)inlineImageScale;

@end

@interface NSAttributedString (InlineImages)

- (NSAttributedString *)attributedStringByReplacingOccurancesOfString:(NSString *)string withInlineImage:(UIImage *)inlineImage scale:(CGFloat)inlineImageScale;

@end

.

@implementation NSMutableAttributedString (InlineImages)

- (void)replaceCharactersInRange:(NSRange)range withInlineImage:(UIImage *)inlineImage scale:(CGFloat)inlineImageScale {

    if (floorf(inlineImageScale) == 0)
        inlineImageScale = 1.0f;

    // Create resized, tinted image matching font size and (text) color
    UIImage *imageMatchingFont = [inlineImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    {
        // Font size
        NSDictionary *attributesForRange = [self attributesAtIndex:range.location effectiveRange:nil];
        UIFont *fontForRange = [attributesForRange valueForKey:NSFontAttributeName];
        CGSize imageSizeMatchingFontSize = CGSizeMake(inlineImage.size.width * (fontForRange.capHeight / inlineImage.size.height), fontForRange.capHeight);

        // Some scaling for prettiness
        CGFloat defaultScale = 1.4f;
        imageSizeMatchingFontSize = CGSizeMake(imageSizeMatchingFontSize.width * defaultScale,     imageSizeMatchingFontSize.height * defaultScale);
        imageSizeMatchingFontSize = CGSizeMake(imageSizeMatchingFontSize.width * inlineImageScale, imageSizeMatchingFontSize.height * inlineImageScale);
        imageSizeMatchingFontSize = CGSizeMake(ceilf(imageSizeMatchingFontSize.width), ceilf(imageSizeMatchingFontSize.height));

        // Text color
        UIColor *textColorForRange = [attributesForRange valueForKey:NSForegroundColorAttributeName];

        // Make the matching image
        UIGraphicsBeginImageContextWithOptions(imageSizeMatchingFontSize, NO, 0.0f);
        [textColorForRange set];
        [inlineImage drawInRect:CGRectMake(0 , 0, imageSizeMatchingFontSize.width, imageSizeMatchingFontSize.height)];
        imageMatchingFont = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }

    // Text attachment with image
    NSTextAttachment *textAttachment = [NSTextAttachment new];
    textAttachment.image = imageMatchingFont;
    NSAttributedString *imageString = [NSAttributedString attributedStringWithAttachment:textAttachment];

    [self replaceCharactersInRange:range withAttributedString:imageString];
}

@end

@implementation NSAttributedString (InlineImages)

- (NSAttributedString *)attributedStringByReplacingOccurancesOfString:(NSString *)string withInlineImage:(UIImage *)inlineImage scale:(CGFloat)inlineImageScale {

    NSMutableAttributedString *attributedStringWithImages = [self mutableCopy];

    [attributedStringWithImages.string enumerateOccurancesOfString:string usingBlock:^(NSRange substringRange, BOOL *stop) {
        [attributedStringWithImages replaceCharactersInRange:substringRange withInlineImage:inlineImage scale:inlineImageScale];

    }];

    return [attributedStringWithImages copy];
}

@end

라인 변경 UIFont *fontForRange = [attributesForRange valueForKey:NSFontAttributeName];하려면 UIFont *fontForRange = [attributesForRange valueForKey:NSFontAttributeName] ?: [UIFont fontWithName:@"HelveticaNeue" size:12.0];, 더 나은해야하기 때문에 [attributesForRange valueForKey : NSFontAttributeName은]가 사전에 설정되지 않은 경우 nil이 될 수
빅터 곽을

5

간단한 예의 문제 해결 방법은 여기에 이미지 설명 입력

let attachment = NSTextAttachment()
attachment.image = UIImage(named: "qrcode")

let iconString = NSAttributedString(attachment: attachment)
let firstString = NSMutableAttributedString(string: "scan the ")
let secondString = NSAttributedString(string: "QR code received on your phone.")

firstString.append(iconString)
firstString.append(secondString)

self.textLabel.attributedText = firstString
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.