ios - 如何在自定义表格 View 单元格中保留图像的选定状态?

标签 ios objective-c uitableview uiimageview

好吧,我有新的困境。我一直在搜索 S.O.找到答案,但我似乎无法使用任何代码。我还查看了许多教程和其他资源,但似乎找不到任何帮助。

事情是这样的:我有一个带有带有自定义对象的自定义单元格的表格 View 。自定义单元格包含一个图像,可选择该图像以指示是否使用了单元格中列出的运输类型。图像从灰色的“未选中”状态变为蓝色的“选中”状态(或从“选中”变回“未选中”)。图像上的点击手势会触发警报 View ,用户可以在其中选择"is"或“否”。然后,警报 View 会导致图像更改为“已选择”或“未选择”状态,本质上就像一个复选标记。这一切都很完美。 (我添加了警报 View 作为防止在图像上无意点击手势的保护措施)。

http://tinypic.com/r/s5d3s3/8

当单元格在滚动过程中消失然后再次出现时,就会出现问题,图像变为取消选择状态。很多人都问过这个问题。看起来我需要: (1) 设置一个可变数组来保存选择 (2) 在 cellForRowAtIndexPath 中执行一些检查以告诉单元格要显示什么 (3) 并在某处设置所选图像的状态,以便将其添加到可变数组中。

我已经尝试从一些给定的答案中实现想法,但其中很多都使用按钮或电池配件。部分问题是在哪里实现这些代码,因为我已经在图像上触发了手势识别器和警报 View 。此外,将选择保存到 nsuserdefaults 是否也会在滚动期间保持图像的状态,或者我是否需要分别处理这两个问题? (意思是,添加代码以在滚动期间保持状态以及保存到 nsuserdefaults 的代码)。我试过一些 S.O.使用 nususerdefaults 的答案,但有同样的问题......我应该把这段代码放在哪里?如何保存图像状态而不是保存按钮状态或单元格附件状态?

我还想指出,tableview 嵌入在导航 Controller 中,每个单元格都转到详细 View ,这在将代码添加到 didSelectCellAtIndexPath(大多数 S.O. 答案包括)时增加了问题。我如何挑出被点击的图像而不是整个单元格(这通常会导致在选择图像时出现转场)。

任何形式的帮助将不胜感激!!提前谢谢你。 :)

下面是我的全部代码:

**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;

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

@end


**TRANSPORTCELL.h**

#import <UIKit/UIKit.h>

@interface TransportCell : UITableViewCell

@property (nonatomic, weak) IBOutlet UILabel *nameLabel;
@property (nonatomic, weak) IBOutlet UIImageView *transportImageView;
@property (nonatomic, weak) IBOutlet UIImageView *grayedImageView;

@end


**MAINTABLEVIEWCONTROLLER.h**

#import <UIKit/UIKit.h>
#import "Transport.h"
#import "TransportDataController.h"
#import "DetailTableViewController.h"

@interface MainTableViewController : UITableViewController

@property (nonatomic, strong) TransportDataController *transportController;
@property (nonatomic, strong) NSMutableArray *dataSource;

@end


**MAINTABLEVIEWCONTROLLER.m**

#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;
    cell.grayedImageView.image = transportData.usedTransportImage;

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


    return cell;
}


-(void)transportImageTapped:(UIGestureRecognizer *)gesture
{
    UIImageView *selectedImageView = (UIImageView *)[gesture view];
    UIImage *grayedImage = [UIImage imageNamed:@"stamp-grayed"];
    UIImage *darkImage = [UIImage imageNamed:@"stamp-color"];

    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){

        if (selectedImageView.image == grayedImage)
        {
            selectedImageView.image = grayedImage;
            [selectedImageView setImage:grayedImage];

        }
        else
        {
            selectedImageView.image = darkImage;
            [selectedImageView setImage:darkImage];

        }

        if (selectedImageView.image == darkImage)
        {
            selectedImageView.image = darkImage;
            [selectedImageView setImage:darkImage];

        }
        else
        {
            selectedImageView.image = grayedImage;
            [selectedImageView setImage:grayedImage];

        }

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


    }]];

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

        if (selectedImageView.image == darkImage)
        {
            selectedImageView.image = grayedImage;
            [selectedImageView setImage:grayedImage];

        }
        else
        {
            selectedImageView.image = grayedImage;
            [selectedImageView setImage:grayedImage];
        }

        if (selectedImageView.image == grayedImage)
        {
            selectedImageView.image = grayedImage;
            [selectedImageView setImage:grayedImage];
        }

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

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

}


-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"showDetail"])
    {
        DetailTableViewController *detailController = [segue destinationViewController];
        detailController.transport = [self.dataSource objectAtIndex:[self.tableView indexPathForSelectedRow] .row];
    }
}

@end

最佳答案

远离细节,想想你在做什么。

TableView 显示有关有序集合的信息。

事物就是数据模型。 TableView 是 View 对象, View Controller 是MVC设计模式中的 Controller 对象。

当用户以需要进行持久更改的方式与 View 交互时, Controller 应记录模型中的更改并告诉 View 更新其外观。

然后,如果单元格滚动到屏幕外然后又回到屏幕上,则数据源应使用数据模型中该条目的新状态设置回收单元格。

对于非分段 TableView ,将数据模型存储为某种数据对象的 NSArray 是很常见的。您可以创建自定义数据容器对象或只使用字典。

假设我们有一个自定义数据对象。

只需向您的数据对象添加一个属性,以告知运输项目是否已被使用。

当用户点击 View 对象时, View Controller 应通过更改特定索引路径的数据模型对象的“已使用”属性来响应来自手势识别器的消息,然后告诉 View 重绘本身。

在您的 cellForRowAtIndexPath 方法中,根据“已使用”标志的状态设置 View 对象。由于您将状态更改保存到数据模型中,下次用户在您的表数据中显示给定索引的单元格时,它会显示更改后的状态。

关于ios - 如何在自定义表格 View 单元格中保留图像的选定状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27586332/

相关文章:

iphone - 如何在运行时(以编程方式)在 iPhone 应用程序中切换 Wi-Fi 网络

IOS 谷歌地图相机不指向标记

ios - 仅在 iOS 9 上崩溃 : [MKPlacemark initWithCoordinate:]: unrecognized selector

ios - 将 NSArray 值转换为 int

ios - 如何在表格 View 中编辑一行的文本内容?

ios - UITableViewCell 中 UITextView 的奇怪行为

ios - 以编程方式调用 tableView 单元格的 .delete editorialStyle

ios - 如何使用 ARKit/swift ViewController 创建 React Native 组件?

ios - 如何让 UITextView 检测主题标签?

ios - 无法找到 ScrollView 属性以了解 ScrollView 滚动了多少像素