Erstellen von iOS-Benutzeroberflächen im Code in Xamarin.iOS
Die Benutzeroberfläche einer iOS-App ist wie ein Storefront – die Anwendung erhält in der Regel ein Fenster, kann das Fenster jedoch mit so vielen Objekten wie benötigt füllen, und die Objekte und Anordnungen können je nach Anzeige der App geändert werden. Die Objekte in diesem Szenario – die Dinge, die der Benutzer sieht – werden als Ansichten bezeichnet. Zum Erstellen eines einzigen Bildschirms in einer Anwendung werden Ansichten in einer Hierarchie von Inhaltsansichten aufeinander gestapelt, und die Hierarchie wird von einem einzelnen Ansichtscontroller verwaltet. Anwendungen mit mehreren Bildschirmen weisen mehrere Hierarchien von Inhaltsansichten auf. Jede davon verfügt über ihren eigenen Ansichtscontroller, und die Anwendung platziert Ansichten in das Fenster, um je nach dem vom Benutzer verwendeten Bildschirm eine andere Hierarchie von Inhaltsansichten zu erstellen.
Das folgende Diagramm veranschaulicht die Beziehungen zwischen dem Fenster, den Ansichten, Unteransichten und dem Ansichtscontroller, die die Benutzeroberfläche auf den Gerätebildschirm bringen:
Diese Ansichtshierarchien können mithilfe des Schnittstellen-Generators von Xcode erstellt werden, aber es ist gut, ein grundlegendes Verständnis dafür zu haben, wie Sie vollständig im Code arbeiten. In diesem Artikel werden einige grundlegende Punkte erläutert, um mit der Entwicklung von Nur-Code-Benutzeroberflächen vertraut zu werden.
Erstellen eines Nur-Code-Projekts
Leere Projektvorlage für iOS
Erstellen Sie zunächst ein iOS-Projekt in Visual Studio unter Verwendung des Projekts "Neues > Projekt > Visual C# > i Telefon & iPad > iOS App (Xamarin)", siehe unten:
Wählen Sie dann die Projektvorlage "Leere App " aus:
Die Vorlage "Leeres Projekt" fügt dem Projekt vier Dateien hinzu:
- AppDelegate.cs - Enthält eine
UIApplicationDelegate
Unterklasse,AppDelegate
die zum Behandeln von Anwendungsereignissen von iOS verwendet wird. Das Anwendungsfenster wird in derAppDelegate
Methode 'sFinishedLaunching
erstellt. - Main.cs - Enthält den Einstiegspunkt für die Anwendung, der die Klasse für die
AppDelegate
. - Info.plist – Eigenschaftenlistendatei, die Anwendungskonfigurationsinformationen enthält.
- Permissionss.plist – Eigenschaftenlistendatei, die Informationen zu den Funktionen und Berechtigungen der Anwendung enthält.
iOS-Anwendungen werden mithilfe des MVC-Musters erstellt. Der erste Bildschirm, den eine Anwendung anzeigt, wird über den Stammansichtscontroller des Fensters erstellt. Weitere Informationen zum MVC-Muster selbst finden Sie im Leitfaden zu Hello, iOS Multiscreen .
Die Implementierung für die AppDelegate
von der Vorlage hinzugefügte Anwendung erstellt das Anwendungsfenster, dessen Anwendung nur für jede iOS-Anwendung vorhanden ist, und macht sie mit dem folgenden Code sichtbar:
public class AppDelegate : UIApplicationDelegate
{
public override UIWindow Window
{
get;
set;
}
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
// create a new window instance based on the screen size
Window = new UIWindow(UIScreen.MainScreen.Bounds);
// make the window visible
Window.MakeKeyAndVisible();
return true;
}
}
Wenn Sie diese Anwendung jetzt ausführen würden, würden Sie wahrscheinlich eine Ausnahme auslösen, die besagt, dass Application windows are expected to have a root view controller at the end of application launch
. Fügen wir einen Controller hinzu und machen ihn zum Stammansichtscontroller der App.
Hinzufügen eines Controllers
Ihre App kann viele Ansichtscontroller enthalten, muss jedoch über einen Stammansichtscontroller verfügen, um alle Ansichtscontroller zu steuern. Fügen Sie dem Fenster einen Controller hinzu, indem Sie eine UIViewController
Instanz erstellen und auf die Window.RootViewController
Eigenschaft festlegen:
public class AppDelegate : UIApplicationDelegate
{
// class-level declarations
public override UIWindow Window
{
get;
set;
}
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
// create a new window instance based on the screen size
Window = new UIWindow(UIScreen.MainScreen.Bounds);
var controller = new UIViewController();
controller.View.BackgroundColor = UIColor.LightGray;
Window.RootViewController = controller;
// make the window visible
Window.MakeKeyAndVisible();
return true;
}
}
Jeder Controller verfügt über eine zugeordnete Ansicht, auf die über die View
Eigenschaft zugegriffen werden kann. Der obige Code ändert die Eigenschaft UIColor.LightGray
der Ansicht BackgroundColor
so, dass sie sichtbar ist, wie unten dargestellt:
Wir könnten auch jede UIViewController
Unterklasse auf RootViewController
diese Weise festlegen, einschließlich Controllern von UIKit sowie solche, die wir selbst schreiben. Der folgende Code fügt z. B. folgendes UINavigationController
hinzu:RootViewController
public class AppDelegate : UIApplicationDelegate
{
// class-level declarations
public override UIWindow Window
{
get;
set;
}
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
// create a new window instance based on the screen size
Window = new UIWindow(UIScreen.MainScreen.Bounds);
var controller = new UIViewController();
controller.View.BackgroundColor = UIColor.LightGray;
controller.Title = "My Controller";
var navController = new UINavigationController(controller);
Window.RootViewController = navController;
// make the window visible
Window.MakeKeyAndVisible();
return true;
}
}
Dadurch wird der Controller innerhalb des Navigationscontrollers geschachtelt, wie unten dargestellt:
Erstellen eines Ansichtscontrollers
Nachdem wir nun gesehen haben, wie ein Controller als RootViewController
Fenster hinzugefügt wird, sehen wir uns an, wie ein benutzerdefinierter Ansichtscontroller im Code erstellt wird.
Fügen Sie eine neue Klasse namens CustomViewController
wie unten dargestellt hinzu:
Die Klasse sollte von UIViewController
, die sich im UIKit
Namespace befindet, erben, wie gezeigt:
using System;
using UIKit;
namespace CodeOnlyDemo
{
class CustomViewController : UIViewController
{
}
}
Initialisieren der Ansicht
UIViewController
enthält eine Methode, die aufgerufen ViewDidLoad
wird, wenn der Ansichtscontroller zum ersten Mal in den Arbeitsspeicher geladen wird. Dies ist ein geeigneter Ort für die Initialisierung der Ansicht, z. B. das Festlegen der Eigenschaften.
Der folgende Code fügt beispielsweise eine Schaltfläche und einen Ereignishandler hinzu, um einen neuen Ansichtscontroller auf den Navigationsstapel zu übertragen, wenn die Schaltfläche gedrückt wird:
using System;
using CoreGraphics;
using UIKit;
namespace CodyOnlyDemo
{
public class CustomViewController : UIViewController
{
public CustomViewController ()
{
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
View.BackgroundColor = UIColor.White;
Title = "My Custom View Controller";
var btn = UIButton.FromType (UIButtonType.System);
btn.Frame = new CGRect (20, 200, 280, 44);
btn.SetTitle ("Click Me", UIControlState.Normal);
var user = new UIViewController ();
user.View.BackgroundColor = UIColor.Magenta;
btn.TouchUpInside += (sender, e) => {
this.NavigationController.PushViewController (user, true);
};
View.AddSubview (btn);
}
}
}
Um diesen Controller in Ihrer Anwendung zu laden und die einfache Navigation zu veranschaulichen, erstellen Sie eine neue Instanz von CustomViewController
. Erstellen Sie einen neuen Navigationscontroller, übergeben Sie ihre Ansichtscontrollerinstanz, und legen Sie den neuen Navigationscontroller wie zuvor auf das AppDelegate
Fenster RootViewController
fest:
var cvc = new CustomViewController ();
var navController = new UINavigationController (cvc);
Window.RootViewController = navController;
Wenn die Anwendung nun geladen wird, wird sie CustomViewController
in einem Navigationscontroller geladen:
Wenn Sie auf die Schaltfläche klicken, wird ein neuer Ansichtscontroller auf den Navigationsstapel verschoben :
Erstellen der Ansichtshierarchie
Im obigen Beispiel haben wir begonnen, eine Benutzeroberfläche im Code zu erstellen, indem wir dem Ansichtscontroller eine Schaltfläche hinzufügen.
iOS-Benutzeroberflächen bestehen aus einer Ansichtshierarchie. Weitere Ansichten, z. B. Beschriftungen, Schaltflächen, Schieberegler usw., werden als Unteransichten einiger übergeordneter Ansicht hinzugefügt.
Nehmen wir beispielsweise die CustomViewController
Bearbeitung vor, um einen Anmeldebildschirm zu erstellen, auf dem der Benutzer einen Benutzernamen und ein Kennwort eingeben kann. Der Bildschirm besteht aus zwei Textfeldern und einer Schaltfläche.
Hinzufügen der Textfelder
Entfernen Sie zunächst die Schaltfläche und den Ereignishandler, die im Abschnitt "Ansicht initialisieren" hinzugefügt wurden.
Fügen Sie ein Steuerelement für den Benutzernamen hinzu, indem Sie ein UITextField
Steuerelement erstellen und initialisieren und dann der Ansichtshierarchie hinzufügen, wie unten dargestellt:
class CustomViewController : UIViewController
{
UITextField usernameField;
public override void ViewDidLoad()
{
base.ViewDidLoad();
View.BackgroundColor = UIColor.Gray;
nfloat h = 31.0f;
nfloat w = View.Bounds.Width;
usernameField = new UITextField
{
Placeholder = "Enter your username",
BorderStyle = UITextBorderStyle.RoundedRect,
Frame = new CGRect(10, 82, w - 20, h)
};
View.AddSubview(usernameField);
}
}
Wenn wir das UITextField
Objekt erstellen, legen wir die Frame
Eigenschaft fest, um die Position und Größe zu definieren. In iOS befindet sich die Koordinate 0,0 oben links mit +x nach rechts und +y nach unten. Nach dem Festlegen der Frame
Zusammen mit einigen anderen Eigenschaften rufen View.AddSubview
wir die Ansichtshierarchie auf, um die UITextField
Ansichtshierarchie hinzuzufügen. Dadurch wird die usernameField
Unteransicht der UIView
Instanz, auf die die View
Eigenschaft verweist, erstellt. Eine Unteransicht wird mit einer Z-Reihenfolge hinzugefügt, die höher als die übergeordnete Ansicht ist, sodass sie vor der übergeordneten Ansicht auf dem Bildschirm angezeigt wird.
Die Anwendung mit dem UITextField
Enthaltenen wird unten angezeigt:
Wir können ein UITextField
Kennwort auf ähnliche Weise hinzufügen, nur dieses Mal legen wir die SecureTextEntry
Eigenschaft auf "true" fest, wie unten dargestellt:
public class CustomViewController : UIViewController
{
UITextField usernameField, passwordField;
public override void ViewDidLoad()
{
// keep the code the username UITextField
passwordField = new UITextField
{
Placeholder = "Enter your password",
BorderStyle = UITextBorderStyle.RoundedRect,
Frame = new CGRect(10, 114, w - 20, h),
SecureTextEntry = true
};
View.AddSubview(usernameField);
View.AddSubview(passwordField);
}
}
Durch Festlegen SecureTextEntry = true
wird der vom Benutzer eingegebene UITextField
Text wie unten dargestellt ausgeblendet:
Hinzufügen der Schaltfläche
Als Nächstes fügen wir eine Schaltfläche hinzu, damit der Benutzer den Benutzernamen und das Kennwort übermitteln kann. Die Schaltfläche wird der Ansichtshierarchie wie jedem anderen Steuerelement hinzugefügt, indem sie erneut als Argument an die Methode der übergeordneten Ansicht AddSubview
übergeben wird.
Der folgende Code fügt die Schaltfläche hinzu und registriert einen Ereignishandler für das TouchUpInside
Ereignis:
var submitButton = UIButton.FromType (UIButtonType.RoundedRect);
submitButton.Frame = new CGRect (10, 170, w - 20, 44);
submitButton.SetTitle ("Submit", UIControlState.Normal);
submitButton.TouchUpInside += (sender, e) => {
Console.WriteLine ("Submit button pressed");
};
View.AddSubview(submitButton);
Damit wird der Anmeldebildschirm nun wie unten dargestellt angezeigt:
Im Gegensatz zu früheren Versionen von iOS ist der Standardschaltflächenhintergrund transparent. Wenn Sie die Eigenschaft der Schaltfläche BackgroundColor
ändern, ändert sich folgendes:
submitButton.BackgroundColor = UIColor.White;
Dies führt zu einer quadratischen Schaltfläche anstelle der typischen abgerundeten abgerundeten Schaltfläche. Verwenden Sie den folgenden Codeausschnitt, um den abgerundeten Rand abzurufen:
submitButton.Layer.CornerRadius = 5f;
Bei diesen Änderungen sieht die Ansicht wie folgt aus:
Hinzufügen mehrerer Ansichten zur Ansichtshierarchie
iOS bietet eine Möglichkeit zum Hinzufügen mehrerer Ansichten zur Ansichtshierarchie mithilfe von AddSubviews
.
View.AddSubviews(new UIView[] { usernameField, passwordField, submitButton });
Hinzufügen von Schaltflächenfunktionen
Wenn auf eine Schaltfläche geklickt wird, erwarten Ihre Benutzer, dass etwas passiert. Beispielsweise wird eine Warnung angezeigt, oder die Navigation wird auf einem anderen Bildschirm ausgeführt.
Fügen wir nun Code hinzu, um einen zweiten Ansichtscontroller auf den Navigationsstapel zu übertragen.
Erstellen Sie zuerst den zweiten Ansichtscontroller:
var loginVC = new UIViewController () { Title = "Login Success!"};
loginVC.View.BackgroundColor = UIColor.Purple;
Fügen Sie dann dem Ereignis die Funktionalität hinzu TouchUpInside
:
submitButton.TouchUpInside += (sender, e) => {
this.NavigationController.PushViewController (loginVC, true);
};
Die Navigation ist unten dargestellt:
Beachten Sie, dass bei Verwendung eines Navigationscontrollers iOS der Anwendung eine Navigationsleiste und eine Zurück-Schaltfläche zur Verfügung stellt, damit Sie wieder durch den Stapel navigieren können.
Durchlaufen der Ansichtshierarchie
Sie können die Unteransichtshierarchie durchlaufen und eine bestimmte Ansicht auswählen. Um z. B. jede UIButton
schaltfläche zu finden und eine andere BackgroundColor
zu geben, kann der folgende Codeausschnitt verwendet werden.
foreach(var subview in View.Subviews)
{
if (subview is UIButton)
{
var btn = subview as UIButton;
btn.BackgroundColor = UIColor.Green;
}
}
Dies funktioniert jedoch nicht, wenn die Ansicht, für die iteriert wird, eine UIView
ist, da alle Ansichten als objekte UIView
zurückkommen, die der übergeordneten Ansicht selbst hinzugefügt werden.UIView
Behandeln von Drehungen
Wenn der Benutzer das Gerät in das Querformat dreht, wird die Größe der Steuerelemente nicht entsprechend geändert, wie der folgende Screenshot veranschaulicht:
Eine Möglichkeit, dies zu beheben, besteht darin, die AutoresizingMask
Eigenschaft für jede Ansicht festzulegen. In diesem Fall möchten wir, dass die Steuerelemente horizontal gestreckt werden, sodass wir jedes AutoresizingMask
festlegen würden. Das folgende Beispiel ist für usernameField
, aber das gleiche muss auf jedes Gadget in der Ansichtshierarchie angewendet werden.
usernameField.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
Wenn wir nun das Gerät oder den Simulator drehen, erstreckt sich alles, um den zusätzlichen Platz zu füllen, wie unten gezeigt:
Erstellen benutzerdefinierter Ansichten
Zusätzlich zur Verwendung von Steuerelementen, die Teil von UIKit sind, können auch benutzerdefinierte Ansichten verwendet werden. Eine benutzerdefinierte Ansicht kann durch Erben UIView
und Überschreiben Draw
erstellt werden. Erstellen wir eine benutzerdefinierte Ansicht und fügen sie der Ansichtshierarchie hinzu, um zu veranschaulichen.
Erben von UIView
Als Erstes müssen wir eine Klasse für die benutzerdefinierte Ansicht erstellen. Dazu verwenden wir die Vorlage "Klasse" in Visual Studio, um eine leere Klasse mit dem Namen CircleView
hinzuzufügen. Die Basisklasse sollte auf UIView
", die wir zurückrufen, im UIKit
Namespace festgelegt werden. Außerdem benötigen wir den System.Drawing
Namespace. Die anderen namespaces System.*
werden in diesem Beispiel nicht verwendet, daher können Sie sie entfernen.
Die Klasse sollte wie folgt aussehen:
using System;
namespace CodeOnlyDemo
{
class CircleView : UIView
{
}
}
Zeichnen in einer UIView
Jedes UIView
verfügt über eine Draw
Methode, die vom System aufgerufen wird, wenn sie gezeichnet werden muss. Draw
sollte niemals direkt aufgerufen werden. Es wird vom System während der Ausführungsschleifenverarbeitung aufgerufen. Wenn eine Ansicht der Ansichtshierarchie zum ersten Mal durch die Ausführungsschleife hinzugefügt wurde, wird die Draw
Methode aufgerufen. Nachfolgende Aufrufe, die auftreten, Draw
wenn die Ansicht als gezeichnet werden muss, indem sie entweder SetNeedsDisplay
oder SetNeedsDisplayInRect
in der Ansicht aufgerufen werden muss.
Wir können unserer Ansicht Zeichnungscode hinzufügen, indem wir diesen Code in der überschriebenen Draw
Methode hinzufügen, wie unten dargestellt:
public override void Draw(CGRect rect)
{
base.Draw(rect);
//get graphics context
using (var g = UIGraphics.GetCurrentContext())
{
// set up drawing attributes
g.SetLineWidth(10.0f);
UIColor.Green.SetFill();
UIColor.Blue.SetStroke();
// create geometry
var path = new CGPath();
path.AddArc(Bounds.GetMidX(), Bounds.GetMidY(), 50f, 0, 2.0f * (float)Math.PI, true);
// add geometry to graphics context and draw
g.AddPath(path);
g.DrawPath(CGPathDrawingMode.FillStroke);
}
}
Da CircleView
es sich um ein UIView
, können wir auch Eigenschaften festlegen UIView
. Beispielsweise können wir den BackgroundColor
im Konstruktor festlegen:
public CircleView()
{
BackgroundColor = UIColor.White;
}
Um die CircleView
gerade erstellte Datei zu verwenden, können wir sie entweder als Unteransicht zur Ansichtshierarchie in einem vorhandenen Controller hinzufügen, wie es mit dem UILabels
und UIButton
früheren Vorgang getan hat, oder wir können sie als Ansicht eines neuen Controllers laden. Lassen Sie uns letzteres tun.
Laden einer Ansicht
UIViewController
hat eine Methode namens LoadView
, die vom Controller aufgerufen wird, um seine Ansicht zu erstellen. Dies ist ein geeigneter Ort, um eine Ansicht zu erstellen und sie der Eigenschaft des View
Controllers zuzuweisen.
Zunächst benötigen wir einen Controller. Erstellen Sie also eine neue leere Klasse mit dem Namen CircleController
.
Fügen CircleController
Sie den folgenden Code hinzu, um den View
Wert auf "a CircleView
" festzulegen (Sie sollten die base
Implementierung nicht in Ihrer Außerkraftsetzung aufrufen):
using UIKit;
namespace CodeOnlyDemo
{
class CircleController : UIViewController
{
CircleView view;
public override void LoadView()
{
view = new CircleView();
View = view;
}
}
}
Schließlich müssen wir den Controller zur Laufzeit präsentieren. Gehen wir dazu vor, indem wir einen Ereignishandler für die Schaltfläche "Absenden" hinzufügen, die wir zuvor hinzugefügt haben:
submitButton.TouchUpInside += delegate
{
Console.WriteLine("Submit button clicked");
//circleController is declared as class variable
circleController = new CircleController();
PresentViewController(circleController, true, null);
};
Wenn wir die Anwendung ausführen und auf die Schaltfläche "Absenden" tippen, wird nun die neue Ansicht mit einem Kreis angezeigt:
Erstellen eines Startbildschirms
Ein Startbildschirm wird angezeigt, wenn Ihre App gestartet wird, um Ihren Benutzern anzuzeigen, dass sie reaktionsfähig ist. Da beim Laden der App ein Startbildschirm angezeigt wird, kann sie nicht im Code erstellt werden, da die Anwendung weiterhin in den Arbeitsspeicher geladen wird.
Wenn Sie ein iOS-Projekt in Visual Studio erstellen, wird ein Startbildschirm für Sie in Form einer XIB-Datei bereitgestellt, die sich im Ordner "Ressourcen " in Ihrem Projekt befindet.
Dies kann bearbeitet werden, indem Sie darauf doppelklicken und im Xcode-Schnittstellen-Generator öffnen.
Apple empfiehlt, eine XIB- oder Storyboard-Datei für Anwendungen für iOS 8 oder höher zu verwenden, wenn Sie eine Datei im Xcode-Schnittstellen-Generator starten, können Sie Größenklassen und autolayout verwenden, um Ihr Layout so anzupassen, dass es gut aussieht und ordnungsgemäß für alle Gerätegrößen angezeigt wird. Ein statisches Startimage kann zusätzlich zu einem XIB oder Storyboard verwendet werden, um die Unterstützung für Anwendungen für frühere Versionen zu ermöglichen.
Weitere Informationen zum Erstellen eines Startbildschirms finden Sie in den folgenden Dokumenten:
Wichtig
Ab iOS 9 empfiehlt Apple, Storyboards als primäre Methode zum Erstellen eines Startbildschirms zu verwenden.
Erstellen eines Startimages für Vor-iOS 8-Anwendungen
Ein statisches Bild kann zusätzlich zu einem XIB- oder Storyboardstartbildschirm verwendet werden, wenn Die Anwendung auf Versionen vor iOS 8 ausgerichtet ist.
Dieses statische Bild kann in der Datei Info.plist oder als Objektkatalog (für iOS 7) in Ihrer Anwendung festgelegt werden. Sie müssen separate Images für jede Gerätegröße (320x480, 640x960, 640x1136) bereitstellen, auf der Ihre Anwendung ausgeführt werden kann. Weitere Informationen zu den Größen des Startbildschirms finden Sie im Leitfaden "Startbildschirmbilder ".
Wichtig
Wenn Ihre App keinen Startbildschirm hat, stellen Sie möglicherweise fest, dass sie nicht vollständig auf den Bildschirm passt. Wenn dies der Fall ist, sollten Sie mindestens ein 640 x 1136-Bild mit dem Namen Default-568@2x.png
"Info.plist" einschließen.
Zusammenfassung
In diesem Artikel wurde erläutert, wie iOS-Anwendungen programmgesteuert in Visual Studio entwickelt werden. Wir haben uns angesehen, wie Sie ein Projekt aus einer leeren Projektvorlage erstellen und erläutern, wie Sie einen Stammansichtscontroller zum Fenster erstellen und hinzufügen. Anschließend haben wir gezeigt, wie Sie Steuerelemente aus UIKit verwenden, um eine Ansichtshierarchie innerhalb eines Controllers zu erstellen, um einen Anwendungsbildschirm zu entwickeln. Als Nächstes haben wir untersucht, wie die Ansichten in unterschiedlichen Ausrichtungen entsprechend angeordnet werden, und wir haben gesehen, wie sie eine benutzerdefinierte Ansicht durch Unterklassen erstellen UIView
und wie die Ansicht in einem Controller geladen wird. Schließlich haben wir uns mit dem Hinzufügen eines Startbildschirms zu einer Anwendung befasst.