簡體   English   中英

UITableview不通過willdisplaycell選擇單元格

[英]UITableview not selecting cells through willdisplaycell

我正在嘗試通過加載與傳遞中單擊的單元格相對應的數字列表來預選表視圖中的單元格。 我從nsuserdefaults加載此文件,並使用willdisplaycell方法單擊單元格。 我包括了我用來執行此操作的tableviewcontroller類。

@implementation AllergenTableViewController

static NSMutableArray *data;

-(instancetype)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];

    if (self)
    {
        data = [[[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"DictKey"] allKeys] mutableCopy];
        self.allergens = [[NSMutableArray alloc] init];
    }

    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
     self.clearsSelectionOnViewWillAppear = NO;

    //first need to load in array to a number list, then convert it to index path list and set allergens equal to that
    NSMutableArray *allergenNumberList;

    allergenNumberList = [[[NSUserDefaults standardUserDefaults] objectForKey:@"allergens"] mutableCopy];

    if (allergenNumberList != nil)
    {
        for (NSNumber *num in allergenNumberList)
        {
            NSIndexPath *path = [NSIndexPath indexPathForRow:num.integerValue inSection:1]; //[NSIndexPath indexPathWithIndex:num.integerValue];

            if (![self.allergens containsObject:path])
            {
                [self.allergens addObject:path];
            }
        }
    }

    NSLog(@"loading view, allergens size: %lu", [self.allergens count]);
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([self.allergens containsObject:indexPath])
    {
        [cell setSelected:YES animated:NO];
    }
}

....

// the cell will be returned to the tableView
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: @"allergenslabel"forIndexPath:indexPath];

    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"allergenslabel"];
        [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
    }

    cell.textLabel.text = [NSString stringWithFormat:@"%@", data[indexPath.row]];

    return cell;
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSMutableArray *arr = [[NSMutableArray alloc] init];

    for (NSIndexPath *idx in self.allergens)
    {
        [arr addObject:[NSNumber numberWithInteger:idx]];
    }

    [[NSUserDefaults standardUserDefaults] setObject:arr forKey:@"allergens"];
    NSLog(@"saving");
    NSLog(@"allergens count: %lu", [self.allergens count]);
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

    //contains isnt working because the index pths arent the same but have the same row numbers so check those instead
    if (cell.accessoryType == UITableViewCellAccessoryCheckmark)
    {
        cell.accessoryType = UITableViewCellAccessoryNone;

        if ([self.allergens containsObject:indexPath])
        {
            [self.allergens removeObject:indexPath];
        }
    }
    else
    {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;

        if (![self.allergens containsObject:indexPath])
        {
            [self.allergens addObject:indexPath];
            NSLog(@"adding object");
        }
        else
        {
            NSLog(@"object already in allergens list");
        }
    }
}

@end

問題是,當我返回導航控制器並再次移至表格視圖時,已選中行arent,但是如果我在導航控制器中返回並返回,則默認情況下將選擇它們(我沒有為做到這一點做任何事情)。

更新:

我仔細研究並排除了一些並不實際相關的通用方法。

當您返回導航控制器時,視圖控制器將被釋放,因此所選行上的數據將丟失。 向前導航到此頁面將實例化視圖控制器的新實例。 那不再是您以前看到的同一張桌子。 當您在導航中繼續前進(在堆棧上扔一個新的視圖控制器)時,帶有表的視圖控制器將保留在導航堆棧中,因此數據在您離開時仍然存在。 您將需要尋找其他地方來保存數據並將其傳遞給這個新實例。

@Andrew McKinley的答案是完全正確的,因此提供一個解決方案,您可以使用單例來保存所選的單元格。

文件>新建>文件>可可類>類:單例子類:NSObject

// Singleton.h    

#import <Foundation/Foundation.h>

@interface Singleton : NSObject
+ (Singleton *)shared;
@property (strong, nonatomic) NSMutableArray *allergens;
@end

// Singleton.m

#import "Singleton.h"

@implementation Singleton

static Singleton *sharedInstance = nil;

+ (Singleton*)shared
{
    @synchronized(self)
    {
        if( sharedInstance == nil )
        {
            sharedInstance = [[Singleton alloc] init];
        }
        return sharedInstance;
    }
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.allergens = [[NSMutableArray alloc] init];
    }
    return self;
}

現在,您只需要將Singleton.h導入您的AllergenTableViewController類,並按如下所示調用allergens數組:

[[Singleton shared].allergens addObject:@"obj"];

什么是辛格爾頓? “在軟件工程中,單例模式是一種將類的實例化限制為一個對象的設計模式。當僅需要一個對象來協調整個系統中的動作時,這將非常有用。” 鏈接

因此,事實證明,我對NSIndexPath的比較或路徑到數字的轉換存在問題。 我添加了包裝程序來檢查我的過敏原數組中的包容性(不使用NSMutableArray的containsObject:方法和擴展名NSIndexPath的isEqual方法,而是使用行比較),現在問題似乎已解決。 首次加載tableview時,將調用willDisplayCell:並檢查我的單元格。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM