====== Source Code iOSEditionSample DrawEditFeatures.zip ====== ====AppDelegate.cs==== using Foundation; using UIKit; using System; namespace DrawEditFeatures { // The UIApplicationDelegate for the application. This class is responsible for launching the // User Interface of the application, as well as listening (and optionally responding) to // application events from iOS. [Register("AppDelegate")] public partial class AppDelegate : UIApplicationDelegate { // class-level declarations public override UIWindow Window { get; set; } // This method is invoked when the application is about to move from active to inactive state. // OpenGL applications should use this method to pause. public override void OnResignActivation(UIApplication application) { } // This method should be used to release shared resources and it should store the application state. // If your application supports background exection this method is called instead of WillTerminate // when the user quits. public override void DidEnterBackground(UIApplication application) { } // This method is called as part of the transiton from background to active state. public override void WillEnterForeground(UIApplication application) { AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; } void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Console.WriteLine(); } // This method is called when the application is about to terminate. Save data, if needed. public override void WillTerminate(UIApplication application) { } } } ====Main.cs==== using UIKit; namespace DrawEditFeatures { public class Application { // This is the main entry point of the application. static void Main(string[] args) { // if you want to use a different Application Delegate class from "AppDelegate" // you can specify it here. UIApplication.Main(args, null, "AppDelegate"); } } } ====MainViewController.cs==== using CoreGraphics; using System; using System.Collections.Generic; using System.Drawing; using ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.iOSEdition; using UIKit; namespace DrawEditFeatures { public partial class MainViewController : UIViewController { private MapView mapView; private UIButton editButton; private UIButton lineButton; private UIButton pointButton; private UIButton clearButton; private UIButton cursorButton; private UIButton circleButton; private UIButton polygonButton; private UIButton ellipseButton; private UIButton rectangleButton; private UIButton drawButton; private UIView drawButtonsView; public MainViewController(IntPtr handle) : base(handle) { } public override void ViewDidLoad() { base.ViewDidLoad(); View.AutoresizingMask = UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleWidth; mapView = new MapView(View.Frame); mapView.MapUnit = GeographyUnit.DecimalDegree; mapView.BackgroundColor = UIColor.FromRGB(244, 242, 238); mapView.CurrentExtent = (new RectangleShape(-180.0, 83.0, 180.0, -90.0)); WorldMapKitOverlay worldOverlay = new WorldMapKitOverlay(); worldOverlay.TileType = TileType.MultiTile; mapView.Overlays.Add("WMK", worldOverlay); View.AddSubview(mapView); InitializeInstruction(); mapView.Refresh(); } public override void WillAnimateRotation(UIInterfaceOrientation toInterfaceOrientation, double duration) { base.WillAnimateRotation(toInterfaceOrientation, duration); double resolution = Math.Max(mapView.CurrentExtent.Width / mapView.Frame.Width, mapView.CurrentExtent.Height / mapView.Frame.Height); mapView.Frame = View.Bounds; mapView.CurrentExtent = GetExtentRetainScale(mapView.CurrentExtent.GetCenterPoint(), mapView.Frame, resolution); mapView.Refresh(); } public override void WillRotate(UIInterfaceOrientation toInterfaceOrientation, double duration) { base.WillRotate(toInterfaceOrientation, duration); SampleUIHelper.InstructionContainer.Hidden = true; } public override void DidRotate(UIInterfaceOrientation fromInterfaceOrientation) { base.DidRotate(fromInterfaceOrientation); InitializeInstruction(); SampleUIHelper.InstructionContainer.Hidden = false; } private void InitializeInstruction() { if (!SampleUIHelper.IsOnIPhone) { SampleUIHelper.InitializeInstruction(View, isIphone => 140, contentView => { cursorButton = GetUIButton(GetButtonLeft(0), "Cursor", TrackButtonClick); pointButton = GetUIButton(GetButtonLeft(1), "Point", TrackButtonClick); lineButton = GetUIButton(GetButtonLeft(2), "Line", TrackButtonClick); rectangleButton = GetUIButton(GetButtonLeft(3), "Rectangle", TrackButtonClick); circleButton = GetUIButton(GetButtonLeft(4), "Circle", TrackButtonClick); polygonButton = GetUIButton(GetButtonLeft(5), "Polygon", TrackButtonClick); ellipseButton = GetUIButton(GetButtonLeft(6), "Ellipse", TrackButtonClick); editButton = GetUIButton(GetButtonLeft(7), "Edit", TrackButtonClick); clearButton = GetUIButton(GetButtonLeft(8), "Clear", TrackButtonClick); contentView.AddSubviews(new UIView[] { cursorButton, pointButton, lineButton, rectangleButton, circleButton, polygonButton, ellipseButton, editButton, clearButton }); }); } else { SampleUIHelper.InitializeInstruction(View, isIphone => isIphone ? 140 : 120, contentView => { cursorButton = GetUIButton(GetButtonLeft(0), "Cursor", TrackButtonClick); drawButton = GetUIButton(GetButtonLeft(1), "Draw", TrackButtonClick); editButton = GetUIButton(GetButtonLeft(2), "Edit", TrackButtonClick); clearButton = GetUIButton(GetButtonLeft(3), "Clear", TrackButtonClick); pointButton = GetUIButton(0, 0, "Point", TrackButtonClick); lineButton = GetUIButton(GetButtonLeft(1), 0, "Line", TrackButtonClick); rectangleButton = GetUIButton(GetButtonLeft(2), 0, "Rectangle", TrackButtonClick); circleButton = GetUIButton(GetButtonLeft(3), 0, "Circle", TrackButtonClick); polygonButton = GetUIButton(GetButtonLeft(4), 0, "Polygon", TrackButtonClick); ellipseButton = GetUIButton(GetButtonLeft(5), 0, "Ellipse", TrackButtonClick); drawButtonsView = new UIView(new CGRect(View.Frame.Right, 0, View.Frame.Width, 44)); drawButtonsView.Layer.BorderWidth = 0; drawButtonsView.Layer.BorderColor = UIColor.Clear.CGColor; drawButtonsView.BackgroundColor = UIColor.FromRGBA(126, 124, 129, 255); drawButtonsView.Add(pointButton); drawButtonsView.Add(lineButton); drawButtonsView.Add(rectangleButton); drawButtonsView.Add(circleButton); drawButtonsView.Add(polygonButton); drawButtonsView.Add(ellipseButton); contentView.AddSubviews(new[] { cursorButton, drawButton, editButton, clearButton, drawButtonsView }); }); } } private static int GetButtonLeft(int i) { int size = 50; int left = size * i; return left; } private static RectangleShape GetExtentRetainScale(PointShape currentLocationInMecator, CGRect frame, double resolution) { double left = currentLocationInMecator.X - resolution * frame.Width * .5; double right = currentLocationInMecator.X + resolution * frame.Width * .5; double top = currentLocationInMecator.Y + resolution * frame.Height * .5; double bottom = currentLocationInMecator.Y - resolution * frame.Height * .5; return new RectangleShape(left, top, right, bottom); } private static UIButton GetUIButton(int leftLocation, string imageName, EventHandler handler) { CGSize buttonSize = new CGSize(44, 44); UIButton button = UIButton.FromType(UIButtonType.System); button.Frame = new CGRect(new Point(leftLocation, 0), buttonSize); button.SetImage(UIImage.FromBundle(imageName), UIControlState.Normal); button.SetTitle(imageName, UIControlState.Application); button.TouchUpInside += handler; button.TintColor = UIColor.White; return button; } private static UIButton GetUIButton(int leftLocation, int topLocation, string imageName, EventHandler handler) { CGSize buttonSize = new CGSize(44, 44); UIButton button = UIButton.FromType(UIButtonType.System); button.Frame = new CGRect(new Point(leftLocation, topLocation), buttonSize); button.SetImage(UIImage.FromBundle(imageName), UIControlState.Normal); button.SetTitle(imageName, UIControlState.Application); button.TouchUpInside += handler; button.TintColor = UIColor.White; return button; } private IEnumerable GetButtons() { yield return lineButton; yield return pointButton; yield return editButton; yield return clearButton; yield return circleButton; yield return cursorButton; yield return polygonButton; yield return ellipseButton; yield return rectangleButton; } private void TrackButtonClick(object sender, EventArgs e) { foreach (var tempButton in GetButtons()) { tempButton.Layer.BorderWidth = 0; tempButton.Layer.BorderColor = UIColor.Clear.CGColor; } if (SampleUIHelper.IsOnIPhone) { drawButton.Layer.BorderWidth = 0; drawButton.Layer.BorderColor = UIColor.Clear.CGColor; } UIButton button = (UIButton)sender; button.Layer.BorderWidth = 1; button.Layer.BorderColor = UIColor.White.CGColor; switch (button.Title(UIControlState.Application)) { case "Cursor": if (drawButtonsView != null) { if (drawButtonsView.Frame.Left != View.Frame.Right && SampleUIHelper.IsOnIPhone) { UIView.Animate(.3, () => { drawButtonsView.Frame = new CGRect(View.Frame.Right, 0, drawButtonsView.Frame.Width, 44); }); } } foreach (var item in mapView.EditOverlay.EditShapesLayer.InternalFeatures) { if (!mapView.TrackOverlay.TrackShapeLayer.InternalFeatures.Contains(item)) { mapView.TrackOverlay.TrackShapeLayer.InternalFeatures.Add(item); } } mapView.TrackOverlay.TrackMode = TrackMode.None; mapView.EditOverlay.EditShapesLayer.InternalFeatures.Clear(); mapView.EditOverlay.ClearAllControlPoints(); mapView.Refresh(); break; case "Clear": mapView.EditOverlay.ClearAllControlPoints(); mapView.EditOverlay.EditShapesLayer.Open(); mapView.EditOverlay.EditShapesLayer.Clear(); mapView.TrackOverlay.TrackShapeLayer.Open(); mapView.TrackOverlay.TrackShapeLayer.Clear(); mapView.Refresh(); break; case "Point": mapView.TrackOverlay.TrackMode = TrackMode.Point; break; case "Line": mapView.TrackOverlay.TrackMode = TrackMode.Line; break; case "Rectangle": mapView.TrackOverlay.TrackMode = TrackMode.Rectangle; break; case "Polygon": mapView.TrackOverlay.TrackMode = TrackMode.Polygon; break; case "Circle": mapView.TrackOverlay.TrackMode = TrackMode.Circle; break; case "Ellipse": mapView.TrackOverlay.TrackMode = TrackMode.Ellipse; break; case "Edit": mapView.TrackOverlay.TrackMode = TrackMode.None; foreach (Feature feature in mapView.TrackOverlay.TrackShapeLayer.InternalFeatures) { mapView.EditOverlay.EditShapesLayer.InternalFeatures.Add(feature); } mapView.TrackOverlay.TrackShapeLayer.InternalFeatures.Clear(); mapView.EditOverlay.CalculateAllControlPoints(); mapView.Refresh(); break; case "Draw": UIView.Animate(.3, () => { drawButtonsView.Frame = new CGRect(drawButton.Frame.Left, 0, drawButtonsView.Frame.Width, 44); ellipseButton.Hidden = true; }); pointButton.Layer.BorderWidth = 1; pointButton.Layer.BorderColor = UIColor.White.CGColor; mapView.TrackOverlay.TrackMode = TrackMode.Point; break; default: mapView.TrackOverlay.TrackMode = TrackMode.None; break; } } } } ====MainViewController.designer.cs==== // WARNING // // This file has been generated automatically by Xamarin Studio from the outlets and // actions declared in your storyboard file. // Manual changes to this file will not be maintained. // using System; using Foundation; using UIKit; using System.CodeDom.Compiler; namespace DrawEditFeatures { [Register|("MainViewController")] partial class MainViewController { [Outlet] [GeneratedCode|("iOS Designer", "1.0")] UIButton btnClose { get; set; } [Outlet] [GeneratedCode|("iOS Designer", "1.0")] UIButton dailogBackground { get; set; } [Outlet] [GeneratedCode|("iOS Designer", "1.0")] UIView longPressDailog { get; set; } [Outlet] [GeneratedCode|("iOS Designer", "1.0")] UITableView tbvLongPressOptions { get; set; } [Action|("btnClose_TouchUpInside:")] [GeneratedCode|("iOS Designer", "1.0")] partial void btnClose_TouchUpInside (UIButton sender); [Action|("dailogBackground_TouchUpInside:")] [GeneratedCode|("iOS Designer", "1.0")] partial void dailogBackground_TouchUpInside (UIButton sender); void ReleaseDesignerOutlets () { if (btnClose != null) { btnClose.Dispose (); btnClose = null; } if (dailogBackground != null) { dailogBackground.Dispose (); dailogBackground = null; } if (longPressDailog != null) { longPressDailog.Dispose (); longPressDailog = null; } if (tbvLongPressOptions != null) { tbvLongPressOptions.Dispose (); tbvLongPressOptions = null; } } } } ====AssemblyInfo.cs==== using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly:|AssemblyTitle("DrawEditFeatures")] [assembly: AssemblyDescription("")] [assembly:|AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly:|AssemblyProduct("DrawEditFeatures")] [assembly: AssemblyCopyright("Copyright © 2015")] [assembly:|AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly:|ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly:|Guid("38e125d5-8180-4b44-9cff-100b569b69d5")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly:|AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("9.0.0.0")] [assembly:|AssemblyFileVersion("9.0.0.0")] ====SampleUIHelper.cs==== using CoreGraphics; using UIKit; using System; using System.Drawing; namespace DrawEditFeatures { public class SampleUIHelper { private static nfloat fullHeight; private static nfloat minHeight = 44; private static UIView instructionContainer; public static void InitializeInstruction(UIView containerView, Func getInstructionHeight, Action getInstructionContent = null) { bool isIphone = UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone; float instructionHeight = getInstructionHeight(isIphone); UIView instructionView = new UIView(new CGRect(0, containerView.Frame.Bottom - instructionHeight, containerView.Frame.Width, instructionHeight)); containerView.Add(instructionView); instructionContainer = instructionView; instructionContainer.Alpha = 0.9f; instructionContainer.BackgroundColor = UIColor.FromRGBA(126, 124, 129, 255); fullHeight = instructionView.Frame.Height + minHeight; UIButton collapseButton = UIButton.FromType(UIButtonType.RoundedRect); collapseButton.Frame = new CGRect(new CGPoint(instructionView.Frame.Width - 60, 10), new CGSize(60, 30)); collapseButton.SetImage(UIImage.FromBundle("More"), UIControlState.Normal); collapseButton.TintColor = UIColor.White; collapseButton.TouchUpInside += CollapseButton_TouchDown; UILabel instructionLable = new UILabel(); instructionLable.BackgroundColor = instructionView.BackgroundColor; instructionLable.Text = "Instruction"; instructionLable.Font = UIFont.FromName("Helvetica-Bold", 20); instructionLable.TextColor = UIColor.White; instructionLable.ShadowColor = UIColor.Gray; instructionLable.ShadowOffset = new CGSize(1, 1); instructionLable.Center = new CGPoint(instructionView.Frame.Width / 2, 20); instructionLable.Frame = new CGRect(0, 0, instructionView.Frame.Width, 44); instructionLable.TextAlignment = UITextAlignment.Center; ConstForDevice constaint; if (IsOnIPhone) constaint = new ConstForIPhone(instructionLable, instructionView); else constaint = new ConstForIPad(instructionLable, instructionView); UIView leftLineView = new UIView(new CGRect(new CGPoint(constaint.DescriptionMargin, 25), new CGSize(constaint.ContainerCenterX - constaint.InstructionWidthHalf - constaint.DescriptionMargin * 2, 1))); leftLineView.BackgroundColor = UIColor.FromRGB(240, 240, 240); UIView rightLineView = new UIView(new CGRect(new CGPoint(constaint.ContainerCenterX + constaint.InstructionWidthHalf + DescriptionMarginLeft, 25), new CGSize(constaint.ContainerCenterX - constaint.DescriptionMargin - constaint.InstructionWidthHalf - 60, 1))); rightLineView.BackgroundColor = UIColor.FromRGB(240, 240, 240); UIButton titleView = new UIButton(); titleView.Layer.BorderWidth = 0; titleView.Layer.BorderColor = UIColor.Clear.CGColor; titleView.BackgroundColor = UIColor.Clear; titleView.SetTitle(string.Empty, UIControlState.Normal); titleView.Frame = new CGRect(0, 0, instructionView.Frame.Width, 44); titleView.TouchUpInside += CollapseButton_TouchDown; titleView.Add(instructionLable); titleView.Add(leftLineView); titleView.Add(rightLineView); titleView.Add(collapseButton); UILabel descriptionLableView = new UILabel(new CGRect(DescriptionMarginLeft, 44, instructionView.Frame.Width - DescriptionMarginLeft * 2, 20)); descriptionLableView.Text = "Draw and Edit Shapes."; descriptionLableView.TextColor = UIColor.White; descriptionLableView.ShadowColor = UIColor.Gray; descriptionLableView.ShadowOffset = new CGSize(1, 1); descriptionLableView.LineBreakMode = UILineBreakMode.WordWrap; descriptionLableView.Lines = 0; descriptionLableView.PreferredMaxLayoutWidth = instructionView.Frame.Width - DescriptionMarginLeft * 2; descriptionLableView.SizeToFit(); instructionView.Add(titleView); instructionView.Add(descriptionLableView); if (getInstructionContent != null) { nfloat contentViewLeft = isIphone ? 10 : 20; nfloat contentViewTop = descriptionLableView.Frame.Bottom + 10; UIView contentView = new UIView(new CGRect(contentViewLeft, contentViewTop, instructionView.Frame.Width - 2 * contentViewLeft, instructionView.Frame.Height - (contentViewTop))); instructionView.Add(contentView); getInstructionContent(contentView); } } public static bool IsOnIPhone { get { return UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone; } } public static UIView InstructionContainer { get { return instructionContainer; } set { instructionContainer = value; } } private static void CollapseButton_TouchDown(object sender, EventArgs e) { nfloat barHeight = fullHeight - instructionContainer.Frame.Height; UIView.Animate(.2, () => { instructionContainer.Frame = new CGRect(new CGPoint(0, instructionContainer.Frame.Bottom - barHeight), new CGSize(instructionContainer.Frame.Width, barHeight)); }); } private static int DescriptionMarginLeft { get { return IsOnIPhone ? 10 : 20; } } private class ConstForDevice { public ConstForDevice(UILabel label, UIView container) { SetInstructionSize(label); SetContainerCenter(container); } public nfloat ContainerCenterX { get; set; } public nfloat ContainerCenterY { get; set; } public nfloat DescriptionMargin { get; set; } public nfloat InstructionWidth { get; set; } public nfloat InstructionWidthHalf { get; set; } public nfloat InstructionHeight { get; set; } public nfloat InstructionHeightHalf { get; set; } private void SetInstructionSize(UILabel label) { SizeF size = (SizeF)UIStringDrawing.StringSize(label.Text, label.Font); InstructionWidth = size.Width; InstructionHeight = size.Height; InstructionWidthHalf = size.Width * .5f; InstructionHeightHalf = size.Height * .5f; } private void SetContainerCenter(UIView container) { ContainerCenterX = container.Center.X; ContainerCenterY = container.Center.Y; } } private class ConstForIPhone : ConstForDevice { public ConstForIPhone(UILabel label, UIView container) : base(label, container) { DescriptionMargin = 10; } } private class ConstForIPad : ConstForDevice { public ConstForIPad(UILabel label, UIView container) : base(label, container) { DescriptionMargin = 20; } } } }