iOS/Swift

[Swift] 속성 문자열 사용법 (NSAttributedString)

HUISOO 2022. 8. 12. 14:17

이 포스트는 속성 문자열 (NSAttributedString) 사용법과 정규식을 이용한 사용법에 대한 포스팅입니다 :)

 

애플의 공식 문서여기서 확인하실 수 있습니다.

최종 수정일 - 22. 08. 12 PM 2:15



 사용법

 

1. UILabel을 준비합니다.

@IBOutlet weak var label: UILabel!

label.text = "AttributedString text label"

 

2. String을 NSAttributedString으로 변환합니다.

extension String {
    func attributed(of searchString: String, key: NSAttributedString.Key, value: Any) -> NSMutableAttributedString {
    
        // 문자열을 속성 문자열로 변환 
        let attributedString = NSMutableAttributedString(string: self)
        
        // 문자열의 길이 확인
        let length = self.count
        
        var range = NSRange(location: 0, length: length)
        var rangeArray = [NSRange]()

        // 문자열에서 특정 문자열의 위치 찾기
        while range.location != NSNotFound {
            range = (attributedString.string as NSString).range(of: searchString, options: .caseInsensitive, range: range)
            rangeArray.append(range)

            if range.location != NSNotFound {
                range = NSRange(location: range.location + range.length, length: self.count - (range.location + range.length))
            }
        }

        // 찾은 범위의 문자열에 속성 추가
        rangeArray.forEach {
            attributedString.addAttribute(key, value: value, range: $0)
        }

        return attributedString
    }
}

 

3. 적용 방법 및 결과

label.attributedText = "AttributedString text label".attributed(of: "text", 
                                                                key: .font, 
                                                                value: UIFont.systemFont(ofSize: 18, weight: .bold))

결과

 


 활용법 01 - 다수의 속성 추가

 

1. NSMutableAttributedString에 속성 추가하기

extension NSMutableAttributedString {
    func addAttribute(of searchString: String, key: NSAttributedString.Key, value: Any) -> NSMutableAttributedString {
        let length = self.string.count
        var range = NSRange(location: 0, length: length)
        var rangeArray = [NSRange]()

        while range.location != NSNotFound {
            range = (self.string as NSString).range(of: searchString, options: .caseInsensitive, range: range)
            rangeArray.append(range)

            if range.location != NSNotFound {
                range = NSRange(location: range.location + range.length, length: self.string.count - (range.location + range.length))
            }
        }

        rangeArray.forEach {
            self.addAttribute(key, value: value, range: $0)
        }

        return self
    }
}

 

2. 적용 방법 및 결과

label.attributedText = "AttributedString text label".attributed(of: "text",
                                                                key: .font,
                                                                value: UIFont.systemFont(ofSize: 18, weight: .bold))
                                                    .addAttribute(of: "text",
                                                                  key: .foregroundColor,
                                                                  value: UIColor.systemRed)
                                                    .addAttribute(of: "AttributedString",
                                                                  key: .foregroundColor,
                                                                  value: UIColor.systemBlue)

결과


 활용법 02 - 자주 쓰는 속성

 

1. extention에 자주 쓰는 속성 만들기

func bold(of searchString: String) -> NSMutableAttributedString {
    let attributedString = NSMutableAttributedString(string: self)
    let length = self.count
    var range = NSRange(location: 0, length: length)
    var rangeArray = [NSRange]()

    while range.location != NSNotFound {
        range = (attributedString.string as NSString).range(of: searchString, options: .caseInsensitive, range: range)
        rangeArray.append(range)

        if range.location != NSNotFound {
            range = NSRange(location: range.location + range.length, length: self.count - (range.location + range.length))
        }
    }

    rangeArray.forEach {
        attributedString.addAttribute(.font, value: UIFont.systemFont(ofSize: 18, weight: .bold), range: $0)
    }

    return attributedString
}

func color(_ color: UIColor, of searchString: String) -> NSMutableAttributedString {
    let attributedString = NSMutableAttributedString(string: self)
    let length = self.count
    var range = NSRange(location: 0, length: length)
    var rangeArray = [NSRange]()

    while range.location != NSNotFound {
        range = (attributedString.string as NSString).range(of: searchString, options: .caseInsensitive, range: range)
        rangeArray.append(range)

        if range.location != NSNotFound {
            range = NSRange(location: range.location + range.length, length: self.count - (range.location + range.length))
        }
    }

    rangeArray.forEach {
        attributedString.addAttribute(.foregroundColor, value: color, range: $0)
    }

    return attributedString
}

 

2. 적용 방법 및 결과

label.attributedText = "AttributedString text label".bold(of: "text")
                                                    .color(.systemYellow, of: "text")
                                                    .color(.systemGreen, of: "AttributedString")

결과


 

정규식을 이용한 AttributedText

 

1. 위의 방법은 정규식이 적용되지 않으므로 새로운 방법 사용

func attributed(using pattern: String, key: NSAttributedString.Key, value: Any) -> NSMutableAttributedString {
    let attributedString = NSMutableAttributedString(string: self)

    do {
        // 정규식 패턴 생성
        let regex = try NSRegularExpression(pattern: pattern)
        let length = self.count
        let range = NSRange(location: 0, length: length)

        // 문자열에서 정규식에 맞는 위치 찾기
        let matches = (regex.matches(in: self, options: [], range: range))

        // 찾은 범위의 문자열에 속성 추가
        matches.forEach {
            attributedString.addAttribute(key, value: value, range: $0.range)
        }
    } catch {
        print(error)
    }

    return attributedString
}

 

2. 적용 방법 및 결과

label.attributedText = "(?:^|\\s|$|[.])@[\\p{L}0-9_]*\n\nThis is Hashtag Regular Expression.\n Let this use @Hashtag"
    .attributed(using: "(?:^|\\s|$|[.])@[\\p{L}0-9_]*", key: .foregroundColor, value: UIColor.systemBlue)

결과



 

여기까지 속성 문자열 (NSAttributedString) 사용법과 정규식을 이용한 사용법에 대해 알아보았습니다.

 

다음에 기회가 된다면 iOS 15 부터 사용이 가능한 AttributedString을 사용해보고 포스팅을 남겨보겠습니다.