ios - 为什么我的自定义配件按钮在点击时没有改变图像 (ios)?

标签 ios uibutton uitableview

我正在尝试制作类似于 Apple's demo 的附属 View ,但我一定错过了什么,因为我的点击时不会切换图像。它只是 flickers .

不确定我错过了什么,我试图完全基于演示代码。 我不得不将几个字典更改为可变的,并添加一个 if cell null 子句以使我的工作正常进行。
项目被提取并正确显示在 tableview 中。
我鼓励了我改变的部分,我想我得到了它们。

非常感谢任何帮助。

我的代码:

header 声明:

@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"]];
        <b>
        NSArray * pollsData = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"pollData" ofType:@"plist"]];
        NSMutableArray * choices = [[[pollsData objectAtIndex:0] objectForKey:@"choices"] mutableCopy]; // mutable</b>

    //    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];

    <b>// i had to add this, whereas the demo doesnt do this.

           if (cell == nil) {
               cell = [[FeedCell3 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"feedcell3"];
           }</b>


        <b>NSMutableDictionary *item = [[self.dataArray objectAtIndex:indexPath.row] mutableCopy];   // mutable</b>
        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
    {
        <b>NSMutableDictionary *item = [[self.dataArray objectAtIndex:indexPath.row] mutableCopy] ; // mutable</b>

        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

最佳答案

这里的问题是,通过使用 mutableCopy,您每次都会实例化一个新对象。因此,在您的 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 调用中,项目的检查值始终为 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

关于ios - 为什么我的自定义配件按钮在点击时没有改变图像 (ios)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21110039/

相关文章:

ios - setImageData 在 iOS 8.3 中失败

ios - 在 UITableView 单元格中检测点击并按住

ios - 以编程方式使用 UIButton 进行 3DTouch 预览和弹出

ios - 如果我只需要 1 个 UITableViewCell,我可以在不使用重用标识符和所有这些东西的情况下创建它吗?

swift - 带有 Tableview 的自定义 Xib 单元格不起作用

iphone - 如何卸载 UIViewController 的 View

ios - 访问 UIImagePickerController 相机 View 的顶部栏

swift - UIButton 在 Swift 3 中更新 UITableView

xcode - 如何为 UIButton 添加工具提示?

arrays - 无法使用 [NSIndexPath] 类型的索引为 [String] 类型的值添加下标 -prepareForSegue