Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 800
Ignacio Oroná Avatar asked Jul 21 '17 01:07

Ignacio Oroná


2 Answers

It might make more sense for you to just remove this as a cell & footer and replace it as its own UIView below the UITableView, and have the UITableView's frame height only come down to the y origin of this view, rather than take up the entire screen. This way you will be able to see and interact with the view at all times. Is there any reason you need this to be a UITableViewCell?

like image 184
richiereitz Avatar answered Nov 05 '22 23:11

richiereitz


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

like image 41
Johnny Rockex Avatar answered Nov 05 '22 22:11

Johnny Rockex