【问题标题】:Identifying table cells in a method识别方法中的表格单元格
【发布时间】:2023-09-02 21:45:01
【问题描述】:

我正在尝试在我的 ViewController 内的 UITableView 中的自定义单元格中实现 FlatUIKit,该单元格根据开关状态将值返回给 NSUserDefaults。作为一个常用的开关,我将方法“saveSwitchState”连接到 valueChanged 插座。问题在于我想将状态传递给用户默认值并使用标签作为键,但该方法无法访问单元格和标签。我已经尝试添加:

static NSString *CellIdentifier = @"Cell";
setupOneCell *cell = (setupOneCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

到方法,但仍然没有运气。如果有更好的方法来保存使用 valueChanged 方法的开关状态,我会全力以赴。下面是我的 ViewController 和自定义单元格。

ViewController.m:

#import "setup1ViewController.h"
#import "setup1TableView.h"
#import "setupOneCell.h"
#import "Social.h"
#import "FUISwitch.h"
#import "UIFont+FlatUI.h"
#import "UIColor+FlatUI.h"

@interface setup1ViewController ()

- (IBAction)saveSwitchState:(id)sender;

@end

@implementation setup1ViewController


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.oneTableView.dataSource = self;
    self.oneTableView.delegate = self;

    self.medias = [[NSMutableArray alloc] init];

    Social *media = [[Social alloc] init];
    media.socialMedia = @"Facebook";
    [self.medias addObject:media];

    media = [[Social alloc] init];
    media.socialMedia = @"Twitter";
    [self.medias addObject:media];

    media = [[Social alloc] init];
    media.socialMedia = @"Instagram";
    [self.medias addObject:media];

    media = [[Social alloc] init];
    media.socialMedia = @"Tumblr";
    [self.medias addObject:media];

    media = [[Social alloc] init];
    media.socialMedia = @"Gmail";
    [self.medias addObject:media];

    media = [[Social alloc] init];
    media.socialMedia = @"Linked In";
    [self.medias addObject:media];

    media = [[Social alloc] init];
    media.socialMedia = @"GitHub";
    [self.medias addObject:media];

    media = [[Social alloc] init];
    media.socialMedia = @"You Tube";
    [self.medias addObject:media];

    media = [[Social alloc] init];
    media.socialMedia = @"Vine";
    [self.medias addObject:media];

    media = [[Social alloc] init];
    media.socialMedia = @"SoundCloud";
    [self.medias addObject:media];


    //self.setup1Table.editing = YES;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.medias count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    setupOneCell *cell = (setupOneCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    cell.cellSwitch.onColor = [UIColor turquoiseColor];
    cell.cellSwitch.offColor = [UIColor cloudsColor];
    cell.cellSwitch.onBackgroundColor = [UIColor midnightBlueColor];
    cell.cellSwitch.offBackgroundColor = [UIColor silverColor];
    cell.cellSwitch.offLabel.font = [UIFont boldFlatFontOfSize:14];
    cell.cellSwitch.onLabel.font = [UIFont boldFlatFontOfSize:14];

    Social *media = (self.medias)[indexPath.row];

    cell.socialName.text = media.socialMedia;


    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    return;
}

- (IBAction)saveSwitchState:(id)sender
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    if ([cell.cellSwitch isOn])
        [defaults setBool:YES forKey:cellLabel];
    else
        [defaults setBool:NO forKey:cellLabel];
}

@end

setupOneCell.h:

#import <UIKit/UIKit.h>
#import "FUISwitch.h"
#import "UIFont+FlatUI.h"
#import "UIColor+FlatUI.h"

@interface setupOneCell : UITableViewCell

@property (weak, nonatomic) IBOutlet UILabel *socialName;
@property (weak, nonatomic) IBOutlet FUISwitch *cellSwitch;

@end

【问题讨论】:

    标签: ios objective-c uitableview nsuserdefaults uiswitch


    【解决方案1】:

    基本思想是让您的单元格监听开关值的变化,然后通过委托调用将该变化报告给您的视图控制器。然后在您的视图控制器中,您可以查找与该单元格关联的数据并使用它来修改NSUserDefaults

    如何做到这一点:

    在单元格的设置代码中,您应该将单元格添加为开关的目标,而不是让您的视图控制器成为目标。 (可能在您的单元格的-awakeFromNib 中,但它也可以在某种-configureWithSocialMedia: 方法中工作。)

    - (void)awakeFromNib {
        [self.cellSwitch addTarget:self action:@selector(switchValueChanged:) forControlEvents:UIControlEventValueChanged];
    }
    
    - (void)switchValueChanged:(id)sender {
        [self.delegate setupOneCell:self witchValueDidChange:[self.cellSwitch isOn]];
    }
    

    然后使用-setupOneCell:switchValueDidChange: 之类的方法创建一个协议,该方法传递您的单元格和开关值。让您的单元接受遵循此协议的委托。

    协议的代码如下:

    @protocol SetupOneCellDelegate;
    
    @interface setupOneCell : UITableViewCell
    
    @property (weak, nonatomic) IBOutlet UILabel *socialName;
    @property (weak, nonatomic) IBOutlet FUISwitch *cellSwitch;
    
    @property (weak, nonatomic) id<SetupOneCellDelegate> delegate;
    
    @end
    
    
    @protocol SetupOneCellDelegate <NSObject>
    
    - (void)setupOneCell:(setupOneCell *)cell switchValueDidChange:(BOOL)switchValue;
    
    @end
    

    现在,您的视图控制器已全部设置为在其开关值更改时从单元格获取回调。配置单元格时,请确保将视图控制器设置为委托:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";
        setupOneCell *cell = (setupOneCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    
        cell.cellSwitch.onColor = [UIColor turquoiseColor];
        cell.cellSwitch.offColor = [UIColor cloudsColor];
        cell.cellSwitch.onBackgroundColor = [UIColor midnightBlueColor];
        cell.cellSwitch.offBackgroundColor = [UIColor silverColor];
        cell.cellSwitch.offLabel.font = [UIFont boldFlatFontOfSize:14];
        cell.cellSwitch.onLabel.font = [UIFont boldFlatFontOfSize:14];
    
        Social *media = (self.medias)[indexPath.row];
    
        cell.socialName.text = media.socialMedia;
    
        cell.delegate = self;
    
        return cell;
    }
    

    最后实现委托方法:

    - (void)setupOneCell:(setupOneCell *)cell switchValueDidChange:(BOOL)switchValue {
        NSIndexPath *indexPath = [self.oneTableView indexPathForCell:cell];
        NSString *label = [self.medias[indexPath.row] socialMedia];
    
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        [defaults setBool:switchValue forKey:label];
    }
    

    【讨论】: