[iPhone]주어진 넓이 만큼 문자열 자르기

http://lambert.tistory.com/480
https://gist.github.com/906714


NSString-truncateToSize.h

//
// NSString-truncateToSize
// Fast Fonts
//
// Created by Stuart Shelton on 28/03/2010.
// Copyright 2010 Stuart Shelton.
//
// NSString truncate function for Objective C / iPhone SDK by
// Stuart Shelton is licensed under a Creative Commons Attribution 3.0
// Unported License (CC BY 3.0)
//
// http://creativecommons.org/licenses/by/3.0/
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface NSString (truncateToSize)
- (NSString *)truncateToSize: (CGSize)size withFont: (UIFont *)font lineBreakMode: (UILineBreakMode)lineBreakMode;
- (NSString *)truncateToSize: (CGSize)size withFont: (UIFont *)font lineBreakMode: (UILineBreakMode)lineBreakMode withAnchor: (NSString *)anchor;
- (NSString *)truncateToSize: (CGSize)size withFont: (UIFont *)font lineBreakMode: (UILineBreakMode)lineBreakMode withStartingAnchor: (NSString *)startingAnchor withEndingAnchor: (NSString *)endingAnchor;
@end
NSString-truncateToSize.m
//
// NSString-truncateToSize
// Fast Fonts
//
// Created by Stuart Shelton on 28/03/2010.
// Copyright 2010 Stuart Shelton.
//
// NSString truncate function for Objective C / iPhone SDK by
// Stuart Shelton is licensed under a Creative Commons Attribution 3.0
// Unported License (CC BY 3.0)
//
// http://creativecommons.org/licenses/by/3.0/
//
#import "NSString-truncateToSize.h"
@implementation NSString (truncateToSize)
- (NSString *)truncateToSize: (CGSize)size withFont: (UIFont *)font lineBreakMode: (UILineBreakMode)lineBreakMode {
    return [self truncateToSize: size withFont: font lineBreakMode: lineBreakMode withStartingAnchor: nil withEndingAnchor: nil];
} /* (NSString *)truncateToSize: withFont: lineBreakMode: */
- (NSString *)truncateToSize: (CGSize)size withFont: (UIFont *)font lineBreakMode: (UILineBreakMode)lineBreakMode withAnchor: (NSString *)anchor {
    return [self truncateToSize: size withFont: font lineBreakMode: lineBreakMode withStartingAnchor: anchor withEndingAnchor: anchor];
} /* (NSString *)truncateToSize: withFont: lineBreakMode: withAnchor: */
- (NSString *)truncateToSize: (CGSize)size withFont: (UIFont *)font lineBreakMode: (UILineBreakMode)lineBreakMode withStartingAnchor: (NSString *)startingAnchor withEndingAnchor: (NSString *)endingAnchor {
    if( !( lineBreakMode & ( UILineBreakModeHeadTruncation | UILineBreakModeMiddleTruncation | UILineBreakModeTailTruncation ) ) )
        return self;
    if( [self sizeWithFont: font].width <= size.width )
        return self;
   
    NSString *ellipsis = @"…";
    // Note that this code will find the first occurrence of any given anchor,
    // so be careful when choosing anchor characters/strings...
    NSInteger start;
    if( startingAnchor ) {
        start = [self rangeOfString: startingAnchor options: NSLiteralSearch].location;
        if( NSNotFound == start ) {
            if( [startingAnchor isEqualToString: endingAnchor] )
                return [self truncateToSize: size withFont: font lineBreakMode: lineBreakMode];
            else
                return [self truncateToSize: size withFont: font lineBreakMode: lineBreakMode withAnchor: endingAnchor];
        }
    } else {
        start = 0;
    }
   
    NSUInteger end;
    if( endingAnchor ) {
        end = [self rangeOfString: endingAnchor options: NSLiteralSearch range: NSMakeRange( start + 1, [self length] - start - 1 )].location;
        if( NSNotFound == end ) {
            if( [startingAnchor isEqualToString: endingAnchor] )
                // Shouldn't ever occur, since filtered out in block above...
                return [self truncateToSize: size withFont: font lineBreakMode: lineBreakMode];
            else
                return [self truncateToSize: size withFont: font lineBreakMode: lineBreakMode withAnchor: startingAnchor];
        }
    } else {
        end = [self length];
    }
    NSUInteger targetLength = end - start;
    if( [[self substringWithRange: NSMakeRange( start, targetLength )] sizeWithFont: font].width < [ellipsis sizeWithFont: font].width )
        if( startingAnchor || endingAnchor )
            return [self truncateToSize: size withFont: font lineBreakMode: lineBreakMode];
        else
            return self;
   
    NSMutableString *truncatedString = [[NSMutableString alloc] initWithString: self];
   
    switch( lineBreakMode ) {
        case UILineBreakModeHeadTruncation:
            // Avoid anchor...
            if( startingAnchor )
                start++;
            while( targetLength > [ellipsis length] + 1 && [truncatedString sizeWithFont: font].width > size.width) {
                // Replace our ellipsis and one additional following character with our ellipsis
                NSRange range = NSMakeRange( start, [ellipsis length] + 1 );
                [truncatedString replaceCharactersInRange: range withString: ellipsis];
                targetLength--;
            }
            break;
           
        case UILineBreakModeMiddleTruncation:
        {
            NSUInteger leftEnd = start + ( targetLength / 2 );
            NSUInteger rightStart = leftEnd + 1;
            if( leftEnd + 1 <= rightStart - 1 )
                break;
           
            // leftPre and rightPost consist of any characters before and beyond
            // any specified anchor(s).
            // left and right are the two halves of the string to be truncated - although
            // the initial split is still performed based upon the length of the
            // (sub)string to be truncated, so we could still make a bad initial split given
            // a short string with predominantly narrow characters on one side and wide
            // characters on the other.
            NSString *leftPre = @"";
            if( startingAnchor )
                leftPre = [truncatedString substringWithRange: NSMakeRange( 0, start + 1 )];
            NSMutableString *left = [NSMutableString stringWithString: [truncatedString substringWithRange: NSMakeRange( ( startingAnchor ? start + 1 : start ), leftEnd - start )]];
            NSMutableString *right = [NSMutableString stringWithString: [truncatedString substringWithRange: NSMakeRange( rightStart, end - rightStart )]];
            NSString *rightPost = @"";
            if( endingAnchor )
                rightPost = [truncatedString substringWithRange: NSMakeRange( end, [truncatedString length] - end )];
           
            /* NSLog( @"pre '%@', left '%@', right '%@', post '%@'", leftPre, left, right, rightPost ); */
            // Reassemble substrings
            [truncatedString setString: [NSString stringWithFormat: @"%@%@%@%@%@", leftPre, left, ellipsis, right, rightPost]];
           
            while( leftEnd > start + 1 && rightStart < end + 1 && [truncatedString sizeWithFont: font].width > size.width) {
                CGFloat leftLength = [left sizeWithFont: font].width;
                CGFloat rightLength = [right sizeWithFont: font].width;
               
                // Shorten string of longest width
                if( leftLength > rightLength ) {
                    [left deleteCharactersInRange: NSMakeRange( [left length] - 1, 1 )];
                    leftEnd--;
                } else { /* ( leftLength <= rightLength ) */
                    [right deleteCharactersInRange: NSMakeRange( 0, 1 )];
                    rightStart++;
                }
               
                /* NSLog( @"pre '%@', left '%@', right'%@', post '%@'", leftPre, left, right, rightPost ); */
                [truncatedString setString: [NSString stringWithFormat: @"%@%@%@%@%@", leftPre, left, ellipsis, right, rightPost]];
            }
        }
            break;
           
        case UILineBreakModeTailTruncation:
            while( targetLength > [ellipsis length] + 1 && [truncatedString sizeWithFont: font].width > size.width) {
                // Remove last character
                NSRange range = NSMakeRange( --end, 1);
                [truncatedString deleteCharactersInRange: range];
                // Replace original last-but-one (now last) character with our ellipsis...
                range = NSMakeRange( end - [ellipsis length], [ellipsis length] );
                [truncatedString replaceCharactersInRange: range withString: ellipsis];
                targetLength--;
            }
            break;
    }
   
    NSString *result = [NSString stringWithString: truncatedString];
    [truncatedString release];
    return result;
} /* (NSString *)truncateToSize: withFont: lineBreakMode: withStartingAnchor: withEndingAnchor: */
@end

Posted by incree

2011/09/17 04:56 2011/09/17 04:56
,
Response
0 Trackbacks , 0 Comments
RSS :
http://www.incree.com/tc/incree/rss/response/34

Trackback URL : 이 글에는 트랙백을 보낼 수 없습니다


Notices

Archives

Authors

  1. incree

Recent Trackbacks

Calendar

«   2017/10   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

Site Stats

Total hits:
427667
Today:
67
Yesterday:
210