为什么我的自定义配件按钮在敲击(ios)时不会改变图像?

时间:2014-01-14 09:33:30

标签: ios uibutton uitableview

我正在尝试制作类似于Apple's demo的配件视图,但我一定错过了一些东西,因为我点击时不会切换图像。它只是 flickers

不确定我错过了什么,我试图完全基于演示代码。 我不得不将几个字典更改为mutable并添加一个if cell null子句以使我的工作正常工作。
这些项目在tableview中正确获取和显示。
我已经改变了我改变的部分,我想我得到了所有这些。

任何帮助非常感谢。

我的代码:

标题声明:

@interface PollQueryController : UIViewController <UITableViewDataSource, UITableViewDelegate>

.m文件:




    @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

3 个答案:

答案 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)

如果您不需要mutableCopyNSMutableDictionary *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"]];