ios - 横向自动布局内容大小的 UIScrollview

标签 ios xcode uiscrollview uinavigationcontroller autolayout

我正在尝试在我的应用程序中显示一个简单的设置屏幕,并且我正在使用自动版式。由于我的应用程序支持横向,并且设置控件在手机横向时不太适合垂直放置,因此我添加了一个 UIScrollview。

似乎 UIScrollview 和 Autolayout 的组合在这里和其他地方都是一个常见的问题。我已经阅读了几篇关于它的文章,从它所知道的情况来看,似乎实现我正在尝试做的事情的一个好方法是将我的各种控件放在一个 View 中,比如带有约束的“contentView”在该 View 中对齐。然后让 contentView 成为 UIScrollView 的唯一 subview 。我有约束绑定(bind)到 UIScrollView 边缘的 contentView。

UINavigationView -> UIScrollview -> contentView (UIView) -> Control Subviews

xib

即使我在 contentView 中添加需要滚动才能看到的内容,它在纵向模式下也能正常工作,但是当我转到横向模式时,它不会让我向下滚动得足够远。这就像当我旋转时内容大小被重置为可见区域的框架(或导航 Controller super View 的框架)。

simulator

我想知道是否需要检查旋转然后重新设置内容大小?如果是这样,有没有办法从 View (contentView)中动态获取该大小?

感谢您提供的任何帮助! 吉姆

最佳答案

让自动布局正确处理 ScrollView 有两个组成部分:

  1. ScrollView subview 的约束: ScrollView 的 contentSize 将由 ScrollView subview 的约束决定。因此,您需要为 ScrollView 中的最后一个控件(即第二个开关)对其父 View (即 ScrollView )设置一个底部约束。看起来你确实有这个。 ScrollView 的 subview 的这些约束将根据需要自动调整 ScrollView 的 contentSize

    顺便说一句,第二个开关的底部约束的常量 通常会默认为某个较大的值,对应于纵向布局的方式。您可能希望为最后一个控件选择和编辑底部约束并更改它,使其成为“标准”值。

    enter image description here

  2. ScrollView 本身的约束:您需要确保 ScrollView 本身对其父 View 具有底部约束(并确保您具有高度 ScrollView 上的约束)。这将在屏幕旋转时调整 ScrollView 的 frame。我想知道您的项目中是否缺少此内容。

    您可以通过在调试器中运行您的应用并点击“暂停”按钮来确认这一点:

    enter image description here

    然后在 (lldb) 提示符下,键入 po [[UIWindow keyWindow] recursiveDescription],您应该会看到如下内容:

    (lldb) po [[UIWindow keyWindow] recursiveDescription]
    <UIWindow: 0x8b97ff0; frame = (0 0; 320 480); autoresize = W+H; gestureRecognizers = <NSArray: 0x8b98450>; layer = <UIWindowLayer: 0x8b97af0>>
       | <UIView: 0x8b9a830; frame = (0 0; 320 480); transform = [0, -1, 1, 0, 0, 0]; autoresize = RM+BM; layer = <CALayer: 0x8b9a240>>
       |    | <UIScrollView: 0x8b9aa50; frame = (0 0; 480 320); clipsToBounds = YES; autoresize = RM+TM; gestureRecognizers = <NSArray: 0x8b9a6c0>; layer = <CALayer: 0x8b9a130>; contentOffset: {0, 0}>
       |    |    | <UILabel: 0x8b9ade0; frame = (20 20; 63 21); text = 'Settings'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x8b9aec0>>
       |    |    | <UILabel: 0x8b9d590; frame = (20 49; 51 21); text = 'View 1'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x8b9d6b0>>
       |    |    | <UILabel: 0x8b9db70; frame = (408 49; 51 21); text = 'View 2'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x8b9dc10>>
       |    |    | <UIView: 0x8b9de60; frame = (335 78; 124 53); autoresize = RM+BM; layer = <CALayer: 0x8b9dec0>>
       |    |    | <UIView: 0x8b9e000; frame = (20 78; 284 53); autoresize = RM+BM; layer = <CALayer: 0x8b9e060>>
       |    |    | <UILabel: 0x8b9e250; frame = (20 139; 59 21); text = 'Slider 1'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x8b9e2f0>>
       |    |    | <UISlider: 0x8b9e460; frame = (18 238; 444 34); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x8b9e5c0>; value: 0.500000>
       |    |    |    | <UIView: 0x8ace410; frame = (2 16; 440 2); userInteractionEnabled = NO; layer = <CALayer: 0x8ace470>>
       |    |    |    |    | <UIView: 0x8ace610; frame = (221 0; 219 2); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8ace670>>
       |    |    |    |    |    | <UIView: 0x8ace6e0; frame = (-221 0; 440 2); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8ace740>>
       |    |    |    |    |    |    | <CAGradientLayer: 0x8ace7b0> (layer)
       |    |    |    |    | <UIView: 0x8ace7e0; frame = (0 0; 221 2); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8ace840>>
       |    |    |    | <UIImageView: 0x8ace9d0; frame = (207 1; 31 31); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8acea60>>
       |    |    |    |    | <UIImageView: 0x8ace8b0; frame = (-13 -6.5; 57 43.5); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8ace940>>
       |    |    | <UISlider: 0x8b9e850; frame = (17 168; 444 34); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x8b9e930>; value: 0.500000>
       |    |    |    | <UIView: 0x8ba5430; frame = (2 16; 440 2); userInteractionEnabled = NO; layer = <CALayer: 0x8ba5490>>
       |    |    |    |    | <UIView: 0x8acc190; frame = (221 0; 219 2); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8acae30>>
       |    |    |    |    |    | <UIView: 0x8acc3f0; frame = (-221 0; 440 2); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8ac84d0>>
       |    |    |    |    |    |    | <CAGradientLayer: 0x8accb90> (layer)
       |    |    |    |    | <UIView: 0x8acdf50; frame = (0 0; 221 2); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8acdfb0>>
       |    |    |    | <UIImageView: 0x8ace070; frame = (207 1; 31 31); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8ace100>>
       |    |    |    |    | <UIImageView: 0x8acdfe0; frame = (-13 -6.5; 57 43.5); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8acdc80>>
       |    |    | <UILabel: 0x8b9e9c0; frame = (20 209; 59 21); text = 'Slider 2'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x8b9ea60>>
       |    |    | <UISwitch: 0x8b9ece0; frame = (411 279; 51 31); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x8b9edd0>>
       |    |    |    | <_UISwitchInternalViewNeueStyle1: 0x8b9f0c0; frame = (0 0; 51 31); gestureRecognizers = <NSArray: 0x8b723f0>; layer = <CALayer: 0x8b9f1c0>>
       |    |    |    |    | <UIView: 0x8b9f750; frame = (35.5 0; 15.5 31); clipsToBounds = YES; layer = <CALayer: 0x8b9f7b0>>
       |    |    |    |    |    | <UIView: 0x8b9f3b0; frame = (-35.5 0; 51 31); layer = <CALayer: 0x8b9f410>>
       |    |    |    |    | <UIView: 0x8b9f6c0; frame = (0 0; 35.5 31); clipsToBounds = YES; layer = <CALayer: 0x8b9f720>>
       |    |    |    |    |    | <UIView: 0x8b9f440; frame = (0 0; 51 31); layer = <CALayer: 0x8b9f4a0>>
       |    |    |    |    | <UIView: 0x8ba11e0; frame = (0 0; 51 31); layer = <CALayer: 0x8ba1240>>
       |    |    |    |    |    | <UIImageView: 0x8ba0f10; frame = (39 16; 0 0); alpha = 0; userInteractionEnabled = NO; layer = <CALayer: 0x8ba10f0>>
       |    |    |    |    |    | <UIImageView: 0x8ba1120; frame = (12 16; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x8ba11b0>>
       |    |    |    |    | <UIImageView: 0x8b9fab0; frame = (7 -6; 57 43.5); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8ba0a40>>
       |    |    | <UISwitch: 0x8b974b0; frame = (411 318; 51 31); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x8b75570>>
       |    |    |    | <_UISwitchInternalViewNeueStyle1: 0x8b7d6a0; frame = (0 0; 51 31); gestureRecognizers = <NSArray: 0x8b845e0>; layer = <CALayer: 0x8b78750>>
       |    |    |    |    | <UIView: 0x8b7df70; frame = (35.5 0; 15.5 31); clipsToBounds = YES; layer = <CALayer: 0x8b7be00>>
       |    |    |    |    |    | <UIView: 0x8b72410; frame = (-35.5 0; 51 31); layer = <CALayer: 0x8b7a660>>
       |    |    |    |    | <UIView: 0x8b7ba80; frame = (0 0; 35.5 31); clipsToBounds = YES; layer = <CALayer: 0x8b7bd00>>
       |    |    |    |    |    | <UIView: 0x8b78dd0; frame = (0 0; 51 31); layer = <CALayer: 0x8b7ba20>>
       |    |    |    |    | <UIView: 0x8b81580; frame = (0 0; 51 31); layer = <CALayer: 0x8b77ee0>>
       |    |    |    |    |    | <UIImageView: 0x8b97880; frame = (39 16; 0 0); alpha = 0; userInteractionEnabled = NO; layer = <CALayer: 0x8b7e1a0>>
       |    |    |    |    |    | <UIImageView: 0x8b77460; frame = (12 16; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x8b7e350>>
       |    |    |    |    | <UIImageView: 0x8b80670; frame = (7 -6; 57 43.5); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8b80700>>
       |    |    | <UILabel: 0x8b97cf0; frame = (335 284; 67 21); text = 'Switch 1'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x8b808b0>>
       |    |    | <UILabel: 0x8b79d60; frame = (335 323; 67 21); text = 'Switch 2'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x8b77b90>>
       |    |    | <UIImageView: 0x8ac44f0; frame = (476 473; 3 7); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x8a89130>>
       |    |    | <UIImageView: 0x8ac2be0; frame = (313 316; 7 3); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x8ac2c70>>
       |    | <_UILayoutGuide: 0x8b9cb20; frame = (0 0; 0 20); hidden = YES; layer = <CALayer: 0x8b9e5f0>>
       |    | <_UILayoutGuide: 0x8ac4440; frame = (0 320; 0 0); hidden = YES; layer = <CALayer: 0x8a90370>>
    

    检查 UIScrollViewframe(例如,上面是 iPhone 上的横向),并确保它与屏幕尺寸相对应。如果您尚未定义 ScrollView 与其父 View 之间的约束,则此 frame 可能不正确。

关于ios - 横向自动布局内容大小的 UIScrollview,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22206789/

相关文章:

javascript - Phonegap/Cordova 更改单个声音的音量?

ios - 在 iOS Swift2 中读取本地 HTML 文件

ios - 创建新对象时查询核心数据的特定属性,如果存在则返回对象,如果不存在则创建一个新对象

iphone - 应用商店更新后的核心数据

swift - 如何使用 Realm 保存和删除 2 个文本文件?

ios - 我怎样才能得到 UILabel 的高度?

ios - 尝试使用 NSUserDefaults() 保存数组时出错

ios - 仅在命令行工具中找不到匹配的配置文件

ios - 在 UIPageViewController 内的 ViewController 内的 ScrollView 中检测 ScrollOffset?

ios - UITableViewCell 内的 UIScrollView - 水平滚动