LoginSignup
5
1

More than 5 years have passed since last update.

NSAttributedStringを空文字で生成すると2度とAttributesを取り出せなくなる

Posted at

環境

Swift4.2.1

本題

例えば、以下のようなコードを書いて、xibやstoryboardで設定したattributesを取り出そうとします。

extension NSAttributedString {
    var allAttributes: [NSAttributedString.Key: Any] {
        return self.attributes(at: 0, effectiveRange: nil)
    }
}

すると、文字列が空(isEmpty == true)の場合にNSRangeExceptionで落ちます。

😱

attributes(at:effectiveRange:)のDiscussionに記載がある通りです。

Raises an rangeException if index lies beyond the end of the receiver’s characters.
For a list of possible attributes, see Character Attributes.

文字列がからの場合は、at: 0が存在しないのでCrashするわけですね。

結果無理

回避策

空文字列でNSAttributedStringを生成しないようにする

以下のようにUILabelのExtensionでisEmptyにならないように、空の場合は半角スペースを入れるようにする。
これなら上で作ったExtensionがバグることもない。

extension UILabel { 
     func updateAttributedText(_ text: String) { 
         // スペースいれておかないと、allAttributesが空文字で設定したAttributesを返さなくなる 
         let string = text.isEmpty ? " " : text 
         self.attributedText = NSAttributedString(string: string, attributes: self.attributedText?.allAttributes) 
     }
}

そもそもxibやstoryboardでattributedを設定しない

そもそもxibやstoryboardでattributedを設定しなければ、self.attributedText?.allAttributesを使わずに、以下のように毎回attributesを生成して設定すれば良い

extension UILabel { 
    func setAttributes() {
        // lineSpace設定
        let pStyle = NSMutableParagraphStyle()
        pStyle.lineSpacing = 3
        let attr = [NSAttributedString.Key.paragraphStyle: paragraphStyle]
        // 文字色設定
        attr[NSAttributedString.Key.foregroundColor] = .red
        self.attributedText = NSAttributedString(string: self.text, attributes: attr)
    }
}

あきらめる

最悪CrashしないようにisEmptyだけはチェックしとく

extension NSAttributedString {
    var allAttributes: [NSAttributedString.Key: Any] {
        if self.string.isEmpty {
            return [:]
        }
        return self.attributes(at: 0, effectiveRange: nil)
    }
}

最後に

最近IB系の調子が悪いので、使わないほうがいいんじゃあないかなーと思ってきました。
Attribute周りはコードでやったほうが良いのかもしれません。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1