Подтвердить что ты не робот

Переключить флажок в UITableViewCell

Мне нужно некоторое руководство по созданию UITableViewCell с изображением слева, которое можно переключать. Изображение должно быть накладным и действовать как переключатель (флажок).

Мои части, с которыми я борюсь:

  1. Как я могу обнаружить касания на изображении и обработать их по-другому для didSelectRowAtIndexPath?
  2. Как я могу изменить изображение, не выполняя [tableView reloadData]?
4b9b3361

Ответ 1

На самом деле это довольно легко.

Просто создайте новый подкласс 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 для обновления изображения; что вызовет перерисовку без побочных эффектов.

- (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

Здесь реализация подхода "override touchesBegan:", который я использую, проста и, кажется, работает хорошо.

Просто включите этот класс в свой проект и создайте и настройте TouchIconTableViewCell вместо ячейки UITableView в вашем методе tableView:cellForRowAtIndexPath:.

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. Когда ваш значок будет затронут, делегат будет вызван. Затем вы можете обновить значок или что-то еще.

Ответ 3

Итак, "... нужно немного массировать материал". Комментарий означает "... этот код не работает...".

Итак,

- (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

Кажется, что Apple загрузила "TableMultiSelect" в качестве образцов кода в iOS Developer Program начиная с 2011-10-12.

Этот код можно активировать в режиме редактирования.

self.tableView.allowsMultipleSelectionDuringEditing = YES;

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

Хотя он может использоваться только с iOS5.

Несколько часов я не смог найти этот пример кода в Stack Overflow, поэтому я добавил эту информацию к этому сообщению.

Ответ 5

Существует даже способ EASIER сделать это, если вы переопределите touchhesBegan: вам нужно сделать оператор if, чтобы решить, находится ли он в близости галочки, если он не вызывает [super touchesBegan:touches withEvent:event], и он будет действовать так, как если бы он был выбран.

Ответ 6

Я делаю что-то подобное (в главной роли фаворит), как это, но я думаю, что вы многого требуете от больших пальцев пользователей iPhone, когда ячейка направляет людей к другому виду. Прежде всего, я бы посмотрел опцию раскрытия подробностей на ячейках. Один из вариантов - это предварительно созданная кнопка со стрелкой, к которой вы можете подключиться. Ваш звонок.

Возможно, вам удастся уловить событие didSelectRowAtIndexPath, а затем сделать другую логику вместо перенаправления, если прикосновение было на вашем флажке, хотя я не знаю, как вы получите позицию. Это означает, что вам может потребоваться найти способ получить событие касания до того, как он назовет путь didSelectRowAtIndex, который я не совсем уверен, как это сделать. Сработали ли вы с обработкой touchBegan и тому подобное?