当用户点击行时,表格视图在导航栏下滑动

时间:2014-01-02 22:20:34

标签: ios uinavigationcontroller uitableview uipageviewcontroller

我有UINavigationController(NC),其中包含UITableViewController(TVC0)。当用户点击一行时,它会加载UIPageViewController(PVC),在其他UITableViewController(TVC1)之间来回翻页。

TVC0显示在NC内部(意味着它不会隐藏在顶部的导航栏或底部的标签栏后面)。当它推动PVC时,第一个TVC1出现在导航栏和标签栏的边界内。但是当我滑动时,里面的TVC1隐藏在导航栏和标签栏后面。我可以拉开以显示内容,但是当我释放时,它会快速回到栏后面。

如何强制一切出现在两个酒吧之间?我不能使用storyboard(因为它是一个遗留应用程序)并且嵌入...选项不可用。

[编辑]

我添加了一些日志记录并发现我的嵌入式TVC1s帧的绝对原点是0,64,但是一旦点击,它就会变为0,0。如果我找不到真正的解决方案,我可以总是假装它加64,但我更想弄清楚实际上是什么错误。

[/编辑]

[更多编辑]

我正在测试iOS 6模拟器中的另一个区域,发现这个分页在iOS 6中运行完美。所以我看到的问题是iOS 7特定的。

[/更多编辑]

以下是我的TVC0 viewDidLoad,PVC pageViewController:viewControllerBeforeViewController:和帮助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];
}

3 个答案:

答案 0 :(得分:14)

我有类似行为的非常痛苦的学习经历:(

把它放在你的视图控制器的init:

self.automaticallyAdjustsScrollViewInsets = NO;

这是一个新的UIViewController属性,默认为iOS 7中的YES

UIViewController Docs

答案 1 :(得分:2)

你的代码似乎有点困惑。你说它是你的页面视图控制器的viewDidLoad,但它创建了一个新的PVC,并将其作为子视图控制器添加到自身作为父级。如果您真的这样做,那么您将在另一个PVC中创建一个PVC。我怀疑这是你想要的。

此代码确实属于TVC0,当用户点击一行时,它会调用PVC。这个调用在viewDidLoad中不正确,但可能很适合didSelectRowAtIndexPath方法。我们可以简单地将它推送到我们的navigationController堆栈,而不是将其作为子控制器引入。 (我希望你在最外层的PVC中这样做。)

但为了以防万一,我会删除这三行:

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

并用

替换它们
    [self.navigationController pushViewController:self.pageController 
                                         animated:YES];

(这是从您的TVC0调用的 - 您显示的所有代码都可以存在于TVC0中)

然后,为了防止您描述的行为,在创建UINavigationController时,将translucent的{​​{1}}属性设置为NO就足够了。

<强>更新

我已经足够详细地查看了这个问题,看到某些错误的行为正如你在某些环境中所描述的那样,但它很难复制。

“跳起”行为的原因很明显。如果您有半透明的navBar,它的navigationBar设置为YES,在某些情况下,这可能会导致pageViewController(automaticallyAdjustsScrollViewInsets)的私有子视图设置它的contentOffset。首次加载pageViewController时y到-64。然而,只要pageVC有机会自我更新(例如通过滑动或其他触摸手势),它就会重置其内部子视图状态,从而丢失该流氓contentOffset。因此,当您触摸第一页时,它会跳起来。它留在哪里。这个可能被认为是一个错误,虽然它可能是滥用pageViewController的结果。

_UIQueuingScrollView设置为NO并不能解决您的问题,因为您的页面全部位于导航栏后面。你需要做的是调整pageViewController本身的框架。

我可以详细介绍一下,但是在这一点上,由于您的应用设计看起来有点奇怪,很难将答案应用于您的具体情况,这可能会导致问题。

  • 如果您可以将导航栏的导航栏的automaticallyAdjustsScrollViewInsets属性设置为“否”,则问题应该消失。

  • 正如我之前提到的,我无法像您描述的那样完全复制您的问题,所以我认为您还没有完整清晰地了解您的应用设计

  • 将pageViewController作为 tableViewController 的子项加载,并使其视图为tableView的子视图,这是一个非常奇怪的方法,无疑会导致您的问题。

  • translucent中,pageViewController子似乎弹出了它的parentViewController(tableViewController) - 所以你永远不会看到它的表内容?要么应用程序有更多相关细节,要么您没有准确描述它。

我建议你先处理这些问题。你的问题可能会消失。

答案 2 :(得分:2)

因为您要在容器中呈现视图控制器,该容器小于您需要设置的屏幕的完整大小

self.pageViewController.definesPresentationContext = YES; 

 viewControllerWhichIsApageInPageController.modalPresentationStyle = UIModalPresentationCurrentContext