Swift Playgroundsで学ぶiOSプログラミング

QRコードを生成するプログラム

文●柴田文彦 編集●吉田ヒロ

2017年11月29日 17時00分

入力した文字列から2次元バーコードを生成して表示するアプリを作る

 すでにここまでで、Core Imageフィルターを使って2次元バーコードを生成できることが確かめられたので、今回の主目的はほとんど達成されたも同然です。しかし、それだけでは、プログラムを編集しないと任意の文字列を2次元バーコード化することができず、実用上不便です。そこで、ユーザーが入力した文字列を2次元バーコードとして表示するアプリ風のプログラムを作ってみましょう。

 ユーザーインターフェースとしては、任意の文字列を入力するテキストフィールド(UITextField)と、結果の2次元バーコードを表示するイメージビュー(UIImageView)を用意します。

 プログラム本体として、QRCodeViewControllerというビューコントローラーを作り、それをテキストフィールドのデリゲート(UITextFieldDelegate)にします。それによって、ユーザーがテキストフィールドへの入力を完了したら(iPadのキーボードを閉じたら)、その時点でCore Imageフィルターを使って、入力された文字列を2次元バーコードに変換して表示する、という流れを実現します。

 このプログラムの前半のviewDidLoadメソッドの中では、ビューコントローラーのビューの背景色を明るいグレーに設定し、テキストフィールドに必要な設定を加え、イメージビューとともに、そのサブビューとして張り付けています。

ユーザーが入力した文字列を2次元バーコードに変換して表示するアプリ風プログラムの前半部分です。UI部品としては、テキストフィールドとイメージビューだけを配置します。2次元バーコードを生成するCore Imageフィルターもプロパティとして用意しています

 後半のviewWillLayoutSubviewsメソッドの中では、いつものように、UIパーツとして張り付けたサブビューのレイアウトを設定しています。

文字列を2次元バーコードに変換するプログラムの後半です。2つのUI部品のレイアウトと、テキストフィールドの入力が完了した際の処理を記述しています。その処理とは、入力された文字列から2次元バーコードを生成し、その画像をイメージビューに張り付けるだけです

 テキストフィールドの編集が完了すると呼ばれるtextFieldDidEndEditingメソッドの中では、入力された文字列をinputMessageのパラメータとして与え、さらにエラー訂正レベルを「H」に設定して2次元バーコードを生成しています。もちろん、その結果の画像はイメージビューのimageとして画面に表示します。2次元バーコードのエラー訂正レベルは、L、M、Q、Hの4段階で指定できます。Hは、エラーに対してもっとも強くなりますが、その分コード量は増えます。

 このプログラムを動かして、テキストフィールドに適当な文字列を入力し、キーボードを閉じると、その文字列を変化した結果の2次元バーコードが表示されます。

これで任意の文字列を、その場で2次元バーコードに変換することができるようになりました。ただし、表示された2次元バーコードが画像の解像度変換の結果か、少しボケているのが気になります

 これで基本的な動作には、何も問題がないのですが、気になることが2つあります。1つは、2次元バーコードの画像がボケたものになっていることです。もう1つは、別の文字列を入力しようとしてテキストフィールドをタップすると、再びキーボードが表示されますが、その結果2次元バーコード画像が移動して、テキストフィールドを覆い隠してしまうことです。

いったん2次元バーコードを表示したあとでも、再びテキストフィールドに文字列を入力して再変換させることができます。しかし、その際には以前に表示した2次元バーコードが移動してテキストフィールドを覆うので、非常に入力しにくくなってしまいます

 次に、これらの点を解消します。

そのままではぼやけてしまう2次元バーコードをシャープな画像として表示

 画面に表示した2次元バーコードががぼやけてしまうのは、iOSのイメージビューが画像を拡大する際に、自動的にジャギー(ギザギザ)を解消するフィルターがかかってしまうからです。これは、一般的な写真などには好都合なのですが、2次元バーコードのように白黒のバターンからなる画像には不向きです。

 これは、イメージビューのレイヤーの拡大フィルターとして、kCAFilterNearestを指定することで解決できます。コードとしてはviewDidLoadメソッドの中に1行、

codeView.layer.magnificationFilter = kCAFilterNearest

のように追加するだけです。

画像のボケを解消するため、イメージビューの画像拡大時のフィルターを変更します。といっても、viewDidLoadメソッドの中に1行加えているだけです

 もう1つの2次元バーコードがテキストフィールドを覆ってしまう問題は、2次元バーコードをビューの中央に配置しているために起こります。キーボードが表示されると、ビューの大きさが変更され、上下方向にぎゅっと圧縮された形になります。そのため、イメージビューとテキストフィールドが重なってしまうのです。

 これは、プレイグラウンドの構成上やむを得ないので、テキスト入力中には、イメージビューの表示を隠すことにしました。具体的には、ビューコントローラーにtextFieldDidBeginEditingというメソッドを付け加え、その中でイメージビューのimageをnilに設定します。

2次元バーコードとテキストフィールドが重なってしまう問題を解消するため、テキストフィールドの文字列を編集中は、2次元バーコードの画像が表示されないようにします。編集が始まると呼ばれるtextFieldDidBeginEditingメソッドを追加しています

 変更したプログラムを動かしてみると、こんどはシャープな2次元バーコードが表示されるはずです。

イメージビューのフィルターの変更により、シャープな2次元バーコードが表示されるようになりました。画面は示しませんが、この状態からテキストフィールドをタップして編集を始めると2次元バーコードが消えて入力しやすくなります

 いったん2次元バーコードを表示したあとでも、テキストフィールドをタップすると2次元バーコードの表示が消えるので、安心して入力するできるはずです。

次回の予定

 今回は、意外に簡単に使えるCore Imageのコードジェネレーターを使って、入力した任意の文字列を2次元バーコードに変換して表示するアプリを作ってみました。それだけでは一方通行なので、次回は2次元バーコードを読み取って内容の文字列を表示するプログラムを作ってみることにします。もちろんiPadの内蔵カメラを使いますが、これまでのようにイメージピッカーから使うのではありません。もっと低レベルでカメラを動かして、撮影しながらコードを認識できるようにするつもりです。

mobileASCII.jp TOPページへ

mobile ASCII

Access Rankingアクセスランキング