Zaakceptowałem SwiftArchitect's answer, ale widząc, jak byłem po podejście oparte na kod na TableCell dodaję osobną odpowiedź. Bez jego pomocy nie byłby w stanie dojść tak daleko.
Używam MVVMCross i Xamarin iOS i moją TableCell dziedziczy MvxTableViewCell
Tworzenie subviews
Z ctor komórki tworzę wszystkie niezbędne UILabels i wyłącz AutoResizingMasks ustawiając view.TranslatesAutoresizingMaskIntoConstraints = false
W tym samym czasie tworzę dwa UIViews leftColumnContainer i rightColumnContainer. Te ponownie TranslatesAutoresizingMaskIntoConstraints
ustawione na false.
Odpowiednie etykiety są dodawane jako subviews do UIViews leftColumnContainer
i rightColumnContainer
. Oba pojemniki są następnie dodawane jako subviews do TableCell za contentView
this.ContentView.AddSubviews(this.leftColumnContainer, this.rightColumnContainer);
this.ContentView.TranslatesAutoresizingMaskIntoConstraints = true;
W UILabels są wszystkie dane związane poprzez wywołanie MVVMCross DelayBind
Ustawianie Ograniczenia Układ (UpdateConstraints())
układ TableCell jest zależna od danych dla komórki, z których 5 z 8 etykiet jest opcjonalnych, a 4 z 8 muszą obsługiwać zawijanie tekstu:
Pierwsza rzecz Robię to przypinam Górny i Lewy z leftColumnContainer
do TableCell.ContentView. Następnie górny i prawy "rightColumnContainer" do TableCell.ContentView. Projekt wymaga, aby prawidłowa kolumna była mniejsza niż lewa, więc odbywa się to za pomocą skalowania. Używam FluentLayout do zastosowania tych ograniczeń
this.ContentView.AddConstraints(
this.leftColumnContainer.AtTopOf(this.ContentView),
this.leftColumnContainer.AtLeftOf(this.ContentView, 3.0f),
this.leftColumnContainer.ToLeftOf(this.rightColumnContainer),
this.rightColumnContainer.AtTopOf(this.ContentView),
this.rightColumnContainer.ToRightOf(this.leftColumnContainer),
this.rightColumnContainer.AtRightOf(this.ContentView),
this.rightColumnContainer.WithRelativeWidth(this.ContentView, 0.35f));
połączenia do ToLeftOf i ToRight of którzy tworzą prawą krawędź lewej kolumnie i lewą krawędź prawej kolumnie obok siebie
Kluczowym kawałek Rozwiązaniem, które pochodziło od SwiftArchitect było ustawienie wysokości ContentView w TableCell na> = na wysokość leftColumnContainer
i rightColumnContainer
. To nie było tak oczywiste, jak zrobić to z FluentLayout więc są one „longhand”
this.ContentView.AddConstraint(
NSLayoutConstraint.Create(this.ContentView, NSLayoutAttribute.Height, NSLayoutRelation.GreaterThanOrEqual, this.leftColumnContainer, NSLayoutAttribute.Height, 1.0f, 5.0f));
this.ContentView.AddConstraint(
NSLayoutConstraint.Create(this.ContentView, NSLayoutAttribute.Height, NSLayoutRelation.GreaterThanOrEqual, this.rightColumnContainer, NSLayoutAttribute.Height, 1.0f, 5.0f));
I wtedy ograniczenie górnej, lewej i prawej pierwszej etykiety w każdej kolumnie do kontenera kolumny. Oto przykład z pierwszej etykiety w lewej kolumnie
this.leftColumnContainer.AddConstraints(
this.categoryLabel.AtTopOf(this.leftColumnContainer, CellPadding),
this.categoryLabel.AtRightOf(this.leftColumnContainer, CellPadding),
this.categoryLabel.AtLeftOf(this.leftColumnContainer, CellPadding));
Dla każdej z etykiet, które są opcjonalne ja najpierw sprawdzić MVVMCross DataContext aby sprawdzić, czy są one widoczne. Jeśli są widoczne podobne ograniczenia dla lewego, górnego i prawego są stosowane z górnym jest ograniczony do dolnej części etykiety powyżej. Jeśli nie są one widoczne są usuwane z widokiem jak tak
this.bodyText.RemoveFromSuperview();
Jeśli zastanawiasz się, w jaki sposób komórki te będą pracować z iOSs komórki Ponowne omówię że następny.
Jeśli etykieta będzie ostatnia etykieta w kolumnie (jest to zależne od danych) I zastosować inną naukę klucz od SwiftArcthiect za odpowiedź
Let [kolumny] obliczenia ich idealnej wysokości przez dodanie pojedynczego wysokość ograniczenia do dołu najniższej etykietę (leftColumn.bottom Równe lowestLeftLabel.bottom)
czynienia z komórką Ponowne
Przy tak skomplikowanym zestawie ograniczeń i wielu komórkach opcjonalnych nie chciałem ponownie stosować ograniczeń za każdym razem, gdy komórka była ponownie wykorzystywana z potencjalnie różnymi etykietami opcjonalnymi. W tym celu buduję i ustawiam identyfikator ponownego użycia w czasie wykonywania.
Źródło TableSource pochodzi z MvxTableViewSource. W zamienione na GetOrCreateCellFor sprawdzić zadaniu reuseIdentifier (normalnego użytkowania), a jeśli tak wezwanie DequeueReusableCell jednak w tym przypadku mogę odroczyć do rutynowych zawarta w niestandardowej klasy komórka, która wie, jak należy budować konkretny identyfikator danych
protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item)
{
MvxTableViewCell cell;
if (this.reuseIdentifier != null)
{
cell = (MvxTableViewCell)tableView.DequeueReusableCell(this.reuseIdentifier);
}
else
{
// No single reuse identifier, defer to the cell for the identifer
string identifier = this.itemCell.GetCellIdentifier(item);
if (this.reuseIdentifiers.Contains(identifier) == false)
{
tableView.RegisterClassForCellReuse(this.tableCellType, identifier);
this.reuseIdentifiers.Add(identifier);
}
cell = (MvxTableViewCell)tableView.DequeueReusableCell(identifier);
}
return cell;
}
i wezwanie do budowania tożsamości
public string GetCellIdentifier(object item)
{
StringBuilder cellIdentifier = new StringBuilder();
var entry = item as EntryItemViewModelBase;
cellIdentifier.AppendFormat("notes{0}", entry.Notes.HasValue() ? "yes" : "no");
cellIdentifier.AppendFormat("_body{0}", !entry.Body.Any() ? "no" : "yes");
cellIdentifier.AppendFormat("_priority{0}", entry.Priority.HasValue() ? "yes" : "no");
cellIdentifier.AppendFormat("_prop1{0}", entry.Prop1.HasValue() ? "yes" : "no");
cellIdentifier.AppendFormat("_prop2{0}", entry.Prop2.HasValue() ? "yes" : "no");
cellIdentifier.AppendFormat("_warningq{0}", !entry.IsWarningQualifier ? "no" : "yes");
cellIdentifier.Append("_MEIC");
return cellIdentifier.ToString();
}
Jakie są ograniczenia w widokach kontenerowych? Nawet jeśli masz 1000 setów, a widok zewnętrzny zdecydował, że musi być mniejszy, _ coś musi dać! Przechwytywanie hierarchii widoków i przeglądanie ograniczeń środowiska wykonawczego może dostarczyć potrzebnych informacji. – Ben