diff --git a/SDK v6 Examples/PlaygroundSamples/PlaygroundSamples.xcodeproj/project.pbxproj b/SDK v6 Examples/PlaygroundSamples/PlaygroundSamples.xcodeproj/project.pbxproj index 28eebbd..7813dad 100644 --- a/SDK v6 Examples/PlaygroundSamples/PlaygroundSamples.xcodeproj/project.pbxproj +++ b/SDK v6 Examples/PlaygroundSamples/PlaygroundSamples.xcodeproj/project.pbxproj @@ -33,6 +33,9 @@ 4B0000011111111111111128 /* arena_concert.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B0000010000000000000018 /* arena_concert.png */; }; 4B0000011111111111111129 /* Mappedin in Frameworks */ = {isa = PBXBuildFile; productRef = 4B0000020000000000000001 /* Mappedin */; }; D175A38A2EF9CE9600F925EF /* LocationsDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D175A3892EF9CE9300F925EF /* LocationsDemoViewController.swift */; }; + D175A3962EFB239A00F925EF /* StackedMapsDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D175A3942EFB239A00F925EF /* StackedMapsDemoViewController.swift */; }; + D175A3972EFB239A00F925EF /* StackedMapsUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D175A3952EFB239A00F925EF /* StackedMapsUtils.swift */; }; + D175A3982EFB239A00F925EF /* MultiFloorViewDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D175A3932EFB239A00F925EF /* MultiFloorViewDemoViewController.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -63,6 +66,9 @@ 4B0000010000000000000019 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4B000001000000000000001A /* PlaygroundSamples.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PlaygroundSamples.app; sourceTree = BUILT_PRODUCTS_DIR; }; D175A3892EF9CE9300F925EF /* LocationsDemoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationsDemoViewController.swift; sourceTree = ""; }; + D175A3932EFB239A00F925EF /* MultiFloorViewDemoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiFloorViewDemoViewController.swift; sourceTree = ""; }; + D175A3942EFB239A00F925EF /* StackedMapsDemoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StackedMapsDemoViewController.swift; sourceTree = ""; }; + D175A3952EFB239A00F925EF /* StackedMapsUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StackedMapsUtils.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -88,32 +94,35 @@ 4B0000040000000000000002 /* PlaygroundSamples */ = { isa = PBXGroup; children = ( - D175A3892EF9CE9300F925EF /* LocationsDemoViewController.swift */, + 4B0000010000000000000015 /* 3d_assets */, 4B0000010000000000000001 /* AppDelegate.swift */, - 4B0000010000000000000002 /* SceneDelegate.swift */, - 4B0000010000000000000003 /* ViewController.swift */, - 4B0000010000000000000007 /* DisplayMapDemoViewController.swift */, 4B0000010000000000000008 /* AreaShapesDemoViewController.swift */, + 4B0000010000000000000017 /* arena_basketball.png */, + 4B0000010000000000000018 /* arena_concert.png */, + 4B0000010000000000000016 /* arena_hockey.png */, + 4B0000010000000000000005 /* Assets.xcassets */, 4B0000010000000000000009 /* BuildingFloorSelectionDemoViewController.swift */, 4B000001000000000000000A /* CameraDemoViewController.swift */, + 4B0000010000000000000007 /* DisplayMapDemoViewController.swift */, 4B000001000000000000000B /* Image3DDemoViewController.swift */, + 4B0000010000000000000019 /* Info.plist */, 4B000001000000000000000C /* InteractivityDemoViewController.swift */, 4B000001000000000000000D /* LabelsDemoViewController.swift */, + 4B0000040000000000000005 /* LaunchScreen.storyboard */, + D175A3892EF9CE9300F925EF /* LocationsDemoViewController.swift */, + 4B0000040000000000000004 /* Main.storyboard */, 4B000001000000000000000E /* MarkersDemoViewController.swift */, + 4B0000010000000000000014 /* model_positions.json */, 4B000001000000000000000F /* ModelsDemoViewController.swift */, + D175A3932EFB239A00F925EF /* MultiFloorViewDemoViewController.swift */, 4B0000010000000000000010 /* NavigationDemoViewController.swift */, 4B0000010000000000000011 /* PathsDemoViewController.swift */, 4B0000010000000000000012 /* QueryDemoViewController.swift */, + 4B0000010000000000000002 /* SceneDelegate.swift */, 4B0000010000000000000013 /* SearchDemoViewController.swift */, - 4B0000040000000000000004 /* Main.storyboard */, - 4B0000010000000000000005 /* Assets.xcassets */, - 4B0000040000000000000005 /* LaunchScreen.storyboard */, - 4B0000010000000000000019 /* Info.plist */, - 4B0000010000000000000014 /* model_positions.json */, - 4B0000010000000000000015 /* 3d_assets */, - 4B0000010000000000000016 /* arena_hockey.png */, - 4B0000010000000000000017 /* arena_basketball.png */, - 4B0000010000000000000018 /* arena_concert.png */, + D175A3942EFB239A00F925EF /* StackedMapsDemoViewController.swift */, + D175A3952EFB239A00F925EF /* StackedMapsUtils.swift */, + 4B0000010000000000000003 /* ViewController.swift */, ); path = PlaygroundSamples; sourceTree = ""; @@ -215,6 +224,9 @@ 4B0000011111111111111118 /* AreaShapesDemoViewController.swift in Sources */, 4B0000011111111111111119 /* BuildingFloorSelectionDemoViewController.swift in Sources */, 4B000001111111111111111A /* CameraDemoViewController.swift in Sources */, + D175A3962EFB239A00F925EF /* StackedMapsDemoViewController.swift in Sources */, + D175A3972EFB239A00F925EF /* StackedMapsUtils.swift in Sources */, + D175A3982EFB239A00F925EF /* MultiFloorViewDemoViewController.swift in Sources */, 4B000001111111111111111B /* Image3DDemoViewController.swift in Sources */, 4B000001111111111111111C /* InteractivityDemoViewController.swift in Sources */, 4B000001111111111111111D /* LabelsDemoViewController.swift in Sources */, diff --git a/SDK v6 Examples/PlaygroundSamples/PlaygroundSamples/MultiFloorViewDemoViewController.swift b/SDK v6 Examples/PlaygroundSamples/PlaygroundSamples/MultiFloorViewDemoViewController.swift new file mode 100644 index 0000000..453a198 --- /dev/null +++ b/SDK v6 Examples/PlaygroundSamples/PlaygroundSamples/MultiFloorViewDemoViewController.swift @@ -0,0 +1,108 @@ +import UIKit +import Mappedin + +final class MultiFloorViewDemoViewController: UIViewController { + private let mapView = MapView() + private let loadingIndicator = UIActivityIndicatorView(style: .large) + + override func viewDidLoad() { + super.viewDidLoad() + title = "Multi-Floor View" + view.backgroundColor = .systemBackground + + let container = mapView.view + container.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(container) + + // Add loading indicator + loadingIndicator.translatesAutoresizingMaskIntoConstraints = false + loadingIndicator.startAnimating() + view.addSubview(loadingIndicator) + + NSLayoutConstraint.activate([ + container.leadingAnchor.constraint(equalTo: view.leadingAnchor), + container.trailingAnchor.constraint(equalTo: view.trailingAnchor), + container.topAnchor.constraint(equalTo: view.topAnchor), + container.bottomAnchor.constraint(equalTo: view.bottomAnchor), + + loadingIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor), + loadingIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor), + ]) + + // See Trial API key Terms and Conditions + // https://developer.mappedin.com/docs/demo-keys-and-maps + let options = GetMapDataWithCredentialsOptions( + key: "mik_yeBk0Vf0nNJtpesfu560e07e5", + secret: "mis_2g9ST8ZcSFb5R9fPnsvYhrX3RyRwPtDGbMGweCYKEq385431022", + mapId: "67a6641530e940000bac3c1a" + ) + + // Load the map data. + mapView.getMapData(options: options) { [weak self] r in + guard let self = self else { return } + if case .success = r { + print("getMapData success") + + // Display the map with multi-floor view enabled. + let show3dMapOptions = Show3DMapOptions( + multiFloorView: Show3DMapOptions.MultiFloorViewOptions( + enabled: true, +//TODO remove commented code after fix released. +// floorGap: 10.0, +// updateCameraElevationOnFloorChange: true + ) + ) + + self.mapView.show3dMap(options: show3dMapOptions) { r2 in + if case .success = r2 { + DispatchQueue.main.async { + self.loadingIndicator.stopAnimating() + } + self.onMapReady() + } else if case .failure(let error) = r2 { + DispatchQueue.main.async { + self.loadingIndicator.stopAnimating() + } + print("show3dMap error: \(error)") + } + } + } else if case .failure(let error) = r { + print("getMapData error: \(error)") + } + } + } + + // Place your code to be called when the map is ready here. + private func onMapReady() { + print("show3dMap success - Map displayed with multi-floor view") + + // Get all floors and find the ones we need. + mapView.mapData.getByType(MapDataType.floor) { [weak self] (result: Result<[Floor], Error>) in + guard let self = self else { return } + switch result { + case .success(let floors): + // Set the current floor to the one with elevation 9. + if let floor9 = floors.first(where: { $0.elevation == 9.0 }) { + self.mapView.setFloor(floorId: floor9.id) { _ in + print("Set floor to elevation 9: \(floor9.name)") + } + } + + // Show the 6th floor (elevation 6) as well. + if let floor6 = floors.first(where: { $0.elevation == 6.0 }) { + self.mapView.updateState( + floor: floor6, + state: FloorUpdateState( + geometry: FloorUpdateState.Geometry(visible: true) + ) + ) { _ in + print("Made floor with elevation 6 visible: \(floor6.name)") + } + } + case .failure(let error): + print("Failed to get floors: \(error)") + } + } + } +} + diff --git a/SDK v6 Examples/PlaygroundSamples/PlaygroundSamples/StackedMapsDemoViewController.swift b/SDK v6 Examples/PlaygroundSamples/PlaygroundSamples/StackedMapsDemoViewController.swift new file mode 100644 index 0000000..9533367 --- /dev/null +++ b/SDK v6 Examples/PlaygroundSamples/PlaygroundSamples/StackedMapsDemoViewController.swift @@ -0,0 +1,202 @@ +import UIKit +import Mappedin + +final class StackedMapsDemoViewController: UIViewController { + private let mapView = MapView() + private let loadingIndicator = UIActivityIndicatorView(style: .large) + + private var animate = true + private var distanceBetweenFloors: Double = 10.0 + private var gapValueLabel: UILabel! + + override func viewDidLoad() { + super.viewDidLoad() + title = "Stacked Maps" + view.backgroundColor = .systemBackground + + let container = mapView.view + container.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(container) + + // Add loading indicator + loadingIndicator.translatesAutoresizingMaskIntoConstraints = false + loadingIndicator.startAnimating() + view.addSubview(loadingIndicator) + + // Add control panel + let controlPanel = createControlPanel() + controlPanel.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(controlPanel) + + NSLayoutConstraint.activate([ + container.leadingAnchor.constraint(equalTo: view.leadingAnchor), + container.trailingAnchor.constraint(equalTo: view.trailingAnchor), + container.topAnchor.constraint(equalTo: view.topAnchor), + container.bottomAnchor.constraint(equalTo: view.bottomAnchor), + + loadingIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor), + loadingIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor), + + controlPanel.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16), + controlPanel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16), + ]) + + // See Trial API key Terms and Conditions + // https://developer.mappedin.com/docs/demo-keys-and-maps + let options = GetMapDataWithCredentialsOptions( + key: "mik_yeBk0Vf0nNJtpesfu560e07e5", + secret: "mis_2g9ST8ZcSFb5R9fPnsvYhrX3RyRwPtDGbMGweCYKEq385431022", + mapId: "666ca6a48dd908000bf47803" + ) + + // Load the map data. + mapView.getMapData(options: options) { [weak self] r in + guard let self = self else { return } + if case .success = r { + print("getMapData success") + + // Display the map with higher pitch for better stacked view. + let show3dMapOptions = Show3DMapOptions( + pitch: 80.0 + ) + + self.mapView.show3dMap(options: show3dMapOptions) { r2 in + if case .success = r2 { + DispatchQueue.main.async { + self.loadingIndicator.stopAnimating() + } + self.onMapReady() + } else if case .failure(let error) = r2 { + DispatchQueue.main.async { + self.loadingIndicator.stopAnimating() + } + print("show3dMap error: \(error)") + } + } + } else if case .failure(let error) = r { + print("getMapData error: \(error)") + } + } + } + + private func createControlPanel() -> UIView { + let panel = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial)) + panel.layer.cornerRadius = 12 + panel.clipsToBounds = true + + let stackView = UIStackView() + stackView.axis = .vertical + stackView.spacing = 12 + stackView.translatesAutoresizingMaskIntoConstraints = false + panel.contentView.addSubview(stackView) + + NSLayoutConstraint.activate([ + stackView.leadingAnchor.constraint(equalTo: panel.contentView.leadingAnchor, constant: 16), + stackView.trailingAnchor.constraint(equalTo: panel.contentView.trailingAnchor, constant: -16), + stackView.topAnchor.constraint(equalTo: panel.contentView.topAnchor, constant: 16), + stackView.bottomAnchor.constraint(equalTo: panel.contentView.bottomAnchor, constant: -16), + ]) + + // Expand button + let expandButton = UIButton(type: .system) + expandButton.setTitle("Expand", for: .normal) + expandButton.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium) + expandButton.addTarget(self, action: #selector(expandTapped), for: .touchUpInside) + stackView.addArrangedSubview(expandButton) + + // Collapse button + let collapseButton = UIButton(type: .system) + collapseButton.setTitle("Collapse", for: .normal) + collapseButton.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium) + collapseButton.addTarget(self, action: #selector(collapseTapped), for: .touchUpInside) + stackView.addArrangedSubview(collapseButton) + + // Animate toggle + let animateStack = UIStackView() + animateStack.axis = .horizontal + animateStack.spacing = 8 + + let animateLabel = UILabel() + animateLabel.text = "Animate" + animateLabel.font = UIFont.systemFont(ofSize: 14) + + let animateSwitch = UISwitch() + animateSwitch.isOn = animate + animateSwitch.addTarget(self, action: #selector(animateToggled(_:)), for: .valueChanged) + + animateStack.addArrangedSubview(animateLabel) + animateStack.addArrangedSubview(animateSwitch) + stackView.addArrangedSubview(animateStack) + + // Floor gap label + let floorGapLabel = UILabel() + floorGapLabel.text = "Floor Gap:" + floorGapLabel.font = UIFont.systemFont(ofSize: 14) + stackView.addArrangedSubview(floorGapLabel) + + // Floor gap slider + let slider = UISlider() + slider.minimumValue = 0 + slider.maximumValue = 50 + slider.value = Float(distanceBetweenFloors) + slider.addTarget(self, action: #selector(sliderChanged(_:)), for: .valueChanged) + stackView.addArrangedSubview(slider) + + // Gap value display + gapValueLabel = UILabel() + gapValueLabel.text = "\(Int(distanceBetweenFloors))m" + gapValueLabel.font = UIFont.systemFont(ofSize: 14) + gapValueLabel.textAlignment = .center + stackView.addArrangedSubview(gapValueLabel) + + return panel + } + + @objc private func expandTapped() { + StackedMapsUtils.expandFloors( + mapView: mapView, + options: ExpandOptions( + distanceBetweenFloors: distanceBetweenFloors, + animate: animate + ) + ) + } + + @objc private func collapseTapped() { + StackedMapsUtils.collapseFloors( + mapView: mapView, + options: CollapseOptions(animate: animate) + ) + } + + @objc private func animateToggled(_ sender: UISwitch) { + animate = sender.isOn + } + + @objc private func sliderChanged(_ sender: UISlider) { + distanceBetweenFloors = Double(sender.value) + gapValueLabel.text = "\(Int(distanceBetweenFloors))m" + + // Automatically expand floors with new gap value + StackedMapsUtils.expandFloors( + mapView: mapView, + options: ExpandOptions( + distanceBetweenFloors: distanceBetweenFloors, + animate: animate + ) + ) + } + + // Place your code to be called when the map is ready here. + private func onMapReady() { + print("show3dMap success - Map displayed") + + // Hide the outdoor map and configure camera for stacked view. + mapView.outdoor.hide() + mapView.camera.setMaxPitch(88.0) + mapView.camera.set( + target: CameraTarget(pitch: 75.0) + ) + } +} + diff --git a/SDK v6 Examples/PlaygroundSamples/PlaygroundSamples/StackedMapsUtils.swift b/SDK v6 Examples/PlaygroundSamples/PlaygroundSamples/StackedMapsUtils.swift new file mode 100644 index 0000000..7103f0d --- /dev/null +++ b/SDK v6 Examples/PlaygroundSamples/PlaygroundSamples/StackedMapsUtils.swift @@ -0,0 +1,223 @@ +import Foundation +import Mappedin + +/// Options for expanding floors in a stacked view. +public struct ExpandOptions { + /// The vertical spacing between floors in meters. Default: 10 + public let distanceBetweenFloors: Double + /// Whether to animate the floor expansion. Default: true + public let animate: Bool + /// The camera pan mode to use ("default" or "elevation"). Default: "elevation" + public let cameraPanMode: String + + public init( + distanceBetweenFloors: Double = 10.0, + animate: Bool = true, + cameraPanMode: String = "elevation" + ) { + self.distanceBetweenFloors = distanceBetweenFloors + self.animate = animate + self.cameraPanMode = cameraPanMode + } +} + +/// Options for collapsing floors back to their original positions. +public struct CollapseOptions { + /// Whether to animate the floor collapse. Default: true + public let animate: Bool + + public init(animate: Bool = true) { + self.animate = animate + } +} + +/// Utility class for managing stacked floor views. +/// +/// Provides functions to expand all floors vertically (stacked view) and collapse them back +/// to a single floor view. This creates a 3D exploded view effect where all floors are visible +/// at different altitudes. +/// +/// Example usage: +/// ```swift +/// // Expand floors with default options +/// StackedMapsUtils.expandFloors(mapView: mapView) +/// +/// // Expand floors with custom gap +/// StackedMapsUtils.expandFloors(mapView: mapView, options: ExpandOptions(distanceBetweenFloors: 20.0)) +/// +/// // Collapse floors back +/// StackedMapsUtils.collapseFloors(mapView: mapView) +/// ``` +public class StackedMapsUtils { + + /// Expands all floors vertically to create a stacked view. + /// + /// Each floor is positioned at an altitude based on its elevation multiplied by the + /// distance between floors. This creates a 3D exploded view where all floors are visible. + /// + /// - Parameters: + /// - mapView: The MapView instance + /// - options: Options controlling the expansion behavior + public static func expandFloors( + mapView: MapView, + options: ExpandOptions = ExpandOptions() + ) { + // Set camera pan mode to elevation for better navigation in stacked view + mapView.camera.setPanMode(options.cameraPanMode) + + // Get the current floor ID to identify the active floor + mapView.currentFloor { currentFloorResult in + let currentFloorId: String? + switch currentFloorResult { + case .success(let floor): + currentFloorId = floor?.id + case .failure: + currentFloorId = nil + } + + // Get all floors + mapView.mapData.getByType(MapDataType.floor) { (result: Result<[Floor], Error>) in + switch result { + case .success(let floors): + for floor in floors { + let newAltitude = floor.elevation * options.distanceBetweenFloors + let isCurrentFloor = floor.id == currentFloorId + + // First, make sure the floor is visible + mapView.getState(floor: floor) { stateResult in + switch stateResult { + case .success(let currentState): + if let state = currentState, + (!state.visible || !state.geometry.visible) { + // Make the floor visible first with 0 opacity if not current + mapView.updateState( + floor: floor, + state: FloorUpdateState( + altitude: 0.0, + visible: true, + geometry: FloorUpdateState.Geometry( + opacity: isCurrentFloor ? 1.0 : 0.0, + visible: true + ) + ) + ) + } + + // Then animate or update to the new altitude + if options.animate { + mapView.animateState( + floor: floor, + state: FloorUpdateState( + altitude: newAltitude, + geometry: FloorUpdateState.Geometry( + opacity: 1.0 + ) + ) + ) + } else { + mapView.updateState( + floor: floor, + state: FloorUpdateState( + altitude: newAltitude, + visible: true, + geometry: FloorUpdateState.Geometry( + opacity: 1.0, + visible: true + ) + ) + ) + } + case .failure: + break + } + } + } + case .failure: + break + } + } + } + } + + /// Collapses all floors back to their original positions. + /// + /// Floors are returned to altitude 0, and only the current floor remains fully visible. + /// Other floors are hidden to restore the standard single-floor view. + /// + /// - Parameters: + /// - mapView: The MapView instance + /// - options: Options controlling the collapse behavior + public static func collapseFloors( + mapView: MapView, + options: CollapseOptions = CollapseOptions() + ) { + // Reset camera pan mode to default + mapView.camera.setPanMode("default") + + // Get the current floor ID to identify the active floor + mapView.currentFloor { currentFloorResult in + let currentFloorId: String? + switch currentFloorResult { + case .success(let floor): + currentFloorId = floor?.id + case .failure: + currentFloorId = nil + } + + // Get all floors + mapView.mapData.getByType(MapDataType.floor) { (result: Result<[Floor], Error>) in + switch result { + case .success(let floors): + for floor in floors { + let isCurrentFloor = floor.id == currentFloorId + + if options.animate { + // Animate to altitude 0 and fade out non-current floors + mapView.animateState( + floor: floor, + state: FloorUpdateState( + altitude: 0.0, + geometry: FloorUpdateState.Geometry( + opacity: isCurrentFloor ? 1.0 : 0.0 + ) + ) + ) + + // After animation, hide non-current floors + if !isCurrentFloor { + DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { + mapView.updateState( + floor: floor, + state: FloorUpdateState( + altitude: 0.0, + visible: false, + geometry: FloorUpdateState.Geometry( + opacity: 0.0, + visible: false + ) + ) + ) + } + } + } else { + mapView.updateState( + floor: floor, + state: FloorUpdateState( + altitude: 0.0, + visible: isCurrentFloor, + geometry: FloorUpdateState.Geometry( + opacity: isCurrentFloor ? 1.0 : 0.0, + visible: isCurrentFloor + ) + ) + ) + } + } + case .failure: + break + } + } + } + } +} + diff --git a/SDK v6 Examples/PlaygroundSamples/PlaygroundSamples/ViewController.swift b/SDK v6 Examples/PlaygroundSamples/PlaygroundSamples/ViewController.swift index e895d6e..63b586e 100644 --- a/SDK v6 Examples/PlaygroundSamples/PlaygroundSamples/ViewController.swift +++ b/SDK v6 Examples/PlaygroundSamples/PlaygroundSamples/ViewController.swift @@ -7,7 +7,7 @@ import UIKit class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { - private let demos = ["Areas & Shapes", "Building & Floor Selection", "Camera", "Display a Map", "Image3D", "Interactivity", "Labels", "Locations", "Markers", "Models", "Navigation", "Paths", "Query", "Search"] + private let demos = ["Areas & Shapes", "Building & Floor Selection", "Camera", "Display a Map", "Image3D", "Interactivity", "Labels", "Locations", "Markers", "Models", "Multi-Floor View", "Navigation", "Paths", "Query", "Search", "Stacked Maps"] private let tableView = UITableView(frame: .zero, style: .insetGrouped) override func viewDidLoad() { @@ -79,23 +79,32 @@ class ViewController: UIViewController, UITableViewDataSource, UITableViewDelega if let nav = navigationController { nav.pushViewController(vc, animated: true) } else { present(UINavigationController(rootViewController: vc), animated: true) } case 10: - let vc = NavigationDemoViewController() + let vc = MultiFloorViewDemoViewController() if let nav = navigationController { nav.pushViewController(vc, animated: true) } else { present(UINavigationController(rootViewController: vc), animated: true) } case 11: - let vc = PathsDemoViewController() + let vc = NavigationDemoViewController() if let nav = navigationController { nav.pushViewController(vc, animated: true) } else { present(UINavigationController(rootViewController: vc), animated: true) } case 12: - let vc = QueryDemoViewController() + let vc = PathsDemoViewController() if let nav = navigationController { nav.pushViewController(vc, animated: true) } else { present(UINavigationController(rootViewController: vc), animated: true) } case 13: + let vc = QueryDemoViewController() + if let nav = navigationController { nav.pushViewController(vc, animated: true) } + else { present(UINavigationController(rootViewController: vc), animated: true) } + case 14: let vc = SearchDemoViewController() if let nav = navigationController { nav.pushViewController(vc, animated: true) } else { present(UINavigationController(rootViewController: vc), animated: true) } + case 15: + let vc = StackedMapsDemoViewController() + if let nav = navigationController { nav.pushViewController(vc, animated: true) } + else { present(UINavigationController(rootViewController: vc), animated: true) } default: break } } } + diff --git a/readme.md b/readme.md index e9bcb1b..3acc7fd 100644 --- a/readme.md +++ b/readme.md @@ -18,17 +18,20 @@ The following table lists the sample activities that pertain to the latest versi | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | | [DisplayMapDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/DisplayMapDemoViewController.swift) | The most basic example do show a map. | [Getting Started](https://developer.mappedin.com/ios-sdk/getting-started) | | [AreaShapesDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/AreaShapesDemoViewController.swift) | Demonstrates using shapes to show areas and route directions around closed areas. | Coming Soon | -| [BuildingFloorSelectionDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/BuildingFloorSelectionDemoViewController.swift) | Demonstrates switching between maps for venues with multiple floors and or multiple buildings. | Coming Soon | +| [BuildingFloorSelectionDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/BuildingFloorSelectionDemoViewController.swift) | Demonstrates switching between maps for venues with multiple floors and or multiple buildings. | [Building & Floor Selection](https://developer.mappedin.com/ios-sdk/level-selection) | | [CameraDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/CameraDemoViewController.swift) | Demonstrates how to move the camera. | Coming Soon | | [Image3DDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/Image3DDemoViewController.swift) | Demonstrates how to add images on a map. | Coming Soon | -| [InteractivityDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/InteractivityDemoViewController.swift) | Demonstrates how to capture and act on touch events. | Coming Soon | -| [LabelsDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/LabelsDemoViewController.swift) | Demonstrates adding rich labels to the map. | Coming Soon | -| [MarkersDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/MarkersDemoViewController.swift) | Demonstrates adding HTML Markers to the map. | Coming Soon | +| [InteractivityDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/InteractivityDemoViewController.swift) | Demonstrates how to capture and act on touch events. | [Interactivity](https://developer.mappedin.com/ios-sdk/interactivity) | +| [LabelsDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/LabelsDemoViewController.swift) | Demonstrates adding rich labels to the map. | [Labels](https://developer.mappedin.com/ios-sdk/labels) | +| [LocationsDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/LocationsDemoViewController.swift) | Demonstrates using location profiles and categories. | [Location Profiles & Categories](https://developer.mappedin.com/ios-sdk/location-profiles-categories) | +| [MarkersDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/MarkersDemoViewController.swift) | Demonstrates adding HTML Markers to the map. | [Markers](https://developer.mappedin.com/ios-sdk/markers) | | [ModelsDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/ModelsDemoViewController) | Demonstrates adding 3D models to the map. | Coming Soon | +| [MultiFloorViewDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/MultiFloorViewDemoViewController.swift) | Demonstrates using multi floor view. | [Multi Floor View & Stacked Maps](https://developer.mappedin.com/ios-sdk/stacked-maps) | | [NavigationDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/NavigationDemoViewController.swift) | Demonstrates wayfinding and navigation across multiple floors. | Coming Soon | | [PathsDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/PathsDemoViewController.swift) | Demonstrates how to draw a path between two rooms. | Coming Soon | | [QueryDemoViewController](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/QueryDemoViewController.swift) | Demonstrates how to find the nearest room based on a coordinate and click event. | Coming Soon | | [SearchDemoViewController.swift](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/SearchDemoViewController.swift) | Demonstrates how to use the suggest and search feature. | Coming Soon | +| [StackedMapsDemoViewController.swift](./SDK%20v6%20Examples/PlaygroundSamples/PlaygroundSamples/StackedMapsDemoViewController.swift) | Demonstrates how to use the stacked maps. | [Multi Floor View & Stacked Maps](https://developer.mappedin.com/ios-sdk/stacked-maps) | ---