表视图单元格失去了它们的顺序

时间:2014-08-20 19:56:09

标签: ios objective-c facebook

目标

我正在尝试创建像Instegram的主屏幕一样的表格视图。 我已经制作了一个自定义单元格,我用数据初始化它,单元格假设要保留“Post”。

逻辑

我将每个单元格保存在NSMutableDictionary中,关键是发布顺序的索引,值是自己发布的。

当前结果

我向下滚动,一切都很好。您看到的顺序是post1,post2,post3 ... post 8但是当我向上滚动时,一切都搞砸了,邮政订单是post8,post6,post7,post8,post5 ......你明白了。

(在此问我之前我尝试用小对象 - 一个只包含字符串的REGULAR!(非自定义)单元格。

  • 出于某种原因,它有效!订单很完美。)

代码

这是我的UITableViewController - 我的“Home”屏幕“cellForRow”方法。

如果我们向上滚动并且Tableview的索引是alrdy已经初始化了,我从字典中拉出帖子。

  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{   
    static NSString *PC = @"PostCell";
    PostCell *Pcell = [tableView dequeueReusableCellWithIdentifier:PC forIndexPath:indexPath];
    NSString *key = [[NSString alloc] initWithFormat:@"%i", indexPath.section];
    NSLog(@"Cell %i", indexPath.section);

    // Checking if alrdy visted this indexpath.
    if (![_allcells objectForKey:key]) {
         [self setPostUserName:[[NSString alloc] initWithFormat:@"username: %i", indexPath.section]:Pcell];
        // Saving a postcell I wont return, just to save in a dictionary.
        // When we get here again it will get another pointer like that my object wont change.
        PostCell* toSave = [[PostCell alloc] init];
        // saving it with current post data.
        [self copyPost:toSave :Pcell];
        [_allcells setObject:toSave forKey:key];
    }
    else {
        // Copying post daya
        [self copyPost:Pcell :[_allcells objectForKey:key]];
    }
    NSLog(@"Cell %i Returning: %@", indexPath.section, Pcell.userName.text);
    return Pcell;
}

// Check if it reached the end
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    float endScrolling = scrollView.contentOffset.y + scrollView.frame.size.height;
    if (endScrolling >= scrollView.contentSize.height)
    {
        NSDictionary *temparr = [[NSDictionary alloc] initWithDictionary:_allcells];
        [self.tableView reloadData];
         _allcells = [[NSMutableDictionary alloc] initWithDictionary:temparr];
    }
}

这是我的PostCell.h,所以你可以看到属性。

@interface PostCell : UITableViewCell

@property (strong, nonatomic) IBOutlet UIImageView *profilePic;
@property (strong, nonatomic) IBOutlet UILabel *userName;
@property (strong, nonatomic) IBOutlet UILabel *checkIn;
@property (strong, nonatomic) IBOutlet UILabel *uploadedAgo;
@property (strong, nonatomic) IBOutlet UIImageView *mainPic;
@property (strong, nonatomic) IBOutlet UILabel *likes;
@property (strong, nonatomic) IBOutlet UILabel *participants;

@end

顺便说一句,如果你有一个类似于Instagram主屏幕的项目示例,那么如果你可以将我链接到它那就太棒了!

3 个答案:

答案 0 :(得分:3)

您不应存储对单元格的引用,因为它们在离开屏幕时会被tableview重用。目前,在第一次向下滚动时,一切正常,因为您创建了新的单元格。在向上滚动时,您将获得存储的引用,该引用现在指向新创建的单元格之一,因此事情看起来很混乱。

您应该做的只是使用正确的数据填充重复使用的单元格,并且只在需要时才创建它们。像:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *PC = @"PostCell";
    PostCell *Pcell = (PostCell*)[tableView dequeueReusableCellWithIdentifier:PC forIndexPath:indexPath];

    // feed the needed data to the cell

    return Pcell;
}

不确定为什么您只访问indexPath.section,因为通常您会使用indexPath.row填充每个部分包含多个单元格的表格。

答案 1 :(得分:0)

UITableView最适合使用数组。此外,数组在索引时将按顺序保留,而字典没有索引,因此不会保留顺序。另外,相同类型的单元格(在这种情况下为PostCell)不应该具有不同的部分,而是不同的行。使用部分分隔不同类别的单元格。

另一个提示; NSMutableDictionary占用的内存比NSDictionary多。一旦在NSMutableDictionary中设置了所有内容,就将其存储在NSDictionary中。如果您希望将来修改它,请将其复制回NSMutableDictionary,修改它,然后再将其存储为NSDictionary。

@property (strong, nonatomic) NSDictionary *post;

//    To create an NSDictionary
NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] init];
[tempDict setValue:@"74 degrees" forKeyPath:@"weather"];
post = tempDict;

//    To modify an NSDictionary
tempDict = [[NSMutableDictionary alloc] initWithDictionary:post];
[tempDict removeObjectForKey:@"weather"];
post = tempDict;

然后将其存储在数组中。

@property (strong, nonatomic) NSArray *allPosts;

//     NSMutableArray takes up more memory than NSArray
NSMutableArray *tempArray = [[NSMutableArray alloc] initWithArray:allPosts];
[tempArray addObject:post];
allPosts = tempArray;

最后,在你的桌面视图中显示它。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *PC = @"PostCell";
    PostCell *pCell = [tableView dequeueReusableCellWithIdentifier:PC];

    if (!cell) {
        pCcell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:PC];
    }

    NSDictionary *currentPost = [allPosts objectAtIndex:indexPath.row];


//  Instead of having post1, post2, post3 and so forth, each post is now in currentPost.  If there are 10 posts, then this function will run 10 times.  Just write the code as if you are handling one post, and the UITableView will automatically fill in the rest of the posts for you.        

    return cell;
}

答案 2 :(得分:0)

好吧,我发现了这个错误,因为我是第一个保存每个帖子的ID而不是把它从词典中删除它没有用。 而不是我试图通过创建一个"假的"来保存帖子的属性。 postCell并将原始单元格的属性保存在假单元格中,然后将其从数组中取出,并将单元格复制到我刚刚取出的单元格的属性中,并且它不起作用。

为什么呢?因为无论我拯救了什么指针!到那些领域!。

我创建了一个课程,用于保存我所需的数据,这是我输入字典的课程。

现在每次我出列一个单元格时,我都会用索引I的数据加载它。 :)

很高兴终于解决它并学习新东西,谢谢你给我带来了好处!