应用程序崩溃时重新加载和滚动tableview一个方向

时间:2014-05-28 12:12:22

标签: ios uitableview uirefreshcontrol

我有一个UITableView的Instagram Feed。我已经实现了UIRefreshControl来提升刷新功能。

拖动并释放刷新控件后,当微调器移动时,我可以向下拖动tableview而不会导致应用程序崩溃。但是,如果我向上滚动tableview,应用程序崩溃(可能是因为单元格2,3等?)

以下是显示问题的视频:http://www.screenmailer.com/v/DukT4lt2aUGm8c5MLRlGMg/2586/3a23tXo7uXs.mp4

为什么会这样?

.m文件的代码:

#import "InstagramViewController.h"
#import "InstagramCell.h"
#import <InstagramKit/InstagramKit.h>
#import "UIImageView+AFNetworking.h"

@interface InstagramViewController ()
{
    NSMutableArray *mediaArray;
}

@property (nonatomic, strong) InstagramPaginationInfo *currentPaginationInfo;

@end

@implementation InstagramViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        //mediaArray = [[NSMutableArray alloc] init];
    }
    return self;
}

- (void)viewDidLoad
{
    mediaArray = [[NSMutableArray alloc] init];

    [super viewDidLoad];

    [self loadMedia];

    self.refreshControl = [[UIRefreshControl alloc] init];
    [self.refreshControl addTarget:self action:@selector(reloadMedia) forControlEvents:UIControlEventValueChanged];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

-(void)reloadMedia
{
    self.currentPaginationInfo = nil;

    [mediaArray removeAllObjects];

    [self loadMedia];
}

-(IBAction)loadMedia
{
    // start network indicator
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

    [[InstagramEngine sharedEngine] getMediaWithTagName:@"AUFsommer" count:10 maxId:self.currentPaginationInfo.nextMaxId withSuccess:^(NSArray *media, InstagramPaginationInfo *paginationInfo) {

        if (paginationInfo)
        {
            self.currentPaginationInfo = paginationInfo;
        }

        [mediaArray addObjectsFromArray:media];

        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

        [self reloadData];

    } failure:^(NSError *error) {

        NSLog(@"Search Media Failed");

        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

    }];


}

-(void)reloadData
{
    [self.refreshControl endRefreshing];
    [self.tableView reloadData];
}

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

#pragma mark - Table view data source

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    UIView *headerView = [[UIView alloc] init];
    headerView.backgroundColor = [UIColor colorWithWhite:1.0f alpha:0.9f];

    InstagramMedia *media = mediaArray[section];

    // create imageview for profile photo
    AsyncImageView *profilePhoto = [[AsyncImageView alloc] initWithFrame:CGRectMake(8, 8, 32, 32)];
    profilePhoto.layer.borderColor = [[UIColor colorWithRed:204.0/255.0f green:204.0/255.0f blue:204.0/255.0f alpha:1.0f] CGColor];
    profilePhoto.layer.borderWidth = 1;
    profilePhoto.layer.masksToBounds = YES;
    profilePhoto.layer.cornerRadius = 16.0;
    [profilePhoto loadImageFromURL:[media.user.profilePictureURL absoluteString]];

    // uifont settings
    UIFont *labelFont = [UIFont boldSystemFontOfSize:13.0];

    // create label for username
    UILabel *usernameLabel = [[UILabel alloc] initWithFrame:CGRectMake(48, 0, 210, 48)];
    usernameLabel.text = media.user.username;
    usernameLabel.font = labelFont;
    usernameLabel.textColor = [UIColor colorWithRed:235.0/255.0 green:24.0/255.0 blue:22.0/255.0 alpha:1.0f];

    // create label for timestamp
    UILabel *timestampLabel = [[UILabel alloc] initWithFrame:CGRectMake(250, 0, 54, 48)];
    timestampLabel.textAlignment = NSTextAlignmentRight;
    timestampLabel.font = labelFont;
    // timestampLabel.text = [self stringForDisplayFromDate:media.createdDate];

    // add to view
    [headerView addSubview:profilePhoto];
    [headerView addSubview:usernameLabel];
    [headerView addSubview:timestampLabel];

    return headerView;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return mediaArray.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return 1;
}

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

    if (cell == nil)
    {
        cell = [[InstagramCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // clear photo
    [cell.igPhoto setImage:nil];

    if (mediaArray.count >= indexPath.section+1)
    {
        InstagramMedia *media = mediaArray[indexPath.section];

        cell.title.text = media.caption.text;

        [cell.igPhoto loadImageFromURL:[media.standardResolutionImageURL absoluteString]];
    }

    return cell;
}


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    InstagramMedia *media = mediaArray[indexPath.section];

    CGSize maximumLabelSize = CGSizeMake(304.0f, 20000.0f);
    CGSize expectedLabelSize = [media.caption.text sizeWithFont:[UIFont systemFontOfSize:13.0f] constrainedToSize:maximumLabelSize lineBreakMode:NSLineBreakByWordWrapping];

    return (320.0f + expectedLabelSize.height + 20.0f);
}

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    CGFloat currentOffset = scrollView.contentOffset.y;
    CGFloat maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height;

    if (maximumOffset - currentOffset < 10.0)
    {
        [self loadMedia];
    }
}

@end

1 个答案:

答案 0 :(得分:6)

您应该做的第一件事是在项目中add an exception breakpoint,这样您就会知道崩溃的原因和地点。

您的应用崩溃的原因是您尝试读取空数组。在方法reloadMedia中,您可以执行以下操作:

self.currentPaginationInfo = nil;    
[mediaArray removeAllObjects];

所以在这一点上,你的数组是空的,但你的UITableView并不知道。通过在重新加载数据之前滚动,将调用方法cellForRowAtIndexPath并尝试访问空数组中的索引。

要解决此问题,您可以在[self.tableView reloadData];之后致电[mediaArray removeAllObjects];。这样,UITableView将调用它来知道它应该有多少行和部分,并且会知道没有更多的行和部分。

或者,如果您希望旧信息在加载过程中仍然在UITableView,请不要currentPaginationInfomediaArrayreloadMedia },