NSAttributedStrings'i nasıl birleştirebilirim?


159

Bazı dizeleri aramak ve dizeleri birleştirmeden önce bazı öznitelikleri ayarlamak gerekir, bu yüzden NSStrings -> Bunları birleştirmek -> NSAttributedString bir seçenek değil, bir attributeString için attribatenString bitirmek için herhangi bir yolu var mı?


13
Bunun 2016 yılının Ağustos ayında hala ne kadar zor olduğu saçma .
Wedge Martin

17
2018'de bile ...
DehMotth

11
hala 2019'da;)
raistlin

8
hala 2020'de ...
Hwangho Kim

Yanıtlar:


210

@Linuxios tarafından önerilen tek bir değişken ilişkilendirilebilir dize kullanmanızı öneririm ve işte bunun başka bir örneği:

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];

Ancak, tüm seçenekleri orada almak uğruna, zaten bir araya getirilmiş giriş dizelerini içeren biçimlendirilmiş bir NSString'den yapılmış tek bir değiştirilebilir ilişkilendirilebilir dize de oluşturabilirsiniz. Daha addAttributes: range:sonra, olaydan sonra nitelikleri giriş dizelerini içeren aralıklara eklemek için kullanabilirsiniz . Yine de eski yolu tavsiye ederim.


Neden özellik eklemek yerine dizeler eklemenizi öneriyorsunuz?
ma11hew28

87

Swift kullanıyorsanız, +normal dizeleri birleştirdiğiniz şekilde bunları birleştirmek için operatörü aşırı yükleyebilirsiniz:

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

Şimdi bunları yalnızca ekleyerek birleştirebilirsiniz:

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

5
değişebilir sınıf değişmez sınıfın bir alt tipidir.
algal

4
Değişken alt tipini, değiştirilemeyen üst öğe türünü bekleyen ancak tam tersi olmayan herhangi bir bağlamda kullanabilirsiniz. Alt sınıfları ve kalıtımı gözden geçirmek isteyebilirsiniz.
algal

6
Evet, savunmak istiyorsan savunma kopyası yapmalısın. (İğneleme değil.)
algal

1
Gerçekten NSAttributedString dönmek istiyorsanız, o zaman belki de bu işe yarar:return NSAttributedString(attributedString: result)
Alex

2
@ n13 Helpersveya adlı bir klasör oluşturur Extensionsve bu işlevi adlı bir dosyaya koyarım NSAttributedString+Concatenate.swift.
David Lawson

34

Swift 3: Bir NSMutableAttributedString oluşturun ve bu karakterleri bunlara ekleyin.

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

Bunu dene:

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

Nerede astring1ve astring2Hangi NSAttributedStrings.


13
Veya [[aString1 mutableCopy] appendAttributedString: aString2].
JWWalker

@JWWalker 'oneliner' bozuk. appendAttributedString dize döndürmediği için bu "birleştirme" sonucunu alamazsınız. Sözlüklerle aynı hikaye
gaussblurinc

@gaussblurinc: iyi bir nokta, elbette eleştiriniz de yorum yaptığımız cevap için de geçerli. Olmalı NSMutableAttributedString* aString3 = [aString1 mutableCopy]; [aString3 appendAttributedString: aString2];.
JWWalker

@gaussblurinc, JWalker: Cevabı düzeltti.
Linuxios

@Linuxios, ayrıca, resultolarak geri dönersiniz NSMutableAttributedString. yazarın görmek istediği şey bu değil. stringByAppendingString- bu yöntem iyi olacak
gaussblurinc

5

2020 | SWIFT 5.1:

NSMutableAttributedStringAşağıdaki şekilde 2 ekleyebilirsiniz :

let concatenated = NSAttrStr1.append(NSAttrStr2)

Başka bir yol da NSMutableAttributedStringve NSAttributedStringher ikisiyle de çalışır :

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

Başka bir yol ...

var full = NSAttrStr1 + NSAttrStr2 + NSAttrStr3

ve:

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


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

Bunu aşağıdaki uzantıyla yapabilirsiniz:

// 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 kullanıyorum ve birlikte iki NSAttrStrings ekleyemiyorum ...
PaulDoesDev

1
Garip. Bu durumda sadece kullanınNSAttrStr1.append(NSAttrStr2)
Andrew

Cevabımı sadece iki NSAttrStrings eklemek için uzantılarla güncelledi :)
Andrew

4

Cocoapods kullanıyorsanız, yukarıdaki kodlara kendi kodunuzda değişmezliği önlemenizi sağlayan bir alternatif, aşağıdaki gibi bir şey yazmanıza izin veren mükemmel NSAttributedString + CCLFormat kategorisini kullanmaktır NSAttributedString:

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

Tabii ki sadece NSMutableAttributedStringkapakların altında kullanır .

Ayrıca tam teşekküllü bir biçimlendirme işlevi olmanın ekstra avantajına sahiptir - böylece dizeleri bir araya getirmekten çok daha fazlasını yapabilir.


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

Aşağıdaki sözdizimini kullanan SwiftyFormat'ı deneyebilirsiniz

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

1
Lütfen daha ayrıntılı bir şekilde açıklayabilir misiniz?
Kandhal Bhutiya
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.