1
votes

I have a UIView and inside this UIView I have another UIView, lets say parent and child UIView. I have set height and width of parent UIView to 400 in storyboard and set child view constraint to take 8px margin from top, left right and bottom from its superview.

But When I change size of parent view to 200, size of child view remain same. I have tried this in both viewdidload and viewdidappear

CGRect frm = self.mainTimerView.frame;
frm.size.width = size;
frm.size.height = size;
self.mainTimerView.frame = frm;

when I change parent view to 200 child should set it self to 200-16 height and width according to constraints.

5
You are taking size from "mainTimerView" and then again setting "mainTimerView" with same size. How can it change then. - WasimSafdar
call [parent layoutIfNeeded] - akc
Wasim I am changing its width and height in 2nd and 3rd line then assigning it again to mainTimerView - Yawar
arshadkc I am trying it - Yawar
@Yawar you need to take outlet for constraint then change the constraint value . - balkaran singh

5 Answers

2
votes

1) Change the height constraint of the mainview.

2) Call the layoutIfNeeded method.

3) Do it on viewDidAppear.

2
votes

You should not mix using uiconstraint with using frame.If you want to change the size when using uiconstraint, you should make the outlet of the constraint, and then change the constraint's constant property.Call layoutIfNeeded,then you can get the right frame.

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UIButton *mainTimerView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *mainTimerViewHeightConstraint;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.view layoutIfNeeded];
    NSLog(@"%@",@(self.mainTimerView.frame.size.width));

    self.mainTimerViewHeightConstraint.constant = 100;

    [self.view layoutIfNeeded];
    NSLog(@"%@",@(self.mainTimerView.frame.size.height));
}

@end

Calling layoutIfNeeded aim to to force the layout of subviews before drawing, then viewDidLayoutSubviews will be called. Note that you can get the correct frame in viewDidLayoutSubviews. In other words, you can get the right frame after viewDidLayoutSubviews has been called.

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    NSLog(@"%@",NSStringFromCGRect(self.mainTimerView.frame));
}
0
votes

Have you tried calling setNeedsLayout on the parent view? This call is used to ask a view to layout its subviews. From the setNeedsLayout's discussion section:

Call this method on your application’s main thread when you want to adjust the layout of a view’s subviews. This method makes a note of the request and returns immediately. Because this method does not force an immediate update, but instead waits for the next update cycle, you can use it to invalidate the layout of multiple views before any of those views are updated. This behavior allows you to consolidate all of your layout updates to one update cycle, which is usually better for performance.

Calling layoutIfNeeded might be another option. But according to the docs, it forces an immediate layout, and therefore does not provide the consolidation benefit gained by using setNeedsLayout.

layoutIfNeeded documention:

Lays out the subviews immediately.

0
votes

enter image description here

Plz create the IBOutlet of height Constraint of parent view.

IBOutlet NSLayoutConstraint *RedViewHeightconstraint;

- (void)viewWillAppear:(BOOL)animated
{
     RedViewHeightconstraint.constant = 500;
}

it will work for you

0
votes

You just need to create IBOutlets of constraints of height and width of mainTimerView. Once you do so add these lines of code :

constraintOuterViewHt.constant = 200 constraintOuterViewWidth.constant = 200

You don't need to do anything else. Check screen shot here