9

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

Ignacio Oroná
  • 4,371
  • 1
  • 19
  • 25
  • By the looks of it, it might have something to do with how you show/hide the keyboard and how that interacts with your views. As a side note, do you need to create that view all the time? it would behave nicer if you just create it once and simply show and hide the view. – Mihai Timar Aug 08 '17 at 09:00

2 Answers2

5

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?

richiereitz
  • 163
  • 9
  • I am not very fond of moving views around inncesesarily, but I'll definatelly will give this idea a try. Thank you @richiereitz – Ignacio Oroná Jul 25 '17 at 16:30
3

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

Johnny Rockex
  • 4,136
  • 3
  • 35
  • 55