UIStackView on TitleView Spacing issue after iOS 16
Asked Answered
I

2

7

I have an UIStackView set up on the title view of the navigation bar in my app. It simply shows the icon of the app to the left of the title. In iOS 15 and earlier, this displayed fine. Right now, however, it shows fine the first time you launch the app, but navigating to a different view, the icon is in the wrong spot of THAT view, and will be in the incorrect spot when returning to the parent view as well. Pictures of this are below the code.

- (void)viewWillAppear:(BOOL)animated
 UIImageView *theimageView = [[UIImageView alloc] init];
    theimageView.contentMode = UIViewContentModeScaleAspectFit;
    theimageView.image = [UIImage imageNamed:nameOfColor];
    UILabel *titleLabel = [[UILabel alloc] init];
    titleLabel.font = [UIFont fontWithName:@"Roboto-Bold" size:16];
    titleLabel.textColor = [UIColor whiteColor];
    titleLabel.text = self.title;

    UIStackView *hStack = [[UIStackView alloc] init];
    [hStack addArrangedSubview:theimageView];
    [hStack addArrangedSubview:titleLabel];
    hStack.axis = UILayoutConstraintAxisHorizontal;

 
    self.navigationItem.titleView = hStack;
    [super viewWillAppear:animated];

enter image description here enter image description here

Idyll answered 5/10, 2022 at 14:16 Comment(0)
P
4

I'm able to reproduce your issue. One thing I'm sure of is that apple has made some changes to this part of UIKit. enter image description here

Providing a custom UIStackView as a titleView to the navigation bar is totally OK. But to properly set a UIStackView you should add some constraints.

You should add several constraints to help the UIStackView know how you want to layout your arranged subview.

UIImageView *theimageView = [[UIImageView alloc] init];
theimageView.contentMode = UIViewContentModeScaleAspectFit;
theimageView.image = [UIImage systemImageNamed: @"peacesign"];

//  Contraints to image height
[theimageView.heightAnchor constraintEqualToConstant: 20].active = true;


UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.font = [UIFont fontWithName:@"Roboto-Bold" size:16];
titleLabel.textColor = [UIColor blackColor];
titleLabel.text = self.title;
//  Contraints to label height
[titleLabel.heightAnchor constraintEqualToConstant: 20].active = true;


UIStackView *hStack = [[UIStackView alloc] init];
[hStack addArrangedSubview:theimageView];
[hStack addArrangedSubview:titleLabel];
hStack.axis = UILayoutConstraintAxisHorizontal;
//  Center the items
hStack.alignment = UIStackViewAlignmentCenter;

//  Spacing of 6
hStack.spacing = 6;



self.navigationItem.titleView = hStack;
[super viewWillAppear:animated];

If you add the two missing constraints, now the titleView works like iOS 15 and earlier.

enter image description here

Pascasia answered 8/10, 2022 at 0:31 Comment(1)
Thank you. That helped, though to get the image to still stay same size, had to set the constraint to 44 and not 20.Idyll
Y
3

The way we solved this in our app is by setting both the content compression resistance priority and the content hugging priority, of both the image view and the label, for both horizontal and vertical, to UILayoutPriorityRequired.

https://developer.apple.com/documentation/uikit/uiview/1622485-setcontenthuggingpriority?language=objc

https://developer.apple.com/documentation/uikit/uiview/1622526-setcontentcompressionresistancep?language=objc

Yankee answered 8/10, 2022 at 2:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.