NSVisualEffectView の角を丸くする 2 つの方法
- Apple
- 開発
画面の端にぴったりくっつけることが多い iOS と違い、macOS だと余白を設けてビューを配置することが多い。そうすると角を丸くしたくなる。木工家具でやすりがけや面取りをするような基本的な話だ。
AppKit の標準コントロールのほとんどはそういう仕上げがしてあるから意識する必要はないのだけど、先日 NSVisualEffectView
の角を丸くしたい状況があったのでやり方を考えてみた。
方法 1(シンプルだけど邪道?)
ビューを丸くするんでしょう、layer.cornerRadius
を指定すればいいじゃない。iOS の人だったらまずやりそうな方法だ。
ほら普通に丸くなる。
...ところが自分で用意していない layer
には触れるなというのが NSView
の CALayer
対応の基本なので、若干気持ち悪い。frame
などと違って cornerRadius
が原因で動作がおかしくなることなんてまずなさそうではあるけれども。
あと NSVisualEffect
の実装が変わって例えばサブレイヤーで描画するようになったりしたら四角い角に戻ってしまうわけで、不安は残る。
方法 2(正攻法?)
次の方法は maskImage
を指定する方法だ。NSVisualEffectView
自身が用意している正攻法。でも普通のイメージだとビューのサイズが変わるたびにセットし直さないと角丸が引き伸ばされてしまう。
そこで活躍するのが NSImage.capInsets
だ。UIImage
でおなじみの四辺と角を保護しながらリサイズして描画してくれる機能。OS X 10.10 Yosemite 以降から AppKit
でも使用できるようになった1。
イメージを生成してメモリや GPU のリソースを消費することになるので方法 1 の方が優れているように見えるけど、maskImage
の内容は自由なので、例えば Dock っぽく上の角だけ丸くしたいみたいな凝ったことにも対応できる。どの方法を選ぶかはあなた次第だ2。
記事完成直後の追記
方法 2 は Mojave の Playground だと capInsets
が反映されず正しく表示されないことが判明。
自分の環境では今のところ実際の App 上では問題なく動いているけど「正攻法」と呼べるかは怪しい。わざわざ記事にしたのに...
2018.9.27 追記
maskImage
に capInsets
が使用できることは WWDC で明言されているようだ:
正攻法!正攻法!
Share
リンクも共有もお気軽に。記事を書くモチベーションの向上に役立てます。