查找未被UINavigationBar,UITabBar,(等)遮挡的UIViewController视图的边界

时间:2015-01-01 21:02:47

标签: ios uiviewcontroller uiscrollview uiedgeinsets

我可以配置我的UIViewController edgesForExtendedLayout,以便它会扩展到导航栏或标签栏等内容的下方。如果我这样做,有没有办法确定模糊的框架?

作为一种替代方法,UIViewController是否有办法确定要应用于其中包含的UIScrollView的默认contentInset?

用例

我有可缩放的UIScrollView包含图像。

当它完全缩小时,我想调整内容插入,也允许内容保持居中(details here)。但是,我修改后的插图不会考虑UIViewController自动应用的插图,以便其内容不会被导航条等遮挡。

我还需要计算内容的最小缩放比例 - 整个图像将在其中可见而不会被遮挡。为了计算这一点,我需要知道内容视图中未显眼部分的大小。

1 个答案:

答案 0 :(得分:0)

你需要这个

-(CGRect) unobscuredBounds
{
    CGRect bounds = [self.view bounds];
    return UIEdgeInsetsInsetRect(bounds, [self defaultContentInsets]);
}

-(UIEdgeInsets) defaultContentInsets
{
    const CGFloat topOverlay = self.topLayoutGuide.length;
    const CGFloat bottomOverlay = self.bottomLayoutGuide.length;
    return UIEdgeInsetsMake(topOverlay, 0, bottomOverlay, 0);
}

您可以将其放在category中以便于重复使用。

这些方法可以正确处理旋转后视图调整大小时发生的更改 - 正确处理对UINavigationBar大小的更改。

居中内容

要将此用于centre content by adjusting insets,您可以执行以下操作:

-(void) scrollViewDidZoom:(UIScrollView *)scrollView
{
    [self centerContent];
}

- (void)centerContent
{
    const CGSize contentSize = self.scrollView.contentSize;
    const CGSize unobscuredBounds = [self unobscuredBounds].size;

    const CGFloat left = MAX(0, (unobscuredBounds.width - contentSize.width)) * 0.5f;
    const CGFloat top = MAX(0, (unobscuredBounds.height - contentSize.height)) * 0.5f;

    self.scrollView.contentInset = UIEdgeInsetsMake(top, left, top, left);
}

您的内容插入现在将反映他们需要的默认插入(以避免被掩盖),并且还将具有他们需要很好地居中的插图。

处理轮换&变焦

您可能还希望在横向和纵向之间进行动画制作时居中。同时,您可能需要调整最小缩放比例,以便内容始终适合。尝试这样的事情:

-(void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [self centerContent];

    const bool zoomIsAtMinimum = self.scrollView.zoomScale == self.scrollView.minimumZoomScale;

    self.scrollView.minimumZoomScale = [self currentMinimumScale];

    if(zoomIsAtMinimum)
    {
        self.scrollView.zoomScale = self.scrollView.minimumZoomScale;
    }
}

-(CGFloat) currentMinimumScale
{
    const CGFloat currentScale = self.scrollView.zoomScale;
    const CGSize scaledContentSize = self.scrollView.contentSize;
    const CGSize scrollViewSize = [self unobscuredBounds].size;

    CGFloat scaleToFitWidth = currentScale * scrollViewSize.width / scaledContentSize.width;
    CGFloat scaleToFitHeight = currentScale * scrollViewSize.height / scaledContentSize.height;

    return MIN(scaleToFitWidth, scaleToFitHeight);
}

在视图动画块中调用willAnimateRotationToInterfaceOrientation:…方法,因此当您从横向切换到纵向时,它应用的更改将导致更好的平滑动画更改。