Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add map attribution #181

Merged
merged 8 commits into from
Mar 1, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions ios-sdk.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
/* Begin PBXBuildFile section */
7D2FB7671E6103D500CB82CF /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2FB7661E6103D500CB82CF /* DictionaryExtensions.swift */; };
7D2FB7691E64E66B00CB82CF /* DictionaryExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2FB7681E64E66B00CB82CF /* DictionaryExtensionsTests.swift */; };
7D7DAE161E60AF9400FFCA6F /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D7DAE151E60AF9400FFCA6F /* Localizable.strings */; };
7D7847251E6775EA000D56CA /* Dimensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D7847241E6775EA000D56CA /* Dimensions.swift */; };
7D7DAE1D1E60C5C900FFCA6F /* TestApplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D7DAE1C1E60C5C900FFCA6F /* TestApplication.swift */; };
7D7DAE211E60EEA300FFCA6F /* ApplicationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D7DAE201E60EEA300FFCA6F /* ApplicationExtensions.swift */; };
7DF0AA2E1E5520ED00B0406E /* TestTGMapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DF0AA2D1E5520ED00B0406E /* TestTGMapViewController.swift */; };
AC586709D7E7D4C22AA9474D /* Pods_ios_sdk.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 99B3EC60450343448FA4E699 /* Pods_ios_sdk.framework */; };
C8F52AC1BCE46BB17E1CE0A5 /* Pods_ios_sdkTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A3EA87256F2EA6D0C43260A /* Pods_ios_sdkTests.framework */; };
Expand Down Expand Up @@ -75,6 +79,10 @@
5A3EA87256F2EA6D0C43260A /* Pods_ios_sdkTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ios_sdkTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
7D2FB7661E6103D500CB82CF /* DictionaryExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryExtensions.swift; sourceTree = "<group>"; };
7D2FB7681E64E66B00CB82CF /* DictionaryExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryExtensionsTests.swift; sourceTree = "<group>"; };
7D7DAE151E60AF9400FFCA6F /* Localizable.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = "<group>"; };
7D7847241E6775EA000D56CA /* Dimensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Dimensions.swift; sourceTree = "<group>"; };
7D7DAE1C1E60C5C900FFCA6F /* TestApplication.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestApplication.swift; sourceTree = "<group>"; };
7D7DAE201E60EEA300FFCA6F /* ApplicationExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationExtensions.swift; sourceTree = "<group>"; };
7DF0AA2D1E5520ED00B0406E /* TestTGMapViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestTGMapViewController.swift; sourceTree = "<group>"; };
92C35E8790FB3255237B1E77 /* Pods.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods.framework; sourceTree = BUILT_PRODUCTS_DIR; };
99B3EC60450343448FA4E699 /* Pods_ios_sdk.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ios_sdk.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -138,6 +146,14 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
7D7847231E6775EA000D56CA /* dimensions */ = {
isa = PBXGroup;
children = (
7D7847241E6775EA000D56CA /* Dimensions.swift */,
);
path = dimensions;
sourceTree = "<group>";
};
8E4E4B43C1B764470EBBDBBA /* Pods */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -232,20 +248,23 @@
DB188EEB1E28492A0054DEFD /* MapzenManagerTests.swift */,
7DF0AA2D1E5520ED00B0406E /* TestTGMapViewController.swift */,
7D2FB7681E64E66B00CB82CF /* DictionaryExtensionsTests.swift */,
7D7DAE1C1E60C5C900FFCA6F /* TestApplication.swift */,
);
path = "ios-sdkTests";
sourceTree = "<group>";
};
DBC84EA51C985B6D00EE80D8 /* src */ = {
isa = PBXGroup;
children = (
7D7847231E6775EA000D56CA /* dimensions */,
DBC869911D3663C700DDC4FE /* PeliasMapkitExtensions.swift */,
DB70FEA81DE3425800249509 /* MapViewController.swift */,
DB5B31501DE4A173005EB816 /* LocationManager.swift */,
DBFB759E1E2046D100CF6173 /* TangramExtensions.swift */,
DB188EE91E2846600054DEFD /* MapzenManager.swift */,
DB188EED1E290D310054DEFD /* MapzenRoutingController.swift */,
7D2FB7661E6103D500CB82CF /* DictionaryExtensions.swift */,
7D7DAE201E60EEA300FFCA6F /* ApplicationExtensions.swift */,
);
path = src;
sourceTree = "<group>";
Expand Down Expand Up @@ -485,6 +504,8 @@
files = (
DBFB759F1E2046D100CF6173 /* TangramExtensions.swift in Sources */,
DBFB759D1E20345500CF6173 /* SearchPinsViewController.swift in Sources */,
7D7DAE211E60EEA300FFCA6F /* ApplicationExtensions.swift in Sources */,
7D7847251E6775EA000D56CA /* Dimensions.swift in Sources */,
DB188EEA1E2846600054DEFD /* MapzenManager.swift in Sources */,
DBF441AE1D351B0A007DEE95 /* TangramVC.swift in Sources */,
DB22E59E1DA473CA004264E0 /* RouteDirectionCell.swift in Sources */,
Expand All @@ -506,6 +527,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7D7DAE1D1E60C5C900FFCA6F /* TestApplication.swift in Sources */,
7DF0AA2E1E5520ED00B0406E /* TestTGMapViewController.swift in Sources */,
DB188EEC1E28492A0054DEFD /* MapzenManagerTests.swift in Sources */,
DBCBC5BF1E0AE1CF0045B345 /* MapViewControllerTests.swift in Sources */,
Expand Down
13 changes: 12 additions & 1 deletion ios-sdkTests/MapViewControllerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import TangramMap
import CoreLocation

class TestMapViewController: MapViewController {

func lastSetPointValue() -> TGGeoPoint? {
return lastSetPoint
}
Expand All @@ -32,11 +31,13 @@ class MockHTTPHandler: TGHttpHandler {

class MapViewControllerTests: XCTestCase {

let testApplication = TestApplication()
var controller = TestMapViewController()
var tgViewController = TestTGMapViewController()
let mockLocation = CLLocation(latitude: 0.0, longitude: 0.0) // Null Island!

override func setUp() {
controller = TestMapViewController(applicationProtocol: testApplication)
controller.tgViewController = tgViewController
let mockHTTP = MockHTTPHandler()
controller.tgViewController.httpHandler = mockHTTP
Expand Down Expand Up @@ -233,6 +234,7 @@ class MapViewControllerTests: XCTestCase {
}

func testFindMeButtonInitialState() {
controller.setupFindMeButton()
//Test Initial State
XCTAssertTrue(controller.findMeButton.isHidden)
XCTAssertFalse(controller.findMeButton.isEnabled)
Expand Down Expand Up @@ -559,6 +561,15 @@ class MapViewControllerTests: XCTestCase {
controller.mapView(tgViewController, didSelectMarker: nil, atScreenPosition: CGPoint())
XCTAssertFalse(delegate.markerPicked)
}

func testAttributionOpensRights() {
controller.viewDidLoad()
let actions = controller.attributionBtn.actions(forTarget: controller, forControlEvent: .touchUpInside)
let selectorStr = actions?.first
controller.perform(NSSelectorFromString(selectorStr!))
XCTAssertEqual(testApplication.urlToOpen?.absoluteString, "https://mapzen.com/rights/")
}

}

class TestPanDelegate : MapPanGestureDelegate {
Expand Down
20 changes: 20 additions & 0 deletions ios-sdkTests/TestApplication.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// TestApplication.swift
// ios-sdk
//
// Created by Sarah Lensing on 2/24/17.
// Copyright © 2017 Mapzen. All rights reserved.
//

import UIKit
@testable import ios_sdk

class TestApplication: ApplicationProtocol {

open var urlToOpen : URL?

func openURL(_ url: URL) -> Bool {
urlToOpen = url
return false
}
}
15 changes: 15 additions & 0 deletions src/ApplicationExtensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// ApplicationExtensions.swift
// ios-sdk
//
// Created by Sarah Lensing on 2/24/17.
// Copyright © 2017 Mapzen. All rights reserved.
//

import UIKit

protocol ApplicationProtocol {
func openURL(_ url: URL) -> Bool
}

extension UIApplication: ApplicationProtocol {}
119 changes: 86 additions & 33 deletions src/MapViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ open class MapViewController: UIViewController, LocationManagerDelegate {

//Error Domains for NSError Appeasement
open static let MapzenGeneralErrorDomain = "MapzenGeneralErrorDomain"
private static let mapzenRights = "https://mapzen.com/rights/"

let application : ApplicationProtocol
open var tgViewController: TGMapViewController = TGMapViewController()
var currentLocationGem: TGMapMarkerId?
var lastSetPoint: TGGeoPoint?
Expand All @@ -77,6 +79,7 @@ open class MapViewController: UIViewController, LocationManagerDelegate {
open var shouldFollowCurrentLocation = false
open var findMeButton = UIButton(type: .custom)
open var currentAnnotations: [PeliasMapkitAnnotation : TGMapMarkerId] = Dictionary()
open var attributionBtn = UIButton()

open var cameraType: TGCameraType {
set {
Expand Down Expand Up @@ -143,18 +146,32 @@ open class MapViewController: UIViewController, LocationManagerDelegate {
public typealias OnSceneLoaded = (String) -> ()
fileprivate var onSceneLoadedClosure : OnSceneLoaded? = nil

init(){
init() {
application = UIApplication.shared
super.init(nibName: nil, bundle: nil)
defer {
findMeButton = createFindMeButton()
}
}

required public init?(coder aDecoder: NSCoder) {
application = UIApplication.shared
super.init(coder: aDecoder)
defer {
findMeButton = createFindMeButton()
}
}

public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
application = UIApplication.shared
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}

init(applicationProtocol: ApplicationProtocol) {
application = applicationProtocol
super.init(nibName: nil, bundle: nil)
}

open var mapView : GLKView {
return tgViewController.view as! GLKView
}

open var tabBarHeight : CGFloat {
return self.tabBarController?.tabBar.frame.height ?? 0
}

open func animate(toPosition position: TGGeoPoint, withDuration seconds: Float) {
Expand Down Expand Up @@ -396,38 +413,19 @@ open class MapViewController: UIViewController, LocationManagerDelegate {
override open func viewDidLoad() {
super.viewDidLoad()
LocationManager.sharedManager.delegate = self

self.view.addSubview(tgViewController.view)


setupTgControllerView()
setupAttribution()
setupFindMeButton()

tgViewController.gestureDelegate = self
tgViewController.mapViewDelegate = self
}

override open func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
tgViewController.viewWillTransition(to: size, with:coordinator)
}

override open func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let viewRect = view.bounds
findMeButton.frame = CGRect(x: viewRect.width - 60.0, y: viewRect.height - 100.0, width: CGFloat(48), height: CGFloat(48))
view.addSubview(findMeButton)
findMeButton.sizeToFit()
}

func createFindMeButton() -> UIButton {
let findMeButton = UIButton(type: UIButtonType.custom)
findMeButton.addTarget(self, action: #selector(MapViewController.defaultFindMeAction(_:touchEvent:)), for: .touchUpInside)
findMeButton.isEnabled = false
findMeButton.isHidden = true
findMeButton.adjustsImageWhenHighlighted = false
findMeButton.setBackgroundImage(UIImage(named: "ic_find_me_normal"), for: UIControlState())
//TODO: This should also have .Highlighted as well .Selected , but something about the @3x assets and UIButton is misbehaving; might need bug opened with Apple.
findMeButton.setBackgroundImage(UIImage(named: "ic_find_me_pressed"), for: [.selected])
findMeButton.backgroundColor = UIColor.white
findMeButton.autoresizingMask = [.flexibleTopMargin, .flexibleLeftMargin]
return findMeButton
let adjustedSize = CGSize(width: size.width, height: size.height-tabBarHeight)
tgViewController.viewWillTransition(to: adjustedSize, with:coordinator)
}

//MARK: - LocationManagerDelegate
Expand Down Expand Up @@ -469,6 +467,60 @@ open class MapViewController: UIViewController, LocationManagerDelegate {
return
}

//MARK: - private

private func setupTgControllerView() {
tgViewController.view.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(tgViewController.view)

let leftConstraint = tgViewController.view.leftAnchor.constraint(equalTo: view.leftAnchor)
let rightConstraint = tgViewController.view.rightAnchor.constraint(equalTo: view.rightAnchor)
let topConstraint = tgViewController.view.topAnchor.constraint(equalTo: view.topAnchor)
let bottomConstraint = tgViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -tabBarHeight)
NSLayoutConstraint.activate([leftConstraint, rightConstraint, topConstraint, bottomConstraint])
}

private func setupAttribution() {
attributionBtn = UIButton()
attributionBtn.setTitle("Powered by Mapzen", for: .normal)
attributionBtn.setTitleColor(.darkGray, for: .normal)
attributionBtn.titleLabel?.font = UIFont.systemFont(ofSize: 14)
attributionBtn.addTarget(self, action: #selector(openMapzenTerms), for: .touchUpInside)
attributionBtn.sizeToFit()
attributionBtn.translatesAutoresizingMaskIntoConstraints = false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should automatically get set to false when you add new constraints.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thats when constraints are set in IB:

If you want to use Auto Layout to dynamically calculate the size and position of your view, you must set this property to false, and then provide a non ambiguous, nonconflicting set of constraints for the view.
By default, the property is set to true for any view you programmatically create. If you add views in Interface Builder, the system automatically sets this property to false.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. 👍

mapView.addSubview(attributionBtn)

let horizontalConstraint = attributionBtn.leftAnchor.constraint(equalTo: mapView.leftAnchor, constant: Dimensions.defaultPadding)
let verticalConstraint = attributionBtn.bottomAnchor.constraint(equalTo: mapView.bottomAnchor, constant: -Dimensions.defaultPadding)
NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
}

func setupFindMeButton() {
findMeButton = UIButton(type: UIButtonType.custom)
findMeButton.addTarget(self, action: #selector(MapViewController.defaultFindMeAction(_:touchEvent:)), for: .touchUpInside)
findMeButton.isEnabled = false
findMeButton.isHidden = true
findMeButton.adjustsImageWhenHighlighted = false
findMeButton.setBackgroundImage(UIImage(named: "ic_find_me_normal"), for: UIControlState())
//TODO: This should also have .Highlighted as well .Selected , but something about the @3x assets and UIButton is misbehaving; might need bug opened with Apple.
findMeButton.setBackgroundImage(UIImage(named: "ic_find_me_pressed"), for: [.selected])
findMeButton.backgroundColor = UIColor.white
//findMeButton.autoresizingMask = [.flexibleTopMargin, .flexibleLeftMargin]
findMeButton.translatesAutoresizingMaskIntoConstraints = false
mapView.addSubview(findMeButton)

let horizontalConstraint = findMeButton.rightAnchor.constraint(equalTo: mapView.rightAnchor, constant: -Dimensions.defaultPadding)
let verticalConstraint = findMeButton.bottomAnchor.constraint(equalTo: mapView.bottomAnchor, constant: -Dimensions.defaultPadding)
let widthConstraint = findMeButton.widthAnchor.constraint(equalToConstant: Dimensions.squareMapBtnSize)
let heightConstraint = findMeButton.widthAnchor.constraint(equalToConstant: Dimensions.squareMapBtnSize)
NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
}

@objc private func openMapzenTerms() {
guard let url = URL(string: MapViewController.mapzenRights) else { return }
let _ = application.openURL(url)
}

private func updatesWithApiKeyUpdate(_ sceneUpdates: [TGSceneUpdate]) throws -> [TGSceneUpdate] {
guard let apiKey = MapzenManager.sharedManager.apiKey else {
throw NSError(domain: MapViewController.MapzenGeneralErrorDomain,
Expand Down Expand Up @@ -579,5 +631,6 @@ extension MapViewController : TGMapViewDelegate, TGRecognizerDelegate {
open func mapView(_ view: TGMapViewController, recognizer: UIGestureRecognizer, didRecognizeShoveGesture displacement: CGPoint) {
shoveDelegate?.mapController(self, didShoveMap: displacement)
}

}

17 changes: 17 additions & 0 deletions src/dimensions/Dimensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// Dimensions.swift
// ios-sdk
//
// Created by Sarah Lensing on 2/24/17.
// Copyright © 2017 Mapzen. All rights reserved.
//

import CoreGraphics

// Holds constant values for UI element properties such as padding and width/height
public class Dimensions {
// Default padding used for map UI elements
public static let defaultPadding : CGFloat = 10.0
// Size of all square map buttons such as the "find me" button
public static let squareMapBtnSize : CGFloat = 48.0
}