void Select(RingView view) { foreach (var v in RingViews) { if (v.Selected) { v.Selected = false; v.SelectionState?.Invoke(); } v.FannedOut = false; } view.Selected = true; selectedView = view; view.ActionClosure?.Invoke(); }
void SetupRings(int itemCount) { // Define some nice colors. var borderColorSelected = UIColor.FromHSBA(0.07f, 0.81f, 0.98f, 1).CGColor; var borderColorNormal = UIColor.DarkGray.CGColor; var fillColorSelected = UIColor.FromHSBA(0.07f, 0.21f, 0.98f, 1); var fillColorNormal = UIColor.White; // We define generators to return closures which we use to define // the different states of our item ring views. Func <RingView, Action> selectedGenerator = (view) => () => { view.Layer.BorderColor = borderColorSelected; view.BackgroundColor = fillColorSelected; }; Func <RingView, Action> normalGenerator = (view) => () => { view.Layer.BorderColor = borderColorNormal; view.BackgroundColor = fillColorNormal; }; CGPoint startPosition = Bounds.GetCenter(); Func <RingView, Action> locationNormalGenerator = (view) => () => { view.Center = startPosition; if (!view.Selected) { view.Alpha = 0; } }; Func <RingView, CGVector, Action> locationFanGenerator = (view, offset) => () => { view.Center = startPosition.Add(offset); view.Alpha = 1; }; // tau is a full circle in radians var tau = NMath.PI * 2; var absoluteRingSegment = tau / 4; var requiredLengthPerRing = RingRadius * 2 + 5; var totalRequiredCirlceSegment = requiredLengthPerRing * (itemCount - 1); var fannedControlRadius = NMath.Max(requiredLengthPerRing, totalRequiredCirlceSegment / absoluteRingSegment); var normalDistance = new CGVector(0, -fannedControlRadius); var scale = UIScreen.MainScreen.Scale; // Setup our item views. for (int index = 0; index < itemCount; index++) { var view = new RingView(Bounds); view.StateClosures [Selected] = selectedGenerator(view); view.StateClosures [Normal] = normalGenerator(view); nfloat angle = index / (nfloat)(itemCount - 1) * absoluteRingSegment; var fan = normalDistance.Apply(MakeRotation(angle)).RoundTo(scale); view.StateClosures [LocationFan] = locationFanGenerator(view, fan); view.StateClosures [LocationOrigin] = locationNormalGenerator(view); AddSubview(view); RingViews.Add(view); var gr = new UITapGestureRecognizer(Tap); view.AddGestureRecognizer(gr); } // Setup the initial selection state. var rv = RingViews [0]; AddSubview(rv); rv.Selected = true; selectedView = rv; UpdateViews(animated: false); }