kitoko552.memo

kitoko552のメモ

Swift

Swift 3におけるアクセス修飾子

要点 open: 外部モジュールからアクセスでき、外部モジュールで継承・オーバーライドができる(Swift 3未満のpublicと同義)。 public: 外部モジュールからアクセスできるが、外部モジュールで継承・オーバーライド等はできない。 internal: 同じモジュール…

Swift 3のstructがプロパティに合わせて自動で作るイニシャライザはinternalになる

要点 Swift 3では、structがプロパティに合わせて自動で作るイニシャライザは、プロパティのアクセスレベルにかかわらずinternalになる。 ライブラリを公開している方は注意。 外部からも使えるようにするにはpublicなイニシャライザを改めて定義してやる。 …

AlamofireのSwift 3対応バージョンをiOS 8対応のプロジェクトでも使えるようにする

要点 AlamofireのSwift 3対応バージョンである4.0.0は対応OSがiOS 9以上 iOS 8でも使いたい場合は、フォークしてURLSessionStreamTaskを使っている部分をコメントアウトすると使える Swift 3登場 先日正式版のiOS 10, Xcode 8がリリースされ、既存のアプリを…

lazyを使って他のプロパティを使うプロパティの初期化を宣言時に実現する

要点 lazy を使えば他のプロパティを必要とするプロパティの初期化を宣言時にすることができる。 その場合は型宣言を書かなければエラーが出るので注意する。 他のプロパティにはselfを書かないとエラーが出る。 private lazy var hakuba: Hakuba = Hakuba(t…

【Swift】文字列の頭文字を取り除く

String(text.characters.dropFirst()) こんな時に使う let user = "@tanaka" let name = String(text.characters.dropFirst()) print(name) // tanaka

Dictionaryの配列をひとつのDictionaryにする

要点 Dictionaryの配列をflatMapすると reduceを使う reduceについて 要点 Dictionaryの配列をひとつのDictionaryにするにはreduceを使う。 let array = [["one" : 1], ["two" : 2], ["three" : 3]] let dictionary = array.flatMap { $0 }.reduce([String :…

componentsSeparatedByStringで文字列から配列を生成する

要点 文字列から配列を作りたい 配列から文字列を作りたい場合は 要点 SwiftでStringから配列を生成する場合はcomponentsSeparatedByString(_ separator: String) -> [String]を使う。 let string = "hoge,fuga,popi" let array = string.componentsSeparate…

joinWithSeparatorで配列内の文字列を結合する

要点 配列内の文字列を結合したい joinWithSeparatorを使う ちなみに 要点 joinWithSeparator(_ separator: String) -> Stringを使う。 let array = ["h", "o", "g", "e"] let hoge = array.joinWithSeparator("-") print(hoge) // h-o-g-e 配列内の文字列を…

UIViewControllerAnimatedTransitioningを使って自作の画面遷移を実装する【基本編】

要点 iOSアプリの画面遷移 自作の画面遷移を実装する方法 UIViewControllerAnimatedTransitioningに準拠したクラスの実装 transitionDurationメソッド animateTransitionメソッド 1つ目のまとめ UIViewControllerTransitioningDelegateのメソッドの実装 anim…

Swiftで端末のディレクトリ一覧を表示する

要点 ディレクトリの一覧を表示したい contentsOfDirectoryAtPathを使う場合 subpathsAtPathを使えばもっと簡単 enumeratorAtPathというのもある 要点 NSFileManagerを使って探索する。 使えるのはcontentsOfDirectoryAtPath(path: String) -> [String]?, su…

UICollectionViewやUITableViewのスクロール処理はViewが描画されてから行う

要点 UICollectionView, UITableViewのスクロール処理 setContentOffsetかscrollToItemAtIndexPathを使う メソッドを呼ぶのはViewが描画されてから viewDidAppearかviewDidLayoutSubviews内で呼ぶ 要点 UICollectionView, UITableViewのスクロールはsetConte…

SwiftでStringからIntやCGFloatに変換するときの話

要点 Stringから数値に変換する際はNSNumberFormatter().numberFromString(string)がおすすめ Intにはイニシャライザを使って変換する方法もあるが、CGFloatにはStringを引数に取るイニシャライザがない let intStr = "3" let intNum = NSNumberFormatter().…

Stringのlength(文字数)を取得するにはcharacters.countがベスト

要点 Stringの文字数を取得する方法はけっこうある。 characters.countが一番正確っぽい。 print(str.characters.count) print(str.utf16.count) print(str.lengthOfBytesUsingEncoding(NSUnicodeStringEncoding)) swift string lengthとググると... いろい…

iOS9でWKWebViewのdecelerationRateの設定がうまくいかないときの対処法

要点 iOS9でWKWebViewのdecelerationRateの設定がうまくいかないのはiOSのバグ。 対処法としては、WKWebViewのscrollViewのdelegateを指定し、scrollViewWillBeginDraggingでdecelerationRateを設定する。 class HogeViewController: UIViewController { var…

Objective-CからSwiftのenumを使う

要点 enumの宣言の前に@objcをつける。 enumはIntとして宣言する必要がある。 IntでないenumはObjective-Cからは使えない。 // 使えない enum Hoge: String { case hoge ... } // 使える @objc enum Hoge: Int { case hoge ... } Swiftのenum Swiftではenum…

Objective-CからSwiftのstruct(構造体)は使えない

要点 Objective-Cで使えるオブジェクトは全てNSObjectを継承しているため、NSObjectを継承できないSwiftのstruct(構造体)は使えない。 クラスも同様、NSObjectを継承していないクラスはObjective-Cからは使えない。 まだObjective-C書いてるの? そう思う…

Arrayは値型でNSArrayは参照型

要点 Arrayは値型でNSArrayは参照型ですよって話です。 変数の再代入やメソッドの引数に渡す際、Arrayの場合はコピーが渡され、NSArrayの場合は参照が渡される。 Arrayでもinoutを使えば参照渡しができる。 SwiftのArrayは値型 SwiftのArrayは値型です。 Arr…

まだfor文で消耗してるの? map, filter, flatMapを使えばfor文は要りません

要点 Swiftではmap, filter, flatMap, forEachを使えばfor文は必要ありません。 mapの例 let numbers: [Int] = [1, 2, 3] // for文 var twice = [Int]() for num in numbers { twice.append(num * 2) } // map let twice = numbers.map { $0 * 2 } // twice …

forEachを使ってSwiftっぽく書く

要点 SwiftのforEachを使えば、普通のfor文よりもSwiftっぽく書けます。 ただし、配列などのコレクションの中身を変更するようなものはforEachじゃなくてmapとかfilterとかflatMap使いましょう。 // for文 for element in array { if element == 2 { // Do s…

PhotoKitでアルバムを新規作成する

要点 PHPhotoLibraryのperformChangesメソッドでアルバムを作成できる。 performChangeメソッドのchangeBlockにアルバム新規作成のChangeRequestを書くことで作成する。 import Photos let changeBlock: () -> Void = { PHAssetCollectionChangeRequest.crea…

Swiftの配列をNSMutableArrayに変換する

要点 Swiftの配列をNSMutableArrayに変換するには、NSMutableArray(array:)を使います。 前提 Objective-C時代に活躍したNSArrayやNSMutableArrayは、Swiftではほぼ使いません。 しかし、コードがObjective-CとSwiftの共存であるプロジェクトでは、SwiftでNS…

SwiftでrespondToSelectorを呼ぶ必要はない

要点 SwiftにはOptional ChainingがあるのでrespondToSelectorを呼んでチェックする必要はありません。 シンプルにhoge.delegate?.delegateMethod()と書くだけでいいです。 delegateを使った実装 Objective-C時代は、delegateを使ってある処理を他のクラスに…

【Swift】配列の要素をfunctionalに削除する

簡潔にまとめると 削除したい要素を取り除くのではなく、削除したい要素以外を再代入すればいい。 array = array.filter { $0.index != num } もうちょい詳しく Swiftは配列等の集合(SequenceTypeプロトコルを適応したもの)はmapやfilter等を使ってfunctio…

SwiftのクラスをObjective-Cで使う

要約 Objective-Cファイル内で${ProductModuleName}-Swift.hをimportする Swift側のファイルはNSObjectを継承していなければコンパイルエラーになる 詳細 kitoko552.hatenablog.com この記事の反対のことをやろうということです。 SwiftのクラスをObjective-…

Objective-CのクラスをSwiftで使う

要約 ${ProductModuleName}-Bridging-Header.h で該当のObjective-Cファイルをimportする だけです。 詳細 Bridging Headerの作成・設定方法は以下のリンクを読めば大体わかります。 tech.admax.ninja 作成・設定が完了したらBridging Headerファイルに、 //…

SwiftGenでリソースをタイプセーフに扱う

概要 SwiftGenを使えばLocalizable.strings, Storyboard, ImageAssetsなどのリソースをenum化してタイプセーフに書けるよって話です。 github.com SwiftでStringを扱うときの問題点 SwiftでStringを普通に扱うと以下のようになります。 let title = "What th…

Quick Actions (3D Touch Shortcuts)を実装する

iPhone6sから3D touchが導入されました。 ホーム画面のアプリアイコンを3D touchすることで、目的の操作画面でアプリを起動する操作をQuick Actions(または3D Touch Shortcuts)と言います。 この記事では、このQuick Actionsの実装方法や注意事項などを簡…

Swift2.0にtry?を使ってスマートにError Handlingをする

Swift2.0でError Handlingの機能が追加されました。 しかしError Handlingを行うと、ネストが増えたり、一度varで宣言してからdo catchを書いたりと、コードがスマートに書けませんでした。 var audioInput: AVCaptureInput? do { audioInput = try AVCaptur…

Swift2.0でavailableを使ってバージョンチェックをする

Swift2.0からavailableを使ってバージョンチェックができるようになりました。 if #available(iOS 8.0, *) { // iOS8.0以上の場合のみの処理 } 構文は上のように、#abailable(platform version, ...)となります。 末尾の*は、「他のプラットフォームに関して…

Swiftでnil < 数値はtrueになる

Swiftではnilと数値を比較する際、nil < 数値はtrueになります。 let num: Int? = nil if num < 300 { print("true") // numがnilでも通る。 } この問題は特にOptional bindingする際に気をつけるべきです。 Optional bindingをすると、あるoptional型の変数…

UITableViewのviewForHeaderInSectionがsection=0のときに呼ばれない

UITableViewのdelegateメソッドviewForHeaderInSectionは、sectionが0のときに呼ばれないときがあります。 これは、heightForHeaderInSectionを実装していない場合に起きるので、heightForHeaderInSectionを実装すると直ります。 func tableView(tableView: …

NSMutableArrayをSwiftのArrayに変換する

Objective-cとSwiftが共存しているプロジェクトでは、NSMutableArrayをSwiftのArrayに変換したいときがあります。 感覚的に以下のように書きたいのですが、これではコンパイルエラーになってしまいます。 let mutableArray = NSMutableArray(array: ["hoge",…

Swiftのfilterの使い方

Swiftにはmapと同じように、便利に配列を操作できるメソッドがあります。 filterはその名の通り配列のフィルタリングができます。 let array = [1, 2, 3, 4, 5] let even = array.filter { num in num % 2 == 0 } println(even) // [2, 4] 上の例では、配列…

UIButtonのタイトル・色を変える

UIButtonにはtitleLabelというプロパティがありますが、これを直接操作しようとするとタイトルや色を変更することはできません。 button.titleLabel?.text = "Button" // 変更されない button.titleLabel?.textColor = UIColor.blueColor() // 変更されない …

Swiftで円のUIImageをコードで作成する

色がついた円の画像が欲しいけど、画像を作るほどでもない(デザイナーの方に頼むほどではない)ときはコードでUIImageを作っちゃいましょう。 extension UIColor { func circleImage(#size: CGSize) -> UIImage { let rect = CGRectMake(0.0, 0.0, size.wid…

Swiftの??(はてな二つ)の使い方

Swiftでは??(はてな二つ)を使って値がnilのときに代入する値を指定することができます。 let fuga = hoge ?? "hage" 上の例では、hogeがnilでないときはhogeの中身をfugaに代入し、hogeがnilのときは文字列"hage"をfugaに代入しています。 こうすることで…

Swiftのドット(..., ..<)を使った範囲指定

Swiftでは範囲指定を簡単に書くことができます。 他の言語にはあまり見られないので、最初はみても意味がわからないと思いますが、簡単かつ便利なので覚えておいて損はないと思います。 例えば、一般的な言語と同じように範囲指定を書くと以下のようになりま…

複数のif-let文をつなげて書く

少し古い情報ですが、恥ずかしながら最近知ったのでメモします。 Swift1.1では、オプショナル型の変数が複数ある場合はif-let文をネストしなければなりませんでした。 if let hoge = hoge { if let fuga = fuga { // Do something } } /* 本当は以下のように…

Swiftでmapを使って配列を簡単に操作する

Swiftのmapを使うと、配列の操作がとても簡単にできます。 例として、配列の全ての要素を二乗した配列を新たに作成する場合を考えます。 let array = [1, 2, 3, 4, 5] var powArray = [Int]() for num in array { powArray.append(num * num) } mapを使うと…

Swiftでwhere節を使ってネストを浅くする

Swiftではオプショナル型がnilかどうかを調べる際にif-let文が使えます。 しかし、if-let文を使うとネストが深くなりがちです。 if let hoge = hoge { if hoge.fuga > 0 { // Do something } } こういった場合は、where節を使うとネストを浅くすることができ…

Swiftで丸いUIButtonを作る

これは定番ですが、すぐ忘れてしまうのでメモします。 ちなみにUIButtonでなくてもUIViewのサブクラスなら同じ処理で丸くすることができます。 UIButtonを丸くする際は、そのボタンのwidth, heightを同じ値にして(正方形にして)、そのサイズの半分の値をco…

AnyObject型をDictionaryにキャストする

AnyObject型をDictionaryにキャストしたいときは、以下のように書きます。 // let dict = anyObject as [String : AnyObject] これではだめ let dict = anyObject as Dictionary<String, AnyObject> おそらくキャストがうまくいかないので、そのときはif let文等で対処してくだ</string,>…

Swiftでsubviewsに影響が出ないようにviewを透過する

Swiftでは(Objective-cでも)、あるviewのalphaを直接操作してしまうと、そのviewのsubviewsもalphaの影響を受けてしまいます。 override func viewDidLoad() { super.viewDidLoad() let view1 = UIView(frame: CGRectMake(35, 50, 300, 500)) view1.backgr…

Swiftでviewに対するタップを検知する

UIButtonのタップ検知は簡単ですが、UIButton以外のviewに対するタップイベントを取得したいときがあります。 そういったときは、以下を行います。 タップイベントを取得したいviewのuserInteractionEnabledをtrueにする。 タップイベントを取得したいviewに…

CGPathCreateWithEllipseInRectを使って円形のviewを作る

CGPathCreateWithEllipseInRectは、指定されたCGRectの各辺に接するような楕円のCGPathを得ることができます。 class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let view1 = UIView(frame: CGRectMake(35, 50,…

UIViewのframeとboundsの違い

以下の例を見た方がはやいです。 class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let view1 = UIView(frame: CGRectMake(50, 50, 300, 550)) println(view1.frame) // (50.0, 50.0, 300.0, 550.0) println(vi…

CGRectInsetの使い方

SwiftのCGRectInsetは、ある矩形から指定した余白分を除外した矩形を取得するメソッドです(もちろんObjective-Cも同じ)。 CGRectInsetの定義は以下のようになっています。 /** * :param rect 元になる矩形 * :param dx 横の余白 * :param dy 縦の余白 */ f…

Swiftで画像を正方形に切り取る

画像から正方形を切り取りたいときがあったので、メソッドを作りました。 CGImageCreateWithImageInRectを使えば簡単に切り取ることができます。 /** 与えられたimageを正方形にして返すメソッド 横長は真ん中を正方形に切り取って返す 縦長は上から正方形に…

Swiftのオプショナルチェーン(optional chaining)

Swiftのオプショナル型は、値を取り出したいときに開示(unwrap)をしますが、開示した際にnilだった場合、実行時にエラーになってしまいます。 // hoge, fuga, fooのいずれかがnilならエラー println(hoge!.fuga!.foo!.name) そのため、nilかどうかをチェッ…

Swiftのややこしいイニシャライザを整理する

まず、Swiftのイニシャライザに関するキーワードを整理します。 指定イニシャライザ(designated initializer) 簡易イニシャライザ(convenience initializer) 必須イニシャライザ(required initializer) 失敗のあるイニシャライザ(failable initialize…