Search code examples
objective-cuitableviewios7

UITableView glitching on latest iOS update


My client sees this on their iPad which has the latest update.

My simulator shows it fine. Other view controllers in the app don't have this issue. This VC has a NIB with a tableview connected.

bad tableview

Base class:

    @implementation HVPickerViewController

- (id)init {
    self = [self initWithNibName:@"HVPickerViewController" bundle:nil];
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelTapped)];

    [self fetchObjects];

    CGRect f = self.tableView.frame;
    f.origin.y += 40;
    self.tableView.frame = f;
}

- (NSString *)path {
    return nil;
}

- (NSString *)keyPath {
    return nil;
}

- (RKObjectMapping *)RKObjectMapping {
    return nil;
}

- (void)assignMappingResult:(RKMappingResult *)result {
    NSLog(@"mappingResult:%@", result);
    self.objects = result.array;
    [self.tableView reloadData];
    [SVProgressHUD dismiss];
}

- (void)fetchObjects {
    NSString *path = [self path];

    if (path) {
        NSIndexSet *statusCodeSet = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
        RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[self RKObjectMapping]
                                                                                           pathPattern:path
                                                                                               keyPath:[self keyPath]statusCodes:statusCodeSet];

        NSString *baseString = [NSString stringWithFormat:@"%@%@?token=%@", BASE_URL, path, [NSUserDefaults authToken]];
        NSLog(@"fullURLString: %@", baseString);
        NSURL *url = [NSURL URLWithString:baseString];

        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[responseDescriptor]];
        [operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
            [self assignMappingResult:mappingResult];
        } failure:^(RKObjectRequestOperation *operation, NSError *error) {
            [operation handleFailedRequest];
            if (self.retries < 5) {
                self.retries++;
                [self fetchObjects];
            } else {
                NSLog(@"Error: %@", error);
                NSLog(@"Response: %@", operation.HTTPRequestOperation.responseString);
                [SVProgressHUD showErrorWithStatus:@"Please check your connection and reload this screen"];
            }
        }];
        NSOperationQueue *q = [[NSOperationQueue alloc] init]; [q addOperation:operation];
    }
}

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

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

- (id)objectForIndexPath:(NSIndexPath *)indexPath {
    return self.objects[indexPath.row];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *identifier = @"CustomerPickerCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }

    id obj = [self objectForIndexPath:indexPath];

    cell.textLabel.text = [obj name];

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    id obj = self.objects[indexPath.row];
    [self.delegate objectPicked:obj];
}


- (void)cancelTapped {
    [self.delegate pickingCancelled];
}

Subclass:

- (void)assignMappingResult:(RKMappingResult *)result {
    NSMutableArray *trainees = [NSMutableArray array];
    for (HVUser *u in result.array) {
        if (![u isStaff]) {
            [trainees addObject:u];
        }
    }

    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
    self.objects = [NSMutableArray arrayWithArray:[trainees sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]]];

    [SVProgressHUD dismiss];
    [self.tableView reloadData];

    NSString *s = [NSString stringWithFormat:@"%d trainees from %d users", (int)trainees.count, (int)result.array.count]; //This DOES show up in my client's log
    NSLog(@"CREATE LOSS ITEM trainees: %@", trainees);
    NSLog(@"CREATE LOSS ITEM users: %@", result.array);

    [SVProgressHUD showSuccessWithStatus:s];
}

- (NSString *)path {
    return @"/api/v1/users.json";
}

- (NSString *)keyPath {
    return @"users";
}

- (RKObjectMapping *)RKObjectMapping {
    return [HVMappingProvider userMapping];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.allowsMultipleSelectionDuringEditing = YES;
    [self.tableView setEditing:YES animated:YES];

    UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleBordered target:self action:@selector(doneTapped)];
    self.navigationItem.rightBarButtonItem = doneButton;
}

- (void)doneTapped {
    NSArray *selectedRows = [self.tableView indexPathsForSelectedRows];
    if (selectedRows.count > 0) {
        NSMutableArray *trainees = [NSMutableArray array];
        for (NSIndexPath *selectionIndex in selectedRows) {
            HVUser *u = self.objects[selectionIndex.row];
            [trainees addObject:u];
        }
        [self.delegate objectsPicked:trainees];
    } else {
        [SVProgressHUD showErrorWithStatus:@"Please make at least one selection."];
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];

    HVUser *u = self.objects[indexPath.row];

    cell.textLabel.text = u.name;

    if (u.avatarURL && u.avatarURL.length > 0) {
        [cell.imageView setImageWithURL:[NSURL URLWithString:u.avatarURL] placeholderImage:nil];
    } else {
        cell.imageView.image = nil;
    }

    return cell;
}

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

}

- (double)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 88;
}

Solution

  • I changed

    • (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 88; }

    to use CGFloat, per compiler warning.

    Works.