0

我的问题是关于滚动视图的自动布局问题。

我只是想在故事板上添加一个滚动视图,它对超级视图有自己的约束,但里面没有任何子视图,一旦应用程序运行,就在其中添加一个 imageView。但是由于情节提要上的“内容大小不明确”错误,即使我们取消选中“检查歧义”选项,autoLayout 也无法在 scrollView 上工作。如果我应用将 contentView 添加到 scrollView 的解决方案,并用所有这些额外的约束固定它,我仍然可以在 scrollView 内捏和缩放图像,但失去了平移的能力,无论 viewForZoom 是 contentView 还是添加了图像视图。如果 ContentView 是 imageView 我有同样的问题。可以缩放,不能平移。

另外,任何人都可以向我解释为什么当 ScrollView 没有内容时,在这个 Xcode 版本中会触发这种荒谬的“模棱两可的责骂内容错误”?为什么我们需要将一个带有两个冗余约束的 contentView 固定到 scrollView 的 superview 上?

4

3 回答 3

2

Interface Builder / Storyboard 无法知道您将在运行时添加子视图和约束。

因此,它告诉您当前布局的内容大小不明确。

如果滚动视图没有内容,不显示消息会更好吗?也许......但即使它显示设计错误,这并不意味着您必须修复它。

如果您真的想摆脱警告/错误,有几个选项:

1)在 Storyboard 中添加您的 imageView(具有适当的约束),并.image在运行时设置属性。

2)在 Storyboard 中添加一个子视图(具有适当的约束),并viewdidLoad()在添加 imageView 之前删除该视图。


编辑

这是一个简单的例子:https ://github.com/DonMag/ZoomTest

在 IB / Storyboard 中,我添加了一个UIScrollView并只设置了宽度、高度、centerX 和 centerY 约束,所以 Storyboard 告诉我Ambiguous Content Size

viewDidLoad中,我添加了一个UIImageView,设置适当的约束,设置滚动视图委托和最小/最大缩放比例。


编辑 2

结果使用256 x 256图像,并约束滚动视图以填充父视图(滚动视图背景为青色)...

加载时 - zoomScale == 1:

在此处输入图像描述

加载时 - zoomScale == 1 - 旋转:

在此处输入图像描述

zoomScale = 大约 1.5(刚好适合):

在此处输入图像描述

zoomScale = 大约 1.5 - 旋转后:

在此处输入图像描述

zoomScale == 5 - 平移到左上角:

在此处输入图像描述

zoomScale == 5 - 平移到左上角 - 旋转后:

在此处输入图像描述

zoomScale == 5 - 平移到右下方:

在此处输入图像描述

zoomScale == 5 - 平移到右下方 - 旋转后:

在此处输入图像描述

于 2020-01-02T13:25:44.310 回答
0

因此,简而言之,解决方案似乎是在情节提要上添加 ScrollView 约束,忽略无意义的错误,然后在 viewController 上使用 UIImage 初始化 UIImageView 属性,并在 viewDidLoad() 上将 imageView 添加到 scrollView,然后使用 NSLayoutConstraint 的 activate() 方法来设置相对于 scrollView 的 contentLayoutGuide 的 imageView 约束,将其固定到顶部、底部、左侧和右侧。

实现的例子在这里: https ://github.com/HikarusGF/ScrollView-ImageView-Zoom

PS:我喜欢在 storyboard 上设置 scrollView 委托,所以你不会在代码中看到它。

于 2020-01-08T19:21:36.487 回答
0

我终于想出了如何在故事板上实现这一点,并让它变得更简单。直到几个 XCode 版本之前的方式:

我们仍然可以在故事板上添加一个 ScrollView,它们具有典型的约束,使其垂直和水平居中到其 superView,并且宽度和高度相同,因此可以在全屏中看到滚动视图。

到目前为止一切顺利,现在是棘手的部分:在情节提要上添加一个 ImageView,作为 Scroll View 的子视图。在这里,我们需要的约束是四个 PIN THE IMAGEVIEW INSIDE THE SCROLLVIEW,但绝不是 SIZE CONSTRAINTS。如果我们在 ImageView 上使用与 ScrollView 相同的中心/等大小约束,那么当涉及到平移,尤其是旋转屏幕时,ScrollView 将表现出完全不稳定和荒谬的行为。

我们仍然会收到荒谬的故事板警告/错误,告诉我们我们的滚动视图具有“模糊的内容大小”,并且“更新帧”按钮也会有一个不稳定的行为,但我们可以完全忽略所有这些,并手动调整ScrollView 和其中的 ImageView,使其看起来与运行时完全相同。根本不需要额外的冗余约束,尤其是任何触及 ImageView 大小的东西。

然后,我们需要添加到 viewDidLoad() 中的唯一代码是委托方法 viewForZooming(),以通知 ScrollView 使用哪个子视图作为“可缩放”,在这种情况下,我们的 @IBOutlet UIImageView。必要的最小和最大缩放比例参数也可以在情节提要上设置。

func viewForZooming(in scrollView: UIScrollView) -> UIView? { return imageView }

最后,如果我们希望摆脱滚动视图中的初始边距,因为我们只是显示全屏图像,我们需要设置这个我在 IB 上找不到的选项:

scrollView.contentInsetAdjustmentBehavior = .never

这是 GitHub 上的植入项目:https ://github.com/HikarusGF/ScrollView-ImageView-Zoom

代码和故事板解决方案都在项目中实现。要从一个切换到另一个,只需更改情节提要上的初始 viewController。我已将故事板解决方案设置为默认值。

于 2020-01-15T11:48:39.213 回答