web-dev-qa-db-ja.com

UITableViewCellのチェックボックス画像の切り替え

左側に切り替え可能な画像があるUITableViewCellを作成するためのガイダンスが必要です。画像はタップ可能で、トグル(チェックボックス)として機能する必要があります。

私が苦労している私の部分は次のとおりです。

  1. 画像のタップを検出し、それらをdidSelectRowAtIndexPathとは異なる方法で処理するにはどうすればよいですか?
  2. [tableView reloadData]を実行せずに画像を変更するにはどうすればよいですか?
29
rein

実はとても簡単です。

UIControlの新しいサブクラスを作成し、そこにすべて配置するだけです(個別のコントローラーは必要ありません)。これをToggleImageControlと呼びましょう。

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

セルごとにToggleImageControlを作成し、適切な位置に追加します。

ToggleImageControl *toggleControl = [[ToggleImageControl alloc] initWithFrame: <frame>];
toggleControl.tag = indexPath.row;  // for reference in notifications.
[cell.contentView addSubview: toggleControl];

UIImageViewを追加して、画像を含めます。タッチイベントのターゲットを追加します。

- (void) viewDidLoad
{
   normalImage = [UIImage imageNamed: @"normal.png"];
   selectedImage = [UIImage imageNamed: @"selected.png"];
   imageView = [[UIImageView alloc] initWithImage: normalImage];
   // set imageView frame
   [self.view addSubview: imageView];

[self addTarget: self action: @selector(toggleImage) forControlEvents: UIControlEventTouchUpInside];

}

UIImageViewのimageプロパティを設定して、画像を更新します。これにより、副作用なしに再描画がトリガーされます。

- (void) toggleImage
{
   selected = !selected;
   imageView.image = (selected ? selectedImage : normalImage); 

   // Use NSNotification or other method to notify data model about state change.
   // Notification example:
   NSDictionary *dict = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt: self.tag forKey: @"CellCheckToggled"];
   [[NSNotificationCenter defaultCenter] postNotificationName: @"CellCheckToggled" object: self userInfo: dict];

}

あなたは明らかにいくつかのものをマッサージする必要があります。再利用しやすくするために、2つの画像名を渡すことをお勧めします。また、オブジェクトの外部からも通知名の文字列を指定することをお勧めします(通知メソッドを使用している場合)。

28
Amagrammer

これが私が使用している「overridetouchesBegan:」アプローチの実装です。これは単純でうまく機能しているようです。

このクラスをプロジェクトに含め、tableView:cellForRowAtIndexPath:メソッドでTouchIconTableViewCellセルの代わりにUITableViewを作成して構成するだけです。

TouchIconTableViewCell.h:

#import <UIKit/UIKit.h>

@class TouchIconTableViewCell;

@protocol TouchIconTableViewCellDelegate<NSObject>

@required
- (void)tableViewCellIconTouched:(TouchIconTableViewCell *)cell indexPath:(NSIndexPath *)indexPath;

@end

@interface TouchIconTableViewCell : UITableViewCell {
    id<TouchIconTableViewCellDelegate> touchIconDelegate;       // note: not retained
    NSIndexPath *touchIconIndexPath;
}

@property (nonatomic, assign) id<TouchIconTableViewCellDelegate> touchIconDelegate;
@property (nonatomic, retain) NSIndexPath *touchIconIndexPath;

@end

TouchIconTableViewCell.m:

#import "TouchIconTableViewCell.h"

@implementation TouchIconTableViewCell

@synthesize touchIconDelegate;
@synthesize touchIconIndexPath;

- (void)dealloc {
    [touchIconIndexPath release];
    [super dealloc];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    CGPoint location = [((UITouch *)[touches anyObject]) locationInView:self];
    if (CGRectContainsPoint(self.imageView.frame, location)) {
        [self.touchIconDelegate tableViewCellIconTouched:self indexPath:self.touchIconIndexPath];
        return;
    }
    [super touchesBegan:touches withEvent:event];
}

@end

セルを作成または再利用するたびに、touchIconDelegateおよびtouchIconIndexPathプロパティを設定します。アイコンをタッチすると、デリゲートが呼び出されます。次に、アイコンなどを更新できます。

6
Archie

したがって、「..明らかにいくつかのものをマッサージする必要があります..」コメントは「...このコードは機能しません...」を意味します。

そう

_- (void) viewDidLoad
_

する必要があります

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

 // set imageView frame
  [self addSubview: imageView];

  [self addTarget: self action: @selector(toggleImage) forControlEvents: UIControlEventTouchDown];
 }

 return self;
}
_

- (void) viewDidLoadが呼び出されることはありません。

4
Peter Brooke

2011-10-12以降、iOS DeveloperProgramにサンプルコードとしてApple「TableMultiSelect」をアップロードしたようです。

このコードにより、編集モードでの複数選択を有効にすることができます。

self.tableView.allowsMultipleSelectionDuringEditing = YES;

http://developer.Apple.com/library/ios/#samplecode/TableMultiSelect/Introduction/Intro.html

IOS5からしか使えませんが。

数時間、Stack Overflowでこのサンプルコードが見つからなかったため、この情報をこの投稿に追加しました。

3
tokentoken

TouchesBeganをオーバーライドする場合、これを行うさらに簡単な方法があります。それが[super touchesBegan:touches withEvent:event]を呼び出さない場合、チェックマークの近くにあるかどうかを判断するためにifステートメントを実行する必要があり、選択されたかのように動作します。

1
skylerl

私はこのように似たようなことをします(お気に入りを主演します)が、あなたは人々を別のビューに導くセルでiPhoneユーザーの親指に多くを要求していると思います。まず、セルの詳細開示オプションを確認します。オプションの1つは、アタッチできる既製の矢印ボタンです。あなたの呼び出し。

位置を取得する方法はわかりませんが、didSelectRowAtIndexPathイベントをキャッチしてから、タッチがチェックボックスにある場合はリダイレクトする代わりに、他のロジックを実行することで回避できる可能性があります。つまり、didSelectRowAtIndexパスを呼び出す前に、タッチイベントを取得する方法を見つける必要があるかもしれませんが、その方法はよくわかりません。 touchesBeganなどの処理はもう行っていますか?

0
TahoeWolverine