I would like to align views in table cells to have all the trash bins on the left, the text field on the right (with fixed width) and the description filling the space between the two. The top would be breaking description in two lines if too long.
I'm trying with layout constraints in visual format but I'm not sure if it's the right approach.
var views = new UIView[] { btnRemove, lblDescription, txtQuantity };
var stkRoot = IOSUtils.CreateStackView(views, UILayoutConstraintAxis.Horizontal);
this.AddSubview(stkRoot);
var viewMetrics = new Object[] {
"stack", stkRoot,
"remove", btnRemove,
"label", lblDescription,
"field", txtQuantity,
"margin", 8
};
List<NSLayoutConstraint> constraints = new List<NSLayoutConstraint>();
constraints.AddRange(
NSLayoutConstraint.FromVisualFormat(
"V:|-margin-[stack]-margin-|",
NSLayoutFormatOptions.AlignAllLeading,
viewMetrics
)
);
constraints.AddRange(
NSLayoutConstraint.FromVisualFormat(
"H:|-margin-[remove]-margin-[label(>=70)]-margin-[field(60@20)]-margin-|",
NSLayoutFormatOptions.DirectionLeftToRight | NSLayoutFormatOptions.AlignAllCenterY,
viewMetrics
)
);
AddConstraints(constraints.ToArray());
btnRemove and txtQuantity are a UIButton and a UITextField with high resistance to compression and hugging, lblDescription is a UILabel with low resistance to hugging and compression. I still have to setup margin, colors, and so on... Anybody could give me some hints?
I've not used visual formats. This will also get the job done.
ContentView.AddSubviews (btnRemove, lblDescription, txtQuantity);
btnRemove.TranslatesAutoresizingMaskIntoConstraints = false;
lblDescription.TranslatesAutoresizingMaskIntoConstraints = false;
txtQuantity.TranslatesAutoresizingMaskIntoConstraints = false;
// add leading space to btnRemove
var btnRemoveLeading = NSLayoutConstraint.Create (btnRemove, NSLayoutAttribute.Leading,
NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Leading, 1, 8);
ContentView.AddConstraint (btnRemoveLeading);
// add center-y contraint to btnRemove
var btnRemoveCenterY = NSLayoutConstraint.Create (btnRemove, NSLayoutAttribute.CenterY,
NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.CenterY, 1, 0);
ContentView.AddConstraint (btnRemoveCenterY);
// add trailing space to txtQuantity
var txtQuantityTrailing = NSLayoutConstraint.Create (txtQuantity, NSLayoutAttribute.Trailing,
NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Trailing, 1, -8);
ContentView.AddConstraint (txtQuantityTrailing);
// add center-y contraint to txtQuantity
var txtQuantityCenterY = NSLayoutConstraint.Create (txtQuantity, NSLayoutAttribute.CenterY, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.CenterY, 1, 0);
ContentView.AddConstraint (txtQuantityCenterY);
// add horizontal space between btnRemove and lblDescription
var hsBtnRemoveTolblDescription = NSLayoutConstraint.Create (btnRemove, NSLayoutAttribute.Right,
NSLayoutRelation.Equal, lblDescription, NSLayoutAttribute.Left, 1, 8);
ContentView.AddConstraint (hsBtnRemoveTolblDescription);
// add horizontal space between txtQuantity and lblDescription
var hstxtQuantityTolblDescription = NSLayoutConstraint.Create (txtQuantity, NSLayoutAttribute.Left,
NSLayoutRelation.Equal, lblDescription, NSLayoutAttribute.Right, 1, 8);
ContentView.AddConstraint (hsBtnRemoveTolblDescription);
// add center-y contraint to lblDescription
var lblDescriptionCenterY = NSLayoutConstraint.Create (btnRemove, NSLayoutAttribute.CenterY,
NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.CenterY, 1, 0);
ContentView.AddConstraint (lblDescriptionCenterY);
Edit: also add width constrains to button and textfield, so that the label stretches.
var btnRemoveWidth = NSLayoutConstraint.Create (btnRemove, NSLayoutAttribute.Width,
NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, 32);
ContentView.AddConstraint (btnRemoveWidth);
var txtQuantityWidth = NSLayoutConstraint.Create (txtQuantity, NSLayoutAttribute.Width,
NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, 40);
ContentView.AddConstraint (txtQuantityWidth);
for making the label multiline, and make the UITableviewCell grow depending on number of lines your label has, add top and bottom constrains to the label and set height greater than some value:
var vSlblDescriptionToTop = NSLayoutConstraint.Create (lblDescription, NSLayoutAttribute.Top, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Top, 1, 8);
ContentView.AddConstraint (vSlblDescriptionToTop);
var vSlblDescriptionBottom = NSLayoutConstraint.Create (lblDescription, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Bottom, 1, -8);
ContentView.AddConstraint (vSlblDescriptionBottom);
var lblDescriptionHeight = NSLayoutConstraint.Create (lblDescription, NSLayoutAttribute.Height,
NSLayoutRelation.GreaterThanOrEqual, null, NSLayoutAttribute.NoAttribute, 1, 32);
ContentView.AddConstraint (lblDescriptionHeight);
and set your tableview's row height to AutomaticDimension
myTableView.EstimatedRowHeight = 44;
myTableView.RowHeight = UITableView.AutomaticDimension;
myTableView.Source = ....
Also override the UITableViewSource's GetHeightForRow to return AutomaticDimension
public override nfloat GetHeightForRow (UITableView tableView, NSIndexPath indexPath)
{
return UITableView.AutomaticDimension;
}