【问题标题】:imageView centered inside scrollViewimageView 在 scrollView 内居中
【发布时间】:2014-08-28 16:49:09
【问题描述】:

如何在滚动视图中垂直居中图像?

我在 Xcode 5 中使用情节提要。主视图嵌入在导航控制器中,并且在主情节提要中启用了“调整滚动视图插图”选项。这个主视图有一个滚动视图,它的大小等于主视图的大小。

imageView 位于 scrollView 内部,与 scrollView 大小相同。内容模式设置为 AspectFit。

所以,层次结构如下:

- UINavigationController
- UIView
   - UIScrollView
       - UIImageView

图像可以是横向或纵向的,并且可以是任意大小(在运行时加载)。这就是为什么 imageView 和 scrollView 大小一样的原因。

如何在 scrollView 内垂直居中图像?

编辑: 如前所述,我已将 imageView 的 contentMode 设置为 AspectFit,因为图像可能太大,所以我需要调整它的大小。我遇到的问题是图像不是滚动视图的中心。

您可以在link查看截图并在link下载源代码。

【问题讨论】:

  • 如果你选择了 uiimageview,你可以设置它的约束,如果你使用的是自动布局。设置宽度和高度,因为您似乎想要那个常数。然后在容器中设置水平和垂直。
  • 我无法对 imageView 设置约束,因为直到运行时我才知道图像大小(图像将被下载……可能是横向或纵向……也许它会大于屏幕尺寸或可能更小)。还有什么想法吗?我已经上传了代码。链接可以在原帖中找到。谢谢!
  • 但是您通过设置内容模式将图片设置为尽可能多地填充。您是否需要始终查看整个画面?试试我的方法,图片保持居中,你可以看到整个东西。就算换图。我喜欢你评论的方式,这样你就可以来回切换,我一直这样做!
  • 我已经对我的答案进行了编辑以处理捏缩放。

标签: ios uiscrollview uinavigationcontroller uiimageview uistoryboard


【解决方案1】:

使用@Douglas 提到的自动布局会很好。但是,如果您更喜欢传统方式,您也可以使用它。

我会先给你答案,然后再给你解释。您应该先从 storyboard 中删除 image view(我稍后会解释),然后添加 viewWillAppear 方法。

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // 1. Add the image view programatically
        UIImageView * imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"portrait.jpg"]];
        [_scrollView addSubview:imageView];
        _imageView = imageView;

    }

    - (void)viewWillAppear:(BOOL)animated
    {
        // 2. calculate the size of the image view
        CGFloat scrollViewWidth = CGRectGetWidth(_scrollView.frame);
        CGFloat scrollViewHeight = CGRectGetHeight(_scrollView.frame);
        CGFloat imageViewWidth = CGRectGetWidth(_imageView.frame);
        CGFloat imageViewHeight = CGRectGetHeight(_imageView.frame);
        CGFloat widthRatio = scrollViewWidth / imageViewWidth;
        CGFloat heightRation = scrollViewHeight / imageViewHeight;
        CGFloat ratio = MIN(widthRatio, heightRation);
        CGRect newImageFrame = CGRectMake(0, 0, imageViewWidth * ratio, imageViewHeight * ratio);
        _imageView.frame = newImageFrame;

        // 3. find the position of the imageView.
        CGFloat scrollViewCenterX = CGRectGetMidX(_scrollView.bounds);
        CGFloat scrollViewCenterY = CGRectGetMidY(_scrollView.bounds) + _scrollView.contentInset.top / 2 ;
        _imageView.center = CGPointMake(scrollViewCenterX, scrollViewCenterY);
    }    

解释如下:

  1. 不应该把imageView放到storyboard中,否则imageView的frame会被storyboard固定,不会随着图片的大小而变化。即使选择UIViewContentModeScaleAspectFill,imageView的frame依然没有改变。它只是在图像周围添加一些空白区域。

  2. 现在 imageView 的大小与您的图像相同。如果你想让它完全显示,你需要自己计算框架。

  3. 注意_scrollView.contentInset.top / 2,这就是为什么你需要把代码放在viewWillAppear而不是viewDidLoad_scrollView.contentInset.top 是导航栏的高度,在willViewAppear 之前为您自动计算。

你把你的图像视图放在一个滚动视图中,我猜你想放大和缩小。如果是这样,请添加self.imageView = imageView;viewDidLoad 的底部。将_scrollView的delegate设置为self,并添加如下方法:

    - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
    {
        return _imageView;
    }

【讨论】:

  • 谢谢!我会试一试,我会尽快通知你:)
  • 你是对的,有必要在 viewDidLoad 调用 (self.imageView = [[self.imageView alloc] init]) 然后 [self.scrollView addSubview:self.imageView]) 上初始化并添加 imageView,否则 imageView 的位置将因为情节提要而固定。然后按照您的建议计算中心。但有一件事是scrollView.contentInset.top 是在viewDidLayoutSubviews 上计算的,就在viewDidAppear 之前。
【解决方案2】:

我发表了评论,但随后查看了您的项目。你快到了。我执行了以下步骤,并得到了您正在寻找的结果。

首先,确保您已开启自动布局!!!

在故事板中单击滚动视图。您有一个与视图大小相同的滚动视图。您将施加一些限制。在故事板的底部,您会看到一些图标。

上面的第四个看起来有点像侧面的工字梁,它是别针按钮。选择滚动视图后,点击它会弹出一个弹出菜单。

对于滚动视图,请单击中间块周围的所有栏,以便将滚动视图固定到主视图的两侧。

您会注意到它们现在都是红色的。

然后去点击imageview。您再次将其设置为视图的大小。再次使用 pin 按钮,您将仅将 Width 固定为 320,将 Height 固定为 568。完成后,您将使用下一个按钮。

这是对齐按钮。选择图像视图后单击它。您将单击容器中的水平中心和容器中的垂直中心。

接下来,您需要向 ViewController.m 文件添加一种方法。

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    [_scrollView setContentSize:CGSizeMake(self.view.frame.size.width, self.view.frame.size.height)];
}

启动模拟器,让她撕裂!你会得到一个警告。它说滚动视图的内容大小不明确。不过没关系,因为你会在 viewDidLayoutSubviews 上设置它。

希望能有所帮助,或帮助某人。自动布局和滚动视图有点难!

编辑#1

如果您想使图像视图可缩放,可以通过捏缩放执行以下操作。

确保您使 .h 文件遵循 UIScrollViewDelagate。

@interface ViewController : UIViewController <UIScrollViewDelegate>

这将允许滚动视图能够访问滚动视图的委托方法。您正在寻找的方法被称为..

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return self.imageView;
}

然后在 .m 文件的 viewDidLoad 方法中执行以下操作。

_scrollView.minimumZoomScale = 0.5;
_scrollView.maximumZoomScale = 4.0;
_scrollView.delegate = self;

下划线和变量名同self.variable。任何一个都可以。

应该这样做。让我知道它是否有效或您有任何其他问题。尽情享受吧!

【讨论】:

  • 非常感谢!有效!我意识到,如果我不固定 imageView 的宽度和高度,那么我就不会收到与“歧义”问题相关的警告。此外,我不必在 viewDidLayoutSubviews 中设置内容大小。但是有一个警告,添加这些约束将停止使用 scrollView 的放大功能,这就是在这个项目中使用 scrollView 的目的。至于这个问题(在滚动视图中居中图像)我认为你的答案还可以,但仍然是缩放问题:(
  • 我会调查的。如果我的应用程序我使用放大一个,所以我们应该能够弄清楚!
  • 谢谢道格拉斯。关于缩放问题,我的意思是我已经进行了缩放。如果不对 imageView 设置垂直和水平约束,它就可以工作。但是当我这样做时,放大时会出现一些奇怪的行为......我在这里更新了项目文件link
  • 也会看看。尽快回复你。立即下载新项目。
  • @AJGM,你想用你添加的代码来完成什么?让我知道你想要什么,谢谢。
【解决方案3】:

这些是您可以使用的,ImageView 内容显示的 3 种模式。您可以通过动态设置它们来做到这一点,或者您也可以在情节提要中设置它们,单击 ImageView 并转到属性选项卡栏并从中选择在那里,运行它们并选择你想要的输出。

imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.contentMode = UIViewContentModeScaleToFill;
imageView.contentMode = UIViewContentModeScaleAspectFill;

希望对你有帮助

【讨论】:

  • 与@sargeras 相同...我已将 contentMode 设置为 AspectFit。这样,我可以调整图像大小以适合 imageView。问题是该图像不在滚动视图的中心。您可以在link查看屏幕截图并在link下载源代码。
  • 您的 UIView 是否设置在您想要的滚动视图的位置?即中心?
  • 是的,它在中心。你可以从这里下载这个项目link
【解决方案4】:

如果您想在图像视图中居中图像,请使用

imageView.contentMode=UIViewContentModeCenter;

图像在此内容模式下保持其大小。或者,您可以根据需要使用其他内容模式。

UIViewContentModeScaleToFill,
UIViewContentModeScaleAspectFit,      // contents scaled to fit with fixed aspect. remainder is transparent
UIViewContentModeScaleAspectFill,     // contents scaled to fill with fixed aspect. some portion of content may be clipped.
UIViewContentModeRedraw,              // redraw on bounds change (calls -setNeedsDisplay)
UIViewContentModeCenter,              // contents remain same size. positioned adjusted.
UIViewContentModeTop,
UIViewContentModeBottom,
UIViewContentModeLeft,
UIViewContentModeRight,
UIViewContentModeTopLeft,
UIViewContentModeTopRight,
UIViewContentModeBottomLeft,
UIViewContentModeBottomRight,

【讨论】:

  • 如果我使用 UIViewContentModeCenter 那么图像将不会调整大小以适应 imageView。这就是我将 contentMode 设置为 AspectFit 的原因。问题是图像不在滚动视图的中心。
  • 您可以在link查看截图并在link下载源代码。
猜你喜欢
  • 1970-01-01
  • 2021-03-25
  • 2012-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
相关资源
最近更新 更多