objective-cuitableviewtable-footer

UITableView custom UIView duplicates


So, the customer's spec wants the UITableView to have one of it's row present all the time, so the user can interact with this crucial button in any position of the UITableView. Once he scrolls and gets so see the actual Row with the button, the floating footer has to disappear and allow the user to interact with the 'real' Cell, not the floating version.

I've come up with the following code:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{    
    if([self isPostularmeRowVisible])
    {
        [self hidePostularmeFooterView];
    }
    else
    {
        [self showPostularmeFooterView];
    }
}

-(BOOL)isPostularmeRowVisible
{        
    NSArray *indexes = [self.tableView indexPathsForVisibleRows];
    for (NSIndexPath *index in indexes)
    {
        if (index.row == 0 && index.section>=DetalleEmpleoPostularmeCell)
        {
            return YES;
        }
    }
    return NO;
}

-(void) showPostularmeFooterView
{
    NSAssert(_state==ESTADO_POSTULACION_NO_POSTULADO, @"NJDetalleEmpleoViewController: This shouldn't happen");

    if(!self.footerView)
    {
        NJDetalleEmpleoPostularmeTableViewCell *footerView = [self.tableView dequeueReusableCellWithIdentifier:kDetalleEmpleoPostularmeCell];
        [footerView configureCell:self.detaleAviso];
        float h = self.view.frame.size.height-footerView.cellHeight;
        footerView.frame = CGRectMake(0,h,self.view.frame.size.width,footerView.cellHeight);
        footerView.delegate = self;
        self.footerView = footerView;
        [self.view addSubview:self.footerView];
        [self.view bringSubviewToFront:self.footerView];
    }
}

-(void) hidePostularmeFooterView
{
    if(self.footerView)
    {
        [self.footerView removeFromSuperview];
    }

    self.footerView = nil;
}

But this code has a bug I can't seem to figure out: once the user tap's on the UITextBox and enters some text it start to behave erratically, i.e.: 2 or more Cells appear on the screen, when there should be none! Basically, when I call the method 'hidePostularmeFooterView' it doesn't seem to disappear (Only after I've entered some text, if I don't interact with it, it works fine).

enter image description here

It's seems after I enter some text there are 2 version of the Footer, here is the evidence:

enter image description here


Solution

  • enter image description here

    I wouldn't touch the footerView, but instead create a custom view that comes on, like such:

    dataSource = [NSMutableArray new];
    for (int n = 0; n < 100; n++){
        [dataSource addObject:[NSString stringWithFormat:@"%i",n]];
    }
    
    table = [UITableView new];
    table.frame = self.view.bounds;
    table.delegate = self;
    table.dataSource = self;
    [self.view addSubview:table];
    
    popUpView = [UIImageView new];
    popUpView.frame = CGRectMake(0, h-200, w, 200);
    popUpView.image = [UIImage imageNamed:@"Grumpy-Cat.jpg"];
    popUpView.contentMode = UIViewContentModeScaleAspectFill;
    popUpView.clipsToBounds = true;
    popUpView.layer.borderColor = [UIColor redColor].CGColor;
    popUpView.layer.borderWidth = 2.0f;
    [self.view addSubview:popUpView];
    

    Set up the tableView as usual, and in the scrollViewDidScroll method, you could stick something like this:

    NSIndexPath * specialRow = [NSIndexPath indexPathForRow:50 inSection:0];
    NSArray * indices = table.indexPathsForVisibleRows;
    if ([indices containsObject:specialRow]){
        if (isShowing){
            isShowing = false;
            [UIView animateWithDuration:1.0f
                                  delay:0.0f
                 usingSpringWithDamping:1.0f
                  initialSpringVelocity:0.8f
                                options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState
                             animations:^{
                                 popUpView.transform = CGAffineTransformMakeTranslation(0, popUpView.frame.size.height + 10);
                             }
                             completion:^(BOOL finished){
                             }];
        }
    } else if (!isShowing) {
    
        isShowing = true;
        [UIView animateWithDuration:1.0f
                              delay:0.0f
             usingSpringWithDamping:1.0f
              initialSpringVelocity:0.8f
                            options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState
                         animations:^{
                             popUpView.transform = CGAffineTransformIdentity;
                         }
                         completion:^(BOOL finished){
                         }];
    }
    

    Where isShowing is a boolean keeping track of the popUpView state. It's quick and dirty code, should declare specialRow etc elsewhere. In this case it is defined as being the 50th of 100 rows.

    For the record, I don't think it's good design to have duplicate functionality like that, but hey, client knows best :D