自定义 UITableView 的意外行为

发布于 2024-10-28 01:15:20 字数 6689 浏览 3 评论 0原文

我正在创建一个实现自定义 UITableView 的应用程序。我完成此操作的方法如下:

我创建了一个 UINavigationController。此 UINavigationController 推送实现 UITableViewDelegate 和 UITableViewDataSource 的 UIViewController。我为此 UIViewController 创建了一个 .xib,因此 UIViewController 有 3 个文件:TestTableViewController.h、TestTableViewController.m 和 TestTableViewController.xib。

TestTableViewController.xib 只有一个 UITableView 链接到名为 testTableView 的 IBOutlet UITableView,并且此 UITableView 数据源和委托链接到文件的所有者(TestTableViewController)。

另外,我还实现了自定义 UITableViewCell。我创建了一个名为 TestCell.xib 的空 .xib 文件,在其中放置了一个 UITableViewCell 并插入了一个 UIView、一个 UILabel、一个 UIImageView 和一个 UISwitch。然后我创建了一个继承自 UITableViewCell 的类,如下所示(我将 TestCell.xib 的视图定义为 TestCell 类并将标识符设置为 TestCellIdentifier):

TestCell.h:

#import <UIKit/UIKit.h>

#define kTestHeight 40


@interface TestCell : UITableViewCell {
    UIImageView *testImage;
    UILabel *testLabel;
}

@property (nonatomic, retain) IBOutlet UIImageView *testImage;
@property (nonatomic, retain) IBOutlet UILabel *testLabel;

@end

TestCell.m:

#import "TestCell.h"


@implementation TestCell

@synthesize testImage, testLabel;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

- (void)dealloc
{
    [self.testLabel release];
    [self.testImage release];
    [super dealloc];
}

@end

我实现所有 TestTableViewController 如下:

TestTableViewController.h:

#import <UIKit/UIKit.h>


@interface TestTableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
    NSArray *labels;
    NSArray *images;
    UITableView *testTableView; // this is the UITableView linked in the NIB
}

@property (nonatomic, retain) NSArray *labels, *images;
@property (nonatomic, retain) IBOutlet UITableView *testTableView;

@end

TestTableViewController .m:

#import "TestTableViewController.h"
#import "TestCell.h"


@implementation TestTableViewController

@synthesize labels, images;
@synthesize testTableView;

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

- (void)dealloc
{
    [self.labels release];
    [self.images release];
    [self.testTableView release];
    [super dealloc];
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    self.title = @"Test";
    self.labels = [[NSArray alloc] initWithObjects:
                    @"Test 1",
                    @"Test 2",
                    @"Test 3", 
                    @"Test 4",
                    @"Test 5",
                    @"Test 6",
                    @"Test 7",
                    @"Test 8",
                    @"Test 9",
                    @"Test 10",
                    @"Test 11",
                    @"Test 12",
                    @"Test 13",
                    @"Test 14",
                    @"Test 15",
                    @"Test 16",
                    @"Test 17", nil];
    self.images = [[NSArray alloc] initWithObjects:
                         [UIImage imageNamed:@"empty1.png"],
                         [UIImage imageNamed:@"empty2.png"],
                         [UIImage imageNamed:@"empty3.png"],
                         [UIImage imageNamed:@"empty4.png"],
                         [UIImage imageNamed:@"empty5.png"],
                         [UIImage imageNamed:@"empty6.png"],
                         [UIImage imageNamed:@"empty7.png"],
                         [UIImage imageNamed:@"empty8.png"],
                         [UIImage imageNamed:@"empty9.png"],
                         [UIImage imageNamed:@"empty10.png"],
                         [UIImage imageNamed:@"empty11.png"],
                         [UIImage imageNamed:@"empty12.png"],
                         [UIImage imageNamed:@"empty13.png"],
                         [UIImage imageNamed:@"empty14.png"],
                         [UIImage imageNamed:@"empty15.png"],
                         [UIImage imageNamed:@"empty16.png"],
                         [UIImage imageNamed:@"empty17.png"], nil];
    self.testTableView.separatorColor = [UIColor colorWithRed:0 green:0.21 blue:0.43 alpha:1];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    self.labels = nil;
    self.images = nil;
    self.testTableView = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source methods

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return the cell's height
    return kTestCellHeight;
}

-  (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return [self.labels count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *TestCellIdentifier = @"TestCellIdentifier";

    TestCell *cell = (TestCell *)[tableView dequeueReusableCellWithIdentifier:TestCellIdentifier];
    if (cell == nil) {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"TestCell" 
                                                     owner:self 
                                                   options:nil];
        for (id oneObject in nib) {
            if ([oneObject isKindOfClass:[TestCell class]]) {
                cell = (TestCell *)oneObject;
            }
        }
    }

    NSInteger row = [indexPath row];
    cell.testLabel.text = [self.labels objectAtIndex:row];
    cell.testImage.image = [self.images objectAtIndex:row];

    return cell;
}

@end

我想这就是所需上下文的全部描述。现在问题来了。当我将表中的其中一个开关设置为“关闭”(默认情况下它们为“开”),然后向下滚动然后再次向上滚动时,表开始将随机开关调整为“关闭”和“打开”。这一切都非常随机。

任何人都知道为什么会发生这种情况或如何避免它?

I'm creating an application which implements a custom UITableView. The way I have done this is as follows:

There is a UINavigationController that I created. This UINavigationController pushes a UIViewController implementing UITableViewDelegate and UITableViewDataSource. I create a .xib for this UIViewController therefore having 3 file for the UIViewController: TestTableViewController.h, TestTableViewController.m and TestTableViewController.xib.

The TestTableViewController.xib has only a UITableView placed linked to a IBOutlet UITableView called testTableView and this UITableView dataSource and delegate are linked to the File's Owner (the TestTableViewController).

Also, I have implemented custom UITableViewCell. I created a empty .xib called TestCell.xib where I placed a UITableViewCell and inserted a UIView, a UILabel, a UIImageView and a UISwitch. Then I created a class inherited from UITableViewCell as follows (I defined the TestCell.xib's view as TestCell class and set the identifier to TestCellIdentifier):

TestCell.h:

#import <UIKit/UIKit.h>

#define kTestHeight 40


@interface TestCell : UITableViewCell {
    UIImageView *testImage;
    UILabel *testLabel;
}

@property (nonatomic, retain) IBOutlet UIImageView *testImage;
@property (nonatomic, retain) IBOutlet UILabel *testLabel;

@end

TestCell.m:

#import "TestCell.h"


@implementation TestCell

@synthesize testImage, testLabel;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

- (void)dealloc
{
    [self.testLabel release];
    [self.testImage release];
    [super dealloc];
}

@end

I implement all the TestTableViewController as follows:

TestTableViewController.h:

#import <UIKit/UIKit.h>


@interface TestTableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
    NSArray *labels;
    NSArray *images;
    UITableView *testTableView; // this is the UITableView linked in the NIB
}

@property (nonatomic, retain) NSArray *labels, *images;
@property (nonatomic, retain) IBOutlet UITableView *testTableView;

@end

TestTableViewController.m:

#import "TestTableViewController.h"
#import "TestCell.h"


@implementation TestTableViewController

@synthesize labels, images;
@synthesize testTableView;

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

- (void)dealloc
{
    [self.labels release];
    [self.images release];
    [self.testTableView release];
    [super dealloc];
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    self.title = @"Test";
    self.labels = [[NSArray alloc] initWithObjects:
                    @"Test 1",
                    @"Test 2",
                    @"Test 3", 
                    @"Test 4",
                    @"Test 5",
                    @"Test 6",
                    @"Test 7",
                    @"Test 8",
                    @"Test 9",
                    @"Test 10",
                    @"Test 11",
                    @"Test 12",
                    @"Test 13",
                    @"Test 14",
                    @"Test 15",
                    @"Test 16",
                    @"Test 17", nil];
    self.images = [[NSArray alloc] initWithObjects:
                         [UIImage imageNamed:@"empty1.png"],
                         [UIImage imageNamed:@"empty2.png"],
                         [UIImage imageNamed:@"empty3.png"],
                         [UIImage imageNamed:@"empty4.png"],
                         [UIImage imageNamed:@"empty5.png"],
                         [UIImage imageNamed:@"empty6.png"],
                         [UIImage imageNamed:@"empty7.png"],
                         [UIImage imageNamed:@"empty8.png"],
                         [UIImage imageNamed:@"empty9.png"],
                         [UIImage imageNamed:@"empty10.png"],
                         [UIImage imageNamed:@"empty11.png"],
                         [UIImage imageNamed:@"empty12.png"],
                         [UIImage imageNamed:@"empty13.png"],
                         [UIImage imageNamed:@"empty14.png"],
                         [UIImage imageNamed:@"empty15.png"],
                         [UIImage imageNamed:@"empty16.png"],
                         [UIImage imageNamed:@"empty17.png"], nil];
    self.testTableView.separatorColor = [UIColor colorWithRed:0 green:0.21 blue:0.43 alpha:1];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    self.labels = nil;
    self.images = nil;
    self.testTableView = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source methods

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return the cell's height
    return kTestCellHeight;
}

-  (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return [self.labels count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *TestCellIdentifier = @"TestCellIdentifier";

    TestCell *cell = (TestCell *)[tableView dequeueReusableCellWithIdentifier:TestCellIdentifier];
    if (cell == nil) {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"TestCell" 
                                                     owner:self 
                                                   options:nil];
        for (id oneObject in nib) {
            if ([oneObject isKindOfClass:[TestCell class]]) {
                cell = (TestCell *)oneObject;
            }
        }
    }

    NSInteger row = [indexPath row];
    cell.testLabel.text = [self.labels objectAtIndex:row];
    cell.testImage.image = [self.images objectAtIndex:row];

    return cell;
}

@end

I guess this is all the description of the context needed. Now the problem. When I set one of the switches in the table to OFF (they are by default ON) and then scroll down and then up again, the table starts tweaking random switches to OFF and ON. All this very randomly.

Anyone knows why this could be happening or how to avoid it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

想你的星星会说话 2024-11-04 01:15:20

麦克沃斯是对的。我只需创建一个包含每个 UISwitch 状态的布尔值的数组,并将其分配到 cellForrowAtIndexPath 中。

Mackworth was right. I just had to create an array with the boolean values for the state of each UISwitch and assign it in cellForrowAtIndexPath.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文