Làm cách nào tôi có thể nối NSAttributionStrings?


158

Tôi cần tìm kiếm một số chuỗi và đặt một số thuộc tính trước khi hợp nhất các chuỗi, vì vậy, có NSStrings -> Nối chúng -> Tạo NSAttributionString không phải là một tùy chọn, có cách nào để ghép các thuộc tínhString sang một thuộc tính khác không?


12
Thật nực cười khi điều này vẫn còn khó khăn vào tháng 8 năm 2016.
Wedge Martin

16
Ngay cả trong năm 2018 ...
Ngày

10
vẫn còn trong năm 2019;)
raistlin

7
vẫn còn trong năm 2020 ...
Hwangho Kim

Câu trả lời:


210

Tôi khuyên bạn nên sử dụng một chuỗi thuộc tính có thể thay đổi duy nhất mà @Linuxios đề xuất và đây là một ví dụ khác về điều đó:

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

Tuy nhiên, chỉ để có được tất cả các tùy chọn ngoài đó, bạn cũng có thể tạo một chuỗi thuộc tính có thể thay đổi duy nhất, được tạo từ một NSString được định dạng có chứa các chuỗi đầu vào được đặt cùng nhau. Sau đó, bạn có thể sử dụng addAttributes: range:để thêm các thuộc tính sau thực tế vào các phạm vi có chứa các chuỗi đầu vào. Tôi đề nghị cách trước đây mặc dù.


Tại sao bạn đề nghị nối thêm chuỗi thay vì thêm thuộc tính?
ma11hew28

86

Nếu bạn đang sử dụng Swift, bạn chỉ có thể quá tải +toán tử để có thể nối chúng giống như cách bạn nối các chuỗi thông thường:

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

Bây giờ bạn có thể nối chúng chỉ bằng cách thêm chúng:

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

5
lớp đột biến là một kiểu con của lớp bất biến.
tảo

4
Bạn có thể sử dụng kiểu con có thể thay đổi trong bất kỳ bối cảnh nào mong đợi kiểu cha mẹ bất biến nhưng không phải ngược lại. Bạn có thể muốn xem lại phân lớp và kế thừa.
tảo

6
Có, bạn nên làm một bản sao phòng thủ nếu bạn muốn phòng thủ. (Không mỉa mai.)
tảo

1
Nếu bạn thực sự muốn trả lại NSAttributionString, thì có lẽ điều này sẽ hoạt động:return NSAttributedString(attributedString: result)
Alex

2
@ n13 Tôi sẽ tạo một thư mục có tên Helpershoặc Extensionsđặt chức năng này vào một tệp có tên NSAttributedString+Concatenate.swift.
David Lawson

34

Swift 3: Đơn giản chỉ cần tạo NSMutableAttributionString và nối các chuỗi được gán cho chúng.

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

cập nhật swift5:

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

25

Thử cái này:

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

Ở đâu astring1astring2đang NSAttributedStrings.


13
Hoặc [[aString1 mutableCopy] appendAttributedString: aString2].
JWWalker

@JWWalker 'oneliner' của bạn bị hỏng. bạn không thể có được kết quả "nối" này vì appendAttributionString không trả về chuỗi. Câu chuyện tương tự với từ điển
gaussblurinc

@gaussblurinc: điểm tốt, tất nhiên lời phê bình của bạn cũng áp dụng cho câu trả lời mà chúng tôi đang bình luận. Nó phải NSMutableAttributedString* aString3 = [aString1 mutableCopy]; [aString3 appendAttributedString: aString2];.
JWWalker

@gaussblurinc, JWalker: Đã sửa câu trả lời.
Linuxios

@Linuxios, còn nữa, bạn trở về resultnhư NSMutableAttributedString. nó không phải là những gì tác giả muốn thấy. stringByAppendingString- phương pháp này sẽ tốt
gaussblurinc

5

2020 | Chuyển đổi 5.1:

Bạn có thể thêm 2 NSMutableAttributedStringbằng cách sau:

let concatenated = NSAttrStr1.append(NSAttrStr2)

Một cách khác làm việc với NSMutableAttributedStringNSAttributedStringcả hai:

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

Một cách khác là ....

var full = NSAttrStr1 + NSAttrStr2 + NSAttrStr3

và:

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


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

Bạn có thể làm điều này với phần mở rộng sau:

// 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
Tôi đang sử dụng Swift 5.1 và dường như tôi không thể thêm hai NSAttrStrings cùng nhau ...
PaulDoesDev

1
Lạ thật. Trong trường hợp này chỉ cần sử dụngNSAttrStr1.append(NSAttrStr2)
Andrew

Đã cập nhật câu trả lời của tôi với các tiện ích mở rộng chỉ bằng cách thêm hai NSAttrStrings :)
Andrew

4

Nếu bạn đang sử dụng Cocoapods, một giải pháp thay thế cho cả hai câu trả lời trên cho phép bạn tránh được tính đột biến trong mã của riêng bạn là sử dụng danh mục NSAttributionString + CCLFormat tuyệt vời trên NSAttributedStrings cho phép bạn viết một cái gì đó như:

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

Nó tất nhiên nó chỉ sử dụng NSMutableAttributedStringdưới vỏ bọc.

Nó cũng có thêm lợi thế là một chức năng định dạng đầy đủ - vì vậy nó có thể làm được nhiều việc hơn là nối các chuỗi lại với nhau.


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

Bạn có thể thử SwiftyFormat Nó sử dụng cú pháp sau

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

1
Bạn có thể vui lòng giải thích thêm không? Làm thế nào nó sẽ hoạt động?
Kandhal Bhutiya
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.