RawRepresentable のままで Dictionary にアクセス

MacDev
enum MyKey: String
{
    case identifier
    case colorCode
}

func process(_ dictionary: [String: Any])
{
    let identifier = dictionary[MyKey.identifier.rawValue] as? String
    let colorCode = dictionary[MyKey.colorCode.rawValue] as? Int
    ...
}

この .rawValue を何度も書きたくなかったので extension を書いたという話。シンプルなコードなので誰が書いてもほぼ同じになりそう:

extension Dictionary
{
    subscript<WrappedKey: RawRepresentable>(_ key: WrappedKey) -> Value? where WrappedKey.RawValue == Key
    {
        get { return self[key.rawValue] }
        set { self[key.rawValue] = newValue }
    }
}
これがあると
let identifier = dictionary[MyKey.identifier] as? String
let colorCode = dictionary[MyKey.colorCode] as? Int
こうなる

もちろん最初から [MyKey: Any] にした方がきれいな状況であればその方がいいと思う。すっきりした勢いだけで書いた内容のない記事でした。

callback を登録解除できない IOKit のバグ

MacDev

IOKit で HID デバイスからデータを受け取るには IOHIDDeviceRegisterInputReportCallback() で callback を登録する。逆に callback の登録を解除したいときは専用の関数があるわけではなく Apple の資料によると

Note: To unregister pass NULL for the callback.

登録するときと同じ関数を、(callback: NULL) で呼べばいいらしい。

...と知ってからずっと試しているけど、どんな書き方をしても解除したはずの古い context で callback が呼ばれてしまい、アプリケーションがクラッシュ。

どうしようもないので IOKit のソースコードを読んでみることに。

→ 続きを読む

NSView のレイアウト方式いろいろ

MacDev

AppKit ってせっかく毎年改善されて使い方も変化しているのにほとんど "AppKit Release Notes" 以外の資料が更新されないから長年追い続けている人しか全体像が見えないのでないかといつも思っていたのだけど、WWDC18 ではついにリリースノートすらなくなってしまった! セッションビデオでの説明はあるものの過去の何本ものビデオを見返すなんて現実的ではないし、これ長い目で見るとよくないのでは...

そんなこともあるので zumuya では Cocoa 関係の情報をちょっとずつまとめるのである。今回はビューをレイアウトする方法について 1 つずつ触れていくことにする。

→ 続きを読む

呼び出し元のメソッド名を取得

MacDev

あるメソッドを呼び出すメソッドの名前(または setter のプロパティ名)を使用したいことがときどきある。手動で文字列を渡すのも面倒なのでそれを自動化する方法。

Swift

これは知ってた。

func printCallerMethodName(callerMethodName: String = #function)
{
    print("callerMethodName: \"\(callerMethodName)\"")
}
func awesomeMethod()
{
    printCallerMethodName()
}
Code
callerMethodName: "awesomeMethod()"
Output

C#

ずっと C# でも同じようなことをしたくて、最近になってついに知ったから記事にするのだ。Swift でのやり方とペアで書いておけば検索しやすいだろうし。

void PrintCallerMethodName([CallerMemberName] string callerMethodName = null)
{
    Console.WriteLine($"callerMethodName: \"{callerMethodName}\"");
}
void AwesomeMethod()
{
    PrintCallerMethodName();
}
Code
callerMethodName: "AwesomeMethod"
Output

NSView でくっきりラインを引く

MacDev

アプリケーションを作っていると目盛りを描画する機会があるはず。作り方なんて考えなくてもラインを縦横に並べるだけで描くことができる、描画の中でも基本中の基本。

でもラインって意外にデリケートで、気をつけないとスクリーンのピクセルの格子と合わずアンチエイリアスでぼやけてしまう。普通にくっきりしたラインを引くだけでも意外に難しいのだ。それに、せっかくなら Retina ディスプレイの実力も引き出したい...

そんなビューの簡単なサンプルを作ったので参考にどうぞ。Retina ディスプレイでもそうでなくても、くっきり 1 px のラインが表示されるはず。

Result

→ 続きを読む

ベジェ曲線に沿ったグラデーション

MacDev

ベジェ曲線について調べているときに偶然見つけた記事。

グラデーションをベジェ曲線に沿って曲げながら描画するにはどうすればいいのかという話だ。図がたくさんあってとてもわかりやすい。

Before
After

方法は思ったよりシンプルで、要点を抜き出すと、

  1. ベジェ曲線を直線の集合に分解
  1. それぞれの直線に沿うように長方形を並べる
  2. それぞれの長方形にグラデーションを描画

...というだけの話である。(上の図は前述の記事から引用)

これを Cocoa でもできないものか。いや、特に使う予定はないのだけど、楽しそうなので...!

→ 続きを読む

その数字、ガタガタしてない? - AppKit で数字を等幅にする

MacDev

OS X 10.9-10.11 で連続してシステムフォントが変更された。

  • 10.9 で .Lucida Grande UI(ほとんど変化なし)
  • 10.10 で Helvetica Neue
  • 10.11 で San Francisco

このうち 10.11 で採用された San Francisco が現在も使われている。使い方に合わせてあらゆる部分がダイナミックに変化することによって使用シーンの幅を拡大し、今では Apple 製品全体でおなじみ(スクリーン上のみならず製品のロゴやキーボードの刻印にも使われるようになった)の存在である。

どこで使っても読みやすくスタイリッシュで万能感のあるこのフォントだけど、UI で使うときに一つ気をつけておきたいことがある。数字部分がプロポーショナルになったことだ。

数字は変化する頻度が高いのでこのまま使うと値が増減するたびに幅が変化して表示が左右にずれてしまうことになる。これに対処するためには

→ 続きを読む