学生かえるエンジニアのブログ

iOSを主にやる勉強中エンジニア。かえるが好き。ピクルスってかわいいよね。

Swiftで付属型enumを比較するとき

enumを比較する時、switchifを普通に使いますよね

大抵の場合はうまくいくんですが、付属型enum*1が含まれるとifでの比較がうまくいかなかったりします!

そんな時の書き方!

通常パターン

よく見る何もついてない普通のenumをswitchはうまくいく。

enum Mode {
    case special, normal, other
}
let mode: Mode = .special

// ビルド成功
switch mode {
case .special: break
default: break
}

// ビルド成功
if mode == .special {}

付属型enumパターン

次に1つだけ付属型enumにしてみましょう。

switchの比較では問題なくいきますが、if文ではエラーになります。

しかも、付属型にしたのはotherでありspecialは何もついていないのにビルドは通りません。

enum Mode {
    case special
    case normal
    case other(name: String)
}
let mode: Mode = .special

// ビルド成功
switch mode {
case .special: break
case .other: break
default: break
}

// エラー
if mode == .special {}

解決策

1. if文の書き方を工夫する

このように書きます。=は2つではなく1つです。

いっつもこの書き方を忘れるw

しかもこの書き方検索しても日本語記事が全然見つからない!

// 付属型enum を含む enum と比較する場合
if case Mode.special = mode {}
// 付属型の値を利用したい場合
if case let Mode.other(name) = mode {}

2. enumに関数を用意する (1.の書き方を忘れた場合)

1.での書き方を忘れたパターン。けどいちいちswitch文を書いてると行数が多くなり可読性が下がります。

そんな時はswitch比較をenum内で行いましょう。

enum Mode {
    case special
    case normal
    case other(name: String)
    
    // 関数を用意する
    func isSpecial() -> Bool {
        switch self {
        case .special:
            return true
        default:
            return false
        }
    }
    
    // get-only プロパティ版 (上記と同じ事)
    var isSpecial: Bool {
        switch self {
        case .special:
            return true
        default:
            return false
        }
    }
}

if mode.isSpecial {}

補足

switch文で付属の値を使用したい時は下記のように書きます。

switch mode {
case .other(let name):
    break
}

参考

Advanced & Practical Enum usage in Swift

後記

(Obj-Cから)swiftになりenumが便利になったとよく聞きます。try! Swift ではenumの話ばっかりだったとか。

それに加え自分の中ではswitch文もとても良くなったなと思っています。比較可能なものが増えインデントも同じになり、比較方法も色々かけ、、、

またこのブログでも分かる範囲でまとめていきたいなと思います。

間違い、追加情報等ありましたらコメントなど頂けますと幸いです。

try! Swift いきたいなぁ…

*1:関連型enum, Associated Value ともいう

Xcodeにベクタ画像(pdf)を追加してもジャギる(iOS開発)

iPhoneの種類が増えるにつれ、各解像度にあわせて @1x @2x @3x の画像を用意するようになりました。

そしていつからだか、Xcode(iOS)がベクタ画像 *1 に対応しましたね。

「やったー!これで用意する画像1つだけでいいじゃん!」

と喜びつつも、実際に使用してみると

「ジャギるじゃん!(怒)」

そんなデザイナーエンジニアのみなさん!

原因が判明しました!

実は

「ベクタ画像に対応した」
「 ベクタ画像がそのまま使用され、どの解像度でも綺麗に表示される 。」
→ 「 ベクタ画像をもとにラスタ画像を生成し、従来 *2 と同様に扱われる。 」

ということでした。

100 x 100 pximage.pdf という画像を用意したとすると、ビルド時に下記ファイルが生成される。

ファイル名 サイズ
image.png 100 x 100 px
image@2x.png 200 x 200 px
image@3x.png 300 x 300 px

結論

  • ベクタ画像(PDF)をセットすると、ビルド時にXcode@1x @2x @3xPNG画像が生成されて使用される。

  • PDFを使用する場合は、@1x の時に必要なサイズでPDFを書き出して使用する

参考

xcode 8 import pdf (vector) intro image assets not working well - Stack Overflow

How do vector images work in Xcode (i.e. pdf files)? - Stack Overflow

後記

最低週1くらいは更新できたらいいな。

技術的なこと書くと下調べが面倒臭いからこういう記事になっちゃう。

*1:ただしPDF形式のみ。

*2:ベクタ画像が対応されていなかった時代

自作UIViewに@IBDesignableを適用してもうまくいかない問題

自作UIViewに@IBDesignableを適用して、StoryboardやXibファイルで使用しようとしたらビルドがうまく通りませんでした。

原因は、自作のUIViewをXibを使用して作る時の、Xibを読み込むコードに問題が有りました。

解決策

下記コードではなく、

Bundle.main.loadNibNamed("ファイル名", owner: self, options: nil)?.first as? UIView

下記のコードでXibを読み込みます。

Bundle(for: type(of: self)).loadNibNamed("ファイル名", owner: self, options: nil)?.first as? UIView

参考

ios - @IBDesignable error: IB Designables: Failed to update auto layout status: Interface Builder Cocoa Touch Tool crashed - Stack Overflow

後記

高校時代にGoogleBloggerで技術ブログをやってたんですが、はてなブログはマークダウンで記事がかけて楽しいですね笑

なにか間違いや補足、感想などあればコメントお願いします!

Google日本語入力で矢印を入力

矢印「←↓↑→」を入力する時、やじるしみぎを変換して入力していました。

しかしGoogle日本語入力では変換せずともすぐ入力できるショートカット的なものがありました!

→ を入力する

かな入力の状態で Z キーと L キーを入力するだけ!

調べたら他にも色々あったのでまとめてみました

Google日本語入力 ショートカットまとめ

文字 ショートカット
z h
z j
z k
z l
z .
z ,
z -
z [
z ]

後記

初投稿でした。

Google日本語入力はシークレットモードとかもあるのでまたいつか記事にしますね。

プログラミング関連の投稿をもっとしていきたい。