Checkbox image toggle in UITableViewCell

Potrzebuję wskazówek na temat tworzenia UITableViewCell, który ma obraz po lewej stronie, który można przełączać. Obraz powinien być tappable i działać jako przełącznik (pole wyboru).

Moje części, z którymi się zmagam to:

  1. Jak wykryć krany na obrazie i obsłużyć je inaczej niż didSelectRowAtIndexPath?
  2. Jak zmienić obrazek bez wykonywania [tableView reloadData]?

Zobacz poniższy obrazek dla przykładu:

Alt text http://img208.yfrog.com/img208/6119/screenshotkmr.png

Thanks

Author: rein, 2009-07-23

6 answers

To całkiem proste.

Wystarczy utworzyć nową podklasę UIControl i umieścić tam wszystko (nie ma potrzeby oddzielnego kontrolera. Nazwijmy to ToggleImageControl.

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

Utwórz ToggleImageControl dla każdej komórki i dodaj ją w odpowiedniej pozycji.

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

Dodaj Widok UIImageView, aby zawierał obraz. Dodaj obiekt docelowy dla zdarzenia dotykowego.

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

}

Ustaw właściwość Image UIImageView, aby zaktualizować obraz; spowoduje to ponowne rysowanie bez skutki uboczne.

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

}
Oczywiście będziesz musiał masować niektóre rzeczy. Prawdopodobnie chcesz przekazać w dwóch nazwach obrazów, aby uczynić go bardziej wielokrotnego użytku, a także polecam określenie łańcucha nazwy powiadomienia spoza obiektu, jak również (zakładając, że używasz metody powiadomień.)
 28
Author: Amagrammer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-23 13:40:49

Oto implementacja" override touchesBegan: "podejście, którego używam, jest proste i wydaje się działać dobrze.

Po prostu dołącz tę klasę do swojego projektu i utwórz i skonfiguruj TouchIconTableViewCell zamiast UITableView komórki w swojej metodzie 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

Za każdym razem, gdy tworzysz lub ponownie używasz komórki, ustaw właściwości touchIconDelegate i touchIconIndexPath. Po dotknięciu ikony zostanie wywołany delegat. Wtedy możesz zaktualizuj ikonę lub cokolwiek innego.

 6
Author: Archie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-13 15:15:36

Więc "..oczywiście trzeba trochę masować.."komentarz oznacza"...ten kod nie działa...".

Więc

- (void) viewDidLoad

Powinno być

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

Ponieważ - (void) viewDidLoad nigdy nie zostanie wezwany.

 4
Author: sth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-14 09:18:46

Wygląda na to, że Apple uploaded "TableMultiSelect" jako przykładowe kody w Programie dla programistów iOS od 2011-10-12.

Wielokrotne zaznaczanie w trybie edycji może być włączone przez ten kod.

self.tableView.allowsMultipleSelectionDuringEditing = YES;

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

Chociaż może być używany tylko z iOS5.

Kilka godzin nie mogłem znaleźć tego przykładowego kodu w Stack Overflow, więc dodałem tę informację do tego postu.

 3
Author: tokentoken,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-14 01:57:27

Jest jeszcze łatwiejszy sposób, aby to zrobić, jeśli nadpiszesz touchesBegan: musisz wykonać polecenie if, aby zdecydować, czy znajduje się w pobliżu znaków kontrolnych, jeśli nie jest to wywołanie [super touchesBegan:touches withEvent:event] i będzie działać tak, jakby zostało wybrane.

 1
Author: skylerl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-18 01:13:03

Robię coś podobnego (w roli faworyta), ale myślę, że dużo wymagasz od kciuków użytkowników iPhone ' a z komórką kierującą ludzi do innego widoku. Po pierwsze, chciałbym sprawdzić opcję ujawnienia szczegółów na komórkach. Jedną z opcji jest gotowy przycisk strzałki, do którego możesz dołączyć. Twoja decyzja.

Być może uda Ci się złapać Zdarzenie disselectrowatindexpath, a następnie wykonać inną logikę zamiast przekierowywać, jeśli dotyk był na Twoim checkbox, chociaż Nie wiem, jak zdobyć pozycję. Oznacza to, że być może będziesz musiał znaleźć sposób, aby uzyskać dostęp do zdarzenia touch, zanim wywoła ono ścieżkę didSelectRowAtIndex, co nie jestem do końca pewien, jak to zrobić. Pracowałeś już z obsługą touchesBegan i tym podobnych?

 0
Author: TahoeWolverine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-23 13:23:04