utilisation de contrôles personnalisés avec le concepteur iOS

Avertissement

Le Designer iOS a été déprécié dans Visual Studio 2019 version 16.8 et Visual Studio 2019 pour Mac version 8.8, puis supprimé dans Visual Studio 2019 version 16.9 et Visual Studio pour Mac version 8.9. La méthode recommandée pour créer des interfaces utilisateur iOS est directement sur un Mac exécutant Xcode. Pour plus d’informations, consultez Conception d’interfaces utilisateur avec Xcode.

Spécifications

Le Designer Xamarin pour iOS est disponible dans Visual Studio pour Mac et Visual Studio 2017 et versions ultérieures sur Windows.

Ce guide suppose une connaissance du contenu abordé dans les guides de Prise en main.

Procédure pas à pas

Important

À partir de Xamarin.Studio 5.5, la façon dont les contrôles personnalisés sont créés diffère légèrement des versions antérieures. Pour créer un contrôle personnalisé, l’interface IComponent est requise (avec les méthodes d’implémentation associées) ou la classe peut être annotée avec [DesignTimeVisible(true)]. Cette dernière méthode est utilisée dans l’exemple de procédure pas à pas suivant.

  1. Créez une solution à partir du modèle Application iOS >> Single View C > # , nommez-la ScratchTicket, puis passez à l’Assistant Nouveau projet :

    Créer une solution

  2. Créez un fichier de classe vide nommé ScratchTicketView:

    Créer une classe ScratchTicketView

  3. Ajoutez le code suivant pour ScratchTicketView la classe :

    using System;
    using System.ComponentModel;
    using CoreGraphics;
    using Foundation;
    using UIKit;
    
    namespace ScratchTicket
    {
        [Register("ScratchTicketView"), DesignTimeVisible(true)]
        public class ScratchTicketView : UIView
        {
            CGPath path;
            CGPoint initialPoint;
            CGPoint latestPoint;
            bool startNewPath = false;
            UIImage image;
    
            [Export("Image"), Browsable(true)]
            public UIImage Image
            {
                get { return image; }
                set
                {
                    image = value;
                    SetNeedsDisplay();
                }
            }
    
            public ScratchTicketView(IntPtr p)
                : base(p)
            {
                Initialize();
            }
    
            public ScratchTicketView()
            {
                Initialize();
            }
    
            void Initialize()
            {
                initialPoint = CGPoint.Empty;
                latestPoint = CGPoint.Empty;
                BackgroundColor = UIColor.Clear;
                Opaque = false;
                path = new CGPath();
                SetNeedsDisplay();
            }
    
            public override void TouchesBegan(NSSet touches, UIEvent evt)
            {
                base.TouchesBegan(touches, evt);
    
                var touch = touches.AnyObject as UITouch;
    
                if (touch != null)
                {
                    initialPoint = touch.LocationInView(this);
                }
            }
    
            public override void TouchesMoved(NSSet touches, UIEvent evt)
            {
                base.TouchesMoved(touches, evt);
    
                var touch = touches.AnyObject as UITouch;
    
                if (touch != null)
                {
                    latestPoint = touch.LocationInView(this);
                    SetNeedsDisplay();
                }
            }
    
            public override void TouchesEnded(NSSet touches, UIEvent evt)
            {
                base.TouchesEnded(touches, evt);
                startNewPath = true;
            }
    
            public override void Draw(CGRect rect)
            {
                base.Draw(rect);
    
                using (var g = UIGraphics.GetCurrentContext())
                {
                    if (image != null)
                        g.SetFillColor((UIColor.FromPatternImage(image).CGColor));
                    else
                        g.SetFillColor(UIColor.LightGray.CGColor);
                    g.FillRect(rect);
    
                    if (!initialPoint.IsEmpty)
                    {
                        g.SetLineWidth(20);
                        g.SetBlendMode(CGBlendMode.Clear);
                        UIColor.Clear.SetColor();
    
                        if (path.IsEmpty || startNewPath)
                        {
                            path.AddLines(new CGPoint[] { initialPoint, latestPoint });
                            startNewPath = false;
                        }
                        else
                        {
                            path.AddLineToPoint(latestPoint);
                        }
    
                        g.SetLineCap(CGLineCap.Round);
                        g.AddPath(path);
                        g.DrawPath(CGPathDrawingMode.Stroke);
                    }
                }
            }
        }
    }
    
  4. Ajoutez les FillTexture.pngfichiers et Monkey.pngFillTexture2.png (disponibles à partir de GitHub) au dossier Resources.

  5. Double-cliquez sur le Main.storyboard fichier pour l’ouvrir dans le concepteur :

    Le Designer iOS

  6. Faites glisser/déposez une vue Image à partir de la boîte à outils sur la vue dans le storyboard.

    Une vue Image ajoutée à la disposition

  7. Sélectionnez la vue Image et remplacez sa propriété Image par Monkey.png.

    Définition de la propriété Image de vue d’image sur Monkey.png

  8. Comme nous utilisons des classes de taille, nous devons limiter cette vue d’image. Cliquez deux fois sur l’image pour la mettre en mode contrainte. Limitons-la au centre en cliquant sur la poignée d’épinglage central et alignons-la verticalement et horizontalement :

    Centrage de l’image

  9. Pour limiter la hauteur et la largeur, cliquez sur les poignées d’épinglage de taille (les poignées en forme d’os) et sélectionnez respectivement largeur et hauteur :

    Ajout de contraintes

  10. Mettez à jour le cadre en fonction des contraintes en cliquant sur le bouton Mettre à jour dans la barre d’outils :

    Barre d’outils Contraintes

  11. Ensuite, générez le projet de sorte que l’affichage Ticket scratch s’affiche sous Composants personnalisés dans la boîte à outils :

    Boîte à outils Composants personnalisés

  12. Faites glisser et déposez une vue Ticket scratch afin qu’elle apparaisse sur l’image de singe. Ajustez les poignées de glissement afin que la vue Ticket scratch couvre complètement le singe, comme indiqué ci-dessous :

    Une vue de ticket à gratter sur l’affichage Image

  13. Limitez l’affichage de ticket de travail à la vue Image en dessinant un rectangle englobant pour sélectionner les deux vues. Sélectionnez les options permettant de le limiter aux trames Largeur, Hauteur, Centre et Milieu et mettre à jour en fonction des contraintes, comme indiqué ci-dessous :

    Centrage et ajout de contraintes

  14. Exécutez l’application et « rayez » l’image pour révéler le singe.

    Exemple d’exécution d’application

Ajout de propriétés Design-Time

Le concepteur inclut également la prise en charge au moment du design pour les contrôles personnalisés de type de propriété numérique, énumération, chaîne, bool, CGSize, UIColor et UIImage. Pour illustrer cette opération, nous allons ajouter une propriété au ScratchTicketView pour définir l’image « rayée ».

Ajoutez le code suivant à la ScratchTicketView classe pour la propriété :

[Export("Image"), Browsable(true)]
public UIImage Image
{
    get { return image; }
    set {
            image = value;
              SetNeedsDisplay ();
        }
}

Nous pouvons également ajouter une case activée null à la Draw méthode, comme suit :

public override void Draw(CGRect rect)
{
    base.Draw(rect);

    using (var g = UIGraphics.GetCurrentContext())
    {
        if (image != null)
            g.SetFillColor ((UIColor.FromPatternImage (image).CGColor));
        else
            g.SetFillColor (UIColor.LightGray.CGColor);

        g.FillRect(rect);

        if (!initialPoint.IsEmpty)
        {
             g.SetLineWidth(20);
             g.SetBlendMode(CGBlendMode.Clear);
             UIColor.Clear.SetColor();

             if (path.IsEmpty || startNewPath)
             {
                 path.AddLines(new CGPoint[] { initialPoint, latestPoint });
                 startNewPath = false;
             }
             else
             {
                 path.AddLineToPoint(latestPoint);
             }

             g.SetLineCap(CGLineCap.Round);
             g.AddPath(path);
             g.DrawPath(CGPathDrawingMode.Stroke);
        }
    }
}

L’inclusion d’un ExportAttribute et d’un BrowsableAttribute avec l’argument défini sur aboutit à true l’affichage de la propriété dans le panneau Propriétés du concepteur. La modification de la propriété par une autre image incluse dans le projet, par FillTexture2.pngexemple , entraîne la mise à jour du contrôle au moment de la conception, comme indiqué ci-dessous :

Modification des propriétés de l’heure de conception

Résumé

Dans cet article, nous avons décrit comment créer un contrôle personnalisé et l’utiliser dans une application iOS à l’aide du concepteur iOS. Nous avons vu comment créer et générer le contrôle pour le rendre disponible pour une application dans la boîte à outils du concepteur. En outre, nous avons examiné comment implémenter le contrôle de sorte qu’il s’affiche correctement au moment de la conception et à l’exécution, ainsi que comment exposer les propriétés de contrôle personnalisées dans le concepteur.