🚥
ネオン風にテキストを表示するUILabelを作成する
概要
- ぼやっと光るネオン風のテキスト表示を実装してみました。
参考
- UILabels with Neon-Effect
- Swiftで文字列の輪郭に線をつける
-
strokeWidth
- strokeWidthの標準が
3.0
ということでこれに習っています。負の値で指定することに注意。 -
For example, a typical value for outlined text would be 3.0.
- strokeWidthの標準が
-
How to render shadows using NSShadow and setShadow()
- 似たようなことをやってそう
コード
NeonLabel.swift
-
UILabel
のカスタムクラスを作成します - テキスト周りのぼやっとした描画を
CGContext
で行います - またテキストの描画設定は
text.draw
で行います - 色の定義を3つしています。
UIColor
の引数1つでいい感じにその他の色を計算して出せると良いのですが(試せてないです)。
import UIKit
class NeonLabel: UILabel {
// MARK: - Overrides
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let context = UIGraphicsGetCurrentContext(),
let text = self.text
else {
return
}
let insideColor = UIColor(red: 69.0/255.0, green: 254.0/255.0, blue: 0, alpha: 1)
let outlineColor = UIColor(red: 22.0/255.0, green: 145.0/255.0, blue: 0, alpha: 0.8)
let blurColor = UIColor(red: 104.0/255.0, green: 248.0/255.0, blue: 0, alpha: 0.7)
context.setShadow(offset: .zero, blur: self.font.pointSize/2.0, color: blurColor.cgColor)
context.setTextDrawingMode(.fillStroke)
let attributeDict: [NSAttributedString.Key : Any] = [
.font: self.font!,
.foregroundColor: insideColor,
.strokeColor: outlineColor,
.strokeWidth: -3.0,
]
text.draw(in: self.bounds, withAttributes: attributeDict)
}
}
呼び出し例
- 通常通り
NeonLabel
を表示するだけでOKです -
AutoLayout
のextensionは以下を使用しています
//
// ViewController.swift
// NeonLikeDemo
import UIKit
class ViewController: UIViewController {
// MARK: - Properties
private var neonLabel: NeonLabel = {
let neonLabel = NeonLabel()
neonLabel.font = .systemFont(ofSize: 30)
neonLabel.text = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
return neonLabel
}()
private lazy var fontSizeSlider: UISlider = {
let slider = UISlider()
slider.minimumValue = 10.0
slider.maximumValue = 400.0
slider.value = 30.0
slider.isContinuous = false
slider.addTarget(self, action: #selector(fontSizeSliderValueChanged(_:)), for: .valueChanged)
return slider
}()
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .black
view.addSubview(neonLabel)
neonLabel.anchor(top: view.topAnchor, left: view.leftAnchor, right: view.rightAnchor, bottom: view.bottomAnchor,
paddingTop: 12, paddingLeft: 12, paddingRight: 12, paddingBottom: 12)
view.addSubview(fontSizeSlider)
fontSizeSlider.centerX(inView: view)
fontSizeSlider.anchor(left: view.leftAnchor, right: view.rightAnchor, bottom: view.bottomAnchor,
paddingLeft: 12, paddingRight: 12, paddingBottom: 12)
}
// MARK: - Selectors
@objc
private func fontSizeSliderValueChanged(_ sender: UISlider) {
neonLabel.font = .systemFont(ofSize: CGFloat(sender.value))
}
}
Discussion