iOS デザイン実装はつらい話のあとがきみたいなの。
Qiita に久々に記事を書いたのですけれど、なんか途中で力尽きていろいろツッコミどころが多い感じになってしまった。
わたしとしてはコメントがとても勉強になったので良かったのですけれど…。
以下、書ききれなかった内容の供養みたいなの。
画像リソース周りの話
- ついにラスタライズされた偽ベクタ画像じゃなくて、本物のベクタ画像が使えるようになった
- Slicing の機能はわりと便利だと思うのですけれど、あまり使われてるのを見ない…
みたいなことを書こうと思って忘れたらしい。
Named Color の話
iOS11 以降しか使えないので(R.swift とか SwiftGen とかでバックポートできると思いますが)、まだ本格普及しないと思うのですけれど、これの動作はわりと謎です。
単に Assets Catalog から UIColor を生成して KVC で設定してるだけかと思いきや、シミュレータで見ると View がロードされてから、実際に表示されるまでの間に色空間が別物になっていたりとか。iOS10 辺りで入ったカラーマネジメントとか Display P3 が関係しているのだと思いますが、あんま詳しくないので適当なことしか書けない…。
// viewDidLoad() UIExtendedSRGBColorSpace 0.562 0.529 0.342 1 // viewDidAppear() kCGColorSpaceModelRGB 0.562 0.529 0.342 1
なので、Named Color で指定した場所は、viewDidLoad() で色を変えても反映されないですし、KVC で値を渡すだけの @IBInspectable
で Named Color を指定しても (Missing) という表示になります。
Named Color の登場で割を食ったのが Color Literal で、実体が RGBA 値をコードにベタ書きしてるだけなので、Named Color としては使えません。(なのに、Media Library から Named Color をドラッグすると、Color Literal に化けてしまうのがよくない)
Attributed String の話
JLREQ の要求が高すぎて目眩がしつつ、せめてベタ組みと連続約物の処理くらいはちゃんとやりたいなと思いながら、どう実装すればいいのか悩んでいる今日この頃。
iOS でリッチテキストの描画をするときは、Attributed String を使うわけですが、System Font で日本語の1行だけの Attributed String を作ると、Paragraph Style に lineSpacing を指定したときに、高さ計算に失敗するというバグ?があります。
これはそもそも Attributed String に System Font を渡すのが、想定された使い方ではない…という感じなんでしょうか。実際、Storyboard 上では System Font の Attributed String は作れませんし。
普通のテキストには System Font を推奨しているわりに、Attributed な場合は System Font を使うとダメっぽいのが罠として優秀。
追記:もうちょっと調査した
UIFontDescriptor
でヒラギノを持つカスケードリストを作っても上記の問題が回避できないですね。
// これは擬似コードなんですけれど、こういう書き方をすると bese にない文字は .cascadeList で指定したものにフォールバックされる let baseFontDescriptor = UIFontDescriptor(name: "HelveticaNeue-Medium", size: size) let hiragino = UIFontDescriptor(name: "HiraginoSans-W3", size: size) let font = UIFont(descriptor: baseFontDescriptor.addingAttributes([.cascadeList: [hiragino]]), size: size)
System Font 固有の問題というわけではなく、iOS 内臓のヒラギノの抱える闇の一端っぽい感じ?UIFontDescriptor
はめっちゃバギーな感じがするのでもっと使われてヤバさが広がってほしい…。
@IBDesignable の話
@IBDesignable
って実際使われてるんでしょうか。分かってくると結構便利だと思うんですけれど、トラップがいろいろあってとっかかりが悪い感じ。
init(frame:)
を実装する必要がある- UITextView の場合は、
textContainer
を引数に取るイニシャライザが必須
- UITextView の場合は、
layer
プロパティの操作やaddSubLayer(_:)
やmaskLayer
など CALayer に対する各種操作はできる- class function の
layerClass
を変更しても反映されない
- class function の
TARGET_INTERFACE_BUILDER
で処理を分岐させると、その範囲はリファクタリングの対象外になったり、IB でのみビルドエラーになっていても気付かなかったりする- Storyboard 上で致命的なクラッシュが発生した(IUO の Outlet とかを触ったとか)は、
~/library/Logs/DiagnosticReports/
にログが吐かれるので読めば分かる Editor > Debug Selected Views
を実行すると、当該のカスタム View のイニシャライザやdraw(_:)
が走って、breakpoint で止まる
アプリケーションを実行せずに View だけでデバッグできるのは良い機能だと思います。