Xamarin.iOS Stopwatch control using Infragistics Nuclios

At work I have the pleasure of using some awesome Infragistic controls for winform applications. At local .Net users group meeting I won a license for the NetAdvantage Ultimate Suite! Awesomesauce! Included with this suite is a set of controls for iOS. They’ve even compiled dll’s for monotouch! Included in their sample projects is an awesome Stopwatch that uses a couple of IGGaugeViews. All of the samples shipped with nucliOS are all in objective-c. With a bit of help from my friends at Infragistics, I was able to get the Stopwatch control Xamafied. The sample code can be downloaded on Github . You’ll need to install nuclios. A free trial can be found here . Below is the Stopwatch UIView…

    public class StopWatch : UIView
    {
        private IGGaugeView _backgroundGauge;
        private UIImageView _glassImage;
        public IGGaugeView HoursGauge;
        private UIImageView _imageView;

        public StopWatch()
        {
            Setup();
        }

        public string ImageName
        {
            get { return @"Clock2.png"; }
        }

        public override RectangleF Frame
        {
            get { return base.Frame; }
            set
            {
                base.Frame = value;

                if (_backgroundGauge == null)
                    return;

                float val = .11f;

                if (Frame.Size.Height > Frame.Size.Width)
                {
                    val = .09f;
                }

                if (UIScreen.MainScreen.PreferredMode.Size == new SizeF(640, 1136))
                {
                    val = .070f;
                }

                _backgroundGauge.CenterY = HoursGauge.CenterY = .48f + val;
            }
        }

        public void Setup()
        {
            if (HoursGauge == null)
            {
                _imageView = new UIImageView(new RectangleF(0, 0, Frame.Size.Width, Frame.Size.Height))
                {
                    AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight,
                    ContentMode = UIViewContentMode.ScaleAspectFit,
                    Image = UIImage.FromBundle(ImageName)
                };
                AddSubview(_imageView);

                // Initialize all Gauges with the same exact frame
                HoursGauge = new IGGaugeView
                {
                    Frame = new RectangleF(0, 0, Frame.Size.Width, Frame.Size.Height),
                    AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
                };
                _backgroundGauge = new IGGaugeView
                {
                    Frame = new RectangleF(0, 0, Frame.Size.Width, Frame.Size.Height),
                    AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
                };

                // Add all of our subviews to the visual tree
                AddSubview(_backgroundGauge);
                AddSubview(HoursGauge);

                // Hide the 0 label
                _backgroundGauge.DuplicateLabelOmissionStrategy =
                    IGGaugeDuplicateLabelOmissionStrategy.IGGaugeDuplicateLabelOmissionStrategyOmitFirst;

                // Hide the other gauge labels
                HoursGauge.Font = UIFont.SystemFontOfSize(1);

                _backgroundGauge.NeedlePivotShape = IGGaugePivotShape.IGGaugePivotShapeNone;

                // Hide elements from our top level gauges by setting the brush color to clear
                _backgroundGauge.NeedleOutline =
                    HoursGauge.MinorTickBrush =
                    HoursGauge.TickBrush =
                    _backgroundGauge.ScaleBrush =
                    HoursGauge.BackingBrush =
                    _backgroundGauge.NeedleBrush =
                    HoursGauge.ScaleBrush = HoursGauge.BackingOutline = new IGBrush(UIColor.Clear);

                HoursGauge.BackingStrokeThickness = 0;

                // Set the Start and End Angles of the scale - All gauges must have the same values
                _backgroundGauge.ScaleStartAngle = HoursGauge.ScaleStartAngle = 270;
                _backgroundGauge.ScaleEndAngle = HoursGauge.ScaleEndAngle = 270 + 360;

                // Since we don't want to see the major tick marks, lets set the internval to a larger number to limit how many tick marks try to render.
                HoursGauge.Interval = 60;

                // Set the Max Values
                _backgroundGauge.MaximumValue = HoursGauge.MaximumValue = 60;

                // Since we don't want to see these tick marks, lets set the minor tick marks count to zero so no tick marks try to render.
                HoursGauge.MinorTickCount = 0;

                // Setup the Tick marks for the background
                _backgroundGauge.Interval = 1;
                _backgroundGauge.MinorTickCount = 4;

                SetupStyling();

                HoursGauge.Value = 60;
            }
        }

        public void SetupStyling()
        {
            _glassImage = new UIImageView(new RectangleF(0, 0, Frame.Size.Width, Frame.Size.Height))
            {
                AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight,
                ContentMode = UIViewContentMode.ScaleAspectFit,
                Image = UIImage.FromBundle(@"Clock2Shadow.png")
            };
            AddSubview(_glassImage);

            bool iPhone = UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone;

            // Make the Number labels render inside of the tickmarks as opposed to outside of them
            _backgroundGauge.LabelExtent = .50f;

            // Move the TickMarks further out from the center of the clock
            _backgroundGauge.TickStartExtent = .59f;
            _backgroundGauge.TickEndExtent = .64f;
            _backgroundGauge.MinorTickStartExtent = .59f;
            _backgroundGauge.MinorTickEndExtent = .64f;

            _backgroundGauge.MaximumValue = 60f;
            _backgroundGauge.Interval = 5f;

            // Set the font for our labels
            _backgroundGauge.Font = UIFont.FromName(@"Verdana", (iPhone) ? 20f : 40f);

            // Move the Backing out and set its colors and stroke thickness
            _backgroundGauge.BackingOuterExtent = .93f;
            _backgroundGauge.BackingStrokeThickness = 0f;
            _backgroundGauge.BackingOutline = _backgroundGauge.BackingBrush = new IGBrush(UIColor.Clear);

            // Make the hours hand smaller
            HoursGauge.NeedleEndExtent = .6f;
            HoursGauge.NeedlePointFeatureExtent = .55f;

            // Change the thickness of the minutes and hours hands.
            HoursGauge.NeedleStartWidthRatio = .03f;
            HoursGauge.NeedleEndWidthRatio = .03f;
            HoursGauge.NeedlePointFeatureWidthRatio = .02f;

            HoursGauge.NeedlePivotWidthRatio = .001f;

            HoursGauge.NeedlePivotBrush = new IGBrush(UIColor.Black);
            HoursGauge.NeedlePivotOutline = new IGBrush(UIColor.White);

            HoursGauge.NeedleShape = IGGaugeNeedleShape.IGGaugeNeedleShapeTriangle;

            HoursGauge.NeedlePivotShape = IGGaugePivotShape.IGGaugePivotShapeCircleUnderlayWithHole;

            var range = new IGGaugeRange
            {
                Outline = new IGBrush(UIColor.Black),
                StrokeThickness = 2,
                StartValue = 0,
                EndValue = 60,
                InnerStartExtent = .59f,
                InnerEndExtent = .59f,
                OuterEndExtent = .59f,
                OuterStartExtent = .59f
            };
            _backgroundGauge.AddRange(range);

            Frame = Frame;
        }
    }

And the usage..

    public class MyViewController : UIViewController
    {
        //declare StopWatch UIView
        private StopWatch _stopWatch;

        //Timer to adjust watch hand
        private NSTimer _timer;

        //Tick count to set value for stopwatch
        private float _tickCount;

        public MyViewController()
        {
        }

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            View.Frame = UIScreen.MainScreen.Bounds;
            View.BackgroundColor = UIColor.White;
            View.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;

            //Init tickcount
            _tickCount = 60;

            //Init StopWatch
            _stopWatch = new StopWatch
            {
                Frame = new RectangleF(0, 0, this.View.Frame.Size.Width, this.View.Frame.Size.Height),
                AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight,
            };

            View.AddSubview(_stopWatch);

            //Let the countdown begin!
            _timer = NSTimer.CreateRepeatingScheduledTimer(TimeSpan.FromSeconds(.1d), () =>
                {
                    if (_tickCount > 0)
                    {
                        _tickCount -= .1f;
                    }
                    else
                    {
                        _timer.Invalidate();
                        _timer.Dispose();
                    }

                    //The value property of IGGauge determines where the gauge value is set
                    _stopWatch.HoursGauge.Value = _tickCount;
                });
        }    }
Advertisements