iOS two views cover exactly half of parent view

拈花ヽ惹草 提交于 2019-12-11 03:45:13

问题


In my app I want to achieve this layout:

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


回答1:


This is possible using constraints, but it is made a bit fiddly by IBs rather annoying and inflexible constraint manager. Here is how I managed it:

  • In IB, set the two views with the correct frames
  • Add an equal height constraint between the two views
  • Reduce the priority of any default height constraints on either of the views. Unfortunately IB does not let you remove these entirely, but setting them to anything less than 1000 will make sure they are ignored.
  • In the view controllers viewDidLoad method, add the constraint you already tried.

eg

- (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];
}

Thats it. Screengrabs of the IB constraints are shown below:




回答2:


Try this code . It will set constraint value dynamically

In your .h file , implement this lines.

  #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;

Now create this constraint's as per given screen shot

connect TopsubviewheightConstraint height constraint from screen

implement this code in .m file

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

I hope it will help you.




回答3:


you have 2 options.

  1. create a second IB file for iPad
  2. do everything by programm and use [[UIScreen mainScreen] bound]; instead of getting the sizes of parent ;)

I would do it without the constraints at all and set as follow:

// 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;

here you don't need any device specific options, everything is dynamic, bound to the size of your device's screen ;)




回答4:


OK so I just figured out how to do this. Simply put the code into viewDidLayoutSubviews method and not to viewDidLoad. The solution I found in the topic Unable to set frame correctly before viewDidAppear.

Here is my code:

[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)];

Thanks to all for effort!




回答5:


Thanks to Tark's answer, I managed to to this using constraints as well:

  1. Add Vertical Space constraint for TobView to Top Layout Guide (Using StoryBoard)
  2. Add Vertical Space constraint for BottomView to Bottom Layout Guide (Using StoryBoard)
  3. Add two height constraints for each view in ViewDidLoad

Code:

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];



回答6:


You can do this with constrains (no code required!)

1.- First create two UIview and manually set it's height to half of the size of the current device, positioning one over the other, just like this:

2.- Next you must set the constraints for each one of them like this (this will allow to the container fill the whole screen, one over the another):

Top container

Bottom container

3.- Finally you must select both containers and add a new constrain that specify that they will have in the same height

(remember to clid "Add X Constrains" for each step)

now it should be ready to put the label inside each container, and you will ready



来源:https://stackoverflow.com/questions/16769847/ios-two-views-cover-exactly-half-of-parent-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!