我正在尝试制作类似于Apple's demo的配件视图,但我一定错过了一些东西,因为我点击时不会切换图像。它只是 flickers
不确定我错过了什么,我试图完全基于演示代码。
我不得不将几个字典更改为mutable并添加一个if cell null子句以使我的工作正常工作。
这些项目在tableview中正确获取和显示。
我已经改变了我改变的部分,我想我得到了所有这些。
任何帮助非常感谢。
我的代码:
标题声明:
@interface PollQueryController : UIViewController <UITableViewDataSource, UITableViewDelegate>
@interface PollQueryController ()
@property (nonatomic, strong) NSMutableArray *dataArray;
@end
@implementation PollQueryController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// NSString *path = [[NSBundle mainBundle] pathForResource:@"pollData" ofType:@"plist"];
// NSDictionary *pollsDictionary = [NSDictionary dictionaryWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"pollData" ofType:@"plist"]];
NSArray * pollsData = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"pollData" ofType:@"plist"]];
NSMutableArray * choices = [[[pollsData objectAtIndex:0] objectForKey:@"choices"] mutableCopy]; // mutable
// NSMutableArray *choices = [NSMutableArray arrayWithArray:choicesArray]; // Mutable
self.dataArray = choices;
NSLog(@"array: %@", self.dataArray);
// swipe gestures
UISwipeGestureRecognizer * Swiperight=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swiperight:)];
Swiperight.direction=UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:Swiperight];
UISwipeGestureRecognizer * Swipeleft=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeleft:)];
Swipeleft.direction=UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:Swipeleft];
self.title = @"Poll Query";
self.feedTableView.dataSource = self;
self.feedTableView.delegate = self;
self.feedTableView.backgroundColor = [UIColor whiteColor];
self.feedTableView.separatorColor = [UIColor colorWithWhite:0.9 alpha:0.6];
UIColor* mainColor = [UIColor colorWithRed:50.0/255 green:102.0/255 blue:147.0/255 alpha:1.0f];
NSString* fontName = @"Optima-Italic";
NSString* boldFontName = @"Optima-ExtraBlack";
UIFont* socialFont = [UIFont fontWithName:boldFontName size:10.0f];
UIColor* socialColor = [UIColor lightGrayColor];
}
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.dataArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath{
static NSString *kCustomCellID = @"MyCellID";
FeedCell3* cell = [tableView dequeueReusableCellWithIdentifier:kCustomCellID];
// i had to add this, whereas the demo doesnt do this.
if (cell == nil) {
cell = [[FeedCell3 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"feedcell3"];
}
NSMutableDictionary *item = [[self.dataArray objectAtIndex:indexPath.row] mutableCopy]; // mutable
cell.textLabel.text = [item objectForKey:@"text"];
[item setObject:cell forKey:@"cell"];
BOOL checked = [[item objectForKey:@"checked"] boolValue];
UIImage *image = (checked) ? [UIImage imageNamed:@"ticked24"] : [UIImage imageNamed:@"unticked24"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
button.frame = frame;
[button setBackgroundImage:image forState:UIControlStateNormal];
[button addTarget:self action:@selector(checkButtonTapped:event:) forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor clearColor];
cell.accessoryView = button;
UIColor* blueColor = [UIColor colorWithRed:47.0/255 green:168.0/255 blue:228.0/255 alpha:1.0f];
cell.textLabel.textColor = blueColor;
NSString* fontName = @"Optima-Italic";
NSString* boldFontName = @"Optima-ExtraBlack";
UIFont* socialFont = [UIFont fontWithName:boldFontName size:10.0f];
cell.textLabel.font = socialFont;
cell.textLabel.textAlignment = UITextAlignmentCenter;
return cell;
}
#pragma mark - UITableViewDelegate
- (void)checkButtonTapped:(id)sender event:(id)event
{
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self.feedTableView];
NSIndexPath *indexPath = [self.feedTableView indexPathForRowAtPoint: currentTouchPosition];
if (indexPath != nil)
{
[self tableView: self.feedTableView accessoryButtonTappedForRowWithIndexPath: indexPath];
}
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
NSMutableDictionary *item = [[self.dataArray objectAtIndex:indexPath.row] mutableCopy] ; // mutable
BOOL checked = [[item objectForKey:@"checked"] boolValue];
[item setObject:[NSNumber numberWithBool:!checked] forKey:@"checked"];
UITableViewCell *cell = [item objectForKey:@"cell"];
UIButton *button = (UIButton *)cell.accessoryView;
UIImage *newImage = (checked) ? [UIImage imageNamed:@"unticked24"] : [UIImage imageNamed:@"ticked24"];
[button setBackgroundImage:newImage forState:UIControlStateNormal];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self tableView: self.feedTableView accessoryButtonTappedForRowWithIndexPath: indexPath];
[self.feedTableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)swipeleft:(UISwipeGestureRecognizer*)gestureRecognizer
{
if(_hasVoted){
[self performSegueWithIdentifier: @"QueryToResults" sender: self];
}
}
-(void)swiperight:(UISwipeGestureRecognizer*)gestureRecognizer
{
[self performSegueWithIdentifier: @"friendsBackToPollSeg" sender: self];
}
@end
答案 0 :(得分:1)
这里的问题是,通过使用mutableCopy
,您每次都会实例化一个新对象。因此,在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
调用中,item的checked值始终为false。
我假设在某些时候也存在某种tableview reloadData。因此,它将accessoryView设置为已选中的图像,而不是重新加载它,并将其重置为未选中的值,因为对dataArray项的更改未持久化(因为它应用于对象的副本)。
长话短说,- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
和- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
中的项目不相同。
编辑:
@interface PollQueryController () {
NSMutableDictionary * _checkStates;
}
@property (nonatomic, strong) NSMutableArray *dataArray;
@end
@implementation PollQueryController
- (void)viewDidLoad {
[super viewDidLoad];
NSArray * pollsData = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"pollData" ofType:@"plist"]];
NSMutableArray * choices = [[[pollsData objectAtIndex:0] objectForKey:@"choices"] mutableCopy]; // mutable
self.dataArray = choices;
_checkStates = [[NSMutableDictionary alloc] init];
NSLog(@"array: %@", self.dataArray);
[…]
}
#pragma mark - UITableViewDataSource
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCustomCellID = @"MyCellID";
FeedCell3* cell = [tableView dequeueReusableCellWithIdentifier:kCustomCellID];
// i had to add this, whereas the demo doesnt do this.
if (cell == nil) {
cell = [[FeedCell3 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"feedcell3"];
}
NSDictionary * item = [self.dataArray objectAtIndex:indexPath.row]
cell.textLabel.text = [item objectForKey:@"text"];
NSNumber checkedState = [_checkStates objectForKey:@"item"];
BOOL checked = checkedState ? [checkedState boolValue] : NO;
UIImage *image = (checked) ? [UIImage imageNamed:@"ticked24"] : [UIImage imageNamed:@"unticked24"];
[…]
return cell;
}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *item = [self.dataArray objectAtIndex:indexPath.row];
NSNumber checkedState = [_checkStates objectForKey:item];
BOOL checked = checkedState ? YES : ![checkedState boolValue];
[_checkStates setObject:@(checked) forKey:item];
// You don't have a reference to the cell here anymore to update the cell accessoryView, but I believe it would be simpler to reload the cell (or the tableView)
// I'll go with the tableview there for the sake of simplicity, but feel free to update this
[tableView reloadData];
}
@end
答案 1 :(得分:0)
如果您不需要mutableCopy
即NSMutableDictionary *item = [self.dataArray objectAtIndex:indexPath.row];
,请在更改附件按钮点按中的checked
值后尝试重新编码单元格,请使用
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
更新单元格的方法
将- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
方法更改为
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
NSMutableDictionary *item = [self.dataArray objectAtIndex:indexPath.row];
BOOL checked = [[item objectForKey:@"checked"] boolValue];
[item setObject:[NSNumber numberWithBool:!checked] forKey:@"checked"];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
答案 2 :(得分:0)
哇。我发现为什么不使用mutableCopy它不适合我
原始数组不可变
NSArray * pollsData = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"pollData" ofType:@"plist"]];
改为mutable修正了问题。
NSMutableArray * pollsData = [NSMutableArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"pollData" ofType:@"plist"]];