5

aのテキストUILabelが切り捨てられると、デフォルトで3つのドットが挿入されます。これらの文字を変更または無効にすることは可能ですか?

4

6 に答える 6

11

どこにいてもコードをポップできるカスタムの切り捨てクラスを作成しました。以下のこの方法を使用してください。切り捨てが行われた場合はtrueを返し、ラベルのデフォルトのフレーム幅を使用する場合はMaxWidthを0のままにしておくことができます。maxWidthをフレーム幅よりも小さいものとして配置し、フレーム境界内で短くします。

スイフト2(変換のためのいくつかのスイフト3コメント付き)

利用方法:

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
        }
    }
}

Objective 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
于 2013-02-22T09:06:01.887 に答える
0

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

リンク

于 2012-03-13T14:05:30.770 に答える
0

設定することもできます

[lbl setAdjustsFontSizeToFitWidth:YES];

これにより、テキストを切り捨てる必要がなくなり、に完全なテキストを表示できますlabel

于 2011-01-25T12:54:24.123 に答える
0

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

于 2011-10-24T15:11:19.060 に答える
0

Fonixが以前に提供したもののより迅速なバージョンをSwift5構文を使用して提供したいと思います。また、の拡張として関数を書くことにしましたUILabel

extension UILabel {
    func replaceEllipsis(withString replacement: String, andMaximumWidth width: CGFloat = 0) -> Bool {

        if let labelText = self.text, let font = self.font {
            let origSize = self.frame
            var useWidth = width

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

            self.sizeToFit()
            let labelSize = labelText.size(withAttributes: [NSAttributedString.Key.font: font])

            if labelSize.width > useWidth {
                let truncateWidth = useWidth
                let subLength = labelText.count

                var newText = String(labelText[..<labelText.index(labelText.endIndex, offsetBy: -1)])
                newText = String(newText[..<newText.index(labelText.startIndex, offsetBy: getTruncatedStringPoint(splitPoint: subLength,
                                                                                                                  original: labelText,
                                                                                                                  truncatedWidth: truncateWidth,
                                                                                                                  font: font,
                                                                                                                  length: subLength))])
                newText = String.localizedStringWithFormat("%@%@", newText, replacement)
                var count = 0

                while newText.size(withAttributes: [NSAttributedString.Key.font: font]).width > useWidth {
                    count += 1
                    newText = String(labelText[..<labelText.index(labelText.endIndex, offsetBy: -(1 + count))])
                    newText = newText.trimmingCharacters(in: NSCharacterSet.whitespaces)
                    newText = String.localizedStringWithFormat("%@%@", newText, replacement)
                }
                self.text = newText
                self.frame = origSize
                return true
            } else {
                self.frame = origSize
                return false
            }
        } else {
            return false
        }
    }

    private func getTruncatedStringPoint(splitPoint: Int, original: String, truncatedWidth: CGFloat, font: UIFont, length: Int) -> Int {
        let index = original.index(original.startIndex, offsetBy: splitPoint)
        let splitLeft = String(original[..<index])

        let subLength = length / 2

        if subLength <= 0 {
            return splitPoint
        }

        let width = splitLeft.size(withAttributes: [NSAttributedString.Key.font: font]).width

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

次のように使用されます。

<UILabel>.replaceEllipsis(withString: " ...Read More") // if you want to use the label width

また、必要に応じてカスタム幅を渡すこともできます。上記の例では、デフォルトの幅を選択しました。

リファクタリングで使用したものに関するリファレンスについては、以下のStackOverflowリンクが役立ちました。

リファクタリングによる高度化

substringToIndexリファクタリング

于 2022-02-13T19:13:34.603 に答える
-3

文字列の長さをカウントし、ビューを超えている場合はそのサブ文字列を作成するようにコーディングしないのはなぜですか。またはあなたがやりたいことを何でもしますそれは生ですが効果的な方法です

于 2011-01-25T12:25:59.687 に答える