2013-05-16 3 views
4

내 문제는 다음과 같습니다. iOS 앱에서 동적 콘텐츠가 있습니다 (twitter 앱은 아니지만 twits와 같이 텍스트와 이미지가 모두 포함됨). 주로 아이콘/이모티콘 및 미리보기 이미지). 텍스트와 이미지를 함께 테이블 행에 렌더링하려고합니다. 여기에서 가장 큰 어려움은 각 행마다 다른 크기 (캐싱이 어렵게 됨)가있을 것이고, 이미지 크기를 동적으로 계산하여 각 이미지 발생에 텍스트를 맞출 필요가 있습니다 (20 개의 이모티콘을 다른 + 텍스트 + 이모티콘 + 등).동적 텍스트와 이미지가 함께 렌더링 된 iOS UITableView (NSAttributedString + images)

저는 주변을 둘러 보았고 몇 가지 방법을 시도했습니다. 나의 초기 아이디어는 UIWebView를 사용하는 것이었다. 행마다 하나의 UIWebView가있는 샘플 앱을 만들 수 있었고 사전 렌더링 된 셀 성능에 대한 일부 "스마트 한"NSCache도 좋지 않았고 더하기 콘텐츠가 제대로로드되었을 때 UIWebView 자바 스크립트 콜백을 처리해야했습니다 .

두 번째 시도는 새로운 UITableViewCell에 대해 drawRect를 덮어 쓰는 것입니다. drawRect 메서드 내에서는 NSAttributedString과 NSSelectorFromString을 사용하여 각 종류의 내용 (일반 텍스트, 굵게, 기울임 꼴, 다른 색상, 이미지)의 범위를 설정합니다. 이미지에 맞게 CTRunDelegateCallbacks 콜백 (getAscent, getDescent, getWidth)을 사용하고 있습니다. 이런 식으로 뭔가 :이 방법에 대한 자세한 내용은

  CTRunDelegateCallbacks callbacks; 
      callbacks.version = kCTRunDelegateVersion1; 
      callbacks.getAscent = ascentCallback; 
      callbacks.getDescent = descentCallback; 
      callbacks.getWidth = widthCallback; 

      CTRunDelegateRef delegate = CTRunDelegateCreate(&callbacks, (__bridge void *)imgAttr); // img Attr is a Dictionary with all image info 

이 우수한 게시물을 확인하십시오 : http://www.raywenderlich.com/4147/how-to-create-a-simple-magazine-app-with-core-text#

마지막으로, 두 가지 질문 :

  • 이 나는, 가장 좋은 방법 할 수 있나요 좋은 성능으로 이것을 만드시겠습니까? 각 스크롤에 대해 각 셀에 drawRect를 호출해야한다면 번거롭지 않을지 궁금합니다. 사전에 할 수있는 것이 있습니까? 난 잠시 동안 놀았어요, 그리고 여전히 큰 지연 -하지만 아직 별도의 스레드에있는 모든 단일 행을 캐시하고 cellForRowAtIndexPath (메모리 사용을 초과 할 수 있습니다)에서 사용하려고하지 않았습니다;

  • 각 tableview 셀의 행 높이를 얻는 가장 좋은 방법을 알 수 없습니다. NSAttributedString이 내 모든 내용을 올바르게 처리 한 후에 내 drawRect 함수에서 사용하는 높이를 어떻게 알 수 있습니까?

    CGRect frame = [self.attString boundingRectWithSize:CGSizeMake(320, 10000) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading | NSStringDrawingUsesDeviceMetrics context:nil]; 
    

    이 작품 : 내의 drawRect 후 추가 정보를

    추가

는 --- 모든 컨텐츠 (문자열과 이미지) 나는 적절한 높이를 얻을 수 boundingRectWithSize를 사용하기 위해 노력하고있어 생성 괜찮 으면 텍스트 만,하지만 콘텐츠에 이미지 글리프를 추가하면 높이가 제대로 계산되지 않습니다 ...

답변

2

이 게시물은 r을 계산하는 올바른 방향으로 갈 수 있습니다 아야 높이 : 성능에 관해서는

Retrieve custom prototype cell height from storyboard?

, 당신은 지연의 원인을 좁힐 시간 프로파일 러를 실행 한?

+0

나는 즉시 시간 프로파일 러와 성능을 확인합니다. 그 게시물은 훌륭하지만 높이 계산 방법을 알려주지 않습니다 ... 사용하려고했습니다 : CGRect frame = [self.attString boundingRectWithSize : CGSizeMake (320, 10000) options : NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading | NSStringDrawingUsesDeviceMetrics 컨텍스트 : nil]; 하지만 적절한 값을 얻지는 못합니다. 내 인라인 이미지를 고려하지 않습니다. – cusquinho

+0

속성이 지정된 문자열에 대한 경험은 제한적이지만 rect를 계산하도록 요구하는 것은 올바른 접근 방식과 비슷합니다. 그러나 잘못된 대답을하는 경우, 해결 방법을 생각할 수 없다면 막 다른 골목 일 수 있습니다. 문자열을 UILabel에 넣고 sizeToFit을 호출 할 수 있습니까? 이것은 평범한 문자열만으로도 내가 과거에해온 것입니다. –

+0

sizeToFit 작동하지만 다른 크기의 인라인 이미지에 대한 지원이 느슨합니다 ... CTFrameGetLineOrigins를 사용하고 배열의 마지막 항목에 y 원점을 사용하여 접근법을 발견했을 수 있습니다. 그것이 작동하면 여기에 최종 결과를 게시합니다 .. 감사합니다! – cusquinho

3

같은 문제가 발생하여 오늘 해결했습니다. CTRunDelegateCallbacks이있는 텍스트 사이에 사용자 지정 개체를 그리지 만 boundingRectWithSize:options:context:은 정확한 높이를 제공하지 않았습니다. (그것은 내 사용자 정의 객체를 무시합니다).

대신 Core Text에 낮은 수준의 API가 있으며 모든 요구 사항을 충족하며 완전히 맞습니다. 그 문제에 대한 카테고리를 만들었습니다. 그것을 사용하여 재미있게 보내십시오! :-)

헤더 파일 :

#import <Foundation/Foundation.h> 

@interface NSAttributedString (boundsForWidth) 

- (CGRect)boundsForWidth:(float)width; 

@end 

실행 파일 : 나는 높이를 계산하는 방법을 그림과 같이

#import "NSAttributedString+boundsForWidth.h" 
#import <CoreText/CoreText.h> 

@implementation NSAttributedString (boundsForWidth) 

- (CGRect)boundsForWidth:(float)width 
{ 
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)self); 

    CGSize maxSize = CGSizeMake(width, 0); 

    CGSize size = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, 0), NULL, maxSize, nil); 

    CFRelease(framesetter); 

    return CGRectMake(0, 0, ceilf(size.width), ceilf(size.height)); 
} 

@end 
관련 문제