お?いけるくさい?

iPhoneアプリエンジニアのたまごです。いっちょまえエンジニア目指してちいさな発見や学んだことを覚え書きしていきます!Objective-C/iOS/開発

UITableViewの選択したセルにチェックマークをつける

ヒントもらって!/

格闘して!         /

無事に!          /

解決!          /  

!               /

\( ^ヮ゜)>いぇい☆

 

さてさて上長の方も閲覧し始めましたが、

ありのままを書いていきます。

決して評価あげようとか思ってません。

今期は一日一記事目標です!

目標ってかノルマ!\( ^ヮ゜;;;;)>キラ

 

今日一番嬉しかったのは、

タイトル↑の実装をできたこと!!(鼻息)

 

テーブルビューがありまして。

セクションは1つ。

行数は配列のカウント分。

よくあるテーブルビューです。

 

【今回やりたいこと】は、

、初めて画面を開いたときは、0行目(一番上)にチェックマークがついている

、別のセルを選択すると、0行目のチェックマークが消えて、選択したセルにチェックマークがつく

、次回画面を開くと、先ほど選択したセルにチェックマークがついている

という3本立てです。

 

さてさてまずはセルにチェックマークをつける方法!

「(上から)0行目のセルはチェックマークのついたものにします」と命令

(cellForRow内で)

 

if (indexPath.row == 0) {

                    cell.accessoryType = UITableViewCellAccessoryCheckmark;

                }

 

セルのアクセサリーをデフォルトのNoneからCheckmarkにすればOK.

このままでも0番目のセルだけにしかチェックマークはつかないけど、

念のためelseで他のセルはアクセサリNoneにしておく。

 

if (indexPath.row == 0) {

                    cell.accessoryType = UITableViewCellAccessoryCheckmark;

                } else {

                    cell.accessoryType = UITableViewCellAccessoryNone;

                }

 

 

では次。

「選択されたら状態を変化させたい」ときは、didSelectRow内に書けばいいんよね。

てことでdidSelectに書いてみたところ、

 

UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];

            cell.accessoryType = UITableViewCellAccessoryCheckmark;

 

 

 

前につけたチェックマークが...消えない...ヽ(´c_,`)ノ....

 

ついたらつきっぱなし ってやつです。これは...困った。

でも「選択されたとき」やからここのはずなんやけどなあー。

 

そしたら「テーブルビューは何をするにもリロードが必要だよ」という天使の一声。

リロード!!

それか!

 

と思い書き足すも、今度はチェックマークすらつかない状態に。

...あれ。

 

しかし違ったのです。

didSelectですべきことは、「選択されたセルを保存すること」だったのです。

さあここでUserDefaultちゃんの登場。

何を保存しましょう。

やはりここは一番に思いつくのはあれですね、「選択された行数」!!

しかーし!!

次回画面を開いたときにもしも配列の個数が変わってしまっていたら?

3番目のセルがタップされていたのに2個しか配列の中身がなくなってしまっていたら?

クラーッシュ\( ^ヮ゜)>★

 

はいそうですね。

ということで今回はまぁいろいろはしょってとりあえず、

選択されたセルの中の文字列(userId)を保存することにしました。

(そしてUserDefaultsの値の保存の方法ははしょる)

「選択されたらUserDefalutsに保存」さらにここで「リロードをかける」

didSelectで実装すべき項目はこの2点だったのです!

以下いろいろはしょったソース。

 

NSUserDefaults* ud = [NSUserDefaultsstandardUserDefaults];

            [ud setValue:userId forKey:@"userID"];

            [ud synchronize];

            [_twitterTableViewreloadData];

 

 

これで「前回選択したセル」の情報は保存できた....

この情報さえあれば!ゴールは近い!

あたしはここから迷走したけど!

保存した情報をもとに、

「初回かどうかの判別」「チェックをつけるセルの判別」が可能になります!!!

先ほどセルの表示をいじったのはcellForRowでしたよね?

ということでセルの状態はcellForRowで管理させます。

reloadさえかければリアルタイムで管理してくれるぽい。(!)

 

まず「初回かどうかの判別」

選択して初めてUserDefaultsに値が保存される。

ということは、一度も選択されていなければ値は入っていない(=nil)!

ここで判定します。

//UserDefaultsから値を呼び出す

            NSUserDefaults* ud  = [NSUserDefaultsstandardUserDefaults];

            NSString* udUserID = [ud valueForKey:@"userID"];

            

            

            if (udUserID == nil) {//UDに値入ってない=初回→0行目にチェックマーク

                if (indexPath.row == 0) {

                    cell.accessoryType = UITableViewCellAccessoryCheckmark;

                } else {

                    cell.accessoryType = UITableViewCellAccessoryNone;

                }

これで初回判定ができます。

で、2回目以降の処理をelseに書けばよいわけです。

 

2回目以降は、「前回選択されたセルにチェックマークをつけておく」

今セルに表示されてる情報の文字列を比較して、

そのセルの文字列がUserDefaultsに保存されている文字列と一致すれば

そのセルにチェックマークをつけといてね!

ってお願いすればいいのです。

ここでハマったのが、cellForRowはそれ自体がfor文みたいなもので、

常にindexPath.rowで番目(行数)をとれるということ!

意識はしていたけど、さらにその中でfor文とか回して私は迷走したのでした。

「cell.」 って書いたら、いつでもそれは

「(indexPath.row番目の)cellの」を意味できるってこと。

個別に指定してるみたいなもんだ。(と※私なりの※理解)

 

今回は配列の要素がさらにDictionary型になっていたので、

まずはdicをindexPath.row番目で1つずつとりだす。

その中の文字列と、userDefaultsの文字列を比較して、

一致すればチェックマーーーーーク!

出来上がったものはこんな感じ。

(ちなみにintValueしてるのは数値で扱えたプラス

 [isEqual:]使うのが面倒だったからってだけ。)

NSDictionary* dic = [self.twitterAccountArray objectAtIndex:indexPath.row];

            NSString* userID = [[dic valueForKey:@"properties"] valueForKey:@"user_id"];//ユーザID

            

            //UserDefaultsから値を呼び出す

            NSUserDefaults* ud  = [NSUserDefaultsstandardUserDefaults];

            NSString* udUserID = [ud valueForKey:@"userID"];

            NSLog(@"cellForRow UserDefaultsに格納されてるid = %@",udUserID);

            NSLog(@"self.twitterAccountに格納されてるオブジェクト =%d",[self.twitterAccountArray count]);

            

            if (udUserID == nil) {//UDに値入ってない=初回→0行目にチェックマーク

                if (indexPath.row == 0) {

                    cell.accessoryType = UITableViewCellAccessoryCheckmark;

                } else {

                    cell.accessoryType = UITableViewCellAccessoryNone;

                }

            

            } else {//2回目以降

                if ([userID intValue] == [udUserID intValue]) {//合致したら

                    cell.accessoryType = UITableViewCellAccessoryCheckmark;

                } else {

                    cell.accessoryType = UITableViewCellAccessoryNone;

                }

            }

 

よくできました。ちゃんちゃん。