2012年10月アーカイブ
※当blogの英語学習に関する記事の一覧はこちらです(随時更新しています)。
できれば今月中、遅くとも来月中には約二年振りに英語学習を再開する予定です。
わざわざblogで報告しなくとも勝手に始めればいいと言われればその通りなのですが、2008年に英語の勉強を始めるときにblogで宣言したので、それに倣って今回も。
ちなみに、英語学習開始を宣言したのが四年前の今日でした。
あと、英語学習系の情報目当てでこのblogを訪れている方がありがたいことにたくさんいるので、その方々向けの宣言でもあります。
前回の勉強期間同様、今回もできるだけ情報を共有していこうと考えていますので、たまにblogを覗いていただけると幸いです。
どんな感じで学習を進めるかはこれから考えます!!
楽しく勉強していこうっと。
タイトルの通りです。
興味を持ちましたのでKnockout.jsを使ってみました。
興味を持ちましたのでKnockout.jsを使ってみました。
要はMVVMフレームワーク(MVVMについてはWikipediaをご参照)。
端的に言ってしまうとインタラクティブな仕組みをJavaScriptで実現するためのライブラリです。
端的に言ってしまうとインタラクティブな仕組みをJavaScriptで実現するためのライブラリです。
どこかで値が変わったときにそれを他の箇所でも自動で反映するということが容易にできます。
使ってみましたが、本当に便利です。
jQueryと一緒でなくてはならない存在になりそう。
jQueryと一緒でなくてはならない存在になりそう。
ということでKnockout.jsの使い方の第一歩を紹介!
動作環境とか
- 対応ブラウザ:
IE 6以降, Firefox 2以降, Chrome, Opera, Safari
主要ブラウザは網羅しています。 - 使うために必要なライブラリ:
他のライブラリ(jQuery等)との依存関係はありません。単体で使用可能です。 - 配布:
MIT licenseにて配布されています。
公式サイト以外に以下の二箇所でも配布されています(現在の最新バージョン2.1.0のURLです)。
Microsoft Ajax CDN: http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.1.0.js
cdnjs: http://cdnjs.cloudflare.com/ajax/libs/knockout/2.1.0/knockout-min.js
チュートリアルの紹介
これからKnockout.jsがどんなものか、サンプルコードを元にしてさわりだけですが紹介していこうと思います。
内容としては、公式ページのチュートリアルのIntroductionを少しいじったぐらいの感じです。
かなりよくできたチュートリアルなので、英語に抵抗がなければぜひどうぞ。
以下、公式ページチュートリアル各章へのリンクです。
以下、公式ページチュートリアル各章へのリンクです。
- Introduction
- Working with Lists and Collections
- Single page applications
- Creating custom bindings
- Loading and saving data
準備
まず、HTMLのhead内にてknockout.jsを読み込みます。
(サンプルファイルではMicrosoft Ajax CDNで読み込んでいますが、以下の記述はダウンロードしてjsフォルダに入れたと仮定)
(サンプルファイルではMicrosoft Ajax CDNで読み込んでいますが、以下の記述はダウンロードしてjsフォルダに入れたと仮定)
<script type='text/javascript' src='js/knockout-2.1.0.js'></script>
私は一緒にjQueryも読み込んでおきました。
現時点ではファイル読み込み完了の検知のためぐらいにしか使っていないですが。
現時点ではファイル読み込み完了の検知のためぐらいにしか使っていないですが。
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
また、自分でJavaScriptのコードを書くファイルも準備。
私はdatabind.jsとしてjsフォルダに入れました。
私はdatabind.jsとしてjsフォルダに入れました。
<script type='text/javascript' src='js/databind.js'></script>
お試しその1
画面にsample textと表示されています。
この文字はHTMLではなく、JavaScriptにて記述しています。
以下、実際のコードです。まずはHTML側。
<span data-bind="text:sample"></span>
data-bindという属性がKnockout.jsを使っていく上での鍵となります。
ちなみに、データバインド(あるいはデータバインディング)とはデータ結合を意味します。
ちなみに、データバインド(あるいはデータバインディング)とはデータ結合を意味します。
今回の場合、このspanはtext形式のsampleという名前、であることを記述しています。
続きましてJavaScript側です。
$(function() {
function TestViewModel(){
this.sample = "sample text";
}
ko.applyBindings(new TestViewModel());
});
function TestViewModel(){
this.sample = "sample text";
}
ko.applyBindings(new TestViewModel());
});
まず、TestViewModelと名付けられたファンクションが、実際の処理を行う部分です。
this.sample = "sample text";の行で、sampleに"sample text"という文字列を代入しています。
sampleというのはHTML側でspanに指定した名前です。
ko.applyBindings(new TestViewModel());はデータバインドの適用を意味します。
要は上で指定したファンクションlが機能するための定義部みたいなもの。
要は上で指定したファンクションlが機能するための定義部みたいなもの。
ko.applyBindingsというコマンドは今後常に出てきます。
これだけだとなにがすごいのかわからないですよね。
なんか回りくどいコードを書いて一行表示しただけ。
なんか回りくどいコードを書いて一行表示しただけ。
ということで、次のお試しその2を見てください。
お試しその2
入力欄にNakanoと書かれていて、その下にはHello , dear Nakanoと書かれています。
入力欄の内容を変更しますと、それに合わせて自動で下の文章も変わることがわかります。
たとえば、入力欄をAkiyamaとすると、その下にはHello , dear Akiyamaと表示されます。
コードを見てみましょう。
まずはHTML側。
まずはHTML側。
<input data-bind="value:sample"><br>
<span data-bind="text:sample_add"></span>
<span data-bind="text:sample_add"></span>
inputにはvalue形式でsampleという名前が、spanにはtext形式でsample_addという名前を指定しています。
続きましてJavaScript側です。
$(function() {
function TestViewModel(){
this.sample = ko.observable("Nakano");
this.sample_add = ko.computed(function() {
return "Hello , dear " + this.sample();
}, this);
}
ko.applyBindings(new TestViewModel());
});
function TestViewModel(){
this.sample = ko.observable("Nakano");
this.sample_add = ko.computed(function() {
return "Hello , dear " + this.sample();
}, this);
}
ko.applyBindings(new TestViewModel());
});
お試しその1と似ていますが、違う点が二つあります。
まず一つ目が、sampleがobservable指定されていること。
これは、sampleを監視対象にすることを意味します。
つまり、sampleの値が変わったことをJavaScript側で検知できます。
つまり、sampleの値が変わったことをJavaScript側で検知できます。
次に二つ目としまして、sample_addにcomputed時の動作が記述されています。
computed時にHello , dear と、sampleにて指定した値が表示されるようになっています。
computedは、observableで指定した値の変化を検知し、処理を実行するという関数です。
つまり、sampleの値が変化するとこの関数が呼び出され、sample_addの表示内容が変わります。
たかだか数行のコードでインタラクティブな仕組みを可能とするのがKnockout.jsのすごいところです。
お試しその3
お試しその2に消去というボタンをつけたものです。
このボタンを押すと、入力欄もその下の出力欄も、値が消えます。
まずはHTMLのコードです。
<input data-bind="value:sample"></br>
<span data-bind="text:sample_add"></span></br>
<button data-bind="click:clearButton">消去</button>
<span data-bind="text:sample_add"></span></br>
<button data-bind="click:clearButton">消去</button>
新たにbuttonが追記されています。
data-bindeはclick:clearButtonです。
data-bindeはclick:clearButtonです。
これはclickした際にclearButtonを呼び出すことを意味します。
続きましてJavaScript側のコードです。
$(function() {
function TestViewModel(){
this.sample = ko.observable("Nakano");
this.sample_add = ko.computed(function() {
return "Hello , dear " + this.sample();
}, this);
this.clearButton = function() {
this.sample("");
};
}
ko.applyBindings(new TestViewModel());
});
function TestViewModel(){
this.sample = ko.observable("Nakano");
this.sample_add = ko.computed(function() {
return "Hello , dear " + this.sample();
}, this);
this.clearButton = function() {
this.sample("");
};
}
ko.applyBindings(new TestViewModel());
});
this.clearButtonにて、this.sampleを空にしています。
this.sample_addはthis.sampleを監視しているため、新たになにも記述しなくても勝手に内容が変わってくれます。
トリガはclickの他にも以下のようなものが用意されています。
最後に
今回はKnockout.jsがどんなものなのか、とりあえずさわりだけ紹介してみました。
便利さの片鱗は伝わったのではないかなと。
機会があれば続編記事も書く予定です!
なんだこれ!!「NHKスタジオパーク」のレスポンシブ・ウェブデザインが凄まじくレスポンシブ!!という記事で話題になっていますjQuery Masonry。
jQuery Masonryはfloatブロック配置用のjQueryプラグインです。
ブラウザの幅によって配置した要素がアニメーション付きで綺麗に並び変わります。
ブラウザの幅によって配置した要素がアニメーション付きで綺麗に並び変わります。
これを活用すればレスポンシブなWebサイトが制作しやすくなるかも?
ということで早速使ってみましたので、以下、そのまとめです!
※レスポンシブデザイン(レスポンシブWebデザイン)とは、単一のHTMLで様々なディスプレイサイズの各端末で最適化表示をする手法です。
はじめに
jQuery MasonryはMIT licenseにて配布されています。
現在のバージョンは2.1.05です。
お試しその1
アニメーション抜きでとりあえず配置してみました。
スクリーンショット
HTML
長いですが、JavaScriptファイル、CSSファイルの読み込みと適当なdivの配置のみです。
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>jQuery Masonry Sample 1</title>
<link rel="stylesheet" href="css/sample.css" type="text/css" media="all">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type='text/javascript' src='js/jquery.masonry.min.js'></script>
<script type='text/javascript' src='js/sample.js'></script>
</head>
<body>
<div id="container">
<div class="item">
あああああああああああああああああああああああああああああああああああああああああああああああ
</div>
<div class="item">
いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい
</div>
<div class="item">
うううううううううううううううううううううううううううううううううううううううううううううううううううううううううううううう
</div>
<div class="item">
ええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええ
</div>
<div class="item">
おおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおお
</div>
<div class="item">
かかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかか
</div>
<div class="item">
きききききききききききききききききききききききききききききききききききききききききききききききききききき
</div>
<div class="item">
くくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくく
</div>
<div class="item">
けけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけ
</div>
<div class="item">
こここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここ
</div>
</div>
<!-- container -->
</body>
</html>
<head>
<meta charset="utf-8">
<title>jQuery Masonry Sample 1</title>
<link rel="stylesheet" href="css/sample.css" type="text/css" media="all">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type='text/javascript' src='js/jquery.masonry.min.js'></script>
<script type='text/javascript' src='js/sample.js'></script>
</head>
<body>
<div id="container">
<div class="item">
あああああああああああああああああああああああああああああああああああああああああああああああ
</div>
<div class="item">
いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい
</div>
<div class="item">
うううううううううううううううううううううううううううううううううううううううううううううううううううううううううううううう
</div>
<div class="item">
ええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええ
</div>
<div class="item">
おおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおお
</div>
<div class="item">
かかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかか
</div>
<div class="item">
きききききききききききききききききききききききききききききききききききききききききききききききききききき
</div>
<div class="item">
くくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくく
</div>
<div class="item">
けけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけ
</div>
<div class="item">
こここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここ
</div>
</div>
<!-- container -->
</body>
</html>
CSS
floatの指定を忘れずにしてください。
.item{
width:200px;
margin:10px;
float:left;
background-color:#ccffcc;
color:#333333;
}
width:200px;
margin:10px;
float:left;
background-color:#ccffcc;
color:#333333;
}
JavaScript
$(function() {
$('#container').masonry({
itemSelector : '.item',
columnWidth : 220
});
});
$('#container').masonry({
itemSelector : '.item',
columnWidth : 220
});
});
オプション項目については後述しますが、columnWidthは列幅です。
この数値によって配置を計算しています。
この数値によって配置を計算しています。
たとえばcolumnWidthが240pxでその中のdivのwidthが100pxだったりすると、不自然な余白が140pxできてしまいます。
画像ロード完了した後でMasonryを動作させたい場合は、imageLoadedというメソッドを指定します。
以下、その際のサンプルコードです。
var $container = $('#container');
$container.imagesLoaded(function(){
$container.masonry({
itemSelector : '.item',
columnWidth : 240
});
});
$container.imagesLoaded(function(){
$container.masonry({
itemSelector : '.item',
columnWidth : 240
});
});
お試しその2
上と同じものにアニメーションを指定してみました。
ブラウザの横幅を変えるとアニメーションと共に配置が変更されます。
ブラウザの横幅を変えるとアニメーションと共に配置が変更されます。
HTML
変更なし
CSS
変更なし
JavaScript
isAnimatedにてtrueを、animationOptionsにてdurationとして600を指定しています。
前者はアニメーション可否、後者はアニメーションの時間(m秒)を意味します。
前者はアニメーション可否、後者はアニメーションの時間(m秒)を意味します。
オプションについては本記事の最後に一覧をつけています。
$(function() {
$('#container').masonry({
itemSelector : '.item',
columnWidth : 220,
isAnimated : true,
animationOptions: {
duration: 600
}
});
});
$('#container').masonry({
itemSelector : '.item',
columnWidth : 220,
isAnimated : true,
animationOptions: {
duration: 600
}
});
});
お試しその3
スクリーンショット
HTML(body要素のみ抜粋)
長いですが、同じようなdivを繰り返し書いているだけです。
<div id="container">
<div class="item small">
あああああああああああああああああああああああああああああああああああああああああああああああ
</div>
<div class="item big">
いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい
</div>
<div class="item small">
うううううううううううううううううううううううううううううううううううううううううううううううううううううううううううううう
</div>
<div class="item big">
ええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええ
</div>
<div class="item small">
おおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおお
</div>
<div class="item small">
かかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかか
</div>
<div class="item">
きききききききききききききききききききききききききききききききききききききききききききききききききききき
</div>
<div class="item">
くくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくく
</div>
<div class="item small">
けけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけ
</div>
<div class="item">
こここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここ
</div>
<div class="item small">
ささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささ
</div>
<div class="item">
ししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししし
</div>
<div class="item small">
すすすすすすすすすすすすすすすすすすすすすすすすすすすすすす
</div>
<div class="item">
せせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせ
</div>
</div>
<div class="item small">
あああああああああああああああああああああああああああああああああああああああああああああああ
</div>
<div class="item big">
いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい
</div>
<div class="item small">
うううううううううううううううううううううううううううううううううううううううううううううううううううううううううううううう
</div>
<div class="item big">
ええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええ
</div>
<div class="item small">
おおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおお
</div>
<div class="item small">
かかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかかか
</div>
<div class="item">
きききききききききききききききききききききききききききききききききききききききききききききききききききき
</div>
<div class="item">
くくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくくく
</div>
<div class="item small">
けけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけけ
</div>
<div class="item">
こここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここここ
</div>
<div class="item small">
ささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささささ
</div>
<div class="item">
ししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししししし
</div>
<div class="item small">
すすすすすすすすすすすすすすすすすすすすすすすすすすすすすす
</div>
<div class="item">
せせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせせ
</div>
</div>
CSS
.item{
width:420px;
margin:10px;
float:left;
background-color:#ccffcc;
color:#333333;
}
.small{
width:200px;
}
.big{
width:640px;
}
width:420px;
margin:10px;
float:left;
background-color:#ccffcc;
color:#333333;
}
.small{
width:200px;
}
.big{
width:640px;
}
JavaScript
変更なし
お試しその4
スクリーンショット
HTML(body要素のみ抜粋)
長いですが、同じようなdivを繰り返し書いているだけです。
<div id="container">
<div class="item big">
1
</div>
<div class="item small">
2
</div>
<div class="item small">
3
</div>
<div class="item">
4
</div>
<div class="item small">
5
</div>
<div class="item small">
6
</div>
<div class="item small">
7
</div>
<div class="item small">
8
</div>
<div class="item small">
9
</div>
<div class="item small">
10
</div>
<div class="item big">
11
</div>
<div class="item small">
12
</div>
<div class="item small">
13
</div>
<div class="item small">
14
</div>
<div class="item small">
15
</div>
</div>
<div class="item big">
1
</div>
<div class="item small">
2
</div>
<div class="item small">
3
</div>
<div class="item">
4
</div>
<div class="item small">
5
</div>
<div class="item small">
6
</div>
<div class="item small">
7
</div>
<div class="item small">
8
</div>
<div class="item small">
9
</div>
<div class="item small">
10
</div>
<div class="item big">
11
</div>
<div class="item small">
12
</div>
<div class="item small">
13
</div>
<div class="item small">
14
</div>
<div class="item small">
15
</div>
</div>
CSS
.item{
width:420px;
height:330px;
margin:10px;
float:left;
background-color:#ccffcc;
color:#333333;
}
.small{
width:200px;
height:330px;
}
.big{
width:420px;
height:450px;
}
width:420px;
height:330px;
margin:10px;
float:left;
background-color:#ccffcc;
color:#333333;
}
.small{
width:200px;
height:330px;
}
.big{
width:420px;
height:450px;
}
JavaScript
変更なし
お試しその5
HTML
変更なし
CSS
以下を追加しました。
#container{
margin:0 auto;
}
margin:0 auto;
}
JavaScript
オプションにisFitWidth : trueを追加しました。
$(function() {
$('#container').masonry({
itemSelector : '.item',
columnWidth : 220,
isAnimated : true,
isFitWidth : true,
animationOptions: {
duration: 600
}
});
});
$('#container').masonry({
itemSelector : '.item',
columnWidth : 220,
isAnimated : true,
isFitWidth : true,
animationOptions: {
duration: 600
}
});
});
オプション
以下のようなオプションが用意されています。
itemSelectorとcolumnWidthは推奨項目ですので設定しましょう。
- animationOptions
アニメーションオプション指定。 - columnWidth
一列の幅。 - containerStyle
containerがrelativeかabsoluteか。 - gutterWidth
列と列の間にさらにつける間隔値です。
デフォルトは0です。 - isAnimated
レイアウト変更時のアニメーション可否。
デフォルトはfalseです。 - isFitWidth
containerのサイズを列幅に合わせて変更するかどうか。
demoを見ると早いです。
デフォルトはfalseです。 - isResizable
ブラウザのウィンドウサイズが変わったときにリサイズするか。
デフォルトはtrueです。 - isRTL
右から左に視線を動かすようなレイアウト対応にするか。
これもdemoを見ると早いです。
デフォルトはfalseです。 - itemSelector
処理対象となる要素(#containerの中の.itemが並び変わるなら、.item)
メソッド
以下のようなメソッドが用意されています。
- appended
新たな要素を追加します。画面スクロールに合わせての要素追加にも対応。 - destroy
Masonryを削除し、元の状態に戻します。 - layout
レイアウトを特定要素に反映します。 - option
オプションをセットします。 - reload
リロード命令です。要素を挿入した際に使うと便利です(挿入はそれより後ろの要素も並べ替えとなるから、そのときに)。 - reloadItems
reloadと同じで再構成のようですが、私の方で違いをまだ試していません。 - remove
特定の要素を削除します。
アニメーション
animationについてさらに詳しくはこちらを参照。
CSS3について、CSS3対応していないブラウザについて等も書かれています。
CSS3について、CSS3対応していないブラウザについて等も書かれています。
最後に
今回の話題の元となりましたNHKスタジオパークのソースが実用的かつシンプルなんで見てみると面白いです!
興味がある方はjQuery Masonry、ぜひ試してみてくださいませ
レスポンシブデザインは使いどころが難しく、制作陣の自己満足みたいになってしまうこともあるでしょうから、そこはご注意を。
あまりにも今さら過ぎる内容ですが、自分用のメモ。
iPhone、iPadアプリ開発で使うXcode。
コード部分に以下を記述すると、それがファンクションメニューに反映されます。
コード部分に以下を記述すると、それがファンクションメニューに反映されます。
- #pragma mark
- #pragma mark -
- MARK:
- TODO:
- FIXME:
- !!!:
- ???:
詳しくは公式DocumentよりThe Text Editorをどうぞ。
ここから先は表示例と記述例です。
MARK:以下はただそのまま表示されるだけですが。
#pragma mark
#pragma mark first function
-(void)function1{}
#pragma mark second function
-(void)function2{}
-(void)function1{}
#pragma mark second function
-(void)function2{}
#pragma mark -
#pragma mark - first function
-(void)function1{}
#pragma mark - second function
-(void)function2{}
-(void)function1{}
#pragma mark - second function
-(void)function2{}
-が入ることでファンクションメニューに線(セパレーター)が引かれます。
ただセパレーターを入れたいなら#pragma mark -だけ書けば良し!
MARK:
// MARK: first function
-(void)function1{}
// MARK: second function
-(void)function2{}
-(void)function1{}
// MARK: second function
-(void)function2{}
MARK:って文字は表示されないと記憶していたのだけれど、試してみたら表示される。
なにか書き方がおかしいのかな?
それともXcodeの仕様が変わった?
なにか書き方がおかしいのかな?
それともXcodeの仕様が変わった?
TODO:
// TODO: write later
-(void)function1{}
// TODO: change name later
-(void)function2{}
-(void)function1{}
// TODO: change name later
-(void)function2{}
FIXME:
// FIXME: write later
-(void)function1{}
// FIXME: change name later
-(void)function2{}
-(void)function1{}
// FIXME: change name later
-(void)function2{}
!!!:
// !!!: important function!
-(void)function1{}
// !!!: very important function!
-(void)function2{}
-(void)function1{}
// !!!: very important function!
-(void)function2{}
???:
// ???: for what?
-(void)function1{}
// ???: necessary?
-(void)function2{}
-(void)function1{}
// ???: necessary?
-(void)function2{}
XcodeでのiOSアプリ(iPhoneアプリ/iPadアプリ)開発において、StoryBoard(Xcode4.2の新機能である、画面UIの簡単実装)で画面遷移させたいときの方法まとめです。
前半は画面遷移そのもの、後半は画面遷移時の値の受け渡しについて書いています。
可能な限りシンプルに余計なことは書かないようにというモットーでありながらも、デリゲートとかボタンアクションとかのiPhoneアプリ開発で必須となる知識も一緒におまとめのお得記事!
XCodeのバージョンは4.4.1でやっていますが、他のバージョンでもほとんど差異はないかと思います(現時点においては)。
画面遷移にせよ値の受け渡しにせよ、方法は幾通りもあります
本記事はその一例となりますことはご了承くださいませ。
本記事はその一例となりますことはご了承くださいませ。
下準備
まずはFile→New→Projectで新規プロジェクトを作ります。
構造がシンプルで説明しやすいし理解しやすいと思うので、Single View Applicationを選択。
Product NameはsegueSampleとしました。
DevicesはiPhoneで。他のデバイスでも手順は変わりません。
DevicesはiPhoneで。他のデバイスでも手順は変わりません。
Use Storyboardのチェックを入れるのを忘れずに。
Use Automatic Reference Countingはデフォルトのままチェックを入れておきました。
Automatic Reference Counting(ARC)はオブジェクトの管理をOSに任せてしまう機能です。retainやreleaseを記述しなくてよくなります。
これもXcode4.2から追加されました。
これもXcode4.2から追加されました。
ARC使っても使わなくても本記事の本質そのものに変わりはありませんが、もしもARCを使わない場合、記述が変わります。
プロジェクトを生成すると、segueSampleフォルダの中に五つのファイルがあります。
AppDelegate.h、AppDelegate.m、MainStoryboard.storyboard、ViewController.h、ViewController.mの五つです。
AppDelegate.h、AppDelegate.mはアプリ全体に関わる処理を受け取るためのクラスです。
たとえば、アプリが起動したときとか、バックグラウンドに移行したときとか。
今回は変更しません。
たとえば、アプリが起動したときとか、バックグラウンドに移行したときとか。
今回は変更しません。
MainStoryboard.storyboardが画面構成を記述するファイルです。
これが今回の肝であるStoryBoard。
これが今回の肝であるStoryBoard。
選択してみると↓のように表示されます。
ViewControllerって名前がついたものが一つだけあります。これがiPhoneで表示される初期画面になります。
(正確には画面に表示されるものはViewで、ViewControllerはそれの管理)
(正確には画面に表示されるものはViewで、ViewControllerはそれの管理)
まだなにもしていないので真っ白です。
ViewController.h、ViewController.mはこのViewControllerについてコードを記述するファイルになります。
.hが定義を書くファイル、.mが実装を書くファイルです。
外向きが.h、内向きが.m、みたいな言い方もできるのですが、このあたりの細かい説明は省きます。
外向きが.h、内向きが.m、みたいな言い方もできるのですが、このあたりの細かい説明は省きます。
iPhoneアプリ開発では、用意されているオブジェクトに手を加えるためには、この名前が同じで拡張子が異なるhとmの一対のファイルを新たに作っていくことになります。
Single View Applicationの場合、初期画面に関するクラス(ViewController.hとViewController.m)は自動で作られます。
では、StoryBoardに二つ目の画面を置いてみます。
Objects(画像の赤く囲んだ部分にあります)からView Controllerをドラッグアンドドロップすると上記画像のようになります。
位置はご自由にどうぞ。
位置はご自由にどうぞ。
これで下準備は完了です!
一つ目の画面から二つ目の画面へ遷移
まず、一つ目の画面上にRound Rect Buttonをドラッグアンドドロップしてください。
わかりやすくするため、ボタンをダブルクリックして「遷移」と書いておきました。
controlを押しながら今置いたボタンをクリックし、そのままマウスカーソルを二つ目の画面に引っ張るとボタンクリック→画面遷移という流れが実現できるのですが、今回はこの手は使いません。
ボタンクリック以外での画面遷移にも今後対応できるよう、ちょっと遠回りですがボタンクリック→それを検知→画面遷移というステップを踏むことにします。
一つ目の画面の下にあるView Controllerのアイコンをcontrolを押しながらクリックし、そのままマウスカーソルを二つ目の画面に引っ張ってください。
すると上の画像のように線が伸びます。
マウスから指を離すと"Push"、"Modal"、"Custom"のいずれかを選ぶようにポップアップが出ます。
今回はModalを選択します。
(元画面の上に新画面を表示する方式)
(元画面の上に新画面を表示する方式)
上の画像のように一つ目の画面から二つ目の画面に矢印が描かれます。
この矢印をクリックして、Identiferのところに画面遷移の名称を書きます。
私はmySegueとしました。
他の名称にするときは、以降のコードでもそれに合わせてください。
他の名称にするときは、以降のコードでもそれに合わせてください。
ちなみにProduct Nameにも出てきましたSegueという単語は切れ目なく移行するという意味です。
iPhoneアプリ開発では画面遷移をSegueと呼びます。
iPhoneアプリ開発では画面遷移をSegueと呼びます。
Editorの表示を三つ並んだうちの真ん中Show The Assistant Editorにすると、Xcode上に二つの作業領域が表示されます。
左側はStoryBoardのまま、右側でViewController.hを表示します。
そして、controlを押しながらボタンをクリックし、そのままマウスカーソルを@interface ViewController : UIViewControllerの下まで引っ張ってください。
ConnectionでActionを選んで、NameにpushBtnと入れ、Connectを押します。
このNameは、ボタンをタップした際に呼び出されるメソッド名となります。
他の名称でも構いません。
このNameは、ボタンをタップした際に呼び出されるメソッド名となります。
他の名称でも構いません。
ViewController.hに- (IBAction)pushBtn:(id)senderというメソッドが記述されました。
ボタンを押すとこのメソッドが呼び出されます。
ボタンを押すとこのメソッドが呼び出されます。
次にViewController.mを開きます。
こちらにも- (IBAction)pushBtn:(id)senderというメソッドが記述されています。
hに書き込まれたのが定義、mに書き込まれるのが処理です。
つまり、このmの側でメソッドになにをさせるかを書くことになります。
つまり、このmの側でメソッドになにをさせるかを書くことになります。
上の画像のように一行追加してください。
追加したコードは下記。
追加したコードは下記。
[self performSegueWithIdentifier:@"mySegue" sender:self];
self(つまり自分)がmySegue(さっき自分でつけた名前)を使って遷移しますという意味の処理です。
画面遷移が複数あるときも、Identifierで分岐可能です。
画面遷移が複数あるときも、Identifierで分岐可能です。
これで一つ目の画面から二つ目の画面への遷移は完成です!
二つ目の画面を閉じる
次に、二つ目の画面を閉じて一つ目の画面に戻る処理を書きます。
左側にあるProjectNavigaterでメニューを表示して
NewFileを選択。
Objective-C classを選択。
名前は二画面目ってことで、SecondViewControllerとしました。名前は自由ですが、わかりやすいものにしましょう
Subclass ofはUIViewControllerにしてください。こちらは自由ではありません。
Subclass ofはUIViewControllerにしてください。こちらは自由ではありません。
これでUIViewControllerを継承したSecondViewControllerというクラスが作られます。
継承というのはクラスの内容を受け継ぐことです。
継承というのはクラスの内容を受け継ぐことです。
はい、作られました。SecondViewController.hとSecondViewController.m。
StoryBoardを表示して二つ目の画面を選択し、ClassをSecondViewControllerにしてください。
これでこの画面はSecondViewControllerのインスタンス(クラスを元としたデータ)となります。
二つ目の画面にRound Rect Buttonをドラッグアンドドロップしてください。一つ目の画面のときと同じです。
こちらはボタンを「閉じる」としました。
こちらはボタンを「閉じる」としました。
左側にStoryBoard、右側にSecondViewControllerを映します。
そして、controlを押しながらボタンをクリックし、そのままマウスカーソルを@interface ViewController : UIViewControllerの下まで引っ張っります。
一つ目の画面と同じ手順です。
一つ目の画面と同じ手順です。
ConnectionでActionを選んで、NameにpushBtnと入れ、Connectを押します。
これも一つ目の画面のときと同じ。
これも一つ目の画面のときと同じ。
SecondViewController.mを開き、pushBtnメソッドの中にコードを書きます。
[self dismissModalViewControllerAnimated:YES];
dismissModalViewControllerAnimatedはmodalで表示した画面を閉じるメソッドです。
画面遷移はこれで完成です!
一つ目の画面と
二つ目の画面がしっかり遷移します。
一つ目の画面から二つ目の画面へ値を渡す
まずSecondViewController.hにNSString* _myValue;と@property (nonatomic)NSString* myValue;の二行を追加します。
↓のように。
↓のように。
@interface SecondViewController : UIViewController{
NSString* _myValue;
}
@property (nonatomic) NSString* myValue;
NSString* _myValue;
}
@property (nonatomic) NSString* myValue;
追加した一つ目は_myValueという名の文字列インスタンスを宣言しています。
二つ目はmyValueという名の文字列のプロパティを宣言しています。
二つ目はmyValueという名の文字列のプロパティを宣言しています。
プロパティとは、端的に言えばクラスを外部から扱いやすく設定すること、です。説明すると本筋から離れすぎるので、詳しくは検索してください。
_myValueとmyValueは別物なの?
なんで_がついてるの?
と思うかもしれません。
なんで_がついてるの?
と思うかもしれません。
後述するsynthesize文により、二つは結びつけられるようになります。
どうせわざわざ結びつけるなら、なんで別の名前にするの?
最初から同じにしておけばいいんじゃない?
どうせわざわざ結びつけるなら、なんで別の名前にするの?
最初から同じにしておけばいいんじゃない?
これはわざわざ_をつけることでどういう用途のものかを明示的にし、バグを防ぐためです。
一つの文法マナーです。守らなくてもプログラムは動きます。
詳しくは検索してみてください。ちなみに、つけるべきではないって人もけっこういます。
一つの文法マナーです。守らなくてもプログラムは動きます。
詳しくは検索してみてください。ちなみに、つけるべきではないって人もけっこういます。
続いて、SecondViewController.mに@synthesize myValue = _myValue;を追加します。
この一文によって、myValueと_myValueが結びつけられます。myValueが変わると、_myValueも変わります。
この一文によって、myValueと_myValueが結びつけられます。myValueが変わると、_myValueも変わります。
@synthesize myValue = _myValue;
次に、ViewController.hを開き、#import "SecondViewController.h"の一文を追加します。
こうすることによって、ViewControllerがSecondViewcontroller.hで定義されているものにアクセスできるようになります。
#import "SecondViewController.h"
この段階ではViewController.mの側に記述しても動作します。
二つ目の画面から値を受け取るときのため、h側に書いておいてください。
ViewController.hに書いた内容はViewController.mでもアクセスできます(mがhをimportしているため)。
ViewController.hに書いた内容はViewController.mでもアクセスできます(mがhをimportしているため)。
次に、ViewController.mに新たにprepareForSegueというメソッドを記述します。
↓のコードをまるまるコピーアンドペーストしてください。
↓のコードをまるまるコピーアンドペーストしてください。
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"mySegue"]) {
SecondViewController *viewCon = segue.destinationViewController;
viewCon.myValue = @"test";
}
}
if ([segue.identifier isEqualToString:@"mySegue"]) {
SecondViewController *viewCon = segue.destinationViewController;
viewCon.myValue = @"test";
}
}
prepareForSegueは画面遷移が行われる前に呼び出されるメソッドです。
if文で画面遷移がmySegueかどうかをチェックしています。
画面遷移が複数のときは、こう書くことで遷移先によって前処理を分岐できます。
画面遷移が複数のときは、こう書くことで遷移先によって前処理を分岐できます。
if文の中には、遷移先画面インスタンスの取得と、遷移先画面のmyValueへの値の設定をしています。
myValueはさきほどSecondViewController.hにプロパティとして記述したものです。
testという文字列にしたことに意味はありません。
testという文字列にしたことに意味はありません。
今回はNSString型にしていますが、他の型でもやり方は同様です。
これで二つ目の画面の_myValueにtestという値がセットされました!
SecondViewController.mのpushBtnの中にNSLogを書いてみました。
NSLog(@"%@" , _myValue);//渡された変数の表示
これで閉じるボタンを押した際に値を確認できます。
二つ目の画面から一つ目の画面へ値を渡す
まず、デリゲートというものについて簡単に説明。
デリゲートとは日本語で言うと委譲です。
デリゲートを使うことによってインスタンスAで起きたことをインスタンスBで処理させるといったことができるようになります。
デリゲートを使うことによってインスタンスAで起きたことをインスタンスBで処理させるといったことができるようになります。
なんかややこしいですが、基本的な記述ルールさえ覚えてしまえば機械的に対応できるようになります。
今回は二つ目の画面が閉じるとき、それをデリゲートによって一つ目の画面に通知する。そのときに値を渡す。という処理を組み込んでみます。
まず、SecondViewController.hです。
追加されたのは三箇所。
追加されたのは三箇所。
まず、↓のコード。
@protocol SecondViewDelegate
- (void)finishView:(NSString*)returnValue;
@end
- (void)finishView:(NSString*)returnValue;
@end
これはSecondViewDelegateというデリゲート名でfinishViewというデリゲートメソッドを定義したことを意味します。
NSStringを渡すという定義にしていますが、これは他の型でも変わりません。
次に、↓の二つ、各一行。
id _delegate;
@property (nonatomic) id delegate;
このdelegate(_delegate)が通知先を入れるためのインスタンスになります。
通知先は、通知を受ける側でセットされます。
今回の場合は一画面目であるViewControllerです。
今回の場合は一画面目であるViewControllerです。
続きましてSecondViewController.mです。
まず、上の方(9行目)に↓のコードがあります。
delegateと_delegateを結びつけています。
delegateと_delegateを結びつけています。
@synthesize delegate = _delegate;
次に、pushBtnメソッドの中に以下の三行が追加されています。
if ([_delegate respondsToSelector:@selector(finishView:)]){
[_delegate finishView:@"finish"];
}
[_delegate finishView:@"finish"];
}
if文において、通知先が存在しているかどうかを確認しています。
その上で通知先のfinishViewメソッドを呼び、その際にfinishという文字列を渡しています。
finishという文字列そのものに意味はありません。適当です。
finishという文字列そのものに意味はありません。適当です。
これで通知元であるSecondViewControllerの記述は完了です。
次に、一つ目の画面である、ViewController.h。
<SecondViewDelegate>という記述が加えられています。
@interface ViewController : UIViewController
これはSecondViewDelegateを受けるという宣言です。
この宣言のために#import "SecondViewController.h"の一文をmではなくhに書きました。
mに書いてしまうと、hではこれが何者かわからないのです。
最後に、ViewController.m。
prepareForSegueの中に以下の一文が追加されています。
viewCon.delegate = self;
delegateというのは先程SecondViewControllerで記述したプロパティです。
このプロパティにself、つまり自らを入れることで、デリゲートの通知先になれます。
実際に呼ばれるのが以下のメソッドです。
- (void)finishView:(NSString*)returnValue{
NSLog(@"%@" , returnValue);
}
NSLog(@"%@" , returnValue);
}
finishViewもSecondViewControllerで先程記述しましたね。
returnValueの中に、SecondViewControllerから渡される値(今回はfinish)が入っています。
returnValueの中に、SecondViewControllerから渡される値(今回はfinish)が入っています。
NSLogは受け取った値の確認用で入れておいたコードです。
終わり
かなり長文になってしまいましたが、その分だけ、画面遷移のみではなく、iPhoneアプリ開発で必要となる重要な要素をいくつも詰め込んだつもりです。
意見等ありましたら、Twitterででも気軽に声かけてください。
1