Pat Long - Munkii Yebee
Pat Long - Munkii Yebee

Reputation: 3629

UIStackView - Positioning Image up against edge of sibling

I am trying to create a custom UITableViewCell in iOS that contains a Label and a related image. The image needs to be as close the the trailing edge of the label as possible.

Below is an image of the progress so far.The Red area is the Horizontal UIStackView in which I have placed the UILabel (Green) and the UIImageView (Cyan).

The UILabel as been set to Lines = 0.

I've played around with a number of the UIStackView Distribution and Alignment properties and have in the past made good use of the approach outlined in this article A UIStackView Hack for Stacking Child Views Compactly. In line with the technique in that article I have a third transparent View that has Lower ContentHugggingPriority so takes up most of the room. This almost works but something is causing the label to wrap at that fix point, it looks like it's a 1/3 of the overall width.

Not all rows will show the image.

Does anyone have any other suggestions for how to achieve this layout? I have tried plain old Autolayout (no UIStackView) but that had other issues

Current layout

Upvotes: 2

Views: 168

Answers (2)

Pat Long - Munkii Yebee
Pat Long - Munkii Yebee

Reputation: 3629

Whilst I have marked DonMag's answer as THE answer for this question I am including my own answer as I am creating the Views programatically as that was my final solution.

First up create the UISTackView container for the label and image

this.drugNameStackView = new UIStackView()
{
    TranslatesAutoresizingMaskIntoConstraints = false,
    Axis = UILayoutConstraintAxis.Horizontal,
    Alignment = UIStackViewAlignment.Top,
    Distribution = UIStackViewDistribution.Fill,
    Spacing = 0
};

Then having already created the UILabel add it to the StackView and set Compression Resistance

this.drugNameStackView.AddArrangedSubview(this.drugNameLabel);
this.drugNameLabel.SetContentCompressionResistancePriority(1000.0f, UILayoutConstraintAxis.Horizontal);

The key part of the solution and the main thing I learned from DonMag's answer where these two constraints that I added to the ContentView

this.ContentView.AddConstraints(
    new[]
    {
        NSLayoutConstraint.Create(this.drugNameStackView, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, this.ContentView, NSLayoutAttribute.LeadingMargin, 1.0f, 0),
        NSLayoutConstraint.Create(this.ContentView, NSLayoutAttribute.TrailingMargin, NSLayoutRelation.GreaterThanOrEqual, this.drugNameStackView, NSLayoutAttribute.Trailing, 1.0f, 0),
    });

Note that it is the ContentView that is the the first item in the constraint and the UISTackView the second for the NSLayoutRelation.GreaterThanOrEqual constraint

Upvotes: 1

DonMag
DonMag

Reputation: 77462

This may be what you're after...

enter image description here

The stack view is constrained to Top and Bottom margins, Leading Margin + 12, and Trailing Margin >= 12, with these settings:

Axis: Horizontal
Alignment: Top
Distribution: Fill
Spacing: 0

The image view has Width and Height constraints of 24

The label has no constraints, but has:

Content Compression Resistance Priority
    Horizontal: Required (1000)

The result (top set with image view, bottom set without):

enter image description here enter image description here

Upvotes: 3

Related Questions