Haptic Feedbackを実装する

Haptic Feedbackとは ユーザーの何かしらのアクションに対して「ドゥッ」とiPhoneをバイブさせるアレ。 スタートトゥデイさんの記事の説明を拝借すると、 iPhone 6s 以降に搭載された Taptic Engineというハードウェアによる振動で、ユーザーのアクションに…

UICollectionView(UITableView)でpull to refreshを実装する

pull to refreshとは UICollectionViewやUITableViewを下に引っ張ってrefreshするあれ。 Twitterやinstagram等フィード型のアプリでよく使われている。 実装方法 iOS 10からUIScrollViewにrefreshControlというプロパティが使える。 @available(iOS 10.0, *)…

Elementが非OptionalのObservableでエラー時にnextを流す

解決したい課題 Elementが非OptionalのObservableでエラーを無視したい時がある。 Observableはエラーが流れてきたらcompleted状態になりもう二度とnextで値が流れてくることがなくなってしまうため、大抵無視したい時はcatchError(_:)やcatchErrorJustRetur…

AVPlayerの再生ステータス(playing/pause/end)を取得する

play or pause 再生中かどうかの判定にはAVPlayer.rateとAVPlayer.errorを使う。 var isPlaying: Bool { return player.rate != 0 && player.error == nil } end 再生が終わったかどうかの判定には、NotificationCenterにAVPlayerItemDidPlayToEndTimeのobse…

radiusが入った三角形のCGPathを作る

rect(四角形)であればUIBezierPathを使えば簡単に生成できる。 三角形の場合はCGMutablePathを使って生成する(三角形でなく他の多角形でも可能)。 下は右向きの三角形のpathを作る例。 // 各頂点を定義 let top = CGPoint(x: 22, y: 18) let right = CGP…

CAShapeLayer.pathに複数のUIBezierPathを指定する

UIBezierPathのappend(_:)を使う。 let leftRect = CGRect(origin: leftOrigin, size: size) let originalPath = UIBezierPath(roundedRect: leftRect, cornerRadius: 1) let rightRect = leftRect.offsetBy(dx: 12, dy: 0) let rightPath = UIBezierPath(ro…

UISliderのカスタマイズ

thumb(丸いやつ)はsetThumbImage(_:for)、thumbより左のプログレスはsetMinimumTrackImage(_:for)、thumbより右のプログレスはsetMaximumTrackImage(_:for)でそれぞれカスタマイズできる。 let thumbImage = UIColor.white.circleImage(width: 16, height:…

UIColorからUIImageに変換する

個人的には以下のようなメソッドをUIColorのextensionとして宣言している。 extension UIColor { /// 四角 func rectImage(width: CGFloat, height: CGFloat) -> UIImage { let rect = CGRect(x: 0, y: 0, width: width, height: height) UIGraphicsBeginIma…

observeValue(forKeyPath:of:change:context:)を使わないKVO

KVOでお馴染みのobserveValue(forKeyPath:of:change:context:)がSwift 3.2以降からdeprecatedになるらしい。 上記をoverrideして定義すると、 Block Based KVO Violation: Prefer the new block based KVO API with keypaths when using Swift 3.2 or later.…

HLSのm3u8ファイルからスナップショットを取得する

iOSでAVPlayer/HLSでストリーミング再生をしているときに、再生時間ごとのスナップショットを取りたいということがあった。 一番例としてピンとくるのは、動画のseek中のスナップショットでしょうか。 色々試行錯誤した結果以下で取得できた。 let asset = A…

Swiftで処理を遅延実行

何か処理を遅延実行させたい時はDispatchQueueのasyncAfter(deadline:execute:)を使う。 DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: { // 3秒後に実行 }) 実行内容にアニメーションが付随する場合はUIView.animte(animateWithDuration:d…

SKStoreReviewControllerを実装する

import StoreKit SKStoreReviewController.requestReview() 以上。超簡単。 SKStoreReviewControllerはiOS 10.3以上のみ対応なので、10.3未満の対応は別途必要。 実装するメリットは、ユーザーがApp Storeに行かなくてもアプリ内でレビューできる点。 ユーザ…

selectedBackgroundViewを使ってUICollectionViewCellの選択時の色を変える

UICollectionViewCellの場合はselectedBackgroundViewはcontentViewの背後にあるので、contentView.backgroundColorを指定した状態でselectedBackgroundViewを設定しても変化が見えない。 class AnyCell: UICollectionViewCell { override func awakeFromNib…

UICollectionViewでセル数が少ないときにスクロールできない

全コンテンツ(セル)が画面に収まる程度の場合、UICollectionViewはスクロールができなくなる。 スクロール方向が縦の場合はalwaysBounceVertical、横の場合はalwaysBounceHorizontalをtrueにすることでスクロールできるようになる。 collectionView.always…

ModalのWebViewでFileReaderを使うとViewControllerごとdismissされる

iOS

FileReaderとは developer.mozilla.org Webページ内でハードウェアのファイルにアクセスするやつ。 iOSの場合これ。 ViewControllerごとdismissされる これをModalで開いたViewController内WebViewで使うと、アクション選択時やキャンセル時にViewController…

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がリリースされ、既存のアプリを…

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…

EMBEDDED CONTENT CONTAINS SWIFT CODEの正体を暴く

要点 CocoaPodsでの警告 Build Settingsの値が最終的に採用される EMBEDDED CONTENT CONTAINS SWIFT CODEってなに? 重複コピーはされないのか CocoaPodsはなぜEMBEDDED CONTENT CONTAINS SWIFT CODEをYESに設定するのか 要点 EMBEDDED CONTENT CONTAINS SWI…

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

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

forEachを使ってSwiftっぽく書く

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

CGImageからUIImageへの変換時に画像の向きが変わってしまう

iOS

要点 UIImage(CGImage:)ではなく、UIImage(CGImage:, scale:, orientation:)を使う。 // Preferred let uiImage = UIImage(CGImage: cgImage, scale: originalImage.scale, orientation: originalImage.imageOrientation) // Not preferred let uiImage = UI…

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のクラスを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…