问题描述
我有一个简单的 UITableViewController
,在 UITableView
中有一些静态单元格.UITableView
正在由另一个 UITableViewController
的 prepareForSegue
填充.这个 UITableViewController
有两个部分,其中第一部分是字符串的 NSMutableArray
,第二部分是包含 .txt 文件的 NSMutableArray
用字符串.一些语言"只有一个部分,而其他语言"有两个.UITableView
没有什么特别之处.使用本教程:
一旦用户选择了星形图像,我希望单元格本身有 UIImage,表示该单元格已加星标.
这里有一些代码,以 cellForRowAtIndexPath
静态 NSString *strCellIdentifier = @"CustomLeafletVideoCell";CustomLeafletVideoTableViewCell *customCell = (CustomLeafletVideoTableViewCell *)[tableView dequeueReusableCellWithIdentifier:strCellIdentifier];self.rightUtilityButton = [NSMutableArray new];if (![[NSUserDefaults standardUserDefaults] boolForKey:@"Favourite"]){[self.rightUtilityButton sw_addUtilityButtonWithColor:[UIColor colorWithRed:1.0f green:0.0f blue:0.0f alpha:1.0]图标:[UIImage imageNamed:@"[email protected]"]];}else if ([[NSUserDefaults standardUserDefaults] boolForKey:@"Favourite"]){[self.rightUtilityButton sw_addUtilityButtonWithColor:[UIColor colorWithRed:1.0f green:0.0f blue:0.0f alpha:1.0]图标:[UIImage imageNamed:@"[email protected]"]];}customCell.rightUtilityButtons = self.rightUtilityButton;customCell.delegate = self;
当用户点击单元格中的图像时,此方法会触发:
- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index{开关(索引){案例0:{self.selectedRowCollection = [[NSMutableDictionary alloc] init];NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];CustomLeafletVideoTableViewCell *cell = (CustomLeafletVideoTableViewCell*)[self.tableView cellForRowAtIndexPath:indexPath];//我们创建一个新的 NSString 并将其分配给自定义标签的文本(从 cellForRow 方法获得)NSString *cellTitle = cell.customCellLabel.text;NSLog(@"文本为 %@", cellTitle);NSManagedObjectContext *context = [self managedObjectContext];收藏夹 *favourites = [NSEntityDescription insertNewObjectForEntityForName:@"Favourites" inManagedObjectContext:context];favourites.title = cellTitle;NSError *error = nil;if (![context save:&error]){//错误}[单元格 hideUtilityButtonsAnimated:YES];[self.tableView reloadData];}}
我将标题"存储在 Core Data 中.
问题
当我滑动单元格并按下星形图像时,它不会在指定区域加载带有 UIImageView
的单元格.它没有的原因是因为我真的不明白该怎么做.
我理解答案表明我应该创建一个自定义类,虽然我理解其背后的理论,但我无法理解如何正确地实际实现它.
我查看了此参考:使用 BOOL 对象在 NSMutableArray 中确定单元格状态 以在选择单元格时使用复选标记作为附件.这行得通,但它会在第一部分和第二部分在同一个相应的单元格上放置一个复选标记.
我发现我可以从 indexPath.row
和 indexPath.section
获得确切的行号和节号,但我只是不确定如何完全处理这些信息.我总是可以将 isFavourite
BOOL
添加到 Core Data
模型中,但我如何在 cellForRowAtIndexPath 中实际设置它?代码>
所以总结一下,对于我提出这个问题的 250 赏金,我需要了解如何:
- 用图片设置具体的
indexPath.row
和indexPath.section
, - 维护它,这样每次我回到这个
UITableViewController
时,星星都在相应的单元格上
我是这里的新手,所以如果您乐于提供尽可能多的信息,我将不胜感激.
另外,我对之后如何处理收藏夹没有问题;这行得通 - 当一个单元格被标记为收藏时,我只需要将图像放到单元格上.
任何指导将不胜感激.
更新
这是我设置收藏夹的代码:
self.isFavourite = @(!self.isFavourite.boolValue);
其中 self.isFavourite
是在此 UITableViewController
上创建的 NSNumber
属性.
在cellForRowAtIndexPath
中:
customCell.customCellLabel.text = [NSString stringWithFormat:@"%@",[self.availableLeaflets objectAtIndex:indexPath.row]];if (self.isFavourite.boolValue){customCell.accessoryType = UITableViewCellAccessoryCheckmark;}别的{customCell.accessoryType = UITableViewCellAccessoryNone;}
这里的代码是从 self.availableLeaflets
设置标题.这可以在单元格上设置复选标记,但问题是,当我回到这个 UITableViewController
时,复选标记并未保留在所选单元格上.
这里,self.availableLeaflets
是一个 NSMutableArray
,它从前面的 UITableViewController
prepareForSegue 填充和设置>.
当用户点击一个单元格中的星号时,您的代码会将所有单元格标记为收藏,因为您在 UserDefaults 中只存储了 1 个键.
您必须单独存储每个单元格的收藏状态.每个单元格必须有自己的最喜欢的"布尔值.
更新:
这是一个关于如何在不使用 Core Data 的情况下实现你想要的工作示例.为了清楚起见,我简化了示例:
- tableview 显示单元格的标题.如果某个单元格是收藏夹,则会显示复选标记附件视图.
- 要标记一个单元格,您只需选择它.(我省略了整个按钮代码以保持示例简单).如果您再次选择该单元格,则会将其从收藏夹中删除
这是你必须做的:
#import "ViewController.h"#import <CoreData/CoreData.h>#import "细胞数据.h"#import "AppDelegate.h"@interface ViewController() <UITableViewDataSource, UITableViewDelegate>@property (nonatomic) UITableView *tableView;@property (nonatomic) NSMutableDictionary *favoritesDict;@property(非原子)NSInteger 上下文;@property (nonatomic) NSString *language;@结尾@implementation 视图控制器- (void)viewDidLoad {[超级视图DidLoad];//设置表格视图self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds];self.tableView.dataSource = 自我;self.tableView.delegate = self;[self.tableView registerClass:[UITableViewCell 类] forCellReuseIdentifier:@"Cell"];[self.view addSubview:self.tableView];//在用户默认设置中设置收藏夹字典(如果它不存在)if ([[NSUserDefaults standardUserDefaults] valueForKey:@"favoritesDict"] == nil) {[[NSUserDefaults standardUserDefaults] setObject:@{} forKey:@"favoritesDict"];}//设置当前表格视图的语言self.language = @"en";//从用户默认值加载收藏夹self.favoritesDict = [[[NSUserDefaults standardUserDefaults] valueForKey:@"favoritesDict"] mutableCopy];}//此方法更改给定索引路径上单元格的收藏状态- (void)toggleFavoriteStateForCellAtIndexPath:(NSIndexPath *)indexPath {//切换单元格的收藏状态NSString *key = [NSString stringWithFormat:@"%@_%ld_%ld", self.language, (long)indexPath.section, (long)indexPath.row];if (self.favoritesDict[key] == nil) {self.favoritesDict[key] = @(1);} 别的 {[self.favoritesDict removeObjectForKey:key];}//保存更改[[NSUserDefaults standardUserDefaults] setObject:self.favoritesDict forKey:@"favoritesDict"];//重新加载单元格[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];}#pragma 标记 - UITableViewDataSource- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {返回 2;}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {返回 10;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];//将文本添加到您的单元格//设置收藏状态NSString *key = [NSString stringWithFormat:@"%@_%ld_%ld", self.language, (long)indexPath.section, (long)indexPath.row];if (self.favoritesDict[key]) {//显示最喜欢的图片cell.accessoryType = UITableViewCellAccessoryCheckmark;//对于这个例子:显示复选标记} 别的 {//隐藏最喜欢的图片cell.accessoryType = UITableViewCellAccessoryNone;//对于这个例子:隐藏复选标记}返回单元格;}#pragma 标记 - UITableViewDelegate//当用户选择单元格时,切换单元格的收藏状态- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {[tableView deselectRowAtIndexPath:indexPath 动画:YES];[self toggleFavoriteStateForCellAtIndexPath:indexPath];}@结尾
此示例适用于具有多个部分的表.它使用 NSDictionary 并将收藏的单元格存储在具有以下语法 LANGUAGE_SECTION_ROW
的键中.要检查一个单元格是否被标记为收藏,只需检查字典中是否存在相关键的对象.该键的实际值无关紧要.您只需检查密钥.
只需确保在 viewDidLoad
中设置语言字符串即可.
I have a simple UITableViewController
with some static cells in the UITableView
. The UITableView
is being populated by another UITableViewController
's prepareForSegue
. There are two sections to this UITableViewController
, where the first section is a NSMutableArray
of strings and the second section is a NSMutableArray
containing a .txt file with strings. Some "languages" will only have one section and others will have two. There's nothing else fancy about the UITableView
. With the use of this tutorial: http://www.appcoda.com/swipeable-uitableviewcell-tutorial/#disqus_thread, I have managed to implement custom gestures on the cell, so I can swipe the cell to mark it as favourite. I had to implement the use of the code in that tutorial to change the default behaviour from Delete to Star, as can be seen in the screenshot below:
Once a user has selected the star image, I want there to be UIImage on the cell itself, representing that this cell has been starred.
Here's some code, starting with the cellForRowAtIndexPath
static NSString *strCellIdentifier = @"CustomLeafletVideoCell";
CustomLeafletVideoTableViewCell *customCell = (CustomLeafletVideoTableViewCell *)[tableView dequeueReusableCellWithIdentifier:strCellIdentifier];
self.rightUtilityButton = [NSMutableArray new];
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"Favourite"])
{
[self.rightUtilityButton sw_addUtilityButtonWithColor:
[UIColor colorWithRed:1.0f green:0.0f blue:0.0f alpha:1.0]
icon:[UIImage imageNamed:@"[email protected]"]];
}
else if ([[NSUserDefaults standardUserDefaults] boolForKey:@"Favourite"])
{
[self.rightUtilityButton sw_addUtilityButtonWithColor:
[UIColor colorWithRed:1.0f green:0.0f blue:0.0f alpha:1.0]
icon:[UIImage imageNamed:@"[email protected]"]];
}
customCell.rightUtilityButtons = self.rightUtilityButton;
customCell.delegate = self;
When the user taps the image in the cell, this method fires off:
- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index
{
switch (index) {
case 0:
{
self.selectedRowCollection = [[NSMutableDictionary alloc] init];
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
CustomLeafletVideoTableViewCell *cell = (CustomLeafletVideoTableViewCell*)[self.tableView cellForRowAtIndexPath:indexPath];
// We create a new NSString and assign it to the custom label's text (which is obtained from the cellForRow method)
NSString *cellTitle = cell.customCellLabel.text;
NSLog(@"The text is %@", cellTitle);
NSManagedObjectContext *context = [self managedObjectContext];
Favourites *favourites = [NSEntityDescription insertNewObjectForEntityForName:@"Favourites" inManagedObjectContext:context];
favourites.title = cellTitle;
NSError *error = nil;
if (![context save:&error])
{
// Error
}
[cell hideUtilityButtonsAnimated:YES];
[self.tableView reloadData];
}
}
I am storing the "title" in Core Data.
Issue
When I swipe the cell and press the star image, it doesn't load up the cell with the UIImageView
in the designated area. The reason it doesn't is because I truly don't understand what to do.
I understand the answer is indicating that I should create a custom class and while I understand the theory behind that, I cannot understand how to actually implement this appropriately.
I've looked at this reference: Using BOOL objects in NSMutableArray to determine cell statuses to use a checkmark as the accessory when a cell is selected. This works, but it places a checkmark in the first section and second section on the same corresponding cell.
I've figured out I can get the exact row number and section number from indexPath.row
and indexPath.section
, but I'm just not sure how to tackle this information at all. I could always add a isFavourite
BOOL
to the Core Data
Model, but how do I actually set that in the cellForRowAtIndexPath?
So to conclude, and for the 250 bounty I'm putting on this question, I need to understand how:
- Set the specific
indexPath.row
andindexPath.section
with the image, and - Maintain it so that every time I come back to this
UITableViewController
, the star is on the appropriate cell
I'm kind of a newbie here, so if you're happy to help with as much information as you can, I'd really appreciate that.
Also, I'm not having issues with what to do with the Favourite after; that works - I just need to get the image onto the cell when a cell has been marked as favourite.
Any guidance would be appreciated.
Update
This is the code I have for setting the favourites:
self.isFavourite = @(!self.isFavourite.boolValue);
Where self.isFavourite
is a NSNumber
property created on this UITableViewController
.
In the cellForRowAtIndexPath
:
customCell.customCellLabel.text = [NSString stringWithFormat:@"%@",[self.availableLeaflets objectAtIndex:indexPath.row]];
if (self.isFavourite.boolValue)
{
customCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
customCell.accessoryType = UITableViewCellAccessoryNone;
}
The code here is setting the titles from the self.availableLeaflets
. This works to set the checkmark on the cell, but the problem is, when I come back to this UITableViewController
, the checkmark hasn't persisted on the selected cell.
Here, self.availableLeaflets
is a NSMutableArray
that gets populated and set from the prepareForSegue
in the previous UITableViewController
.
Your code marks all cells as favorite when a user taps on the star in one cell because you store only 1 key in the UserDefaults.
You have to store the favorite state for each cell individually. Each cell must have its own 'favorite' boolean value.
Update:
This is a working example on how to achieve want you want without using Core Data. I simplified the example for clarity reasons:
- The tableview shows the title of the cell. If a cell is a favorite, it shows the checkmark accessory view.
- To mark a cell you simply select it. (I ommitted the whole button code the keep the example simple). If you select the cell a second time it is removed from the favorites
Here's what you have to do:
#import "ViewController.h"
#import <CoreData/CoreData.h>
#import "CellData.h"
#import "AppDelegate.h"
@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic) UITableView *tableView;
@property (nonatomic) NSMutableDictionary *favoritesDict;
@property (nonatomic) NSInteger context;
@property (nonatomic) NSString *language;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// setup the table view
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
self.tableView.dataSource = self;
self.tableView.delegate = self;
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
[self.view addSubview:self.tableView];
// setup the favorites dictionary in user defaults (if it does not exist)
if ([[NSUserDefaults standardUserDefaults] valueForKey:@"favoritesDict"] == nil) {
[[NSUserDefaults standardUserDefaults] setObject:@{} forKey:@"favoritesDict"];
}
// set the language of your current table view
self.language = @"en";
// load favorites from user defaults
self.favoritesDict = [[[NSUserDefaults standardUserDefaults] valueForKey:@"favoritesDict"] mutableCopy];
}
// this method changes the favorite state of the cell at a given index path
- (void)toggleFavoriteStateForCellAtIndexPath:(NSIndexPath *)indexPath {
// toggle the favorite state of the cell
NSString *key = [NSString stringWithFormat:@"%@_%ld_%ld", self.language, (long)indexPath.section, (long)indexPath.row];
if (self.favoritesDict[key] == nil) {
self.favoritesDict[key] = @(1);
} else {
[self.favoritesDict removeObjectForKey:key];
}
// save the change
[[NSUserDefaults standardUserDefaults] setObject:self.favoritesDict forKey:@"favoritesDict"];
// reload the cell
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
// add the text to your cell
// set up favorite state
NSString *key = [NSString stringWithFormat:@"%@_%ld_%ld", self.language, (long)indexPath.section, (long)indexPath.row];
if (self.favoritesDict[key]) {
// show the favorite image
cell.accessoryType = UITableViewCellAccessoryCheckmark; // for this example: show checkmark
} else {
// hide the favorite image
cell.accessoryType = UITableViewCellAccessoryNone; // for this example: hide checkmark
}
return cell;
}
#pragma mark - UITableViewDelegate
// toggle the favorite state of the cell when the user selects it
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self toggleFavoriteStateForCellAtIndexPath:indexPath];
}
@end
This example works for tables with multiple sections. It uses a NSDictionary and stores favorited cells in a key that has the following syntax LANGUAGE_SECTION_ROW
. To check if a cell is marked as favorite just check if there is a object for the related key in the dictionary. The actual value of that key does not matter. You just check for the key.
Just make sure that you set the language string in viewDidLoad
.
这篇关于事件发生时更改特定 UITableViewCell 的 UIImage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!