SF Symbolsを実装で使う

SF Symbolsとは
WWDC2019で発表されたApple公式のアイコンフォントです。
デザイン系の記事はよくトピックに上がってるのですが、実際に実装に適用する方法がすぐわからなかったので備忘録を残します。
コードで使用する
UIImageにiOS13以降でinit(systemName:)が使えるようになりました。
systemNameに各Symbolの名前を入れればそのイメージが生成できるようになります。
さらにUIImage.SymbolConfigurationを使ってsizeやweightなどを指定します。
// スタイルを指定 let config = UIImage.SymbolConfiguration(pointSize: 14, weight: .bold, scale: .large) // イメージを生成 prevButton.image = UIImage.init(systemName: "chevron.left", withConfiguration: config)
Interface Builderで使用する
カスタムWebブラウザを想定して、BarButtonItemにSF Symbolを適用してみました。

BarItem→imageにSymbolの名前を指定するだけです。
Interface BuilderではSymbolConfigurationを指定する場所はなさそうです。
参考
Option Menuを表示する - Android開発メモ
やりたいこと
- ↓みたいなメニューを表示したい
- メニューごとに何かアクションしたい

やりかた
Activityのメソッドをオーバーライドすれば作れる
Code
// オプションメニューの作成 override fun onCreateOptionsMenu(menu: Menu?): Boolean { // add(groupId, itemId, order(気にしない時はNONE), title) menu?.add(Menu.NONE, 0, Menu.NONE, "Menu 1") menu?.add(Menu.NONE, 1, Menu.NONE, "Menu 2") return true } // メニューが選択された時 override fun onOptionsItemSelected(item: MenuItem): Boolean { if (item.itemId == 0) { // Action } return true }
参考
横向きのみのフルスクリーンで表示する - Android開発メモ

画面を横向きに固定する
画面の向きはAndroidManifest.xmlのandroid:screenOrientation属性から指定する
<activity android:name=".MainActivity" android:screenOrientation="userLandscape">
フルスクリーン表示
以下を非表示にして、さらに非表示にした時のレイアウトを指定しないといけないっぽいです。
- ステータスバー
- タイトルバー
- ナビゲーションバー
今のwindowがフォーカスされた時(onWindowFocusChanged)に呼び出す例。
override fun onWindowFocusChanged(hasFocus: Boolean) { super.onWindowFocusChanged(hasFocus) if (hasFocus) hideSystemUI() } private fun hideSystemUI() { window.decorView.systemUiVisibility = ( // ナビバーを隠れているようにレイアウトする View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION // ステータスバーが隠れているようにレイアウト or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN // ナビゲーションバー(下部)を隠してインタラクションがあっても非表示にし続ける or View.SYSTEM_UI_FLAG_IMMERSIVE // タイトルバー(上部)を隠す or View.SYSTEM_UI_FLAG_LAYOUT_STABLE // インタラクションがない間ナビゲーションバーを非表示にする or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // ステータスバーを隠す or View.SYSTEM_UI_FLAG_FULLSCREEN) }
参考
Material Designメモ - Elevation

今までコンポーネント周りの学習をやってきたけど、Elevation(コンポーネントの標高)について理解を深めたかったので読んでみた。 デフォルトのElevation使うと悪い意味でマテリアルっぽいイモっぽさが出てしまうのでどこまでアレンジできるのか知りたかった。
参考
概要
ElevationはZ軸に沿った2つのサーフェス間の相対距離のこと
Elevation in Material Design
各コンポーネントのサーフェス間の距離として測定される。 1つのサーフェスから別のサーフェスまでの距離はdpsによって測定されそれは車道を使用して描画される
同じElevationのサーフェスでも、他のサーフェスが背後にある婆に異なる表示がされる
例: 8dpのElevationと4dpの上にある4dpのElevationはシャドウの描画が異なる
The elevation system
- 全てのMaterial DesignのサーフェスとComponentはElevationをもつ
- 異なるElevationのサーフェスは次のことを行う
- 他のサーフェスの前後でサーフェスを移動できるようにする
- 例:アプリバーの前後でスクロールするコンテンツ
- 空間的な関係を反映する
- 例:FABのシャドウがCardCollectionと分離していることを示す
- フォーカスする注意は一番上のElevationにする
- 例:ダイアログ表示
- 他のサーフェスの前後でサーフェスを移動できるようにする
- 違うサーフェスの塗りつぶしはシャドウの代わりにElevationを表現できる
- 不透明度の調整もシャドウの代わりにElevationを表現できる
Resting elevation
Resting elevationはデフォルトでComponentに与えられるElevationのこと
Resting elevationは環境、プラットフォーム、アプリによって異なる
例
- Mobileの場合
- コンポーネントがインタラクティブなことを示すためにシャドウのような視覚的な合図が設計されている
- デスクトップの場合
- ホバー状態など、他の合図によってコンポーネントがインタラクティブであることを示すので、Elevationが浅く設計される。例えば
Cardは0dpの高さが設定され、輪郭線が描画される
- ホバー状態など、他の合図によってコンポーネントがインタラクティブであることを示すので、Elevationが浅く設計される。例えば
Changing elevation
コンポーネントはユーザーによるインプットなどのイベントによりElevationが変わることがある。これが発生するとコンポーネントはプリセットされているElevationに移動する(これはコンポーネントが静止していないときにデフォルトのElevationである)
イベントが完了またはキャンセルされると静止時のElevationに移動する。
Elevation interference
Elevationが変化するときに異なるコンポーネントが衝突するべきではない 衝突を避けるためにコンポーネントは邪魔にならないように移動できる。
例
- カードのElevationをあげてFABを通過するように配置された場合、衝突が発生する前にボタンを消したり画面外に移動させる
- ↑の場合はカードとFABが重ならないようにレイアウトを設計する必要がある
Depicting elevation
Surface edges
エッジはマテリアルなサーフェスの触覚品質を表現するのに役立つ。これによりComponentが識別可能になる。
デフォルトでは車道を仕様してエッジを示すけど、サーフェスの色や不透明度を変えることで代替可能。サーフェスが互いに分離して見えるように十分にコントラストを入れる必要がある。
Surface overlap
サーフェスが部分的/完全に別のサーフェスと重なる場合、二つの表面が異なるElevationを示す。上記の色のFillやOpacityによるサーフェスの分離はElevationの程度は示さない。
Elevationの差が判断できないと重なり合ったComponentの境界がわからなくなる
Distance
Scrimmed backgrounds
- スクリム(背景が暗い色透過)されるとElevationを示す。ただし標高差はわからない状態
Shadows
- シャドウは他の手法では不可能な方法でサーフェス間の硬度を表現できる
Motion and elevation
モーションは以下を利用してElevationを強調できる
- シャドウを変える
- オーバーラップを表現する
- 周囲のアイテムを押し出す(同じElevationを共有するサーフェスの場合)
- Scaleを変える
- パララックスを使う
- モーションテクニックの組み合わせ
Elevation hierarchy
コンテンツがより表面に来る場合
- 重要なコンテンツ
- ダイアログなど、注意を集中する
- アプリバーのアクションなど、背後のサーフェスを制御する
サーフェスが同じ高さのものは、互いに同等の重要度であることを示す。 標高を示さないサーフェスの場合(例えばデスクトップ環境)各サーフェスのレイアウト位置によって相対的な階層レベルを表現する。
- 左から親コンテンツを並べる
- 上にメニューを並べる
Default elevations
全てのComponentに静止時のElevationと動的なElevationがある。 ダイアログなどの特定のものは他のComponentよりも高いElevationに配置され全てComponentに渡って一貫したElevationの順序を確立している

iOSとの比較
- iOSはシャドウも使うが、Blurも使う
- コンポーネントの重要度(→Elevationのdp値)も定義されてて普通にすごいな
所感
- 無理してElevationしなくていいのな
- FillやOpacityの調整でもいいのは知らなかった
- プラットフォームごとの設計が必要なんだ...
- 置かれている環境が違うからいいことだと思う
- エッジの境界と、コンテンツの重要度が整理されていればカスタム値を使ってもいいってことね。
DailyUIをはじめてみる

DailyUIをはじめるにあたり、現時点で考えていることと目的を設定してみる。
DailyUIとは
登録すると毎日お題が与えられて、それをこなすことによりデザインのインスピレーションが鍛えられるというサービス。 多くの人達が日々お題にチャレンジして、Twitter、Dribbbleなどでシェアしている。
とまあ、誰でも知ってる内容はこの辺にする。。
正直やっても意味ないと思ってた
何から手を出せばいいかわからないような初学者がいろんなツールを使って使い方を覚えながら試行錯誤したり、他の人のチャレンジを見ながら少しずつ慣れていくのにはいいコンテンツだとは思っていたけれど、 エンジニア/デザイナーの自分がやるとして実業務的に活かせることあるのかな🤔と懐疑的だった
エンジニアとして業務してると以下のようなことを思ったりする。
- 短時間でレイアウトをFixさせるとかなくて、複数案作って検証してくれって思う
- 1画面作って終わりなことはそうそうないんで、画面の前後関係、モデルの関係を意識して画面設計してくれって思う
- (会社やエンジニアによるけど)アプリは特にインスピレーションでごり押したDribbbleUI的なイケてるアニメーションを作ったところで誰が実装できるの...?てなる。
なぜやるのか
手を動かす機会を作るため。
誰かから強制的にお題が出されるっていうシステムはいいなと思っていて、実際にMacの前に向かってみないと何もはじまんないことだけは確かなのでとりあえずやってみようと思った。 自分で勝手にやるものなので、気に入らない点は避けながら自分でルールを作れば良い。 なので上記のような実務に則さないような点については、方針を決めることで軽減できるように考えた。
どうやるのか
やること
- アプリでもできるお題はAndroid想定でMaterial Designベースでレイアウトを組んでみる
- 1画面だけではなく、前後(どっちか)の画面も想定してみる
- 色の使い方が下手なので、そこはできるだけ自由にやってみる
- 時間短縮できるように改善を重ねる
- 短時間でレイアウトをFixするしかないのは許容する(そういうフローだし)
やらないこと
- アニメーション制作
- ゴリゴリカスタムUI作る
気をつけること
- 完璧は捨てる
- カッコいい見た目は捨てる(普通以上を目指す)
- できるだけ毎日やる
- Twitterで共有する
そういうわけで
がんばります💪