NSAttributedStringsを連結するにはどうすればよいですか?


159

文字列をマージする前にいくつかの文字列を検索していくつかの属性を設定する必要があるため、NSStrings->それらを連結します-> NSAttributedStringを作成するオプションはありません。attributedStringを別のattributedStringに連結する方法はありますか?



17
2018年でも...
DehMotth

11
2019年もまだ;)
raistlin

8
まだ2020年...
Hwangho Kim

回答:


210

@Linuxiosが提案する単一の変更可能な属性付き文字列を使用することをお勧めします。ここにその別の例を示します。

NSMutableAttributedString *mutableAttString = [[NSMutableAttributedString alloc] init];

NSString *plainString = // ...
NSDictionary *attributes = // ... a dictionary with your attributes.
NSAttributedString *newAttString = [[NSAttributedString alloc] initWithString:plainString attributes:attributes];

[mutableAttString appendAttributedString:newAttString];

ただし、すべてのオプションを提供するためだけに、すでに組み合わされた入力文字列を含むフォーマットされたNSStringから、単一の変更可能な属性付き文字列を作成することもできます。次に、を使用addAttributes: range:して、事後の属性を入力文字列を含む範囲に追加できます。前者の方法をお勧めします。


属性を追加するのではなく、文字列を追加することをお勧めするのはなぜですか?
ma11hew28 2017

87

Swiftを使用している場合は、+演算子をオーバーロードして、通常の文字列を連結するのと同じ方法で演算子を連結できます。

// concatenate attributed strings
func + (left: NSAttributedString, right: NSAttributedString) -> NSAttributedString
{
    let result = NSMutableAttributedString()
    result.append(left)
    result.append(right)
    return result
}

これで、追加するだけで連結できます。

let helloworld = NSAttributedString(string: "Hello ") + NSAttributedString(string: "World")

5
可変クラスは、不変クラスのサブタイプです。
藻類、2015年

4
変更可能なサブタイプは、変更不可能な親タイプを期待するコンテキストで使用できますが、その逆はできません。サブクラス化と継承を確認することをお勧めします。

6
はい、防御的になりたい場合は防御コピーを行う必要があります。(皮肉ではない。)

1
あなたが本当にNSAttributedStringを返すようにしたい場合は、おそらくこれは動作します:return NSAttributedString(attributedString: result)
アレックス

2
@ n13 Helpersまたはというフォルダを作成し、Extensionsこの関数をというファイルに入れますNSAttributedString+Concatenate.swift
David Lawson、

34

Swift 3:NSMutableAttributedStringを作成し、属性付きの文字列を追加するだけです。

let mutableAttributedString = NSMutableAttributedString()

let boldAttribute = [
    NSFontAttributeName: UIFont(name: "GothamPro-Medium", size: 13)!,
    NSForegroundColorAttributeName: Constants.defaultBlackColor
]

let regularAttribute = [
    NSFontAttributeName: UIFont(name: "Gotham Pro", size: 13)!,
    NSForegroundColorAttributeName: Constants.defaultBlackColor
]

let boldAttributedString = NSAttributedString(string: "Warning: ", attributes: boldAttribute)
let regularAttributedString = NSAttributedString(string: "All tasks within this project will be deleted.  If you're sure you want to delete all tasks and this project, type DELETE to confirm.", attributes: regularAttribute)
mutableAttributedString.append(boldAttributedString)
mutableAttributedString.append(regularAttributedString)

descriptionTextView.attributedText = mutableAttributedString

swift5 upd:

    let captionAttribute = [
        NSAttributedString.Key.font: Font.captionsRegular,
        NSAttributedString.Key.foregroundColor: UIColor.appGray
    ]

25

これを試して:

NSMutableAttributedString* result = [astring1 mutableCopy];
[result appendAttributedString:astring2];

どこastring1astring2しているNSAttributedStringの。


13
または[[aString1 mutableCopy] appendAttributedString: aString2]
JWWalker 2013

@JWWalker 'oneliner'が破損しています。appendAttributedStringは文字列を返さないため、この「連結」結果を取得できません。辞書と同じストーリー
gaussblurinc 2015年

@gaussblurinc:良い点、もちろんあなたの批判は私たちがコメントしている答えにも当てはまります。それはあるはずですNSMutableAttributedString* aString3 = [aString1 mutableCopy]; [aString3 appendAttributedString: aString2];
JWWalker、2015年

@ gaussblurinc、JWalker:答えを修正しました。
Linuxios 2015年

@Linuxiosも、resultとして戻りますNSMutableAttributedString。それは著者が見たいものではありません。stringByAppendingString-この方法は適切です
gaussblurinc 2015年

5

2020 | SWIFT 5.1:

NSMutableAttributedString次の方法で2を追加できます。

let concatenated = NSAttrStr1.append(NSAttrStr2)

もう一つの方法は、と連携NSMutableAttributedStringし、NSAttributedString両方:

[NSAttrStr1, NSAttrStr2].joinWith(separator: "")

別の方法は...

var full = NSAttrStr1 + NSAttrStr2 + NSAttrStr3

そして:

var full = NSMutableAttributedString(string: "hello ")
// NSAttrStr1 == 1


full += NSAttrStr1 // full == "hello 1"       
full += " world"   // full == "hello 1 world"

これを行うには、次の拡張機能を使用します。

// works with NSAttributedString and NSMutableAttributedString!
public extension NSAttributedString {
    static func + (left: NSAttributedString, right: NSAttributedString) -> NSAttributedString {
        let leftCopy = NSMutableAttributedString(attributedString: left)
        leftCopy.append(right)
        return leftCopy
    }

    static func + (left: NSAttributedString, right: String) -> NSAttributedString {
        let leftCopy = NSMutableAttributedString(attributedString: left)
        let rightAttr = NSMutableAttributedString(string: right)
        leftCopy.append(rightAttr)
        return leftCopy
    }

    static func + (left: String, right: NSAttributedString) -> NSAttributedString {
        let leftAttr = NSMutableAttributedString(string: left)
        leftAttr.append(right)
        return leftAttr
    }
}

public extension NSMutableAttributedString {
    static func += (left: NSMutableAttributedString, right: String) -> NSMutableAttributedString {
        let rightAttr = NSMutableAttributedString(string: right)
        left.append(rightAttr)
        return left
    }

    static func += (left: NSMutableAttributedString, right: NSAttributedString) -> NSMutableAttributedString {
        left.append(right)
        return left
    }
}

2
私はSwift 5.1を使用していますが、2つのNSAttrStringsを一緒に追加するだけではうまくいきません...
PaulDoesDev

1
奇妙な。この場合、次のように使用しますNSAttrStr1.append(NSAttrStr2)
Andrew

2つのNSAttrStringを追加するだけの拡張機能で私の回答を更新しました:)
Andrew

4

Cocoapodsを使用している場合、独自のコードで可変性を回避できるようにする上記の両方の回答の代わりに、NSAttributedString次のようなものを記述できるsで優れたNSAttributedString + CCLFormatカテゴリを使用することができます。

NSAttributedString *first = ...;
NSAttributedString *second = ...;
NSAttributedString *combined = [NSAttributedString attributedStringWithFormat:@"%@%@", first, second];

もちろんそれは隠れて使用するだけNSMutableAttributedStringです。

また、本格的なフォーマット機能であるという追加の利点もあります。そのため、文字列を一緒に追加するだけではありません。


1
// Immutable approach
// class method

+ (NSAttributedString *)stringByAppendingString:(NSAttributedString *)append toString:(NSAttributedString *)string {
  NSMutableAttributedString *result = [string mutableCopy];
  [result appendAttributedString:append];
  NSAttributedString *copy = [result copy];
  return copy;
}

//Instance method
- (NSAttributedString *)stringByAppendingString:(NSAttributedString *)append {
  NSMutableAttributedString *result = [self mutableCopy];
  [result appendAttributedString:append];
  NSAttributedString *copy = [result copy];
  return copy;
}

1

次の構文を使用するSwiftyFormatを試すことができます

let format = "#{{user}} mentioned you in a comment. #{{comment}}"
let message = NSAttributedString(format: format,
                                 attributes: commonAttributes,
                                 mapping: ["user": attributedName, "comment": attributedComment])

1
もう少し詳しく説明してもらえますか?
Kandhal Bhutiya 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.