UITableViewCell - отметьте одну строку в каждом разделе

У меня есть 2 раздела и 3 строки в следующем:

  1. ПОИСК РАССТОЯНИЯ

    • 250 футов

    • 1000 футов

    • 4000 футов

  2. ТИП КАРТЫ

    • стандарт

    • спутник

    • Гибридный

Я хочу иметь одну галочку для строки на раздел, но мой текущий код снимет все видимые ячейки для всего табличного представления и оставит одну выбранную строку с галочкой. Другими словами, у меня будет одна галочка для всей таблицы (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;
}
}

На данный момент я нашел следующие ошибки

  1. Вы не сохраняете ячейку, выбранную для типа карты.
  2. То, как вы отмечаете свою ячейку, неверно.
  3. В выключателе вам не нужно использовать break после return заявление
  4. В case kPAWSettingsTableViewNumberOfSections: ты должен вернуться kPAWSettingsTableViewNumberOfSections

Первые два дефекта вызывают много шаблонного кода. Я думаю, что вы должны хранить NSIndexPathдля каждого раздела, который выбран в качестве дополнительного @property, Вместо того, чтобы снять все галочки и проверить нажатыми, вы можете сделать в tableView:didSelectRowAtIndexPath::

  1. Определите, какой из них должен быть выбран.
  2. Храните местное старое значение вашего selectedIndexPath,
  3. + Изменить selectedIndexPath proprty для нового.
  4. Перезагрузите оба ряда.

Затем вы должны добавить в 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];
Другие вопросы по тегам