piątek, 19 sierpnia 2016

Xamarin.iOS kontra Swift odc.3 (własna kontrolka, designer)

Dobry wieczór, Xamarin.iOS kontra Swift, witam serdecznie. Dziś na warsztat weźmiemy pisanie własnej kontrolki na cześć posta z czasów DSP poświęconemu tej tematyce.

IMG_0048

Jak wygląda w C# kod CircleView? Ano tak:

   [Register("CircleView"), DesignTimeVisible(true)]
   public class CircleView: UIView
   {
       private UIColor circleColor;

       [Export("CircleColor"), Browsable(true)]
       public UIColor CircleColor
       {
           get { return circleColor; }
           set
           {
               circleColor = value;
               SetNeedsDisplay();
           }
       }       

       public CircleView(IntPtr p): base(p)
       {
           Initialize();
       }

       public CircleView()
       {
           Initialize();
       }

       private void Initialize()
       {
           circleColor = UIColor.Red;
           ContentMode = UIViewContentMode.Redraw;

           SetNeedsDisplay();
       }

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

           DrawCircle(CircleColor);
       }

       private void DrawCircle(UIColor color)
       {
           using (var context = UIGraphics.GetCurrentContext())
           {
               var a = Math.Min(Bounds.Size.Width, Bounds.Size.Height);
               var leftX = Bounds.GetMidX() - a / 2;
               var topY = Bounds.GetMidY() - a / 2;
               var rectangle = new CGRect(leftX, topY, a, a);

               context.SetFillColor(CircleColor.CGColor);
               context.FillEllipseInRect(rectangle);
           }
       }
   }

Jakie odczucia w stosunku do Swift?  Inne atrybuty, inny konstruktor (z IntPtr) dla designera (pachnie trochę Visual Studio i Windows a nie Xcode i OS X). Pojawia się metoda SetNeedsDisplay, której w oryginale nie musiałem używać. Metoda Draw ma nieco inną nazwę. Z kolei operacje takie jak np. GetMidX czy FillEllipseInRect prezentują się znacznie zgrabniej w C#. Co z designerem?  Też działa, to znaczy prawie. W prostszym projekcie “na boku” działa wszystko jak należy:

image

Jednak w projekcie aplikacji widnieją paski zamiast kółek Sad smile I tak dziś jest lepiej, bo wczoraj w nocy nic się w designerze nie pokazywało. Dodam, że nie zmieniałem nic w kodzie…

image

W Xcode taki sam storyboard wyświetlany jest poprawnie z kółkami. Wygląda na to, że jakiś bardziej złożony scenariusz nie został do końca obsłużony w designerze Visual Studio… Może to kwestia auto layoutu i dużej liczby constraint-ów?

Na koniec ciekawostka. Otóż uświadomiłem sobie dopiero przy pisaniu w C#, że UIColor ma gotową metodę do uzyskania koloru z zadaną wartością kanału alfa na podstawie podanego koloru. Metoda SetLight może być taka prosta:

       private void SetLight(CircleView light, float ratio)
       {
              light.CircleColor = light.CircleColor.ColorWithAlpha(ratio);
       }

Yupi! Wszystko co dziś pokazywałem jest oczywiście na githubie.  Dobranoc Państwu Winking smile

Brak komentarzy: