0

I'm writing my first iOS app in objective-c, and I've been scratching my head at this for a few days now. I live on an island off the coast of Maine, and the app I'm designing will allow users (or quite possibly just me) to select an island, select a departure date, and see the corresponding ferry schedule of boats leaving the mainland.

Here's the issue:

In order to display the correct ferry schedule, users have to be able to select the date they want to depart on and the island they are departing from/headed to. Following the advice given in response to this question, I chose to implement this using a four-row table view positioned just below the nav bar. At all times at least two of those rows are displayed: the dateCell (in row 0) displays which date is currently selected, and the islandCell (in row 2) which displays the currently-selected island. If a user selects the dateCell, row 1 (which contains an inline UIDatePicker) is revealed, allowing them to change the date. Selecting the dateCell again hides the date picker. If a user selects the island cell, row 3 (which contains an inline UIPickerView with a list of all of the available islands) appears, allowing them to change the island. Everything about this process works just fine.

My challenges arose when I decided I wanted that table to remain fixed (not scroll) when a user scrolls down through the schedule displayed below it. I accomplished this by having two table views embedded in the UIView: one for the island/date cells and their pickers, and one for the schedule. Both tables work fine.

The problem is, when the pickers are not being displayed, I would like the schedule table view to cover-up/conceal the wasted real estate in the picker table view. In order to do so I added some animations that I thought would reposition the schedule table view's frame depending on whether the pickers were open or not. It seemed dead simple, however, the animations are not executing the way I expected. They begin to execute and the schedule table view starts to slide up or down accordingly, but the animations always stop abruptly and the schedule jumps back to it's original position. From playing around with the duration of the animations, I believe that it jumps back to its original position as soon as the animations that reveal the picker views are completed. My problem is that I don't call the picker view animations (they are executed automatically) so I don't know how to access them in order to determine if there is some sort of interference going on.

Here's the method that is hiding and displaying the pickers:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{

    CGFloat heightForRow = self.pickerTableView.rowHeight;

    if (tableView == self.pickerTableView) {

        // if the index path row is the row of the datePicker (1) or the islandPicker (3), and the    date picker should be shown, return the height for the picker. If it should be hidden, return 0.0
        if (indexPath.row == 1) {

            heightForRow = (self.isDatePickerShown) ? self.pickerCellRowHeight : 0.0;
            return heightForRow;

         } else if (indexPath.row == 3) {

            heightForRow = (self.isIslandPickerShown) ? self.islandPickerCellRowHeight : 0.0;
            return heightForRow;

        } else {

            // else, return the default height for a picker table row
            return heightForRow;
        }

    } else { // the table view must be the schedule table view

        // return the default height for a schedule table row
        return heightForRow;
    }

}

And here's the first part of the method that the schedule table view animations live in:

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

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

    // if the selected cell is a date cell
    if (cell.reuseIdentifier == kDateCellID)
    {

        // log the datePicker's indexPath
        NSInteger rowToReveal = indexPath.row + 1;
        self.datePickerIndexPath = [NSIndexPath indexPathForRow:rowToReveal inSection:0];

        // move and animate schedule table view accordingly
        if (self.datePickerIsShown == NO && self.islandPickerIsShown == NO)
        {

            // drop the schedule table view down to accomodate change in picker table view
            CGRect newFrame = self.scheduleTableView.frame;
            newFrame.origin.y += self.pickerCellRowHeight;    // shift down by the height of the date Picker Cell

            [UIView animateWithDuration:0.3
                             animations:^{
                                 self.scheduleTableView.frame = newFrame;
                             }];

            // toggle the date picker to display it
            self.datePickerIsShown = ! self.datePickerIsShown;

        } else if (self.datePickerIsShown == NO && self.islandPickerIsShown == YES){

            // toggle the island picker to hide it
            self.islandPickerIsShown = ! self.islandPickerIsShown;

            // toggle the date picker to display it
            self.datePickerIsShown = ! self.datePickerIsShown;

        } else {

            // the date picker is being retracted, so raise the schedule table view up to conceal bottom of picker table view
            CGRect newFrame = self.scheduleTableView.frame;
            newFrame.origin.y -= self.pickerCellRowHeight;    // shift up by the height of the date Picker Cell

            [UIView animateWithDuration:0.3
                             animations:^{
                                 self.scheduleTableView.frame = newFrame;
                             }];

            // toggle the date picker to hide it
            self.datePickerIsShown = ! self.datePickerIsShown;
        }

        // update pickerTableView
        [tableView beginUpdates];
        [tableView endUpdates];

Has anyone experienced this issue before? Does anyone know what animation is getting called when the UIPickerViews or UIDatePickers are revealed? How do I determine if this is in fact what's causing the schedule table to revert back to it's original position?

I've been banging my head against my desk for three days now. All I want for Christmas is for these animations to do what they're supposed to!

Thanks in advance.

-Nathaniel

Community
  • 1
  • 1
  • This sounds like a auto layout problem. If you have not explicitly turned off auto layout, then it is on. Even if you don't add any constraints, the system will add them for you. When using auto layout, you should not set any frames, you adjust the constraints to move or resize a view. – rdelmar Dec 25 '14 at 07:37
  • That did the trick! Thank you so much. In the future I would love to find a better solution that would allow me to not have to sacrifice all the benefits of auto layout, but this is just fine for now. @rdelmar, I would like to vote up and select your response as the correct answer, but I don't see where I might do that. Apologies, I'm very new to all of this... – nathanielrindlaub Jan 02 '15 at 19:28

0 Answers0