iPhoneアプリのユーザインタフェースの作りこみ3

前回、チェックボックスをUITableViewに表示させるところをやりましたので、今回はチェックの動作を作りこんで行きます。
UITableViewに配置するためには

  • チェックボックス内で保持していた選択・非選択の情報を削除し、外からセットできるメソッドを追加する。
  • カスタムセル側にも、自分の中にあるチェックボックスの選択・非選択を行える、メソッドを追加する。
  • UITableViewで、セルを作成または再利用する際に、チェックボックスの選択・非選択を設定するコードの追加。
  • UITableViewでセルが再表示される時に呼ばれる、willDisplayCellメソッドにチェックボックスの選択・非選択を設定するコードの追加。
  • UITableViewでセル選択時に呼ばれる、didSelectRowAtIndexPathメソッドにチェックボックスの選択・非選択を設定するコードの追加。

を行います。


1)チェックボックスの選択・非選択を外からセットできるようにする
ToggleImageControlクラスに、toggleOnメソッドを追加します。BOOL値を渡すことで、選択・非選択できるようになります。

#import <Foundation/Foundation.h>


@interface ToggleImageControl : UIControl
{
	UIImageView* imageView;
	UIImage* normalImage;
	UIImage* selectedImage;
}

- (void)toggleOn:(BOOL)selected;

@end
#import "ToggleImageControl.h"

@implementation ToggleImageControl
- (id)initWithFrame:(CGRect)frame {
	if (self = [super initWithFrame:frame]) {
		normalImage = [UIImage imageNamed: @"normal.png"];
		selectedImage = [UIImage imageNamed: @"selected.png"];
		imageView = [[UIImageView alloc] initWithImage: normalImage];

		// set imageView frame
		[self addSubview:imageView];
		self.userInteractionEnabled = NO;
		[imageView release];
	}
	return self;
}

- (void)toggleOn:(BOOL)selected {
	imageView.image = (selected ? selectedImage : normalImage);
}

- (void)dealloc {
	NSLog(@"ToggleImageControl dealloc");
	[imageView release];
	[normalImage release];
	[selectedImage release];

	[super dealloc];
}

@end



2)カスタムセルにチェックボックスの選択・非選択を行える、メソッドを追加する。
UITableViewCustomCellクラスに、toggleOnメソッドを追加します。これで、中にあるToggleImageControlのインスタンスを操作できるようにします。

#import <UIKit/UIKit.h>
#import "ToggleImageControl.h"

@interface UITableViewCustomCell : UITableViewCell {
	ToggleImageControl* toggleControl_;
	UIImageView* userIcon_;
	UILabel* name_;
	UILabel* screenName_;
	UILabel* text_;
}

- (void)setName:(NSString*)name;
- (void)setScreenName:(NSString*)screenName;
- (void)setText:(NSString*)text;
- (void)toggleOn:(BOOL)selected;

@end
#import "UITableViewCustomCell.h"

@implementation UITableViewCustomCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {

	self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
	if (self) {

		// CheckBox
		toggleControl_ = [[ToggleImageControl alloc] initWithFrame:CGRectMake(-25, 12, 25, 25)];
		[self.contentView addSubview: toggleControl_];

		// Icon
		userIcon_ = [[UIImageView alloc] initWithFrame:CGRectMake( 5, 7, 35, 35)];
		[self.contentView addSubview: userIcon_];

		// Name
		name_ = [[UILabel alloc] init];
		name_.backgroundColor = [UIColor colorWithWhite:1.0 alpha:.0];
		name_.adjustsFontSizeToFitWidth = YES;
		name_.minimumFontSize = 12;
		name_.font = [UIFont fontWithName:@"Verdana" size:12];
		[self.contentView addSubview: name_];

		// Screen Name
		screenName_ = [[UILabel alloc] init];
		screenName_.backgroundColor = [UIColor colorWithWhite:1.0 alpha:.0];
		screenName_.adjustsFontSizeToFitWidth = YES;
		screenName_.minimumFontSize = 9;
		screenName_.font = [UIFont fontWithName:@"Verdana" size:9];
		[self.contentView addSubview: screenName_];

		// Text
		text_ = [[UILabel alloc] init];
		text_.backgroundColor = [UIColor colorWithWhite:1.0 alpha:.0];
		text_.adjustsFontSizeToFitWidth = YES;
		text_.minimumFontSize = 11;
		text_.font = [UIFont fontWithName:@"Verdana" size:11];
		[self.contentView addSubview: text_];
	}
	return self;
}

- (void)setName:(NSString*)name {
	name_.text = name;
}

- (void)setScreenName:(NSString*)screenName {
	screenName_.text = screenName;
}

- (void)setText:(NSString*)text {
	text_.text = text;
}

- (void)toggleOn:(BOOL)selected {
	[toggleControl_ toggleOn:selected];
	if (selected) {
		UIColor *altCellColor = [UIColor colorWithWhite:0.9 alpha:1.0];
		self.backgroundColor = altCellColor;
	} else {
		self.backgroundColor = [UIColor whiteColor];
	}
}

- (void)dealloc {
	NSLog(@"UITableViewCustomCell dealloc");
	[toggleControl_ release];
	[userIcon_ release];
	[name_ release];
	[screenName_ release];
	[text_ release];

	[super dealloc];
}

@end



3)UITableViewで、セルを作成または再利用する際にチェックボックスの選択状態をセットします。
下記ソースでは、instanceArray_に、各セルの選択状態が入っていると考えてください。instanceArray_は、NSMutableArrayで中身はNSNumberが格納されています。
instanceArray_の内容を見て、チェックボックスの選択と非選択を、toggleOnメソッドで設定していきます。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
	UITableViewCell *cell;

	cell = [tableView dequeueReusableCellWithIdentifier:@"custum"];
	if (cell == nil) {
		cell = [[[UITableViewCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"custum"] autorelease];
		cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
	}

	// 作成、再利用したcellに値をセットする。
	[(UITableViewCustomCell*)cell toggleOn:[[instanceArray_ objectAtIndex:indexPath.row] boolValue]];

	return cell;
}



4)UITableViewでセルが再表示される時に呼ばれる、willDisplayCellメソッドにチェックボックスの選択・非選択を設定するコードの追加。
willDisplayCellは、セルが表示される時に呼ばれます。あ、3)で値をセットしなくてもいいかも・・・

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
	// セルの再表示
	[(UITableViewCustomCell*)cell toggleOn:[[instanceArray_ objectAtIndex:indexPath.row] boolValue]];
}



5)UITableViewでセル選択時に呼ばれる、didSelectRowAtIndexPathメソッドにチェックボックスの選択・非選択を設定するコードの追加。
編集モードでだけ、チェックボックスの選択ができるようにするため、ここでも編集モードの判定を入れておきます。
※UITableViewCustomCell、ToggleImageControlとUIViewが階層上になっていますが、一番上のToggleImageControlがタッチされた時、ToggleImageControlでイベント処理をいれてなければ、その上へ上へとイベントが伝播していきます。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
	// セルの選択色解除
	[tableView deselectRowAtIndexPath:indexPath animated:NO];
	
	// 編集モード判定
	if (self.editing == NO) {
		// 非編集モード

	} else {
		// 編集モード
		UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];

		// 現状の選択状態を判定
		if([[instanceArray_ objectAtIndex:indexPath.row] boolValue]) {
			// 非選択に値を書き換え
			[instanceArray_ replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:NO]];
		} else {
			// 選択に値を書き換え
			[instanceArray_ replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:YES]];
		}
		[(UITableViewCustomCell*)cell toggleOn:[[instanceArray_ objectAtIndex:indexPath.row] boolValue]];
	}
}

- (UITableViewCellEditingStyle)tableView:(UITableView*)tableView editingStyleForRowAtIndexPath:(NSIndexPath*)indexPath {
	return UITableViewCellEditingStyleNone;
}

- (BOOL)tableView:(UITableView*)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath*)indexPath
{
	return NO;
}

これで基本的な動きが完成です。中身が空っぽですがw
ここまでのソースをちょっと動くようにして、そのうち配布しまーす。