使用 nsuserdefault 在 uitableviewcell 中保存图像状态

Saving an image state in uitableviewcell using nsuserdefault

我已经为这个问题苦苦思索了几个星期,我不好意思地说,并且搜索了整个堆栈溢出和互联网,但找不到任何适合我的东西。我遇到了一些非常含糊的答案,说 "Well, use these two lines of code, then add these two lines, then maybe throw it into a property..." 到底是什么?没有人说过将代码放在哪里,也很少有人指出需要在 cellForRowAtIndexpath 中完成什么。我尝试了很多东西!

我只是想在我的表格视图单元格中保存 UIImage 的状态。基本上,用户可以点击 tableview 单元格中的图像,当他们这样做时,会弹出一个 UIAlertview。他们可以选择是否使用了表格视图中列出的交通工具类型。如果 'yes',图像颜色变为蓝色(而不是灰色),表明他们已经使用过它。或者,他们可以通过点击 'no' 取消 select 图像,然后图像恢复到灰色状态。我希望能够使用 nsuserdefaults 保留此操作,因为只有少量信息要保存(基本上只是图像状态)。我试过的任何东西都不会保存信息。我将在下面添加我的代码,并祝愿任何能帮助我的人幸福快乐!

或者,我从自定义 class 创建了运输对象。有没有办法在自定义 class 中设置一个布尔值,当用户选择是或否时动态更改它,然后更新自定义 class 以便保存信息?任何想法,将不胜感激!

主要ViewController

@interface MainTableViewController ()
{
    NSMutableArray *selectedImages;
}


@end

@implementation MainTableViewController

-(void)viewDidLoad
{
    [super viewDidLoad];

    _transportController = [[TransportDataController alloc] init];
    self.dataSource = _transportController.populateDataSource;
    self.title = @"Transportation Types";

   selectedImages = [[[NSUserDefaults standardUserDefaults] arrayForKey:@"selected"] mutableCopy];


}


-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _dataSource.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"mainCell";
    TransportCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {
        cell = [[TransportCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    Transport *transportData = [self.dataSource objectAtIndex:indexPath.row];
    cell.nameLabel.text = transportData.name;
    cell.transportImageView.image = transportData.transportImage;


    if (transportData.usedTransportIsSelected == NO)
    {
        cell.grayedImageView.image = transportData.usedTransportImage;


    }
    else if (transportData.usedTransportIsSelected == YES)
    {
        cell.grayedImageView.image = [UIImage imageNamed:@"stamp-color"];


    }


    UITapGestureRecognizer *grayedImageTouched = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(transportImageTapped:)];
    grayedImageTouched.numberOfTapsRequired = 1;
    cell.grayedImageView.tag = indexPath.row;
    [cell.grayedImageView addGestureRecognizer:grayedImageTouched];
    cell.grayedImageView.userInteractionEnabled = YES;



    return cell;
}


-(void)transportImageTapped:(UIGestureRecognizer *)gesture
{
    Transport *transportData = [self.dataSource objectAtIndex:gesture.view.tag];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:gesture.view.tag inSection:0];


    UIAlertController *transportAlert = [UIAlertController alertControllerWithTitle:@"Yes, it's true..." message:@"I have used this type of transport before." preferredStyle:UIAlertControllerStyleAlert];

    [transportAlert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){

        NSLog(@"cancel");

    }]];

    [transportAlert addAction:[UIAlertAction actionWithTitle:@"Yes" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){

        UIImage *darkImage = [UIImage imageNamed:@"stamp-color"];
        transportData.usedTransportImage = darkImage;
        transportData.usedTransportIsSelected = YES;
        [self.dataSource replaceObjectAtIndex:gesture.view.tag withObject:transportData];
        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];

        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        [defaults setBool:YES forKey:@"selected"];
        [defaults synchronize];

        NSLog(@"has taken this transport before");

    }]];

    [transportAlert addAction:[UIAlertAction actionWithTitle:@"No" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){

        UIImage *grayedImage = [UIImage imageNamed:@"stamp-grayed"];
        transportData.usedTransportImage = grayedImage;
        transportData.usedTransportIsSelected = NO;
        [self.dataSource replaceObjectAtIndex:gesture.view.tag withObject:transportData];
        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];

        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        [defaults setBool:NO forKey:@"selected"];
        [defaults synchronize];

        NSLog(@"has not taken this transport before");

    }]];

    [self presentViewController:transportAlert animated:YES completion:nil];

}

您修改 Transport class 可能更有意义;假设它附加了一些唯一标识符。

@interface Transport
@property (strong) id somethingThatUniquelyIdentifiesThisTransport;
@property (nonatomic) BOOL usedTransportIsSelected;
// ...
@end

@implementation Transport
- (void)setUsedTransportIsSelected:(BOOL)value {
  [[NSUserDefaults standardUserDefaults] setObject:@(value) forKey:self.somethingThatUniquelyIdentifiesThisTransport];
}

- (BOOL)usedTransportIsSelected {
  return [[[NSUserDefaults standardUserDefaults] objectForKey:self.somethingThatUniquelyIdentifiesThisTransport] boolValue];
}

// ...
@end

这是工作代码,希望对任何人都有帮助。

MainViewController

#import "MainTableViewController.h"
#import "TransportCell.h"

@interface MainTableViewController ()

@end

@implementation MainTableViewController

-(void)viewDidLoad
{
    [super viewDidLoad];

    _transportController = [[TransportDataController alloc] init];
    self.dataSource = _transportController.populateDataSource;
    self.title = @"Transportation Types";

}


-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _dataSource.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"mainCell";
    TransportCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {
        cell = [[TransportCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    Transport *transportData = [self.dataSource objectAtIndex:indexPath.row];
    cell.nameLabel.text = transportData.name;
    cell.transportImageView.image = transportData.transportImage;


    if (transportData.usedTransportIsSelected == NO)
    {
        cell.grayedImageView.image = transportData.usedTransportImage;
    }
    else if (transportData.usedTransportIsSelected == YES)
    {
        cell.grayedImageView.image = [UIImage imageNamed:@"stamp-color"];
    }


    UITapGestureRecognizer *grayedImageTouched = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(transportImageTapped:)];
    grayedImageTouched.numberOfTapsRequired = 1;
    cell.grayedImageView.tag = indexPath.row;
    [cell.grayedImageView addGestureRecognizer:grayedImageTouched];
    cell.grayedImageView.userInteractionEnabled = YES;


    return cell;
}


-(void)transportImageTapped:(UIGestureRecognizer *)gesture
{
    Transport *transportData = [self.dataSource objectAtIndex:gesture.view.tag];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:gesture.view.tag inSection:0];


    UIAlertController *transportAlert = [UIAlertController alertControllerWithTitle:@"Yes, it's true..." message:@"I have used this type of transport before." preferredStyle:UIAlertControllerStyleAlert];

    [transportAlert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){

        NSLog(@"cancel");

    }]];

    [transportAlert addAction:[UIAlertAction actionWithTitle:@"Yes" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){

        UIImage *darkImage = [UIImage imageNamed:@"stamp-color"];
        transportData.usedTransportImage = darkImage;
        transportData.usedTransportIsSelected = YES;
        [self.dataSource replaceObjectAtIndex:gesture.view.tag withObject:transportData];
        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];

        NSLog(@"has taken this transport before");

    }]];

    [transportAlert addAction:[UIAlertAction actionWithTitle:@"No" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){

        UIImage *grayedImage = [UIImage imageNamed:@"stamp-grayed"];
        transportData.usedTransportImage = grayedImage;
        transportData.usedTransportIsSelected = NO;
        [self.dataSource replaceObjectAtIndex:gesture.view.tag withObject:transportData];
        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];


        NSLog(@"has not taken this transport before");

    }]];

    [self presentViewController:transportAlert animated:YES completion:nil];

}

Transport.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface Transport : NSObject 

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) UIImage *transportImage;
@property (nonatomic, strong) UIImage *usedTransportImage;
@property (nonatomic) BOOL usedTransportIsSelected;

@end

Transport.m

#import "Transport.h"

@implementation Transport

-(void)setUsedTransportIsSelected:(BOOL)value
{
    [[NSUserDefaults standardUserDefaults] setObject:@(value) forKey:self.name];
}

-(BOOL)usedTransportIsSelected
{
    return [[[NSUserDefaults standardUserDefaults] objectForKey:self.name] boolValue];
}

@end

TransportDataController.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "Transport.h"

@interface TransportDataController : NSObject 

@property (nonatomic, strong) NSMutableArray *transportDataArray;

-(NSMutableArray *)populateDataSource;

@end

TransportDataController.m

#import "TransportDataController.h"

@implementation TransportDataController

-(NSMutableArray *)populateDataSource
{
    _transportDataArray = [[NSMutableArray alloc] init];
    Transport *transportData = [[Transport alloc] init];

    transportData.name = @"Bus";
    transportData.transportImage = [UIImage imageNamed:@"Bus"];
    transportData.usedTransportImage = [UIImage imageNamed:@"stamp-grayed"];
    [_transportDataArray addObject:transportData];

    transportData = [[Transport alloc] init];
    transportData.name = @"Helicopter";
    transportData.transportImage = [UIImage imageNamed:@"Helicopter"];
    transportData.usedTransportImage = [UIImage imageNamed:@"stamp-grayed"];
    [_transportDataArray addObject:transportData];

    transportData = [[Transport alloc] init];
    transportData.name = @"Truck";
    transportData.transportImage = [UIImage imageNamed:@"Truck"];
    transportData.usedTransportImage = [UIImage imageNamed:@"stamp-grayed"];
    [_transportDataArray addObject:transportData];

    transportData = [[Transport alloc] init];
    transportData.name = @"Boat";
    transportData.transportImage = [UIImage imageNamed:@"Boat"];
    transportData.usedTransportImage = [UIImage imageNamed:@"stamp-grayed"];
    [_transportDataArray addObject:transportData];

    transportData = [[Transport alloc] init];
    transportData.name = @"Bicycle";
    transportData.transportImage = [UIImage imageNamed:@"Bicycle"];
    transportData.usedTransportImage = [UIImage imageNamed:@"stamp-grayed"];
    [_transportDataArray addObject:transportData];

    transportData = [[Transport alloc] init];
    transportData.name = @"Motorcycle";
    transportData.transportImage = [UIImage imageNamed:@"Motorcycle"];
    transportData.usedTransportImage = [UIImage imageNamed:@"stamp-grayed"];
    [_transportDataArray addObject:transportData];

    transportData = [[Transport alloc] init];
    transportData.name = @"Plane";
    transportData.transportImage = [UIImage imageNamed:@"Plane"];
    transportData.usedTransportImage = [UIImage imageNamed:@"stamp-grayed"];
    [_transportDataArray addObject:transportData];

    transportData = [[Transport alloc] init];
    transportData.name = @"Train";
    transportData.transportImage = [UIImage imageNamed:@"Train"];
    transportData.usedTransportImage = [UIImage imageNamed:@"stamp-grayed"];
    [_transportDataArray addObject:transportData];

    transportData = [[Transport alloc] init];
    transportData.name = @"Car";
    transportData.transportImage = [UIImage imageNamed:@"Car"];
    transportData.usedTransportImage = [UIImage imageNamed:@"stamp-grayed"];
    [_transportDataArray addObject:transportData];

    transportData = [[Transport alloc] init];
    transportData.name = @"Scooter";
    transportData.transportImage = [UIImage imageNamed:@"Scooter"];
    transportData.usedTransportImage = [UIImage imageNamed:@"stamp-grayed"];
    [_transportDataArray addObject:transportData];

    transportData = [[Transport alloc] init];
    transportData.name = @"Caravan";
    transportData.transportImage = [UIImage imageNamed:@"Caravan"];
    transportData.usedTransportImage = [UIImage imageNamed:@"stamp-grayed"];
    [_transportDataArray addObject:transportData];

    return _transportDataArray;


}