2014-03-05 223 views
4

這很奇怪,但我知道我的[UITableView的reloadData]沒有刪除舊的細胞,就像這樣: enter image description hereiOS - [UITableView reloadData]重新加載,但不刪除舊的單元格?

我點擊了+按鈕後,你看到發生的混亂,回來又改值。加上按鈕將導航控制器推到另一個控制器,當我回來後點擊後退按鈕並更改了值,這就是我所看到的。這怎麼可能??我使用了一個自定義視圖(從UIView繼承而來),我使用UILabel將其創建爲UIStepper。這是自定義UIView的代碼,controller.m和.h-.m文件。

Controller.m或者

@interface ViewController() 
@property NSString *docsDir; 
@property sqlite3 *DB; 
@property NSArray *dirPaths; 
@property NSString* databasePath; 
@property (strong, nonatomic) IBOutlet UITableView *tableView; 
@property BOOL isCreatedBefore; 
@property NSArray *theList; 
@end 

@implementation ViewController 
@synthesize docsDir; 
@synthesize DB; 
@synthesize dirPaths; 
@synthesize databasePath; 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    docsDir = [dirPaths objectAtIndex:0]; 
    databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: [NSString stringWithFormat:@"database.db"]]]; 

    [self createDatabase]; 
    self.theList = [self readAllEntries]; 
} 

-(void) viewWillAppear:(BOOL)animated{ 
    self.theList = [self readAllEntries]; 
    [self.tableView reloadData]; 
} 

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

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ SeriesObject * obj = [self.theList objectAtIndex:indexPath.row]; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellocan"]; 
    UILabel *nameLabel = (UILabel *)[cell.contentView viewWithTag:1]; 
    [nameLabel setText:obj.name]; 

    CounterView *seasonCounter = [[CounterView alloc] initWithX:220 WithY:28 WithName:obj.name withCount:obj.session withCustomTag:indexPath.row]; 
    seasonCounter.tag = 2; 
    CounterView *episodeCounter = [[CounterView alloc] initWithX:268 WithY:28 WithName:obj.name withCount:obj.episode withCustomTag:indexPath.row]; 
    episodeCounter.tag = 4; 

    [cell.contentView addSubview:seasonCounter]; 
    [cell.contentView addSubview:episodeCounter]; 

    return cell; 
} 


- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { 
    // Return YES if you want the specified item to be editable. 
    return YES; 
} 

// Override to support editing the table view. 
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 
    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     SeriesObject *obj = [self.theList objectAtIndex:indexPath.row]; 
     [self deleteEntryWithID:obj.idd]; 

     self.theList = [self readAllEntries]; 
     [self.tableView reloadData]; 
    } 
} 
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    return 88; 
} 



- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 

} 

______and more about reading from database or deleting; not about the view. (this is a very simple app, as a free time hobby; so I didn't spend time to follow MVC) 

CounterView.h

@interface CounterView : UIView 
@property NSString* name; 
@property NSInteger count; 
@property UILabel *label; 
@property NSInteger customTag; 

- (id)initWithX:(CGFloat)xPoint WithY:(CGFloat)yPoint WithName:(NSString*)newName withCount:(NSInteger)newCount withCustomTag:(NSInteger)newTag; 
@end 

CounterView.m

@interface CounterView() 

@property NSString *docsDir; 
@property sqlite3 *DB; 
@property NSArray *dirPaths; 
@property NSString* databasePath; 

@end 


@implementation CounterView 

@synthesize docsDir; 
@synthesize DB; 
@synthesize dirPaths; 
@synthesize databasePath; 

- (id)initWithX:(CGFloat)xPoint WithY:(CGFloat)yPoint WithName:(NSString*)newName withCount:(NSInteger)newCount withCustomTag:(NSInteger)newTag 
{ 
    self = [super initWithFrame:CGRectMake(xPoint, yPoint, 24, 52)]; 
    if (self) { 
     self.customTag = newTag; 
     self.count = newCount; 
     self.name = newName; 

     UIButton *btnUp = [[UIButton alloc] initWithFrame:CGRectMake(3, 2, 18, 12)]; 
     [btnUp setImage:[UIImage imageNamed:@"top.png"] forState:UIControlStateNormal]; 
     [btnUp addTarget:self action:@selector(increaseValue) forControlEvents:UIControlEventTouchUpInside]; 
     UIButton *btnDown = [[UIButton alloc] initWithFrame:CGRectMake(3, 38, 18, 12)]; 
     [btnDown setImage:[UIImage imageNamed:@"bottom.png"] forState:UIControlStateNormal]; 
     [btnDown addTarget:self action:@selector(decreaseValue) forControlEvents:UIControlEventTouchUpInside]; 
     self.label = [[UILabel alloc] initWithFrame:CGRectMake(0, 14, 24, 24)]; 
     [self.label setText:[NSString stringWithFormat:@"%ld", (long)self.count]]; 
     self.label.textAlignment = NSTextAlignmentCenter; 

     [self addSubview:btnUp]; 
     [self addSubview:btnDown]; 
     [self addSubview:self.label]; 
    } 
    return self; 
} 

- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents{ 

} 


-(void) increaseValue{ 
    self.count++; 
    [self.label setText:[NSString stringWithFormat:@"%ld", (long)self.count]]; 
} 
-(void) decreaseValue{ 
    self.count--; 
    [self.label setText:[NSString stringWithFormat:@"%ld", (long)self.count]]; 
} 

____and some more database codes too.. 

回答

1

經過一些修改後,在cellForRowAtIndexpath:方法中使用了這個方法解決了所有問題。感謝大家。

if (cell != nil) 
    { 
     NSArray* subviews = [cell.contentView subviews]; 
     for (UIView* view in subviews) 
     { 
      [view removeFromSuperview]; 
     } 
    } 
+0

這將在一個捏,但如果你的細胞變得複雜這種方法可以讓你的滾動感覺波濤洶涌。重複使用視圖比刪除和添加視圖更快。 –

5

在你cellForRowAtIndexPath:您每次都添加一個子視圖。單元格由UITableView重用,所以當你重新加載時,你會得到一個「髒」的單元格。你需要檢查視圖是否已經存在。如果是這樣,修改視圖,而不是添加一個。谷歌「UITableViewCell viewWithTag」查看一些示例代碼。

+0

我之前使用它。所以它每次都發生,但由於內容的穩定性,我從來沒有意識到。謝謝.. –

+0

爲什麼不直接在這裏寫示例代碼? – Esqarrouth

+0

@Esq該模式已被寫入數百次,很容易找到。 –

2
- (void)prepareForReuse 
{ 
    //remove your subviews here 
    [self.subViewToRemove removeFromSuperView]; 
} 
1

我建議您創建一個從UITableViewCell派生的自定義單元類,並讓它包含您的自定義CounterView實例。在這種情況下,你不需要每次在你的cellForRowAtIndexPath(這是造成你遇到的問題)中添加子視圖,你可以改爲傳遞它需要的任何值。

相關問題