【问题标题】:Changing centering of content within UIScrollView在 UIScrollView 中更改内容的居中
【发布时间】:2011-11-08 03:41:59
【问题描述】:

我有一个以 UIImageView 作为内容的 UIScrollView。它显示良好,滚动良好。那里没有问题。图像比屏幕宽得多,所以我希望能够在滚动视图中“自动居中”图像的特定部分(坐标)。

不过,这就是我卡住的地方。所需的居中位置将根据应用程序的使用动态变化,因此我需要能够对其进行配置,以便加载时图像视图(x,y)的所需坐标在滚动视图中自动居中。它不必自动滚动/动画,它只需要在那里。

在使用手势/缩放时,我已经看到了类似的关于内容居中的问题/答案,但这里都没有使用。只是滚动。我只需要能够在第一次加载时让图像的一部分在滚动视图中居中。

我希望我说得有道理。感谢您的宝贵时间。

【问题讨论】:

    标签: ios xcode uiscrollview uiimageview


    【解决方案1】:

    我现在在 iPhone 上,如果这段代码有点古怪,请原谅,因为我不记得在没有先调用 size.center 的情况下,center 属性是否可用...

    CGPoint centerOffset = CGPointMake(0, [scrollView contentSize].(size).center);
    [scrollView setContentOffset: centerOffset animated: YES]; // (or No, depends on you)
    

    【讨论】:

    • 工作就像一个魅力!谢谢你的时间;我之前尝试过偏移,但显然不正确:)
    • 不客气!记得为工作答案投票。
    • 我已经尝试过了,但它不允许,因为我的代表还没有达到 15。一旦有能力,我肯定会回来并这样做。
    【解决方案2】:

    在研究了这个问题几天后,我想出了一个使用 ScrollView 属性的简单解决方案 - contentInset。 这将始终使图像居中,即使在缩放时(如果您遵循所有说明)。

    - (void)centerImage
    {
        if (!self.image) return;
    
        CGFloat imageScaleWidth = self.image.size.width * self.scrollView.zoomScale;
        CGFloat imageScaleHeight = self.image.size.height * self.scrollView.zoomScale;
    
        CGFloat hOffset = (self.frame.size.width - imageScaleWidth) * 0.5f;
        CGFloat vOffset = (self.frame.size.height - imageScaleHeight) * 0.5f;
    
        if (hOffset < 0) hOffset = 0;
        if (vOffset < 0) vOffset = 0;
    
        self.scrollView.contentInset = UIEdgeInsetsMake(vOffset, hOffset, 0, 0);
    }
    

    在 ScrollView 委托中调用此方法:

    - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
    {
        [self centerImage];
    }
    
    - (void)scrollViewDidZoom:(UIScrollView *)scrollView
    {
        [self centerImage];
    }
    

    当你布局子视图时:

    - (void)layoutScrollView
    {
        if (!self.image) return;
    
        CGFloat heightScale = self.frame.size.height / self.image.size.height;
        CGFloat widthScale = self.frame.size.width / self.image.size.width;
        CGFloat scale = MIN(widthScale, heightScale);
    
        self.scrollView.minimumZoomScale = scale;
        self.scrollView.maximumZoomScale = MAX(1.0f ,scale * 2.0f);
        [self.scrollView setZoomScale:self.scrollView.minimumZoomScale animated:NO];
    
        [self centerImage];
    }
    

    【讨论】:

    • 感谢您的回答。我已经在使用 ContentInsets,但问题是即使放大它们也在那里。使用你的方法,放大时没有更多的内容插入。我将它移植到 MonoTouch 的 C# 并且它工作得很好。您还向我介绍了 scrollViewDidZoom 方法,它为在缩放时改变事物提供了各种可能性。
    【解决方案3】:

    只需在滚动视图中设置其位置即可。例如:

    - (void)centreImageView
    {
        CGRect bounds = self.bounds;
        CGSize contentSize = self.contentSize;
        CGFloat offsetX = MAX(0, (bounds.size.width - contentSize.width) * 0.5f);
        CGFloat offsetY = MAX(0, (bounds.size.height - contentSize.height) * 0.5f);
    
        _myContentView.center = CGPointMake(contentSize.width * 0.5 + offsetX, contentSize.height * 0.5 + offsetY);
    }
    

    并在您的初始化中调用它,如果您正在缩放,也可以从- (void)scrollViewDidZoom:(UIScrollView *)scrollView 调用。

    【讨论】:

    • 这实际上解决了我的问题!谢谢!
    【解决方案4】:

    不确定这是否是您正在寻找的,但我只是想我会把它放在那里,这种方法有帮助吗?

    - (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center {
    
        CGRect zoomRect;
    
        // the zoom rect is in the content view's coordinates. 
        //    At a zoom scale of 1.0, it would be the size of the imageScrollView's bounds.
        //    As the zoom scale decreases, so more content is visible, the size of the rect grows.
        zoomRect.size.height = [scroller frame].size.height / scale;
        zoomRect.size.width  = [scroller frame].size.width  / scale;
    
        // choose an origin so as to get the right center.
        zoomRect.origin.x    = center.x - (zoomRect.size.width  / 2.0);
        zoomRect.origin.y    = center.y - (zoomRect.size.height / 2.0);
    
        return zoomRect;
    }
    

    还是这个?

    - (CGRect)zoomRectForScale:(float)scale withOrigin:(CGPoint)origin {
    
        CGRect zoomRect;
    
        // the zoom rect is in the content view's coordinates. 
        //    At a zoom scale of 1.0, it would be the size of the imageScrollView's bounds.
        //    As the zoom scale decreases, so more content is visible, the size of the rect grows.
        zoomRect.size.height = [scroller frame].size.height / scale;
        zoomRect.size.width  = [scroller frame].size.width  / scale;
    
        // choose an origin so as to get the right center.
        zoomRect.origin.x    = origin.x;
        zoomRect.origin.y    = origin.y;
    
        return zoomRect;
    }
    

    注意:这些不是我写的,它们来自Apple提供的示例代码,但我偶尔会使用它们,当我看到你的问题时就想到了它们。

    【讨论】:

    • 重读你的问题,我认为这不是你要找的,但我会把它们留在这里以防万一。
    • 感谢您抽出宝贵时间...与提供的另一个答案相比,我在完成这项工作时遇到了困难,但这可能是由于我缺乏经验。不过再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2013-03-13
    • 1970-01-01
    • 2021-10-23
    • 2011-11-24
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 2012-03-02
    相关资源
    最近更新 更多