UIStackView: Loading views from xib and updating h

2019-02-22 04:11发布

问题:

I have the following hierarchy in my application

- UIScrollView
- UIStackView
 - UIView 1  // load with xib and added in arrangedSubviews
   - UIScrollView 1.1 // horizontal scrolling, fixed height constraint 38
   - UIView 1.2 // called it childView. has fixed height 0 (I load the view from xib and add it here dynamically and update its height)
     - UIView 1.2.1 // called it New View
 - UIView 2
 - UIView 3

So my problem is when I have loaded a view from xib and added it to UIView1.2 also increased height constraint 0 to a height of newly added sub-view but nothing will happen.UIView1.2height did not update expectedly .

self.constraintChildViewHeight.constant = 95;
[self layoutIfNeeded];

NewView *newView = (NewView *)[[[NSBundle mainBundle]loadNibNamed:NSStringFromClass([FieldPhotoView class]) owner:self options:nil]objectAtIndex:0];
[newView setTranslatesAutoresizingMaskIntoConstraints:false];
[self.childView addSubview:newView];
[self applyConstraintsToParent:self.childView andSubView:newView];

Method

- (void)applyConstraintsToParent:(UIView *)parentView andSubView:(UIView *)subView {
//constraints

NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0];

[parentView addConstraint:leading];

NSLayoutConstraint *trailing = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0];


[parentView addConstraint:trailing];

NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];

[parentView addConstraint:top];

NSLayoutConstraint *bottom = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-8];

[parentView addConstraint:bottom];

NSLayoutConstraint *equalWidth = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0];


[parentView addConstraint:equalWidth];

leading.active = true;
trailing.active = true;
top.active = true;
bottom.active = true;
equalWidth.active = true;
}

#Edit1 - Child view constraints

#Edit2 - For better understanding, I want to achieve this functionality programmatically using xib's(In UIStoryBoard is just working fine.)

回答1:

From your question what i understood is that you are not able to scroll your content in the scrollview 1.1.

Try the following steps :

  1. For the scrollview 1.1

    • give top, bottom,leading, trailing constraints w.r.t View1.
    • give scrollview height constraint = 38
  2. For the childview UIView 1.2

    • give top, bottom,leading, trailing constraints w.r.t scrollview1.1
    • pin childview w.r.t View1 for leading & trailing edges
    • give childview height constraints
    • give childview vertically center constraint.
  3. For the newView UIView 1.2.1

    • Load view from nib.
    • Add it to the childview
    • Set its constraints - top, bottom, leading & trailing w.r.t childview.

This will make your content scrollable.

I have shared a sample project here: https://github.com/Abhie87/StackExchangeSample

Hope this will be helpful.



回答2:

Tried to do the same and it worked as expected. What I did:

  • Initial views hierarchy looks like this:
  • Stack view constraints are on the next image:
  • Each view in stack view has only its' height set by constraint (the button in last view I use to add/remove the new view to the stack view at index 0)
  • The view to add is loaded from .xib file called SomeView.xib view hierarchy and constraints for which are on the next image (constraint called View Height Constraint is set to 1 and is changed to 95 when SomeView is added to the stack view):

The function that is called when the button is tapped looks like this:

- (IBAction)buttonTap:(UIButton *)sender {
    if (self.theView) {
        [self.stackView removeArrangedSubview:self.theView];
        [self.theView removeFromSuperview];
        self.theView = nil;
    } else {
        self.theView = [[[NSBundle mainBundle] loadNibNamed:@"SomeView" owner:nil options:nil] firstObject];
        self.theView.translatesAutoresizingMaskIntoConstraints = NO;
        [self.stackView addSubview:self.theView];
        [self.stackView insertArrangedSubview:self.theView atIndex:0];
        self.theView.viewHeightConstraint.constant = 95;
    }
}

Hope this will give you any suggestions in how to fix your situation