[Swift2] ボタンにラベルをのせ、NSLineBreakModeを指定

ボタンにタイトルを与えるだけでは実現できない細かい制御をしたいので、ボタン側のタイトルをブランクにして、ラベルをaddSubviewします。

例えば、文字数を超えた場合に三点リーダを出したい時とか、UILabelのNSLineBreakModeを適宜enumを指定します。

NSLineBreakMode 振る舞い
ByWordWrapping 単語の境界で折り返す。
ByCharWrapping 文字で折り返す。
ByClipping 折り返さず、端を超えた文字は表示されない。
ByTruncatingHead 文字列末尾が表示され、行の先頭に三点リーダ
ByTruncatingTail 文字列先頭が表示され、行の末尾に三点リーダ
ByTruncatingMiddle 文字列先頭と末尾が表示され、中央に三点リーダ

ソースコード

実行

2016-01-22 00.24.00

ByTruncatingHeadした例。先頭が三点リーダってどんな時つかうんだろう。

[Swift2] GCRectMake じゃないやつ (Legacy Constructor Violation)

前回Swiftlintを入れて、.swiftlint.yml ファイルを適宜修正し、なんとかビルドが通る様にはなりましたが、いくつかワーニングががが。

Legacy Constructor Violation: Swift constructors are preferred over legacy convenience functions. (legacy_constructor)

どうやら CGRectMake()が古いやり方らしいです。

こういうの。

    view.frame = CGRectMake(0, 0, self.view.frame.size.width, 300)

とりあえず CGRect.init()を使えばワーニングは消えました。

    view.frame = CGRect.init(x: 0, y: 0, width: self.view.frame.size.width, height: 300)

なるほどですねー。

Swiftlintを入れてみた

初心者なんで、Linter無しでSwift書くの不安だなーと思ってたら、Swiftlintがあったので早速インスコ。

https://github.com/realm/SwiftLint

インストール

brew install swiftlint

して、

XCodeのプロジェクトを開いて、Build Phasesを開き、+ボタンをクリックして、[New Run Script Phase]を選択

作成したやつに下記シェルスクリプトを追記

if which swiftlint >/dev/null; then
  swiftlint
else
  echo "SwiftLint does not exist, download from https://github.com/realm/SwiftLint"
fi

これで、ビルドする度に解析が行われます。

文末セミコロンが無しは未だ判るけど、if文の評価式を()で囲まないのを強制するのってどうなんだろ。
かえって読みにくい気がするけど、郷に入っては郷に従います。

設定ファイル

XCodeプロジェクトのルートフォルダに .swiftlint.yml を作ります。
取り敢えずこんな感じにしています。追々改良していきたいです。

disabled_rules: # rule identifiers to exclude from running
  - trailing_whitespace
  - type_name
  - force_cast
  - line_length
excluded: # paths to ignore during linting. Takes precedence over `included`.
  - Pods
type_body_length:
  - 300 # warning
  - 400 # error
function_body_length:
  - 300 # warning
  - 400 # error
reporter: "xcode" # reporter type (xcode, json, csv, checkstyle)

[Swift2] NavigationController の子ウィンドウ閉じるとき2画面前に遷移させる

Swift初心者のメモです。

やりたいこと

NavigationControllerの下にFirstViewControllerがあって、SecondViewController を PushViewControllerして開いて、そっから ThirdViewController に遷移したとして、ThirdViewControllerを閉じた時に FirstViewController に戻って欲しい。

開く時は

First -> Second -> Third

ときて、閉じる時は

Third -> First

って感じ。

ソースコード

どう書くのが正解なのか判りませんが、なんとかなったので晒します。

leftButton をカスタマイズして popToViewController の類をアレコレすればいける気もするけど、面倒くさいのとシンプルじゃないので、ThirdViewController で NavigationControllerの履歴から 1個前のViewControllerを削除してみた所、やりたい事が出来たみたいです。

[Swift2] カメラで静止画を撮影 (AVFoundation)

Swift初心者がカメラでの画像撮影について書いたメモです。
普段はTitanium使っててこの辺は楽してます。
あんまり詳しく無いけど Objective-C でなら書いた事あります。

先日作ったViewController へ実装していきます。

主なカメラ撮影の方法

iOSでのカメラ撮影といえば、主に2種類の方法があります。

自分は画像を加工とか解析とか色々アレしたりする事が多いので、後者を使います。

前者はTitaniumでいうとTi.MediaのshowCameraとかあたりになります。Tiはこの辺が抽象化されていて扱いがすごく楽で良いのですが、その反面出来ることが限られるので、凝った事しようとすると結局モジュールを作って後者をObjective-Cで書くことになり、AVFoundationだけまぁまぁ判るという事になったりします。

AVFoundation Frameworkで使うクラス達

AVCaptureSession (AVキャプチャセッション)

AVFoundationにおけるキャプチャ入出力をハンドリングする為のクラスです。
まぁ、そういうものだとまる覚えします。

AVCaptureDevice (AVキャプチャデバイス)

前背面カメラやマイク等のデバイスそのものを表すクラスです。

AVCaptureDevieInput (AVキャプチャデバイスインプット)

AVキャプチャデバイスからの入力を表すクラスです。
最初はイメージし辛いですけど、AVFoundation F/W自体のしくみとして、セッションに直接デバイスをぶっ込むのでは無く、デバイスからインプットを生成してセッションにぶっ込む、という仕様になってます。

AVCaputureOutput (AVキャプチャアウトプット)

出力方法を表すクラスです。今回は AVCaptureStillImageOutput を使います。(他に AVCaptureVideoDataOutput も使える様です)

AVCaptureSession の sessionPreset

AVCaptureSession の sessionPresetは種類が色々ありますが、静止画専用の AVCaptureSessionPresetPhoto をセットしておけばデバイスの最大解像度で撮影してくれる筈です。iPhone5 で撮影すると確かに 640 × 1136 でした。

デフォルトはAVCaptureSessionPresetHighらしいです。デフォルトのままiPhone5 で撮影すると、1080 x 1920でした。
つまり一番高解像度なのはAVCaptureSessionPresetHigh (デフォルト) の様です。

セッションの設定を変更するのであれば、その前後で beginConfiguration() と commitConfiguration() をそれぞれ呼んであげましょう。

画面こんな感じ

追々画像をプレビューしたり、加工したりするつもりですが、現状では画面をタップすると撮影しアルバムに保存し、ウィンドウを閉じるだけです。

が、画面がブレてるのは手ブレ補正が効かない iPhone5 のせいだからね!
2016-01-17 11.52.24

ソースコード

100均で見つけた Macbook のスタンド

Seria まな板立て

Seria (100均) で探してきた、まな板立てです。

2016-01-16 19.12.37

Macbookのスタンドに代替出来るかなと思って探したものですが思ったよりフィットしたので紹介します。

Macbook Air 13″

なんという事でしょう。厚み的に安定しないかと思いきや、Macbook Air全然いけます。

結構それっぽいです。
アップルストアで買ってきたと言っても過言では無い勢いです。

2016-01-16 21.28.59

旧Macbook Pro 13″

厚みといい大きさといい、まな板のそれと同じ感じの旧Macbook Pro のフィット感は異常。

金属同士だからちょっと心配していましたが、それもあんまり気にならないです。

旧Macbook Pro 13”

クラムシェルモードな貴兄にオススメです。

[Swift2] UILabelを表示する

Swift初心者がやった事をメモしてます。
寝る前の1〜2時間でちょいちょいやっているので進み遅いです。

前回、追加したウィンドウに何も表示されていないので、Labelでも追加してみようと思います。

Titaniumでいうと Ti.UI.Labelです。めっちゃ使うやつです。

UILabelの追加

UILabelをこさえて、UIViewControllerのrootViewであるviewプロパティにaddSubviewすれば良いようです。

ViewをControllerのコードに書くと、やっぱりごちゃごちゃしますね。
でもStoryboardは使いたくないしなー。
XCodeでもViewをTitaniumやAndroidみたく宣言的に書ければいいのにな。

シミュレータで実行

書いたので変な色ですが、一応ラベルができました。
ラベルはきっと奥が深い筈なんで、また色々しらべます。

2016-01-14 21.53

[Swift2] ViewController を作って画面遷移 (NavigationController)

Swift初心者がやった事をメモします。

前回、追加したNavigationBarのRightBarButtonItemのactionを作ってAlert出しましたが、それを今回は子ウィンドウに遷移する様に変更します。

ViewControllerの追加

Titaniumでいうと Ti.UI.Window って事になるでしょうか。Titanium でいう必要は無いですけど。

兎も角、ViewController を作って追加します。

XCodeで [File] -> [New] -> [File] -> iOS Source の [Cocoa Touch Class]選択し [Next] で、[UIViewController]のサブクラスを作ります。

最終的にカメラ撮影用のViewControllerにするつもりなので、名前はCameraViewControllerとします。

画面遷移

今後とも多分Storyboardは使いません。macbookだし。アレ、iMac とかじゃ無いと使う気にならないです。

Storyboardを使う以外にも、画面遷移には幾つかやり方があるみたいなのですが、まずはMaster-Detailテンプレートの作法通りに、self.navigationControllerのpushViewControllerに作成したViewControllerを与えます。

前回作成したdoCameraメソッドの中身を置き換えます。

シミュレータで実行

カメラボタンをタップすると、作成したCameraViewControllerに遷移しました。
作ったばかりなのでLabel一つありません。

2016-01-14 0.33

やはり NavigationController を使うと画面遷移が楽に実装できます。

[Swift2] Alert を表示する

Swift初心者がやった事をメモします。

前回追加したNavigationBarのRightBarButtonItemのactionを作って、Alert出します。

Titaniumでいうと Ti.UI.AlertDialog です。Titaniumでいう必要は全く無いけど。

ボタンのアクションを作成

MasterViewControllerクラスのインスタンスメソッドとして追加します。
Objective-Cでは “-” で始まるやつ、Swiftでは “func” ではじまります。

引数sender が無いとエラーになります。
色々なサンプルにこう(sender: UIButtonとか、sender: AnyObjectとか)書いているからそのまま書いてますけど、これって
リファレンスの何処をみれば判る事なんだろう。
まだリファレンスの読み方よく判らない。

ふむふむ。現在のViewControllerにモーダルウィンドウ的なやつを出すには、
self.presentViewController (self無くてもいい) を使えばいいのか。なるほど。

ボタンのアクション

UIBarButtonItem のコンストラクタの引数actionを、作った doCameraアクションに変更しています。

ここです。

let cameraButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Camera, target: self, action: "doCamera:")

シミュレータで実行

2016-01-13 1.16

うん。めっちゃアラートです。