관리 메뉴

이 세계에선 내가 개발자?

[Swift] NSAttributedString과 NSMutableAttributedString 비교 본문

Swift/Swift Based Study

[Swift] NSAttributedString과 NSMutableAttributedString 비교

민디고 2022. 6. 9. 16:08

** 아래 내용은 스터디를 위해 정리된 내용입니다 **

 

오늘은 저번에 궁금점이 나왔던 문제에 대해 알아보기로 했다.

바로 NSAttributedString과 NSMutableAttributedString 이 두 친구이다.

본격적으로 비교에 들어가기 전에 두 개가 어떤 친구인지는 알아야 하니까 하나씩 한번 주저리 해보자


NSAttributedString

어김없이 등장한 영어 빌런, 우리의 영원한 친구 파파고를 불러보자.

텍스트의 일부에 대해 연결된 특성(예: 시각적 스타일, 하이퍼링크 또는 내게 필요한 옵션 데이터)이 있는 문자열입니다.

흐음? 이게 무슨 이야기일까? 일단 말 그대로 해석해보자면 텍스트에 특별한 효과? 스타일을 주고 싶을 때 사용하는 거 같다. 

솔직히 저것만 보고 무슨 뜻인지 이해가 가지 않아서 다른 분들의 내용도 참고했다.

 

NSattributedString은 String에 스타일을 줄 수 있는데 주는 방법이 Dictionary을 이용해서 준다.

기본적인 형태는 이렇다.

  let attributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 72)]

NSAttributedString.Key 안에 들어있는 여러 요소들 중에 골라 쓸 수 있다.

저 안에는 몇 개의 요소가 있을까? 궁금해서 쫓아 들어가 봤다.

흐엑 근데 너무 많아!!!

더보기
/************************ Attributes ************************/
    @available(iOS 6.0, *)
    public static let font: NSAttributedString.Key

    @available(iOS 6.0, *)
    public static let paragraphStyle: NSAttributedString.Key // NSParagraphStyle, default defaultParagraphStyle

    @available(iOS 6.0, *)
    public static let foregroundColor: NSAttributedString.Key // UIColor, default blackColor

    @available(iOS 6.0, *)
    public static let backgroundColor: NSAttributedString.Key // UIColor, default nil: no background

    @available(iOS 6.0, *)
    public static let ligature: NSAttributedString.Key // NSNumber containing integer, default 1: default ligatures, 0: no ligatures

    @available(iOS 6.0, *)
    public static let kern: NSAttributedString.Key // NSNumber containing floating point value, in points; amount to modify default kerning. 0 means kerning is disabled.

    @available(iOS 14.0, *)
    public static let tracking: NSAttributedString.Key // NSNumber containing floating point value, in points; amount to modify default tracking. 0 means tracking is disabled.

    @available(iOS 6.0, *)
    public static let strikethroughStyle: NSAttributedString.Key // NSNumber containing integer, default 0: no strikethrough

    @available(iOS 6.0, *)
    public static let underlineStyle: NSAttributedString.Key // NSNumber containing integer, default 0: no underline

    @available(iOS 6.0, *)
    public static let strokeColor: NSAttributedString.Key // UIColor, default nil: same as foreground color

    @available(iOS 6.0, *)
    public static let strokeWidth: NSAttributedString.Key // NSNumber containing floating point value, in percent of font point size, default 0: no stroke; positive for stroke alone, negative for stroke and fill (a typical value for outlined text would be 3.0)

    @available(iOS 6.0, *)
    public static let shadow: NSAttributedString.Key // NSShadow, default nil: no shadow

    @available(iOS 7.0, *)
    public static let textEffect: NSAttributedString.Key // NSString, default nil: no text effect

    
    @available(iOS 7.0, *)
    public static let attachment: NSAttributedString.Key // NSTextAttachment, default nil

    @available(iOS 7.0, *)
    public static let link: NSAttributedString.Key // NSURL (preferred) or NSString

    @available(iOS 7.0, *)
    public static let baselineOffset: NSAttributedString.Key // NSNumber containing floating point value, in points; offset from baseline, default 0

    @available(iOS 7.0, *)
    public static let underlineColor: NSAttributedString.Key // UIColor, default nil: same as foreground color

    @available(iOS 7.0, *)
    public static let strikethroughColor: NSAttributedString.Key // UIColor, default nil: same as foreground color

    @available(iOS 7.0, *)
    public static let obliqueness: NSAttributedString.Key // NSNumber containing floating point value; skew to be applied to glyphs, default 0: no skew

    @available(iOS 7.0, *)
    public static let expansion: NSAttributedString.Key // NSNumber containing floating point value; log of expansion factor to be applied to glyphs, default 0: no expansion

    
    @available(iOS 7.0, *)
    public static let writingDirection: NSAttributedString.Key // NSArray of NSNumbers representing the nested levels of writing direction overrides as defined by Unicode LRE, RLE, LRO, and RLO characters.  The control characters can be obtained by masking NSWritingDirection and NSWritingDirectionFormatType values.  LRE: NSWritingDirectionLeftToRight|NSWritingDirectionEmbedding, RLE: NSWritingDirectionRightToLeft|NSWritingDirectionEmbedding, LRO: NSWritingDirectionLeftToRight|NSWritingDirectionOverride, RLO: NSWritingDirectionRightToLeft|NSWritingDirectionOverride,

    
    @available(iOS 6.0, *)
    public static let verticalGlyphForm: NSAttributedString.Key // An NSNumber containing an integer value.  0 means horizontal text.  1 indicates vertical text.  If not specified, it could follow higher-level vertical orientation settings.  Currently on iOS, it's always horizontal.  The behavior for any other value is undefined.
}

// This defines currently supported values for NSUnderlineStyleAttributeName and NSStrikethroughStyleAttributeName. These values are or'ed together to produce an underline style.
// Underlines will be drawn with a solid pattern by default, so NSUnderlineStylePatternSolid does not need to be specified.
/************************ Attribute values ************************/

 

하나씩 보기엔 너무너무너무너무 많으니까 내가 자주 썼던 것만 살펴보자


font

이름에서도 알다시피 font를 지정해 줄 때 사용한다. 사용 법은 Dictionary 타입이니까

NSAttributedString.Key.font: UIFont() 로 사용하면 된다.

 

foregroundColor

String의 텍스트 컬러를 지정해 줄 때 사용한다. 

NSAttributedString.Key.foregroundColor: UIColor() 로 사용하면 된다.

default는 blackColor이다

 

kern

이걸 어떻게 읽지..?라고 생각하면서 맨날 컭..? 컬ㄴ..? 이랬는데 kerning을 줄인 것이었다.

이 친구는 자간을 조절해줄 때 사용한다.

한국어든 영어든 가독성을 위해서 자간과 행간 조절은 필수다.

행간 조절은 paragraphStyle 이 친구를 이용하는데 좀 더 파고들어야 하기 때문에 일단 kerning부터 살펴보자

NSAttributedString.Key.kern: 0.0 로 사용하면 된다.

0 means kerning is disabled. = 0으로 설정할 경우 kerning을 주지 않겠다라고 받아들여(?)진다.

 

paragraphStyle

이 친구는 NSParagraphStyle 타입을 받는 친구인데 .... 이 친구도 뭐가 굉장히 많다.

....... 이 친구도 나중에 따로 특집으로 빼야겠다. 

어찌 되었던 이 친구는 행간을 조절할 때 사용할 수도 있고 또 여러 가지 용도로 사용할 수 있다.

 

위에 친구들은 실제로 이렇게 사용한다.

let attributes: [NSAttributedString.Key: Any] = [
    .font: font,
    .foregroundColor: UIColor.white,
    .kern: 0.5
]

 

그리고 실제로 attributedString에 적용해줄 때는 이렇게 적용해준다.

 let attributedString = NSAttributedString(string: "민디고", attributes: attributes)

 

NSAttributedString에 대해서 아직 소개 못한 요소들이 엄청나게 많으니까 이 친구는 따로 특집으로 준비해야 할 것 같다.


NSMutableAttributedString

텍스트의 일부에 대해 연관된 특성(예: 시각적 스타일, 하이퍼링크 또는 내게 필요한 옵션 데이터)이 있는 가변 문자열입니다.

..? 뭘까

아까와 달라진 점이라면 가변 문자열이라는 점이 달라졌다. 

나는 NSAttributedString에서 주는 스타일을 사용할 때 위의 방법 말고 NSMutableAttributedString 로 변환해서 스타일을 주는 방식으로 많이 사용했다.

왜 그럴까 생각해봤는데 확장성이 더 좋기 때문이 아닐까?라고 생각한다.

NSMutableAttributedString에는 NSAttributedString을 저리 붙이고 저리 떼고 막 바꾸고 할 수 있는 요 친구들이 있다.

open func replaceCharacters(in range: NSRange, with attrString: NSAttributedString)

open func insert(_ attrString: NSAttributedString, at loc: Int)

open func append(_ attrString: NSAttributedString)

open func deleteCharacters(in range: NSRange)

open func setAttributedString(_ attrString: NSAttributedString)

내 생각에는 NSAttributedString은 문자열 그 자체라면 NSMutableAttributedString은 NSAttributedString들을 이리저리 확장성 있게 이용할 수 있는 친구라고 생각된다.

 

이 친구도 내가 사용할 때는 위의 NSAttributedString 에서 사용했던 font, color, kern 등등을 변경할 때 자주 사용했다.

NSAttributedString은 문자열이고  NSMutableAttributedString은 NSAttributedString들을 조각모음 하듯이 여러 가지 형태로 만들어 줄 수 있는 친구 인 것 같다!

혹시나 아니면 어쩌지...

 

마찬가지로 여기서 소개 못한 NSMutableAttributedString의 여러가지 요소는 특집으로 알아보자

'Swift > Swift Based Study' 카테고리의 다른 글

[Swift] UITableView 동적 셀 만들어보기  (0) 2022.06.15
[Swift] UILabel  (0) 2022.05.28