UIStackView: Loading views from xib and updating height constraint of subView did not reflecting any changes?
Asked Answered
I

2

6

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

enter image description here

#Edit1 - Child view constraints

ChildView(UIView 1.2)

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

Working implementation on UIStoryBoard

Interleave answered 7/8, 2018 at 6:23 Comment(16)
Still not all the constraints mentioned. Do you have bottom constraint connecting child view and its' superview? What is self in your code? (Now can just say that you definitely don't need the equalWidth constraint, cause widths are already have to be equal according to leading and trailing constraints)Malay
Okay, I will put another image for child view constraints and self is UIView 1 which is added to UIStackView. Can you please see my view hierarchy?Interleave
@AntonFilimonov Please see my updated question.Interleave
Tried to do the same - everything works as expected.. Do you get any warnings in console? Maybe some constraints are in conflict.Malay
No, There is not a single warning. but it's not working in my case.Interleave
@AntonFilimonov Can you please share your working code?Interleave
check this out github.com/anton-filimonov/StackViewTest hope this will help youMalay
@AntonFilimonov incompatible project version?Interleave
@Vishal16 I suggest using "Debug View Hierarchy" to check every view properties and layout before continue. To make sure that it REALLY doesn't work. If it doesn't work, then which layout property is WRONGLY set or may you miss any constraints between UIView 1 & 1.2 ? Good luck ;) raywenderlich.com/1879-view-debugging-in-xcode-6Ehudd
@HoaiDam I will do that and update you. Thanks for the suggestion.Interleave
What Xcode version do you use? Changed project format to Xcode 8.0 compatibleMalay
Seems like it'd be easier if you share your not working sample. Because I've made almost exactly what's on your gif except that there was the only one view with expanding child. And it worked as expectedMalay
@AntonFilimonov are you using xib's?Interleave
Yes I load view which contains scroll view and the other view with changed height (like view 1 in your question) from xib.Actually the last possible case is that the view, you insert to view 1.2 (the newView, but we have no idea what's inside its' xib file) has constraints that conflict with others. But in this case there should be warnings about unsatisfiable constraints in console log..Malay
@AntonFilimonov Place your code in the answer I will mark it accepted.Interleave
@Vishal16 Finally got to do thatMalay
S
-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.

Springtime answered 15/8, 2018 at 6:26 Comment(6)
Failed to load project at '...Downloads/StackExchangeSample-master/StachExchangeBounty.xcodeproj', incompatible project version. Which version of Xcode?Interleave
Okay, Let me try. but if you can see my question I have already done as your solution.Interleave
I have edited my answer a bit. You can try that small changeSpringtime
I saw your implementation it's a bit confusing. Why are you adding childView in UIScrollView. It's by default has a parent scrollview. So that I only want to increase childView height when it's subview height changes.Interleave
also you are providing a fixed height constraint 200. Why?Interleave
My answer was based on what I understood from your problem statement. Height is set to 200 just as dummy value. If u have provided the screenshots of expected and current screen then it would have been easy to understand problem. No issues. Hope u would have got it resolved.Springtime
M
-2

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

  • Initial views hierarchy looks like this: enter image description here
  • Stack view constraints are on the next image: enter image description here
  • 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): enter image description here

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

Malay answered 18/8, 2018 at 4:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.