0

I've been struggling with this issue the whole day and would really require some help. What I'm trying to do is create a view whose frame adjusts based on the subviews with it. Based on certain business rules I have to add and remove subviews. Here is some sample code:

-(void)createLinkedAccountDetailsHeaderView {
    CGRect frame = CGRectMake(0, 0, 600, 220);
    CDPAccountDetailsView *accountDetailsView = [[CDPAccountDetailsView alloc ] initWithFrame:frame withViewModel:self.viewModel isInEditState:self.isInEditState];
    self.tableView.tableHeaderView = accountDetailsView;
}

- (instancetype)initWithFrame:(CGRect)frame withViewModel:(CDPDebitOrderDetailsReviewViewModel *)viewModel isInEditState:(BOOL) isInEditState {
    self = [super initWithFrame:frame];
    if (self) {
        self.viewModel = viewModel;
        self.isInEditState = isInEditState;

        [self initialiseView];
        [self configureWithAccountsView];
    }
    return self;
}

 (void)initialiseView {
    NSString *nibName = NSStringFromClass([self class]);
    UINib *nib = [UINib nibWithNibName:nibName bundle:[SBResourcesBundle bundleWithName:[CDPResourceBundle bundleName]]];
    [nib instantiateWithOwner:self options:nil];
    [SBViewUtility addSubview:self.mainView withConstraintsToParentView:self];
    [self layoutIfNeeded];

    self.circleView.layer.cornerRadius = self.circleView.bounds.size.width /2;

    //A lot of subview initialisation is done

    [self layoutIfNeeded];
}

How can I get the UIView to wrap around its subviews and change its frame based on its subviews? As it currently always uses the fixed frame regardless of its subviews.

user481610
  • 3,230
  • 4
  • 54
  • 101

2 Answers2

0

I would double check your constraints to ensure that they are constraining against top, bottom, left and right of your view, and then size to fit, as laid out here.

Community
  • 1
  • 1
Dave Barker
  • 155
  • 1
  • 7
0

I strongly advice against changing .frame of anything. Most of the time, modifying constraints is the way to go.

If I understand your question correctly, you want your view to grow/shrink according to its contents. If that is it, it should be pretty trivial.

Note about naming I'm using :

  • view = the view you're trying to resize.
  • subviews = the subviews contained in that specific view you're trying to resize

Step 1 :

Your view should be positioned but not "sized". I mean that it shouldn't have any constraint's between the view and its superview like "Equal width" or "Top & bottom". You only need to position it X & Y wise. For example, a top-top constraint & left-left constraint, or maybe center X & Y. I don't know, it depends on what you're trying to achieve.

Adding only those constraints will display an error that says "your view does not have enough csontraints, can't calculate width / height ". That's because we're not onto step 2 yet.

Step 2 :

What we're doing is defining the height & width of the view with the constraints of its subviews. Either you can hardcode them (which I usually advise against), or you constraint those subviews to the sides. Classic 4-side constraint building, link left to left, top to top, bottom to bottom and right to right. With or without margin, but thats irrelevant.

What you should have now is a valid view+subview constraint build, with most certainly (if you're using .xibs / .storyboard) a yellow warning, that if you resolve, will end up shrinking your view to a size of 0/0. That's because your current .xib does not have anything in it. If you want to add a label in it just for the sake of testing, you'll see another yellow warning for resize, and if you resolve it, your view will resize itself according to that label.

Pretty much anything inside the subviews will force the view to resize itself accordingly.

If its content is dynamically generated but that you would like to not have a view of size 0,0, you can add a constraint of Height yourself, hardcode a value, and check the box " Remove at build time ". The constraint will help the .xib be visually correct or closer to reality, while not disturbing the flow.

So, to summarize :

step 1 : Position the view, don't give it a size, ignore error.

step 2 : Give constraint to subviews, content will force the view to grow/shrink from the inside

step 3 : profit.

Gil Sand
  • 5,802
  • 5
  • 36
  • 78