UITableViewCell - отметьте одну строку в каждом разделе
У меня есть 2 раздела и 3 строки в следующем:
ПОИСК РАССТОЯНИЯ
250 футов
1000 футов
4000 футов
ТИП КАРТЫ
стандарт
спутник
Гибридный
Я хочу иметь одну галочку для строки на раздел, но мой текущий код снимет все видимые ячейки для всего табличного представления и оставит одну выбранную строку с галочкой. Другими словами, у меня будет одна галочка для всей таблицы (2 раздела). Здесь я разместил весь мой код. У меня есть google'd много, но, похоже, нет, чтобы решить мою проблему. Кто-нибудь, пожалуйста, помогите исправить мой код. Заранее спасибо.
#import "PAWSettingsViewController.h"
#import "PAWAppDelegate.h"
#import <Parse/Parse.h>
@interface PAWSettingsViewController ()
- (NSString *)distanceLabelForCell:(NSIndexPath *)indexPath;
- (PAWLocationAccuracy)distanceForCell:(NSIndexPath *)indexPath;
- (NSString *)maptypeLabelForCell:(NSIndexPath *)indexPath;
- (PAWMaptypeSelect)maptypeForCell:(NSIndexPath *)indexPath;
@property (nonatomic, assign) CLLocationAccuracy filterDistance;
@end
typedef enum {
kPAWSettingsTableViewDistance = 0,
kPAWSettingsTableViewMaptype,
kPAWSettingsTableViewNumberOfSections
} kPAWSettingsTableViewSections;
typedef enum {
kPAWSettingsTableViewDistanceSection250FeetRow = 0,
kPAWSettingsTableViewDistanceSection1000FeetRow,
kPAWSettingsTableViewDistanceSection4000FeetRow,
kPAWSettingsTableViewDistanceNumberOfRows
} kPAWSettingsTableViewDistanceSectionRows;
typedef enum {
kPAWSettingsTableViewMaptypeSectionStandardRow = 0,
kPAWSettingsTableViewMaptypeSectionSatelliteRow,
kPAWSettingsTableViewMaptypeSectionHybridRow,
kPAWSettingsTableViewMaptypeNumberOfRows
} kPAWSettingsTableViewMaptypeSectionRows;
@implementation PAWSettingsViewController
@synthesize tableView;
@synthesize filterDistance;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
PAWAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
self.filterDistance = appDelegate.filterDistance;
}
return self;
}
#pragma mark - Custom setters
// Always fault our filter distance through to the app delegate. We just cache it locally because it's used in the tableview's cells.
- (void)setFilterDistance:(CLLocationAccuracy)aFilterDistance {
PAWAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.filterDistance = aFilterDistance;
filterDistance = aFilterDistance;
}
#pragma mark - View lifecycle
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Private helper methods
- (NSString *)distanceLabelForCell:(NSIndexPath *)indexPath {
NSString *cellText = nil;
switch (indexPath.row) {
case kPAWSettingsTableViewDistanceSection250FeetRow:
cellText = @"250 feet";
break;
case kPAWSettingsTableViewDistanceSection1000FeetRow:
cellText = @"1000 feet";
break;
case kPAWSettingsTableViewDistanceSection4000FeetRow:
cellText = @"4000 feet";
break;
case kPAWSettingsTableViewDistanceNumberOfRows: // never reached.
default:
cellText = @"The universe";
break;
}
return cellText;
}
- (PAWLocationAccuracy)distanceForCell:(NSIndexPath *)indexPath {
PAWLocationAccuracy distance = 0.0;
switch (indexPath.row) {
case kPAWSettingsTableViewDistanceSection250FeetRow:
distance = 250;
break;
case kPAWSettingsTableViewDistanceSection1000FeetRow:
distance = 1000;
break;
case kPAWSettingsTableViewDistanceSection4000FeetRow:
distance = 4000;
break;
case kPAWSettingsTableViewDistanceNumberOfRows: // never reached.
default:
distance = 10000 * kPAWFeetToMiles;
break;
}
return distance;
}
- (NSString *)maptypeLabelForCell:(NSIndexPath *)indexPath {
NSString *cellText = nil;
switch (indexPath.row) {
case kPAWSettingsTableViewMaptypeSectionStandardRow:
cellText = @"Standard";
break;
case kPAWSettingsTableViewMaptypeSectionSatelliteRow:
cellText = @"Satellite";
break;
case kPAWSettingsTableViewMaptypeSectionHybridRow:
cellText = @"Hybrid";
break;
case kPAWSettingsTableViewMaptypeNumberOfRows: // never reached.
default:
cellText = @"?";
break;
}
return cellText;
}
- (PAWMaptypeSelect)maptypeForCell:(NSIndexPath *)indexPath {
PAWMaptypeSelect maptype = nil;
switch (indexPath.row) {
case kPAWSettingsTableViewMaptypeSectionStandardRow:
maptype = @"Standard";
break;
case kPAWSettingsTableViewMaptypeSectionSatelliteRow:
maptype = @"Satellite";
break;
case kPAWSettingsTableViewMaptypeSectionHybridRow:
maptype = @"Hybrid";
break;
case kPAWSettingsTableViewMaptypeNumberOfRows: // never reached.
default:
maptype = nil;
break;
}
return maptype;
}
#pragma mark - UINavigationBar-based actions
- (IBAction)done:(id)sender {
[self.presentingViewController dismissModalViewControllerAnimated:YES];
}
#pragma mark - UITableViewDataSource methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return kPAWSettingsTableViewNumberOfSections;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
switch ((kPAWSettingsTableViewSections)section) {
case kPAWSettingsTableViewDistance:
return kPAWSettingsTableViewDistanceNumberOfRows;
break;
case kPAWSettingsTableViewMaptype:
return kPAWSettingsTableViewMaptypeNumberOfRows;
break;
case kPAWSettingsTableViewNumberOfSections:
return 2;
break;
};
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = @"SettingsTableView";
if (indexPath.section == kPAWSettingsTableViewDistance) {
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
if ( cell == nil )
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier];
}
// Configure the cell.
cell.textLabel.text = [self distanceLabelForCell:indexPath];
if (self.filterDistance == 0.0) {
NSLog(@"We have a zero filter distance!");
}
PAWLocationAccuracy filterDistanceInFeet = self.filterDistance * ( 1 / kPAWFeetToMeters);
PAWLocationAccuracy distanceForCell = [self distanceForCell:indexPath];
if (abs(distanceForCell - filterDistanceInFeet) < 0.001 ) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
else if (indexPath.section == kPAWSettingsTableViewMaptype){
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
if ( cell == nil )
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier];
}
// Configure the cell.
cell.textLabel.text = [self maptypeLabelForCell:indexPath];
return cell;
}
else {
return nil;
}
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
switch ((kPAWSettingsTableViewSections)section) {
case kPAWSettingsTableViewDistance:
return @"Search Distance";
break;
case kPAWSettingsTableViewMaptype:
return @"Map Type";
break;
case kPAWSettingsTableViewNumberOfSections:
return @"";
break;
}
}
#pragma mark - UITableViewDelegate methods
// Called after the user changes the selection.
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == kPAWSettingsTableViewDistance) {
[aTableView deselectRowAtIndexPath:indexPath animated:YES];
// if we were already selected, bail and save some work.
UITableViewCell *selectedCell = [aTableView cellForRowAtIndexPath:indexPath];
if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark) {
return;
}
// uncheck all visible cells.
for (UITableViewCell *cell in [aTableView visibleCells]) {
if (cell.accessoryType != UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
PAWLocationAccuracy distanceForCellInFeet = [self distanceForCell:indexPath];
self.filterDistance = distanceForCellInFeet * kPAWFeetToMeters;
}
else if (indexPath.section == kPAWSettingsTableViewMaptype){
[aTableView deselectRowAtIndexPath:indexPath animated:YES];
// if we were already selected, bail and save some work.
UITableViewCell *selectedCell = [aTableView cellForRowAtIndexPath:indexPath];
if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark) {
return;
}
// uncheck all visible cells.
for (UITableViewCell *cell in [aTableView visibleCells]) {
if (cell.accessoryType != UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
PAWMaptypeSelect maptypeForCell = [self maptypeForCell:indexPath];
}
}
@end
4 ответа
У вас ошибка с этим
// снять все видимые ячейки
for (UITableViewCell *cell in [aTableView visibleCells]) {
if (cell.accessoryType != UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
Здесь цикл for отменяет выбор всей ячейки. Вы должны проверить также раздел в цикле if
Вы можете установить тег для своей клетки, как это
cell.tag = indexPath.section;
и в течение цикла, если условие
for (UITableViewCell *cell in [aTableView visibleCells]) {
if (cell.accessoryType != UITableViewCellAccessoryNone && cell.tag == indexPath.section) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
Попробуй это, у меня получилось просто отлично:
-VARIABLES:
@property NSInteger checkedCellRow;
@property NSInteger checkedCellSection;
-функции:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (checkedCellSection == indexPath.section)
{
if (checkedCellRow == indexPath.row)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
checkedCellRow = indexPath.row;
checkedCellSection = indexPath.section;
[myTable reloadData];
}
Проблема в вашем коде состоит в том, что вы помечаете галочкой только строку для раздела 0, заменяя метод ниже, вы можете решить вашу проблему.
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = @"SettingsTableView";
if (indexPath.section == kPAWSettingsTableViewDistance) {
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
if ( cell == nil )
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier];
}
// Configure the cell.
cell.textLabel.text = [self distanceLabelForCell:indexPath];
if (self.filterDistance == 0.0) {
NSLog(@"We have a zero filter distance!");
}
PAWLocationAccuracy filterDistanceInFeet = self.filterDistance * ( 1 / kPAWFeetToMeters);
PAWLocationAccuracy distanceForCell = [self distanceForCell:indexPath];
if (abs(distanceForCell - filterDistanceInFeet) < 0.001 ) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
else if (indexPath.section == kPAWSettingsTableViewMaptype){
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
if ( cell == nil )
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier];
}
// Configure the cell.
cell.textLabel.text = [self maptypeLabelForCell:indexPath];
PAWLocationAccuracy filterDistanceInFeet = self.filterDistance * ( 1 / kPAWFeetToMeters);
PAWLocationAccuracy distanceForCell = [self distanceForCell:indexPath];
if (abs(distanceForCell - filterDistanceInFeet) < 0.001 ) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
else {
return nil;
}
}
На данный момент я нашел следующие ошибки
- Вы не сохраняете ячейку, выбранную для типа карты.
- То, как вы отмечаете свою ячейку, неверно.
- В выключателе вам не нужно использовать
break
послеreturn
заявление - В
case kPAWSettingsTableViewNumberOfSections:
ты должен вернутьсяkPAWSettingsTableViewNumberOfSections
Первые два дефекта вызывают много шаблонного кода. Я думаю, что вы должны хранить NSIndexPath
для каждого раздела, который выбран в качестве дополнительного @property
, Вместо того, чтобы снять все галочки и проверить нажатыми, вы можете сделать в tableView:didSelectRowAtIndexPath:
:
- Определите, какой из них должен быть выбран.
- Храните местное старое значение вашего
selectedIndexPath
, - + Изменить
selectedIndexPath
proprty для нового. - Перезагрузите оба ряда.
Затем вы должны добавить в tableView:cellForRowAtIndexPath:
следующий код:
if (indexPath.row == self.selectedIndexPath.row && indexPath.section == self.selectedIndexPath.section) {
// Change to checkmark.
} else {
// Change to not checked.
}
У меня очень похожий способ пометить ячейку в моем собственном проекте. Я надеюсь, что приведенный ниже код также поможет вам понять мой способ решения вашей проблемы:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (/*condition*/) {
[...]
}
else if (/*checkmark section*/) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CheckmarkCellId forIndexPath:indexPath];
cell.textLabel.text = [self labelForRow:indexPath.row];
cell.accessoryType = (indexPath.row == [self defaultAgglomerationIndex]) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
cell.imageView.image = (indexPath.row == [self selectedAgglomerationIndex]) ? [UIImage imageNamed:@"icoMap"] : [UIImage imageNamed:@"region"];
return cell;
}
else if (/*Another condition */) {
[...]
}
return nil;
}
И основной код в tableView:didSelectRowAtIndexPath:
(Я перезагружаю весь раздел)
self.selectedIndex = indexPath;
NSIndexSet *set = [NSIndexSet indexSetWithIndex:indexPath.section];
[self.tableView reloadSections:set withRowAnimation:UITableViewRowAnimationNone];