的UIScrollView与iOS自动布局约束:为子视图大小错误 [英] UIScrollView with iOS Auto Layout Constraints: Wrong size for subviews

查看:123
本文介绍了的UIScrollView与iOS自动布局约束:为子视图大小错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想生成code的视图。这是我的看法对象的层次结构

I'm trying to generate a view in code. Here's the hierachy of my view object


  • 的UIScrollView

    • 的UIView

      • 的UIButton

      的滚动型应是大小作为窗口相同。
      该按钮应尽可能大。
      我使用的是iOS自动布局,所以我所有的对象,约束字符串看起来像这样

      The ScrollView should be the same size as the window. The button should be as big as possible. I'm using iOS auto layout, so the constraint strings for all of my objects look like this

      H:|[object]|
      V:|[object]|
      

      我还设置 translatesAutoresizingMaskIntoConstraints NO 为每个对象。

      的问题是,该按钮只获取默认按钮大小。其父视图对象(UIView的)只得到大小子视图所需要的。

      The problem is that the button only gets the default button-size. Its parent view object (UIView) only gets the size its subviews need.

      红:UIScrollView中/黄色:UIView的

      如何可以强制这些观点是一样大的滚动视图?

      How can I force those views to be as big as the scrollView?

      当我使用一个UIView,而不是个UIScrollView的一切都很正常......

      When I use a UIView instead of th UIScrollView everything works great...

      下面是一些code:

          - (void) viewDidLoad {
      
              [super viewDidLoad];
      
              // SCROLL VIEW
              UIScrollView* scrollView = [UIScrollView new];
              scrollView.backgroundColor=[UIColor redColor];
              scrollView.translatesAutoresizingMaskIntoConstraints = NO;
      
              //CONTAINER VIEW
              UIView *containerView = [UIView new];
              containerView.translatesAutoresizingMaskIntoConstraints = NO;
              containerView.backgroundColor = [UIColor yellowColor];
              [scrollView addSubview:containerView];
      
              // CONSTRAINTS SCROLL VIEW - CONTAINER VIEW
              [scrollView addConstraints:
               [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[containerView]|"
                                                       options:0 metrics:nil
                                                         views:@{@"containerView":containerView}]];
              [scrollView addConstraints:
               [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[containerView]|"
                                                       options:0 metrics:nil
                                                         views:@{@"containerView":containerView}]];
      
              // BUTTON
              UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
              button.translatesAutoresizingMaskIntoConstraints = NO;
              [button setTitle:@"I'm way to small" forState:UIControlStateNormal];
              [containerView addSubview:button];
      
              // CONSTRAINTS CONTAINER VIEW - BUTTON
              [containerView addConstraints:
               [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[button]|"
                                                       options:0 metrics:nil
                                                         views:@{@"button":button}]];
              [containerView addConstraints:
               [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[button]|"
                                                       options:0 metrics:nil
                                                         views:@{@"button":button}]];
              self.view = scrollView;
      
          }
      

      更新:
      我真的不知道,为什么发生这种情况。如果您在IB设置来看,连接网点和实例化在code中的视图,滚动视图就像一个普通视图(其中垂直弹跳)。它的contentSize计算不正确。更多这里。但如何正确地做呢?

      推荐答案

      一对夫妇的意见:


      1. 在滚动的意见子视图约束不起作用像其他视图的约束。他们用来设置滚动视图的 contentSize 。 (请参见 TN2154 。)这样,你扔了一堆东西在滚动视图,设置约束它里面的东西,而 contentSize 正在为您计算。这是非常酷的功能,但它是对立的你想在这里做什么。

      1. Constraints for subviews in scroll views don't work like constraints in other views. They're used to set the contentSize of the scroll view. (See TN2154.) That way, you throw a bunch of stuff on a scroll view, set the constraints for the stuff inside it, and the contentSize is calculated for you. It's very cool feature, but it's antithetical to what you're trying to do here.

      更​​糟的是,按键会,除非你为他们的一个按钮的宽度和高度设置明确的约束,将根据其内容调整大小。

      Worse, buttons will, unless you set an explicit constraint for their width and height of a button, will resize according to their content.

      这两种意见的净效应是,现有的限制说:(一)设置我的容器是我按钮的大小;(二)让我的按钮,动态调整自身到文本的大小;及(c )设置滚动型我的 contentSize 根据我的容器的大小(这是按钮的大小)。

      The net effect of these two observations is that your existing constraints say "(a) set my container to be the size of my button; (b) let my button resize itself dynamically to the size of the text; and (c) set my scrollview's contentSize according to the size of my container (which is the size of the button)."

      我是不清楚的业务问题是什么。但这里有一些约束达到什么样的,我认为你的技术问题是:

      I'm unclear as to what the business problem is. But here are some constraints that achieve what I think your technical question was:

      - (void)viewDidLoad
      {
          [super viewDidLoad];
      
          UIView *view = self.view;
      
          UIScrollView *scrollView = [[UIScrollView alloc] init];
          scrollView.backgroundColor = [UIColor redColor]; // just so I can see it
          scrollView.translatesAutoresizingMaskIntoConstraints = NO;
          [self.view addSubview:scrollView];
      
          UIView *containerView = [[UIView alloc] init];
          containerView.backgroundColor = [UIColor yellowColor]; // just so I can see it
          containerView.translatesAutoresizingMaskIntoConstraints = NO;
          [scrollView addSubview:containerView];
      
          UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
          button.translatesAutoresizingMaskIntoConstraints = NO;
          [button setTitle:@"I'm the right size" forState:UIControlStateNormal];
          [containerView addSubview:button];
      
          NSDictionary *views = NSDictionaryOfVariableBindings(scrollView, button, view, containerView);
      
          // set the scrollview to be the size of the root view
      
          [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|"
                                                                            options:0
                                                                            metrics:nil
                                                                              views:views]];
      
          [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|"
                                                                            options:0
                                                                            metrics:nil
                                                                              views:views]];
      
          // set the container to the size of the main view, and simultaneously
          // set the scrollview's contentSize to match the size of the container
      
          [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[containerView(==view)]|"
                                                                             options:0
                                                                             metrics:nil
                                                                               views:views]];
      
          [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[containerView(==view)]|"
                                                                             options:0
                                                                             metrics:nil
                                                                               views:views]];
      
          // set the button size to be the size of the container view
      
          [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[button(==containerView)]"
                                                                                options:0
                                                                                metrics:nil
                                                                                  views:views]];
      
          [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[button(==containerView)]"
                                                                                options:0
                                                                                metrics:nil
                                                                                  views:views]];
      
      }
      

      坦率地说,我不明白你的UI的业务意图,因为这感觉就像汽车布局的扭曲达到了非常简单的用户界面。我不知道为什么你有一个滚动视图,如果你有它的屏幕尺寸的内容(除非你是通过按钮分页)。我不知道为什么你不得不在一个单一的项目内容视图。我不明白为什么您使用的是全屏幕按钮(我只是把一个点击手势根认为在这一点上和收工)。

      Frankly, I don't understand the business intent of your UI, as this feels like a contortion of auto layout to achieve a very simply UI. I don't know why you have a scroll view if you have "screen sized" content in it (unless you were paging through buttons). I don't know why you'd have a content view with a single item in it. I don't understand why you're using a full-screen button (I'd just put a tap gesture on the root view at that point and call it a day).

      我假设你拥有这一切很好的理由,但它可能是有意义的备份,请问你有什么期望的用户体验,然后接近新鲜的问题,看看是否有实现更有效的方法期望的效果。

      I'll assume you have good reasons for all of this, but it might make sense to back up, ask what is your desired user experience is, and then approach the problem fresh to see if there's a more efficient way to achieve the desired effect.

      这篇关于的UIScrollView与iOS自动布局约束:为子视图大小错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆