【Objective-C】stringWithFormatでエスケープする

stringWithFormatで文字連結するとき、文字列の中に「%」を使う記述の仕方。

記述例
-------------------------------------------
NSString *str1 = @"割引率は";
NSString *str2 = [stringWithFormat:@"@%はひゃく%%",str1];
-------------------------------------------

結果:
割引率はひゃく%

stringWithFormat で「%」を使いたいときは「%%」にする。

【Xcode】AppDelegateで変数を他の画面に渡す

Xcode の AppDelegate は中央センターの役割をするので、AppDelegate 内で作った変数はどのクラスからもアクセスできる。

以下は AppDelegate の設定の手順。Single View Application でつくったものとする。

1.AppDelegate.h に全てのクラスから参照できる変数を設定する

//AppDelegate.h 内に記述
-----------------------------------------
//全てのクラスから参照できる変数
@property (nonatmic, weak) NSString *shareString;
-----------------------------------------

2.ViewController.h から AppDelegate.h をインポートする

//ViewController.h 内に記述
-----------------------------------------
//インポート
#import "AppDelegate.h"
-----------------------------------------

3.ViewController から AppDelegate 内の変数を参照する

//ViewController.m 内の viewDidLoad に記述
-----------------------------------------
// AppDelegateのオブジェクトを取得する
AppDelegate *AD = (AppDelegate *)[[UIApplication sharedApplication] delegate];

//変数に文字列を代入する
AD.shareString = @"代入する文字列";
-----------------------------------------

ラベルに表示したい場合

//ViewController.m 内の interface に記述
-----------------------------------------
//変数 myString を宣言する
NSString myString
-----------------------------------------

つづいて、

//ViewController.m 内の viewDidLoad に記述
-----------------------------------------
//変数に文字列を代入する
AD.shareString = @"表示したい文字列";

myString = AD.shareString;

//ラベル(myLabelと命名)に表示
[self.myLabel setText:myString];
-----------------------------------------

【Xcode】master detail applicationの画面遷移をSingle View Applicationテンプレートから作る

「master detail application テンプレート」を使うと作れる画面遷移を「Single View Applicationテンプレート」から作るときの覚書。

参考ページ:こちら

新しいプロジェクトをつくるとき「Single View Applicationテンプレート」を選択すると、最初に storyboard に View Controller シーンがひとつできている。

このシーンを「画面1」と名づける。Object library からもうひとつ View Controller をドラッグして作り「画面2」と名づける。「画面1」に設置したボタンをタップすると「画面2」に遷移する仕組みをつくる。

手順。

1.Navigation Controller シーンを設置する

Object library から Navigation Controller をドラッグして設置する。Navigation Controller を選択して「Is initial View Controller」にチェックを入れる。すると、いままで View Controller の左横にあった矢印(→)が、Navigation Controller の横に移る。

新しく設置した Navigation Controller には Table View が勝手にくっついてくるが、今回は Single View Applicationテンプレート を選択したときにできた View Controller を使用したいので、Table View は delete する。

2.Navigation Controller シーンと View Controller シーンを、Relationshipセグエでつなぐ

設置した Navigation Controllerシーン は最初、Table View と Relationshipセグエでつながっている。これを View Controller シーンにつなぎかえるため、Navigation Controllerシーンを右クリック、もしくは Connections inspector を開く。「Triggered Segues」の「root view controller」に関連付けられている Table View Controller を解除して、View Contoroller につなぎ直す。

3.View Controller(画面1)にボタンを設置する

View Controller シーン(画面1)に、Object library からドラッグした Button を設置する。

4.View Controller(画面2)を設置する

ボタンを押したときの遷移先になる、View Controller シーン(画面2)を設置する。Object library から View Controller を選択してドラッグする。分かりやすく、label で「画面2」とでも書いておく。

新しく設置した View Controller シーン(画面2)には、ViewController.h(m)などのファイルがまだないので追加する。「File」-「New」-「File」-「Cocoa Touch Class」で「NextViewClass」などとそれっぽい名前をつける。そのあと、Storyboardでできたファイルと関連付けをおこなう。「identity inspector」の「Custom Class」から先ほどつけた名前を選択。

詳細はこちら

5.「画面1のボタン」とView Controller(画面2)をPush セグエでつなぐ

「画面1のボタン」を右クリック、および Connections Inspector にある Triggered Segues 項目の action を View Controller シーン(画面2)にドラッグする。選択項目が出てくるので「push(deprecated)」を選択すると、Push セグエで関連付けされる。

プログラムをビルドして実行して、動作に問題が無いか確認する。

画面が真っ暗で何も表示されない場合は、Navigation Controller に「Is initial View Controller」にチェックが入っている確認する。

【Objective-C】配列の要素数を数える

【Objective-C】配列の要素数を数える記述

[配列名 count]

もしくは

配列名.count

【Xcode】UICollectionView で Grid 表示する

Grid(格子)状の表示は UICollectionView を使うとできる。

参考ページ

https://akira-watson.com/iphone/uicollectionview.html

以下はその手順。

1.storyboard に Collection View を設定する

Object Library から Collection View を選んで、 storyboard の View Controller に配置する。背景が黒で見にくいので、Light Gray に設定。

「View」->「Collection View」にある
「Show the Size inspector」アイコンを選択

例として、Cell を横に3つ入るように
Cell Size を 106 x 106 に
Min Spacing For Lines(セルの間隔)を 1 に
設定します。

参考:セルの間隔

2.Collection View Cell に名前をつけ、UIImageView と Label を配置

配置した Collection View には、すでに Collection View Cell がひとつ設定されているはず。そのCell の Identifier に再利用のためのIDを「Cell」と設定する。さらにその Cell の中に、ライブラリーからUIImageView と Label を持ってきて配置。
UIImageView の Attributes inspector で View Tag を「1」とセット。
Label の Attributes inspector で Tag を「2」とセット。
Label の文字色は白に設定。

3.必要な画像をプロジェクトに追加

photo1.jpg から photo10.jpg の画像を10個用意して「Add Files to “xxx”…」でプロジェクトに追加する。

4.ViewController にコードを記述

ViewController.h

UICollectionViewDataSource, UICollectionViewDelegate を設定

UICollectionViewDataSource → UICollectionViewを利用して表示するデータを提供するためのメソッドを定義するプロトコル。
UICollectionViewDelegate → UICollectionViewに対する選択等の操作を委譲するデリゲートプロトコル。

この二つのプロトコルを実装することで、 Collection View の Connecitions inspector の Outlets 欄に 「dataSource」「delegate」の二つの項目ができる。

UICollectionViewを構成するクラス

---------------------------------------
#import

@interface ViewController : UIViewController<UICollectionViewDataSource, UICollectionViewDelegate>

//Assistant editor にして、collectionView オブジェクトをドラッグして作成
@property IBOutlet UICollectionView *collectionView;

@end
---------------------------------------

ViewController.m

---------------------------------------
#import "ViewController.h"

@interface ViewController (){
NSString *selectedName;
}

@end

@implementation ViewController

- (void)viewDidLoad
{
[super viewDidLoad];

}

//section 数の設定、今回は1つにセット

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}

//item 数、今回は10個

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return 10;
}


-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

UICollectionViewCell *cell;

//dequeueReusableCellWithReuseIdentifier の働きは、再利用できるセルがあればそれを使う、再利用できるセルがなければ生成する。

cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];

//storyboard 上の画像につけたタグに合わせて UIImageView のインスタンスを生成する。タグが一致しないと反映されない。

UIImageView *imageView = (UIImageView *)[cell viewWithTag:1];
NSString *imgName = [NSString stringWithFormat:@"photo%d.JPG", (int)(indexPath.row+1)];
UIImage *image = [UIImage imageNamed:imgName];
imageView.image = image;

//storyboard 上の画像につけたタグに合わせて UIImageView のインスタンスを生成する。タグが一致しないと反映されない。

UILabel *label = (UILabel *)[cell viewWithTag:2];
label.text = [NSString stringWithFormat:@"No.%d",(int)(indexPath.row+1)];

//背景色の設定。緑。

cell.backgroundColor = [UIColor greenColor];
return cell;
}

//おまけ
//アイテムをセレクトした時の起こるイベント
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {

}

@end
---------------------------------------

storyboard に戻って Collection View を選択して右クリック。もしくは右端の Connection inspector を開く。
Outlets 欄の dataSource -> view Controller
Outlets 欄の delegate -> view Controller
New Referencing Outlet -> collectionView
とそれぞれ結ぶ。「dataSource」と「delegate」は UICollectionViewDataSource と UICollectionViewDelegate を実装したことでできたもの。

ビルドして実行。

以上。

配列内の値を表示させる場合は、以下のように変更追加する。

ViewController.m

//配列を作る
---------------------------------------------------
@implementation ViewController {

NSArray *testArray;

}
---------------------------------------------------

//配列をセット
---------------------------------------------------
- (void)viewDidLoad {

testArray = [NSArray arrayWithObjects:@"うさぎ",@"かめ",@"きじ", nil];

}
---------------------------------------------------

---------------------------------------------------
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {

//return 10;
//配列の数だけ返す
return [testArray count];
}
---------------------------------------------------

---------------------------------------------------
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

UICollectionViewCell *cell;

cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];

UILabel *label = (UILabel *)[cell viewWithTag:1];
//label.text = [NSString stringWithFormat:@"No.%d",(int)(indexPath.row+1)];
label.text = [testArray objectAtIndex:indexPath.row];
return cell;

}
---------------------------------------------------

2 / 212