2

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

Pat Long - Munkii Yebee
  • 3,592
  • 2
  • 34
  • 68

2 Answers2

3

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

DonMag
  • 69,424
  • 5
  • 50
  • 86
  • That's exactly what I am after. I'm doing it programatically and I do have some content running underneath but i don't think that'll effect this. – Pat Long - Munkii Yebee Jun 20 '19 at 17:31
  • So when I do that I get the image hugging the trailing edge of the Cell rather than prioritizing the connection to the Label – Pat Long - Munkii Yebee Jun 20 '19 at 18:26
  • Did you see I changed the stack view's trailing constraint from `<= 12` to `>= 12`? And how are you adding your *"content running underneath"*? – DonMag Jun 20 '19 at 18:49
  • I didn't notice that you had switched the ContentView to View1 from view2 in the Constraint. I am adding all this stuff in Xamarin using C#. We normally use a library that makes creating Constraints simpler but that abstraction can make you lazy. I've switched to NSLayoutConstraint.Create and I have it working. I am going to mark your answer and update my question to a) refer to your answer b) refer to my own answer when I write it that has the C# Xamarin Code. Many thanks – Pat Long - Munkii Yebee Jun 21 '19 at 08:08
  • I know this isn't SO etiquette but do you have any thoughts on my other StackView question, https://stackoverflow.com/questions/56716147/prevent-uistackview-from-compressing-uitableview – Pat Long - Munkii Yebee Jun 24 '19 at 07:05
1

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

Pat Long - Munkii Yebee
  • 3,592
  • 2
  • 34
  • 68