2

In my app I want to achieve this layout:

enter image description here

So parent view contains two sub views. First one ends exactly in a middle (height / 2) and second starts in a middle of parent view. I have found out that it is impossible to do that in the IB with constraints. So I used this code in viewDidLoad method:

NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:firstView
                                                              attribute:NSLayoutAttributeHeight
                                                              relatedBy:0
                                                                 toItem:self.view
                                                              attribute:NSLayoutAttributeHeight
                                                             multiplier:0.5
                                                               constant:0];

[self.view addConstraint:constraint];

Now it works but only if the app runs on the iPhone. Because size of the view is like iPhone screen. If this app runs on the iPad, there is a problem because screen has different size so this parent view is longer. And constraint (code above) still takes 0.5 * size of the views size from the IB and not size from the iPad size of the view. Item toItem:self.view still takes size from the IB.

Result is that this view has a same size in the iPad as in the iPhone. In the iPad there is a large blank space and then there is a view with iPhone size.

Can you tell what I have to do to make it universal for various screen sizes? Thank you very much

4

6 回答 6

5

这可以使用约束来实现,但是 IB 让这变得有点烦人且不灵活的约束管理器。这是我的管理方式:

  • 在 IB 中,使用正确的框架设置两个视图
  • 在两个视图之间添加等高约束
  • 降低任一视图上任何默认高度约束的优先级。不幸的是,IB 不允许您完全删除这些,但将它们设置为小于 1000 将确保它们被忽略。
  • 在视图控制器的 viewDidLoad 方法中,添加您已经尝试过的约束。

例如

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self.topView
                                                                  attribute:NSLayoutAttributeHeight
                                                                  relatedBy:NSLayoutRelationEqual
                                                                     toItem:self.view
                                                                  attribute:NSLayoutAttributeHeight
                                                                 multiplier:0.5
                                                                   constant:0];
    [self.view addConstraint:constraint];
}

而已。IB 约束的屏幕截图如下所示:

顶视图约束 底视图约束

于 2013-05-27T14:13:20.827 回答
2

试试这个代码。它将动态设置约束值

在您的 .h 文件中,实现这一行。

  #define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
  #define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *TopsubviewheightConstraint;

现在根据给定的屏幕截图创建此约束

苹果手机

适用于 iPad

从屏幕连接 TopsubviewheightConstraint 高度约束

苹果手机

适用于 iPad

在 .m 文件中实现此代码

if (IS_IPHONE_5) 
    _TopSuperViewConstraint.constant = 275;
else if(IS_IPAD)
    _TopSuperViewConstraint.constant = 502;
else
    _TopSuperViewConstraint.constant = 230;

我希望它会帮助你。

于 2013-05-27T09:19:32.110 回答
1

感谢塔克的回答,我也设法使用约束来做到这一点:

  1. 将 TobView 的垂直空间约束添加到Top Layout Guide(使用 StoryBoard)
  2. 将 BottomView 的垂直空间约束添加到Bottom Layout Guide(使用 StoryBoard)
  3. 在 ViewDidLoad 中为每个视图添加两个高度约束

代码:

NSLayoutConstraint *constraint;
constraint = [NSLayoutConstraint constraintWithItem:_viewTop
                                          attribute:NSLayoutAttributeHeight
                                          relatedBy:NSLayoutRelationEqual
                                             toItem:self.view
                                          attribute:NSLayoutAttributeHeight
                                         multiplier:0.5
                                           constant:0];


[self.view addConstraint:constraint];
constraint = [NSLayoutConstraint constraintWithItem:_viewBottom
                                          attribute:NSLayoutAttributeHeight
                                          relatedBy:NSLayoutRelationEqual
                                             toItem:self.view
                                          attribute:NSLayoutAttributeHeight
                                         multiplier:0.5
                                           constant:0];
[self.view addConstraint:constraint];
于 2014-01-27T01:23:28.423 回答
1

你有2个选择。

  1. 为 iPad 创建第二个 IB 文件
  2. 通过程序做所有事情并使用[[UIScreen mainScreen] bound];而不是获取父级的大小;)

我会在没有任何限制的情况下这样做,并设置如下:

// self.view is my container view

CGRect frame = [[UIScreen mainScreen] bound];
frame.size.height /= 2;    

// upper View
upperView.frame = frame;

// lower View
frame.origin.y = frame.size.height;
// or alternatively
//frame.origin.y = CGRectGetMaxY(frame);
lowerView.frame = frame;

在这里,您不需要任何特定于设备的选项,一切都是动态的,与设备屏幕的大小有关;)

于 2013-05-27T09:18:52.680 回答
1

好的,所以我只是想出了如何做到这一点。只需将代码放入viewDidLayoutSubviews方法而不是viewDidLoad. 我在主题Unable to set frame before viewDidAppear中找到的解决方案。

这是我的代码:

[subView1 setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height / 2)];
[subView2 setFrame:CGRectMake(0, self.view.frame.size.height / 2, self.view.frame.size.width, self.view.frame.size.height / 2)];

感谢大家的努力!

于 2013-05-27T13:30:02.237 回答
0

您可以使用约束来执行此操作(无需代码!)

1.- 首先创建两个 UIview 并手动将其高度设置为当前设备大小的一半,将一个放在另一个上,就像这样: 图像 1

2.- 接下来,您必须像这样为它们中的每一个设置约束(这将允许容器填满整个屏幕,一个在另一个之上):

顶部容器 图像 2

底部容器 图像 3

3.- 最后,您必须选择两个容器并添加一个新的约束,指定它们将具有相同的高度 图 4

(记得为每一步添加“添加 X 约束”)

现在应该准备好将标签放入每个容器中,您将准备好

于 2019-02-22T15:17:08.570 回答