LoginSignup
7
4

More than 5 years have passed since last update.

文字につける影の比較

Last updated at Posted at 2018-12-16

はじめに

「影をつけてほしい」とよく言われますが、どんな影を望んでいるか、比較できるものを見せないと意思疎通が難しい...🤔

そういう経験を度々するので、iOSで文字に影をつける方法の比較記事を作ってみました。

まとめると、影の主張の強さは、UILabel#shadow > NSShadow > CALayer の順です。

比較

実装コストは、基本的には、UILabel#shadow < CALayer < NSShadow の順に安いです。

以下では、各実装方法と特徴を整理します。

UILabel#shadowColor

demo1.png

ぼやっとした影ではなく、直線的な影です。
UILabelのshadowColor/shadowOffsetを指定する方法です。InterfaceBuilderのshadowプロパティはこの値を指定するものです。
サンプルはoffsetとして{2,2}を指定しているため、右下にズレた影がついています。
とにかく実装が簡単なのが魅力です。

NSShadow

(2).png

よりぼんやりとした影です。後述のCALayerの方法よりもはっきりと影がつきます。白文字のときにこのような黒影を敷くと、白い背景のときに視認性が良くなります。

NSAttributedStringの属性として指定するため、3つの方法のなかでは最も扱いずらいです。
@IBInspectableのプロパティを作ってAttributedStringに属性を追加するサブクラスを作って使うと、IB上で値を指定できて便利ですね。

import UIKit

@IBDesignable class ShadowAttributeSettableLabel : UILabel {
    @IBInspectable var shadowColorForCustom: UIColor = .clear
    @IBInspectable var shadowOffsetForCustom: CGSize = .zero
    @IBInspectable var shadowRadiusForCustom: CGFloat = 0.0

    override func layoutSubviews() {
        super.layoutSubviews()

        guard let text = text, let attributed = attributedText else { return }
        let mutable = NSMutableAttributedString(attributedString: attributed)
        let shadow = createShadow()
        let range = NSRange(location: 0, length: text.count)
        mutable.addAttribute(.shadow, value: shadow, range: range)
        attributedText = mutable
    }

    private func createShadow() -> NSShadow {
        let shadow = NSShadow()
        shadow.shadowColor = shadowColorForCustom
        shadow.shadowOffset = shadowOffsetForCustom
        shadow.shadowBlurRadius = shadowRadiusForCustom
        return shadow
    }
}

CALayer

(3).png

最もぼんやりした影です。
CoreAnimationのCALayerのlayer.shadowColor/shadowOffset/shadowRadius/shadowOpacityを指定する方法です。

layer.shadowColor以外の値はIBのkeypathで指定できます。ColorはUIColorの値になるため、layer.shadowColorはコードでセットする必要があります。ですので、 @IBInspectableのプロパティを増やしたサブクラスを作らないとIBで指定できません。

import UIKit

@IBDesignable class ShadowUIColorSettableLabel : UILabel {
    @IBInspectable var shadowUIColor: UIColor = .clear {
        didSet {
            layer.shadowColor = shadowUIColor.cgColor
        }
    }
}

画像サンプルは、shadowOpacityを0.3とし、色のアルファを1にしたものです。shadowOpacityを1とし、アルファを0.3としたものと同じ仕上がりになるようです。

おまけ: 全部やると?

concat.png

別次元の三つの影が一緒に現れた絵になります。
邪悪な感じがしますね。

今回のコード

CompareShadows
https://github.com/hsylife/CompareShadows

関連記事

StoryboardでUILabelの文字に黒影つけたいよね

7
4
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
7
4