2011-01-25 38 views

答えて

0

文字列の長さを数えてコード化して、その部分文字列を表示しないと、部分文字列を作成しないのはなぜですか?またはそれは生だが効果的な方法

+0

はこれが唯一の固定幅フォントで確実に動作するわけではないだろうと呼ばれていますか? – Dolbz

+0

私はこれを使って標準APIを作るつもりはありません。フォントの仕様は、私が推測する要件ごとに固定されます。 – Javanator

0

ます。また、これにより

[lbl setAdjustsFontSizeToFitWidth:YES]; 

を設定することができますされて あなたが欲しいものは、テキストを切り捨てる必要はないだろうかと、あなたのlabelに完全なテキストを表示することができます。

+0

私はカスタムフォント(UIAppFonts-keyで設定)を使用しているために動作しません – Felix

1

-[UILabel setLineBreakMode:]およびUILineBreakModeCharacterWrapをご覧ください。 -[UILabel lineBreakMode]のデフォルト値はUILineBreakModeTailTruncationで、最後に省略記号が表示されます。

0

Javanatorは、自分で切り捨てる必要があると言いました。 NSStringクラスのUIKitの追加で sizeWithFont:forWidth:lineBreakMode:メッセージを使用して、特定のフォントの文字列の幅を取得してください。これにより、すべてのタイプのフォントが処理されます。

Link

9

私はあなたのコードところ、これまでに開くことができますカスタム切り捨てクラスを書かれています。以下の方法を使用してください。切り捨てが行われた場合はtrueを返し、ラベルのデフォルトのフレーム幅を使用する場合はMaxWidthを0のままにできます。 maxWidthをフレーム幅よりも小さくして、フレーム境界内で短くします。 (変換のためのいくつかの迅速な3件のコメント付き)

スイフト2

使用:

Truncater.replaceElipsis(forLabel: label, withString: "???") 
let didTruncate = Truncater.replaceElipsis(forLabel: label, withString: "1234", andMaximumWidth: 50) //maxWidth is not number of chars, but label width in CGFloat 

クラス:

import UIKit 

class Truncater { 

    class func replaceElipsis(forLabel label:UILabel, withString replacement:String) -> Bool { 
     return replaceElipsis(forLabel: label, withString: replacement, andMaximumWidth:0) 
    } 

    class func replaceElipsis(forLabel label:UILabel, withString replacement:String, andMaximumWidth width:CGFloat) -> Bool { 

     if(label.text == nil){ 
      return false 
     } 

     let origSize = label.frame; 
     var useWidth = width 

     if(width <= 0){ 
      useWidth = origSize.width //use label width by default if width <= 0 
     } 

     label.sizeToFit() 
     let labelSize = label.text!.sizeWithAttributes([NSFontAttributeName: label.font]) //.size(attributes: [NSFontAttributeName: label.font]) for swift 3 

     if(labelSize.width > useWidth){ 

      let original = label.text!; 
      let truncateWidth = useWidth; 
      let font = label.font; 
      let subLength = label.text!.characters.count 

      var temp = label.text!.substringToIndex(label.text!.endIndex.advancedBy(-1)) //label.text!.substring(to: label.text!.index(label.text!.endIndex, offsetBy: -1)) for swift 3 
      temp = temp.substringToIndex(temp.startIndex.advancedBy(getTruncatedStringPoint(subLength, original:original, truncatedWidth:truncateWidth, font:font, length:subLength))) 
      temp = String.localizedStringWithFormat("%@%@", temp, replacement) 

      var count = 0 

      while temp.sizeWithAttributes([NSFontAttributeName: label.font]).width > useWidth { 

       count+=1 

       temp = label.text!.substringToIndex(label.text!.endIndex.advancedBy(-(1+count))) 
       temp = temp.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()) //remove this if you want to keep whitespace on the end 
       temp = String.localizedStringWithFormat("%@%@", temp, replacement) 
      } 

      label.text = temp; 
      label.frame = origSize; 
      return true; 
     } 
     else { 

      label.frame = origSize; 
      return false 
     } 
    } 

    class func getTruncatedStringPoint(splitPoint:Int, original:String, truncatedWidth:CGFloat, font:UIFont, length:Int) -> Int { 

     let splitLeft = original.substringToIndex(original.startIndex.advancedBy(splitPoint)) 

     let subLength = length/2 

     if(subLength <= 0){ 
      return splitPoint 
     } 

     let width = splitLeft.sizeWithAttributes([NSFontAttributeName: font]).width 

     if(width > truncatedWidth) { 
      return getTruncatedStringPoint(splitPoint - subLength, original: original, truncatedWidth: truncatedWidth, font: font, length: subLength) 
     } 
     else if (width < truncatedWidth) { 
      return getTruncatedStringPoint(splitPoint + subLength, original: original, truncatedWidth: truncatedWidth, font: font, length: subLength) 
     } 
     else { 
      return splitPoint 
     } 
    } 
} 

オブジェクティブC

+ (bool) replaceElipsesForLabel:(UILabel*) label With:(NSString*) replacement MaxWidth:(float) width 

クラス:

//=============================================Header===================================================== 
#import <Foundation/Foundation.h> 
#import <UIKit/UIKit.h> 

@interface CustomTruncater : NSObject 

+ (bool) replaceElipsesForLabel:(UILabel*) label With:(NSString*) replacement MaxWidth:(float) width; 

@end 

//======================================================================================================== 

#import "CustomTruncater.h" 

@implementation CustomTruncater 

static NSString *original; 
static float truncateWidth; 
static UIFont *font; 
static int subLength; 

+ (bool) replaceElipsesForLabel:(UILabel*) label With:(NSString*) replacement MaxWidth:(float) width { 

CGRect origSize = label.frame; 

float useWidth = width; 

if(width <= 0) 
    useWidth = origSize.size.width; //use label width by default if width <= 0 

[label sizeToFit]; 
CGSize labelSize = [label.text sizeWithFont:label.font]; 

if(labelSize.width > useWidth) { 

    original = label.text; 
    truncateWidth = useWidth; 
    font = label.font; 
    subLength = label.text.length; 

    NSString *temp = [label.text substringToIndex:label.text.length-1]; 
    temp = [temp substringToIndex:[self getTruncatedStringPoint:subLength]]; 
    temp = [NSString stringWithFormat:@"%@%@", temp, replacement]; 

    int count = 0; 

    while([temp sizeWithFont:label.font].width > useWidth){ 

     count++; 

     temp = [label.text substringToIndex:(label.text.length-(1+count))]; 
     temp = [temp stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; //remove this if you want to keep whitespace on the end 
     temp = [NSString stringWithFormat:@"%@%@", temp, replacement]; 
    } 

    label.text = temp; 
    label.frame = origSize; 
    return true; 
} 
else { 
    label.frame = origSize; 
    return false; 
} 
} 

+ (int) getTruncatedStringPoint:(int) splitPoint { 

NSString *splitLeft = [original substringToIndex:splitPoint]; 
subLength /= 2; 

if(subLength <= 0) 
    return splitPoint; 

if([splitLeft sizeWithFont:font].width > truncateWidth){ 
    return [self getTruncatedStringPoint:(splitPoint - subLength)]; 
} 
else if ([splitLeft sizeWithFont:font].width < truncateWidth) { 
    return [self getTruncatedStringPoint:(splitPoint + subLength)]; 
} 
else { 
    return splitPoint; 
} 
} 

@end 
関連する問題