本日、久しぶりにMZRPresentationKitという名前のライブラリをCocoapodsに投稿しました〜!
MZRPresentationKitとは?
iOSのアプリをプレゼンテーションする際に、指でタップしたところが表示されるとわかりやすい。これを実現する方法はいろいろありそうだけれど、プロジェクトから直接On/Offを管理できたら良いなぁと思ってできたのが、MZRPresentationKitです。
特徴としては、
MZRPresentationView.start()
の1行で利用できる- 複数のタッチをサポートしている
- 複数のUIWindowをサポートしている(UIWindowを変更してもタップが表示される)
- タップ部分の色や画像を変更できる
という感じです。
使い方
最新は、MZRPresentationKitのREADMEを見て下さい。1/26時点の利用方法は下記のとおりです。
Swiftのライブラリが利用できるように、Cocoapodsのバージョン0.36 betaをインストールする
$ gem install cocoapods —pre
Podfileに下記のように書き込む。
source ’https://github.com/CocoaPods/Specs.git’ platform :ios, ‘8.0’
pod “MZRPresentationKit”, ’~>1.0.0’
Pod install!
$ pod install
installが成功したら、新たに生成された、プロジェクトのワークスペースを開き、AppDelegateのapplication(application:didFinishLaunchingWithOptions:)
のところに下記の一文を書き込みます。あと、import MZRPresentationKit
をしておいて下さい。
MZRPresentationView.start()
タップ部分の色や、イメージを変更したい場合は下記のようにしてスタートします。
MZRPresentationView.start(UIColor.redColor(), image: UIImage(named: “YOUR-IMAGE”))
実行中に止めたい時のためにストップメソッドも用意しています。
MZRPresentationView.stop()
どうしてつくろうと思ったか
まず、「MZRPresentationKitとは?」のところで説明したように、簡単なライブラリがあれば良いなと思ったところがあります。それから、SwiftでCocoapodsのライブラリを作っておきたいなと思ったのがあります。
難しかった所
Objective-Cでできたことが Swiftでできない
タップ部分の検知はUIWindowのsendEvent:
メソッドを利用しています。実はこれ、UIWindowをサブクラスしていじれば簡単なのですが、そうすると、ライブラリを利用するために、設定が面倒になります。そこで、UIWindowのサブクラスを作らないでMethod Swizzlingをして、メソッドを書き換えようと考えました。この部分に関しては、Objective-Cと同じようにやることが出来ました。ただ、動的にプロパティを追加する部分はどうやらSwiftのみではできないようでした。StackOverflowなどを見ると、Objective-Cのファイルを作成し、それをSwift側で利用することでこれを実現する方法がありましたが、今回、簡単に使えるライブラリを目指していたので、ユーザーのbridgeファイルには触りたくありませんでした。やりたいことは、Method Swizzlingが行われたか否かをBoolで知りたいだけだったので、UIWindowのdescription()
メソッドをMethod Swizzlingして、ちょっと工夫してそれと同様のことを表現しました。(MZRPresentationKit/MZRPresentationView.swift at master · morizotter/MZRPresentationKit)
iOS7でCocoapodsで利用するとビルドできない
iOS7も対象に入れて作成を考えていたのですが、どうしてもiOS7を入れるとビルドに失敗します。
embedded dylibs/frameworks are only supported on iOS 8.0 and later
こんなエラーが出ます。いろいろ調べたのですが、Alamofire/Alamofire もiOS7以前でビルドする際は手動でやってねと書いてあったので、これは解消していないですがまぁ良とします。
Alamofireと同様に直接ファイルを自分のプロジェクトに入れてビルドすると問題無いと思います。
解決したい問題
そもそもシングルトンのやつはViewでなくても良いのだ
MZRPresentationViewを最前面のUIWindow(keyWindow)にaddしてその上に、タップ領域を示すビュー(タップビュー)を都度生成していました。ただ、keyWindowの変更を検知して、それに合わせてタップビューをkeyWindowにaddすることができれば十分なので、MZRPresentationViewというよりは、MZRPresentationControllerとかManagerとかそういう感じの純粋Swiftクラスでも良かったかなと思いました。シングルトンにしているのは、appilicationのkeyWindowの変更を検知するためです。
UIAlertControllerでタップ部分が最前面に来ない
これは、開発の途中から発生するようになりました。
keyWindowの変更検知がちょっと雑
もう少ししっかり検知処理書かないとな。
ファイルと機能の分割
記述量も少ないので1ファイルで全て書いてしまったが、メンテナンスと可読性を考えると分けたほうが良さげ。そして、機能もUIWindow側にもう少しやらせても良いかも。MZRPresentationViewの立ち位置が曖昧になってる。
xcassetsをpodに追加したいけどできなかった
これは解決していない問題?bundleに入れたけど、Apple式の圧縮 - .car - されてだめだった><
参考資料
iOS - 自分で作ったSwiftライブラリをCocoapodsにする手順メモ - Qiita
全体的な流れはこちらの資料を参考にさせていただきました。わかりやすかった。あと、Cocoapodsに登録するのが本当に簡単になっていてよかった!ただ、現在は、この解説通りに実行するとエラーが出ます。swiftのブランチがなくなったようなのですそこで次の資料を見ました。
CocoaPods の Swift ライブラリを使えるようにする。
ちょっと全体的に散らかっている感じの印象はあるのですが、エラーとその解決法を書いてあったので、ありがたいです。現在、CocoapodsはSwift移行期なのでSwiftを利用しようとするとまだちょっと試行錯誤が必要そうです。
是非、使ってみてください
まだまだ機能は少ないですし、未知のバグもあると思いますがが、是非使ってみたください〜。