iOS実験専用アプリを作って活用する話の続きです。この話のキモとなる、ボタンの使い方を紹介します。正確には、ボタンに機能を加えて、テストする方法の紹介ですね。今回のソースコードも、前回と同様にViewControllerクラスに入れます。
40個も作ったボタンには、それぞれに2つの関数を用意します。何の実験機能も付けていない、空の状態で用意する関数です。最初の2つ分だけを切り出したswiftコードは、次のようになります。
// ====================================== ボタン0
func startBtn0F() {
aryButton[0].setTitle("B0", forState: .Normal)
}
func testBtn0F(rSender: UIButton) {
setMsgF(1, "タップ0")
}
// ====================================== ボタン1
func startBtn1F() {
aryButton[1].setTitle("B1", forState: .Normal)
}
func testBtn1F(rSender: UIButton) {
setMsgF(1, "タップ1")
}
それぞれ2つの関数には、ボタン番号(0〜39)が含まれていて、番号で区別されます。名前がstartで始まる関数は、アプリが起動したときに呼ばれるもので、開始前の準備処理を記述します。残りの、名前がtestで始まる関数は、ボタンをタップしたときの処理を記述します。こちらの関数は、前回、ボタンを生成した処理の最後のほうで、各ボタンに割り当てられています。
コメント行が右に長く伸びているのは、実験のソースコードを追加したときでも、ボタンの区切りが明確に見えるようにと考えてのことです。ソースコードを短く切り分ける工夫はしていないので、どうしても長くなります。でも、こうして区切りを明確にしておくと、ぜんぜん使いづらくはなりません。
準備処理の関数は、アプリを起動したときに実行しなければなりません。また、前回紹介したボタンやラベルの生成関数も、アプリの起動時に実行しなければなりません。viewDidLoadをオーバーライドする箇所へ入れて、アプリ起動時に実行させます。具体的なswiftコードは次のとおりです。
//
override func viewDidLoad() {
super.viewDidLoad()
zDate = DateController() // 日付機能の開始
zFiles = BaseFiles() // ファイル管理機能を開始
startBasic1() // 基本部品1の生成
startBasic2() // 基本部品2の生成
startTestF() // テスト用ボタンの生成
// ボタンの前処理(startBtnXXF関数)を順番に実行
for i in 0...39 {
let iFuncName = "startBtn" + String(i) + "F"
let iName = "n" + String(i)
NSNotificationCenter.defaultCenter().addObserver(self, selector:Selector(iFuncName), name:iName, object:nil)
let iNotif = NSNotification(name:iName, object:self)
NSNotificationCenter.defaultCenter().postNotification(iNotif)
NSNotificationCenter.defaultCenter().removeObserver(self)
}
}
一番最初に、日付管理やファイル管理といった独自ライブラリーのインスタンスを生成させています。この実験専用アプリにも、いつもの独自ライブラリーを使っているというわけです。
続いて、前回紹介した3つの生成関数を順番に実行します。これが実行し終わった段階で、ラベルやボタンが表示できる状態となります。40個のボタンそれぞれにも、今回紹介した2番目の関数(名前がtestで始まる関数)がリンクされています。
最後に、今回紹介した最初の関数(名前がstartで始まる関数)を、順番に実行しなければなりません。startBtn0F()からstartBtn39f()まで40個すべてを書いても構わないのですが、40行もあると格好が悪いでしょう。また、あまりにも芸がなさ過ぎです。というわけで、別な方法で実行させました。40個の関数名の文字列をfor文で順番に生成し、その文字列を渡して実行してもらう方法です。NSNotificationを使います。関数名の文字列ごとに、名前をつけて登録した後で実行させ、登録を削除するという手順です。もっと簡単な方法があればいいのですが、私が調べた限りでは、この方法しか見付かりませんでした。
以上で、実験専用アプリが出来上がりました。あとは、上手に活用するだけです。
では、実際に実験内容を追加してみましょう。最初は簡単な内容ほど理解しやすいと思いますので、ラベルに現在時間を表示する実験を選びます。実験するほどの内容ではないですが、ボタンの使い方を知るには適しています。最初のボタンとなる、ゼロ番のボタンに追加しましょう。
起動時の処理も使いたいので、起動時に現在時刻をラベル5に表示する機能を作ります。startBtn0F関数に1行を追加するだけです。さらには、何の実験をしているのか、画面から見えなければなりません。そのため、ボタンの名前(タイトル)も書き換えます。
続いて、タップしたときの機能も追加します。こちらもラベル5に、現在の時刻を表示しましょう。起動時に表示した時刻を、タップして上書きする動きとなります。以上を実現するswiftコードは、次のようになります。
// ボタン0に、実験機能(現在時刻を表示)を追加
func startBtn0F() {
aryButton[0].setTitle("現在時刻", forState: .Normal)
setMsgF(5, zDate.getStrTimeF())
}
func testBtn0F(rSender: UIButton) {
setMsgF(1, "タップ0")
setMsgF(5, zDate.getStrTimeF())
}
書き換えたのは3カ所です。startBtn0F関数では、文字列「B0」を「現在時刻」に書き換え、時刻を表示するための1行を追加しました。もう1つのtestBtn0F関数でも、時刻を表示するための1行をしてます。とても簡単ですね。
これを実行すると、ボタン0の表示が「現在時刻」に変わり、何かの実験機能が割り当てられていると知ることができます。そのボタンをタップすれば、ラベル5の現在時刻が更新できます。これで実験は成功に終わりました。
実験のために追加したコードのほかに、ラベル1へメッセージを表示する機能が、最初から付いていました。しかも、表示するメッセージの前に、実行時の時刻(時分秒)を加えて表示するようになっています。表示するメッセージは「タップ0」で、タップした操作であること、タップされたボタンの番号がゼロであることを示しています。
実際にタップすると、現在の時刻と一緒に「タップ0」が表示されます。タップする度に時刻が更新され、同じく「タップ0」が表示されます。タップされたことと、その時刻が毎回表示されているのです。
何のために、こんな機能があるのでしょうか。正常に動いてないとき、念のための確認ができる機能なのです。追加した機能を実験したとき、実験用のビュー上に何の変化もなかったとします。タップが正常に受け付けられていれば、その時刻と「タップ0」が表示されいているはずです。再びタップすれば、時刻の表示が更新されるでしょう。この動きから、基本的な機能は動いていると確認できます。逆に、再びタップしたときに時刻が更新されなければ、基本的な動作が停止していると判断できます。
新しい機能を実験するわけですから、最初は何か問題が発生するでしょう。そのとき、基本的な動作が動いているかどうか確認できれば、探す範囲を少しは絞り込めます。調べるために余計な機能の追加をせず、最低限の確認ができるようにと用意した機能なのです。実験専用アプリならではの工夫といえます。
最大40個もの実験を付けられますから、早々にラベルの数が足りなくなるでしょう。ラベルの数をどんどん増やす手もありますが、使える画面の面積は限られていますし、賢い方法とも思えません。実験が終わったボタンは、その機能をオフするほうが賢い選択でしょう。
追加した行をコメントにしてしまえば、簡単にオフできます。ただし、ボタン名の変更はオフすることが難しいですね。また、最初の「B0」に戻してしまうと、このボタンに機能が割り当てられていることが伝えられません。そこで、機能を表すボタン名を残しながら、オフしていることも伝えられるボタン名に変更します。たとえば、「現在時刻」から「x現在時刻」に変更するとか。ボタン名の先頭に「x」が付いているものは機能がオフ状態だと、自分なりにルールを決めてしまうのです。
このようにして機能をオフした状態は、次のようなソースコードになります。
// ボタン0に追加した実験機能をオフ状態にする
func startBtn0F() {
aryButton[0].setTitle("x現在時刻", forState: .Normal)
//setMsgF(5, zDate.getStrTimeF())
}
func testBtn0F(rSender: UIButton) {
setMsgF(1, "タップ0")
//setMsgF(5, zDate.getStrTimeF())
}
実験機能はオフされたので、この状態でボタンをタップすると、ラベル1に時刻付きの「タップ0」が表示されます。当然のことですが、ソースコードを修正して、コメントでない状態に戻せば、いつでも同じ実験を繰り返せます。
1つの機能を実験するのに、複数のボタンを使う場合もあります。そんなときは、隣り合ったボタンを利用します。大事なのは、複数のボタンが関係していると、アプリを起動した状態で明確に示すことです。余計な手間をかけないで示す方法としては、ボタン名を利用するのが一番でしょう。小文字のアルファベット1文字を決め、両方のボタン名の最初に付ければ、関係性は明確に伝わります。
具体的な例を見るのが一番でしょう。まだ機能を追加してない状態ですが、swiftのコードは次のようになります。
// ボタン2つをペアで使う場合(ボタン名だけ変更し、機能を加える前の状態)
// ====================================== ボタン8
func startBtn8F() {
aryButton[8].setTitle("s画動_前", forState: .Normal)
}
func testBtn8F(rSender: UIButton) {
setMsgF(1, "タップ8")
}
// ==================== ボタン9
func startBtn9F() {
aryButton[9].setTitle("s画動_次", forState: .Normal)
}
func testBtn9F(rSender: UIButton) {
setMsgF(1, "タップ9")
}
// ====================================== ボタン10
見て分かるようにソースコード上では、ボタン名だけではなく、区切りコメントの長さでも関係性を示しています。後ろ側の区切りコメントの長さを半分程度に縮めて、2つのボタンがペアで使われていることを表します。この例では、ボタン9の区切り行が短いので、ボタン8とボタン9がペアで使われていると分かります。
ボタン名の先頭に付ける文字ですが、機能停止用として「x」を使っている場合は、それ以外の文字を選ぶことになります。隣り合っていることが条件なので、離れているボタンであれば、同じ文字を2カ所以上で使っても構いません。ボタン8とボタン9のペアで先頭に「s」を付け、これらから離れたボタン21とボタン22のペアでも先頭に「s」を付けるといった具合に。
機能をオフするときの変更は、単独で使っているボタンと同じです。先頭に「x」を付けるルールなら、上記のボタンを「xs画動_前」と「xs画動_次」に変更することになります。このように停止した状態でも、2つのボタンがペアで使われていることが表現できます。
予想外に長くなってしまいました。さらなる続きは次の投稿にて。
(使用開発ツール:Xcode 6.0.1, SDK iOS 8.0)
0 件のコメント:
コメントを投稿