Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

table view slides up under navigation bar when user taps row

I have a UINavigationController (NC) containing a UITableViewController (TVC0). When the user taps a row, it loads a UIPageViewController (PVC), which pages back and forth between other UITableViewControllers (TVC1).

TVC0 shows up inside NC (meaning it doesn't hide behind the navigation bar at the top or the tab bar at the bottom). When it pushes PVC, the first TVC1 appears inside the bounds of the nav bar and tab bar. However when I swipe, the TVC1s inside are hidden behind the navigation bar and tab bar. I can pull to reveal the contents, but when I release, it snaps back to behind the bar.

How can I force everything to appear between the two bars? I can't use storyboard (because it's a legacy app) and the embed in... option isn't available.

[Edit]

I added some logging and discovered that my embedded TVC1s frame has an absolute origin of 0, 64, but as soon as I tap, it goes to 0, 0. If I can't figure out a real solution, I can always fake it by adding 64, but I'd much rather figure out what's actually wrong.

[/Edit]

[More Edit]

I was testing another area in the iOS 6 simulator and discovered that this paging works flawlessly in iOS 6. So the issue I'm seeing is iOS 7 specific.

[/More Edit]

Here is my TVC0 viewDidLoad, PVC pageViewController:viewControllerBeforeViewController:, and a helper viewControllerAtIndex::

- (void) viewDidLoad
{
    [super viewDidLoad];
    NSDictionary* options = [NSDictionary dictionaryWithObject:
                             [NSNumber numberWithInteger: UIPageViewControllerSpineLocationMin]
                                                        forKey:
                             UIPageViewControllerOptionSpineLocationKey];
    self.pageController = [[UIPageViewController alloc] initWithTransitionStyle:
                           UIPageViewControllerTransitionStyleScroll
                                                          navigationOrientation:
                           UIPageViewControllerNavigationOrientationHorizontal
                                                                        options: options];

    self.pageController.dataSource = self;
    self.pageController.view.frame = self.view.frame;
    NSArray* viewControllers =
            [NSArray arrayWithObject: [self viewControllerAtIndex: self.initialIndex]];

    [self.pageController setViewControllers: viewControllers
                                  direction: UIPageViewControllerNavigationDirectionForward
                                   animated: NO
                                 completion: nil];

    [self addChildViewController: self.pageController];
    [self.view addSubview: self.pageController.view];
    [self.pageController didMoveToParentViewController: self];

    for (UIGestureRecognizer* recognizer in self.pageController.gestureRecognizers)
    {
        if ([recognizer isKindOfClass: [UITapGestureRecognizer class]])
        {
            recognizer.enabled = NO;
        }
    }
}

// SearchResultsList is TVC1
- (SearchResultsList*) viewControllerAtIndex: (NSUInteger) index
{
    if (index >= self.items.count)
    {
        return nil;
    }

    SearchResultsList* retVal = [[SearchResultsList alloc]
                                    initWithNibName: @"SearchResultsList" bundle: nil];

    MyListItem* myItem = [self.items objectAtIndex: index];
    MyMatchesRequest* matches = [[MyMatchesRequest alloc] initWithItemId: myItem.itemId];
    [matches execute: ^(MySearchResults* results)
     {
         retVal.tableData = [NSMutableArray arrayWithArray: results.items];
         retVal.view.frame = self.view.frame;
         retVal.myItem = myItem;
         retVal.index = index;
         self.title = myItem.displayText;
         [[retVal tableView] reloadData];
     }];

    return retVal;
}

- (UIViewController*) pageViewController: (UIPageViewController*) pageViewController
      viewControllerBeforeViewController: (UIViewController*) viewController
{
    SearchResultsList* vc = (SearchResultsList*)viewController;
    if (vc.index == 0)
    {
        [self.navigationController popViewControllerAnimated: YES];
        return nil;
    }

    return [self viewControllerAtIndex: vc.index - 1];
}
like image 441
kwiqsilver Avatar asked Dec 02 '22 17:12

kwiqsilver


2 Answers

I had a very painful learning experience with similar behavior :(

Put this in your view controller's init:

self.automaticallyAdjustsScrollViewInsets = NO;

This is a new UIViewController property that defaults to YES in iOS 7

UIViewController Docs

like image 189
Nick Avatar answered Mar 03 '23 11:03

Nick


Because you're presenting view controllers in a container which is less than the full size of the screen you need to set

self.pageViewController.definesPresentationContext = YES; 

 viewControllerWhichIsApageInPageController.modalPresentationStyle = UIModalPresentationCurrentContext
like image 41
Jef Avatar answered Mar 03 '23 12:03

Jef