9 Stimmen

Wie sollen NSTableCellViews angeordnet werden?

Ich habe eine ziemlich einfache MainWindow.xib mit einer Seitenleiste im Source-List-Stil. Ich habe sie erstellt, indem ich die Vorlage Source List in das Fenster gezogen habe, das bereits zwei NSTableCellViews enthält: HeaderCell und DataCell.

Letzteres besteht aus einem Symbol (mit NSImageView) und einem Label (NSTextField). Stattdessen möchte ich das Label und ein weiteres, kleineres Label darunter haben. In IB sieht das wie folgt aus:

Source-List gemäß IB

Wenn ich mich nur auf DataCell konzentriere, wird es entsprechend hervorgehoben:

Hervorgehobener DataCell

Die Sache ist, wenn ich das Programm tatsächlich ausführe, sieht es überhaupt nicht wie die Vorlage aus:

Zweites Element in live DataCell ausgewählt

Bemerken Sie, wie die beiden NSTextFields einfach zu einem zusammengequetscht werden. Meine Vorstellung war, dass viewbasierte NSOutlineViews (und auch viewbasierte NSTableViews) in IB als Vorlage entworfen sein sollen. Stattdessen scheinen die Abmessungen aus der Vorlage größtenteils ignoriert zu werden.

Hier ist der Code, der die Werte der Ansicht aus der Datenquelle setzt:

public class TourSourceListDelegate : NSOutlineViewDelegate
{
    public override bool IsGroupItem(NSOutlineView outlineView, MonoMac.Foundation.NSObject item)
    {
        return (item as TourSourceListDataSource.Item).IsHeader;
    }

    public override NSView GetView(NSOutlineView outlineView, NSTableColumn tableColumn, MonoMac.Foundation.NSObject item)
    {
        if (IsGroupItem(outlineView, item))
        {
            return outlineView.MakeView("HeaderCell", this);
        }
        else
        {
            var data = item as TourSourceListDataSource.Item;
            var dataView = outlineView.MakeView("DataCell", this);

            (dataView.Subviews[0] as NSTextField).StringValue = data.Name;
            (dataView.Subviews[1] as NSTextField).StringValue = data.Date_start.ToShortDateString();

            return dataView;
        }
    }
}

Ich habe versucht, GetRowHeight zu überschreiben, aber das scheint das Problem nicht zu lösen (es macht mehr Platz, aber lässt die Ansichten trotzdem nicht richtig verteilen), noch scheint es notwendig zu sein.

Ich habe auch mit verschiedenen Einstellungen wie Automatische Größenanpassung, Unteransichten automatisch anpassen usw. in IB gespielt, aber das scheint keine intuitiven Ergebnisse zu bringen, und auch das scheint nicht notwendig zu sein - die Ansicht wie sie in IB präsentiert wird, ist genau das, was ich will, nur mit etwas längeren Labels in der Praxis.

Ich habe dies noch nicht in AutoLayout umgewandelt.

Welchen offensichtlichen Schritt übersehe ich?

Weitere Informationen, die wahrscheinlich keine Rolle spielen: Dies ist ein Xamarin.Mac/MonoMac-Projekt mit Xcode 5.0, MacOSX10.8.sdk, Xamarin Studio 4.0.12, Xamarin.Mac 4.0.12 und Mono 3.2.3 (Ausrichtung auf Mono / .NET 4.0). Ich habe auch die App-Sandbox aktiviert.

1voto

Pierre Houston Punkte 1601

Was wichtig ist im Interface Builder, ist die Ansichtshierarchie. Was für eine Ansicht ist diese Zelle? Sind diese Labels wirklich Unterdarstellungen der Zellenansicht oder nicht? Die Hierarchie sollte ungefähr so aussehen:

Beispiel der NSOutlineView-Zellenhierarchie

Etwas Merkwürdiges, was ich sehe, ist der Zugriff auf dataView.Subviews[0] und [1]. Wenn Sie Unteransichten zu Ihren Zellen hinzufügen, sollten Sie Ihre eigenen NSTableViewCell-Unterklassen erstellen, wobei jede Ansicht mit den IBOutlet-Eigenschaften der Unterklasse verbunden ist. Die Unterklasse benötigt keinen Code in ihrer Implementierung, nur die Deklaration ihrer Eigenschaften in @interface, wie z.B. titleField und descriptionField, sowie eine leere @implementation, die diese automatisch synthetisiert.

Dann sollte makeViewWithIdentifier (oder anscheinend die Verknüpfung MakeView in Xamarin) bei Verwendung des richtigen Bezeichners Ihre NSTableViewCell-Unterklasse erstellen, und zur Laufzeit können Sie dies mit po dataView im Debugger überprüfen. Dann greifen Sie auf die Unterdarstellungen mithilfe der Eigenschaften des NSTableViewCell-Interface Ihrer Unterklasse zu, anstatt anzunehmen, welche Ansicht sich in welcher Position im Unterdarstellungsarray befindet, indem Sie dataView.titleField und dataView.descriptionField verwenden.

Wenn Ihre Zellansicht ein Textfeld hat, dann können Sie NSTableViewCell ohne Unterklassen verwenden, aber verbinden Sie den textField-Outlet (er ist standardmäßig verbunden, solange Sie die Zellenansichts-Labelansicht nicht löschen und neu erstellen), damit Sie darauf über die Eigenschaft zugreifen können, anstelle in das Unterdarstellungsarray einzutauchen.

Alles in allem ist es nicht wirklich klar, warum Sie sehen, was Sie sehen. Es scheint, dass das nicht die Unterdarstellungen sind, die Sie erwarten, und es könnte sogar aussehen wie die falschen Schriftarten sowie an den falschen Positionen. Die Verwendung einer benutzerdefinierten Unterklasse von NSTableViewCell und die Überprüfung ihrer Klasse zur Laufzeit ist eine gute Möglichkeit, sicherzustellen, dass die erwartete Ansicht erstellt wird, aber Sie können auch die Unterdarstellung im Debugger mit po [dataView _subtreeDescription] ausgeben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X