UIStackView's own intrinsicContentSize
Asked Answered
K

3

21

I'm using the UIStackView with the following configuration:

let contentView = UIStackView()
contentView.distribution = .EqualSpacing
contentView.alignment = .Center
contentView.spacing = horizontalSpacing

Each of the elements has it's own intrinsicContentSize so it should be possible for the UIStackView to provide its own intrinsicContentSize. The documentation states that the spacing is used as a minimum spacing.

Example:

view1: width=10
view2: width=15
spacing = 5
[view1(10)]-5-[view2(15)]

The intrinsicContentSize.width of the stackView should be 30.

Instead I get:

▿ CGSize
 - width : -1.0
 - height : -1.0 { ... }

which tells me that the intrinsicContentSize cannot be provided.

Does anyone of you know if I doing something wrong, if the behaviour is intended or if this is a bug?

Kooky answered 26/10, 2015 at 14:52 Comment(0)
E
22

As of iOS 9.1, UIStackView doesn't implement intrinsicContentSize:

import UIKit
import ObjectiveC

let stackViewMethod = class_getInstanceMethod(UIStackView.self, "intrinsicContentSize")
let viewMethod = class_getInstanceMethod(UIView.self, "intrinsicContentSize")
print(stackViewMethod == viewMethod)

Output:

true

You could make a subclass of UIStackView and implement it yourself if you really need it. You shouldn't need to, though. If UIStackView is allowed (by the constraints on it) to choose its own size, it does so based on its arranged subviews' intrinsic content size (or by other constraints you've set on the sizes of its arranged subviews).

Ectomy answered 29/10, 2015 at 18:58 Comment(5)
Imagine if I have all my stuff inside a stackview and I add this stackview to its superView. But I still have another view (actually I have a viewController's view) in my superView. How would constraint these two against each other so the stackview would just take its intrinsic size and leave the rest for the childVC?Lockwood
Sounds like you need to post your own top-level question.Ectomy
You are right. I'm just trying to get a rough idea. Like a 2 line response. Also the reason I didn't post a question is because this is my PlanB...my planA is failing me, but also taking all my coding bandwidth, so I just want to get a rough estimate of what needs to be done. Can you give me a 2 line response? :/ anything further I'll just ask a questionLockwood
I'd need more details of your view hierarchy, which warrants a separate question.Ectomy
@Honey my solution was - don't use UIStackView (implement your own, it's not hard)Encephalomyelitis
L
6

Get this instead:

stackView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)

If you wish to fit it in a view you can pass the actual view's frame and desired priorities for the horizontal and vertical fittings. For example, this will preserve the width of the view and size the height:

stackView.systemLayoutSizeFitting(view.frame.size, withHorizontalFittingPriority: .required, verticalFittingPriority: .defaultLow)
Lighterage answered 27/12, 2020 at 10:9 Comment(0)
A
2

the UIViews you created have an intrinsic height and width of zero. Try using autolayout constraints instead for the underlying UIViews.

You can also use autolayout in order to size the UIStackView, if you do this use do not set alignment to center, you should use fill instead.

example:

@property (nonatomic, strong) UIStackView *firstStackView;

@property (nonatomic, strong) UIView *redView;
@property (nonatomic, strong) UIView *blueView;
@property (nonatomic, strong) UIView *yellowView;
@property (nonatomic, strong) UIView *greenView;

@property (nonatomic, strong) NSArray *subViews;

self.redView = [[UIView alloc] init];
self.redView.backgroundColor = [UIColor redColor];
self.blueView = [[UIView alloc]  init];
self.blueView.backgroundColor = [UIColor blueColor];
self.yellowView = [[UIView alloc] init];
self.yellowView.backgroundColor = [UIColor yellowColor];
self.greenView = [[UIView alloc] init];
self.greenView.backgroundColor = [UIColor blackColor];
self.subViews = @[self.greenView,self.yellowView,self.redView,self.blueView];

self.firstStackView = [[UIStackView alloc] initWithArrangedSubviews:self.subViews];
self.firstStackView.translatesAutoresizingMaskIntoConstraints = NO;
self.firstStackView.distribution = UIStackViewDistributionFillEqually;
self.firstStackView.axis = UILayoutConstraintAxisHorizontal;
self.firstStackView.alignment = UIStackViewAlignmentFill;

[self.firstStackView.heightAnchor constraintEqualToConstant:40].active = YES;
[self.firstStackView.widthAnchor constraintEqualToConstant:500].active = YES;

This will work because the stackview now has a height and width.

Aryanize answered 29/10, 2015 at 18:46 Comment(1)
Where does the stackViewForCell variable come from?Kooky

© 2022 - 2024 — McMap. All rights reserved.