Skip to content
This repository has been archived by the owner on Apr 8, 2023. It is now read-only.

Commit

Permalink
Merge pull request #18 from v-ken/swift-3
Browse files Browse the repository at this point in the history
Merges Swift 3 branch with master branch
  • Loading branch information
Jerome Tan committed Nov 3, 2016
2 parents e1d6ff2 + 02e6c81 commit 2ad2165
Show file tree
Hide file tree
Showing 15 changed files with 591 additions and 577 deletions.
4 changes: 2 additions & 2 deletions LocationPicker.xcodeproj/project.pbxproj
Expand Up @@ -272,7 +272,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 2.3;
SWIFT_VERSION = 3.0.1;
};
name = Debug;
};
Expand All @@ -294,7 +294,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 2.3;
SWIFT_VERSION = 3.0.1;
};
name = Release;
};
Expand Down
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<VariablesViewState
version = "1.0">
<ContextStates>
<ContextState
contextName = "LocationPicker.setupViews() -&gt; ():LocationPicker.swift">
</ContextState>
</ContextStates>
</VariablesViewState>
54 changes: 22 additions & 32 deletions LocationPicker/Helpers.swift
Expand Up @@ -29,30 +29,17 @@
import Foundation
import MapKit

@objc public enum LocationType: Int {
case CurrentLocation
case SearchLocation
case AlternativeLocation
}

@objc public enum NavigationItemOrientation: Int {
case Left
case Right
}



func coordinateObjectFromTuple(coordinateTuple: (latitude: Double, longitude: Double)) -> CLLocationCoordinate2D {
func coordinateObject(fromTuple coordinateTuple: (latitude: Double, longitude: Double)) -> CLLocationCoordinate2D {
return CLLocationCoordinate2D(latitude: coordinateTuple.latitude, longitude: coordinateTuple.longitude)
}

func coordinateTupleFromObject(coordinateObject: CLLocationCoordinate2D) -> (latitude: Double, longitude: Double) {
func coordinateTuple(fromObject coordinateObject: CLLocationCoordinate2D) -> (latitude: Double, longitude: Double) {
return (latitude: coordinateObject.latitude, longitude: coordinateObject.longitude)
}



private func isCoordinateOutOfChina(coordinate: CLLocationCoordinate2D) -> Bool {
private func isOutsideChina(coordinate: CLLocationCoordinate2D) -> Bool {
if coordinate.longitude < 72.004 || coordinate.longitude > 137.8347 {
return true
}
Expand All @@ -62,25 +49,29 @@ private func isCoordinateOutOfChina(coordinate: CLLocationCoordinate2D) -> Bool
return false
}

private func transformLatitude(x x: Double, y: Double) -> Double {
private func transformLatitude(x: Double, y: Double) -> Double {
let a = sin(6.0 * x * M_PI), b = sin(2.0 * x * M_PI), c = sin(y * M_PI), d = sin(y / 3.0 * M_PI), e = sin(y / 12.0 * M_PI), f = sin(y * M_PI / 30.0)

var deltaLatitude = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y
deltaLatitude += 0.1 * x * y + 0.2 * sqrt(abs(x))
deltaLatitude += (20.0 * sin(6.0 * x * M_PI) + 20.0 * sin(2.0 * x * M_PI)) * 2.0 / 3.0
deltaLatitude += (20.0 * sin(y * M_PI) + 40.0 * sin(y / 3.0 * M_PI)) * 2.0 / 3.0
deltaLatitude += (160.0 * sin(y / 12.0 * M_PI) + 320 * sin(y * M_PI / 30.0)) * 2.0 / 3.0
deltaLatitude += (20.0 * a + 20.0 * b) * 2.0 / 3.0
deltaLatitude += (20.0 * c + 40.0 * d) * 2.0 / 3.0
deltaLatitude += (160.0 * e + 320 * f) * 2.0 / 3.0
return deltaLatitude
}

private func transformLongitude(x x: Double, y: Double) -> Double {
private func transformLongitude(x: Double, y: Double) -> Double {
let a = sin(6.0 * x * M_PI), b = sin(2.0 * x * M_PI), c = sin(x * M_PI), d = sin(x / 3.0 * M_PI), e = sin(x / 12.0 * M_PI), f = sin(x / 30.0 * M_PI)

var deltaLongitude = 300.0 + x + 2.0 * y + 0.1 * x * x
deltaLongitude += 0.1 * x * y + 0.1 * sqrt(abs(x))
deltaLongitude += (20.0 * sin(6.0 * x * M_PI) + 20.0 * sin(2.0 * x * M_PI)) * 2.0 / 3.0
deltaLongitude += (20.0 * sin(x * M_PI) + 40.0 * sin(x / 3.0 * M_PI)) * 2.0 / 3.0
deltaLongitude += (150.0 * sin(x / 12.0 * M_PI) + 300.0 * sin(x / 30.0 * M_PI)) * 2.0 / 3.0
deltaLongitude += (20.0 * a + 20.0 * b) * 2.0 / 3.0
deltaLongitude += (20.0 * c + 40.0 * d) * 2.0 / 3.0
deltaLongitude += (150.0 * e + 300.0 * f) * 2.0 / 3.0
return deltaLongitude
}

private func delta(latitude latitude: Double, longitude: Double) -> (Double, Double) {
private func delta(latitude: Double, longitude: Double) -> (Double, Double) {
let r = 6378245.0
let ee = 0.00669342162296594323
let radLatitude = latitude / 180.0 * M_PI
Expand All @@ -94,8 +85,8 @@ private func delta(latitude latitude: Double, longitude: Double) -> (Double, Dou
return (deltaLatitude, deltaLongitude)
}

func wgs2gcj(coordinate: CLLocationCoordinate2D) -> CLLocationCoordinate2D {
if isCoordinateOutOfChina(coordinate) {
func wgsToGcj(coordinate: CLLocationCoordinate2D) -> CLLocationCoordinate2D {
if isOutsideChina(coordinate: coordinate) {
return coordinate
}

Expand All @@ -104,8 +95,8 @@ func wgs2gcj(coordinate: CLLocationCoordinate2D) -> CLLocationCoordinate2D {
return revisedCoordinate
}

func gcj2wgs(coordinate: CLLocationCoordinate2D) -> CLLocationCoordinate2D {
if isCoordinateOutOfChina(coordinate) {
func gcjToWgs(coordinate: CLLocationCoordinate2D) -> CLLocationCoordinate2D {
if isOutsideChina(coordinate: coordinate) {
return coordinate
}

Expand All @@ -115,9 +106,8 @@ func gcj2wgs(coordinate: CLLocationCoordinate2D) -> CLLocationCoordinate2D {
}



func longitudinalDistanceFromMapRect(mapRect: MKMapRect) -> Double {
func getLongitudinalDistance(fromMapRect mapRect: MKMapRect) -> Double {
let westMapPoint = MKMapPointMake(MKMapRectGetMaxX(mapRect), MKMapRectGetMidY(mapRect))
let eastMapPoint = MKMapPointMake(MKMapRectGetMinX(mapRect), MKMapRectGetMidY(mapRect))
return MKMetersBetweenMapPoints(westMapPoint, eastMapPoint)
}
}
60 changes: 30 additions & 30 deletions LocationPicker/LocationCell.swift
Expand Up @@ -31,14 +31,14 @@ import UIKit
public class LocationCell: UITableViewCell {

public var locationItem: LocationItem?
public var locationType: LocationType!
public var locationType: LocationPicker.LocationType!

public let iconView = UIImageView()
public let locationNameLabel = UILabel()
public let locationAddressLabel = UILabel()
public let containerView = UIView()

public convenience init(locationType: LocationType, locationItem: LocationItem?) {
public convenience init(locationType: LocationPicker.LocationType, locationItem: LocationItem?) {
self.init()
self.locationType = locationType
self.locationItem = locationItem
Expand All @@ -50,22 +50,22 @@ public class LocationCell: UITableViewCell {
private func setupViews() {
let length = contentView.bounds.height

backgroundColor = UIColor.clearColor()
backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0)
separatorInset.left = length

iconView.frame = CGRect(x: 0, y: 0, width: length, height: length)

if let locationItem = locationItem {
locationNameLabel.font = UIFont.systemFontOfSize(16)
locationNameLabel.font = UIFont.systemFont(ofSize: 16)
locationNameLabel.text = locationItem.name

locationAddressLabel.font = UIFont.systemFontOfSize(11)
locationAddressLabel.font = UIFont.systemFont(ofSize: 11)
locationAddressLabel.text = locationItem.formattedAddressString
}

contentView.addSubview(iconView)
containerView.addSubview(locationNameLabel)
if locationType! != .CurrentLocation {
if locationType! != .currentLocation {
containerView.addSubview(locationAddressLabel)
}
contentView.addSubview(containerView)
Expand All @@ -79,39 +79,39 @@ public class LocationCell: UITableViewCell {
if #available(iOS 9.0, *) {
let margins = contentView.layoutMarginsGuide

containerView.centerYAnchor.constraintEqualToAnchor(margins.centerYAnchor).active = true
containerView.leadingAnchor.constraintEqualToAnchor(iconView.trailingAnchor).active = true
containerView.trailingAnchor.constraintEqualToAnchor(margins.trailingAnchor).active = true
containerView.centerYAnchor.constraint(equalTo: margins.centerYAnchor).isActive = true
containerView.leadingAnchor.constraint(equalTo: iconView.trailingAnchor).isActive = true
containerView.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true

locationNameLabel.leadingAnchor.constraintEqualToAnchor(containerView.leadingAnchor).active = true
locationNameLabel.trailingAnchor.constraintEqualToAnchor(containerView.trailingAnchor).active = true
if locationType! == .CurrentLocation {
locationNameLabel.centerYAnchor.constraintEqualToAnchor(containerView.centerYAnchor).active = true
locationNameLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
locationNameLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
if locationType! == .currentLocation {
locationNameLabel.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
} else {
locationNameLabel.topAnchor.constraintEqualToAnchor(containerView.topAnchor).active = true
locationNameLabel.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true

locationAddressLabel.topAnchor.constraintEqualToAnchor(locationNameLabel.bottomAnchor).active = true
locationAddressLabel.leadingAnchor.constraintEqualToAnchor(containerView.leadingAnchor).active = true
locationAddressLabel.trailingAnchor.constraintEqualToAnchor(containerView.trailingAnchor).active = true
locationAddressLabel.bottomAnchor.constraintEqualToAnchor(containerView.bottomAnchor).active = true
locationAddressLabel.topAnchor.constraint(equalTo: locationNameLabel.bottomAnchor).isActive = true
locationAddressLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
locationAddressLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
locationAddressLabel.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
}
} else {
NSLayoutConstraint(item: containerView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1, constant: 0).active = true
NSLayoutConstraint(item: containerView, attribute: .Leading, relatedBy: .Equal, toItem: iconView, attribute: .Trailing, multiplier: 1, constant: 0).active = true
NSLayoutConstraint(item: containerView, attribute: .Trailing, relatedBy: .Equal, toItem: contentView, attribute: .Trailing, multiplier: 1, constant: 0).active = true
NSLayoutConstraint(item: containerView, attribute: .centerY, relatedBy: .equal, toItem: contentView, attribute: .centerY, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: containerView, attribute: .leading, relatedBy: .equal, toItem: iconView, attribute: .trailing, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: containerView, attribute: .trailing, relatedBy: .equal, toItem: contentView, attribute: .trailing, multiplier: 1, constant: 0).isActive = true

NSLayoutConstraint(item: locationNameLabel, attribute: .Leading, relatedBy: .Equal, toItem: containerView, attribute: .Leading, multiplier: 1, constant: 0).active = true
NSLayoutConstraint(item: locationNameLabel, attribute: .Trailing, relatedBy: .Equal, toItem: containerView, attribute: .Trailing, multiplier: 1, constant: 0).active = true
NSLayoutConstraint(item: locationNameLabel, attribute: .leading, relatedBy: .equal, toItem: containerView, attribute: .leading, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: locationNameLabel, attribute: .trailing, relatedBy: .equal, toItem: containerView, attribute: .trailing, multiplier: 1, constant: 0).isActive = true

if locationType! == .CurrentLocation {
NSLayoutConstraint(item: locationNameLabel, attribute: .CenterY, relatedBy: .Equal, toItem: containerView, attribute: .CenterY, multiplier: 1, constant: 0).active = true
if locationType! == .currentLocation {
NSLayoutConstraint(item: locationNameLabel, attribute: .centerY, relatedBy: .equal, toItem: containerView, attribute: .centerY, multiplier: 1, constant: 0).isActive = true
} else {
NSLayoutConstraint(item: locationNameLabel, attribute: .Top, relatedBy: .Equal, toItem: containerView, attribute: .Top, multiplier: 1, constant: 0).active = true
NSLayoutConstraint(item: locationNameLabel, attribute: .top, relatedBy: .equal, toItem: containerView, attribute: .top, multiplier: 1, constant: 0).isActive = true

NSLayoutConstraint(item: locationAddressLabel, attribute: .Top, relatedBy: .Equal, toItem: locationNameLabel, attribute: .Bottom, multiplier: 1, constant: 0).active = true
NSLayoutConstraint(item: locationAddressLabel, attribute: .Leading, relatedBy: .Equal, toItem: containerView, attribute: .Leading, multiplier: 1, constant: 0).active = true
NSLayoutConstraint(item: locationAddressLabel, attribute: .Trailing, relatedBy: .Equal, toItem: containerView, attribute: .Trailing, multiplier: 1, constant: 0).active = true
NSLayoutConstraint(item: locationAddressLabel, attribute: .Bottom, relatedBy: .Equal, toItem: containerView, attribute: .Bottom, multiplier: 1, constant: 0).active = true
NSLayoutConstraint(item: locationAddressLabel, attribute: .top, relatedBy: .equal, toItem: locationNameLabel, attribute: .bottom, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: locationAddressLabel, attribute: .leading, relatedBy: .equal, toItem: containerView, attribute: .leading, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: locationAddressLabel, attribute: .trailing, relatedBy: .equal, toItem: containerView, attribute: .trailing, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: locationAddressLabel, attribute: .bottom, relatedBy: .equal, toItem: containerView, attribute: .bottom, multiplier: 1, constant: 0).isActive = true
}
}

Expand Down
49 changes: 23 additions & 26 deletions LocationPicker/LocationItem.swift
Expand Up @@ -58,45 +58,44 @@ public class LocationItem: NSObject, NSCoding {
public let mapItem: MKMapItem



/// The name of the location. A reference to `MKMapItem` object's property `name`.
/// The name of the location. A reference to `MKMapItem` object's property `name`.
public var name: String {
get {
return mapItem.name ?? ""
}
}

/// The coordinate of the location. A reference to `MKMapItem` object's property `placemark.coordinate` and converted to tuple. Only when the `allowArbitraryLocation` property of `LocationPicker` class is set to `true`, can this property be `nil`.
/// The coordinate of the location. A reference to `MKMapItem` object's property `placemark.coordinate` and converted to tuple. Only when the `allowArbitraryLocation` property of `LocationPicker` class is set to `true`, can this property be `nil`.
public var coordinate: (latitude: Double, longitude: Double)? {
get {
let coordinate = mapItem.placemark.coordinate
if CLLocationCoordinate2DIsValid(coordinate) {
return coordinateTupleFromObject(coordinate)
return coordinateTuple(fromObject: coordinate)
} else {
return nil
}
}
}

/// The address dictionary of the location. A reference to `MKMapItem` object's property `placemark.addressDictionary`
/// - Note: This dictionary along with a coordinate can be used to create a `MKPlacemark` object which can create a `MKMapItem` object.
public var addressDictionary: [NSObject: AnyObject]? {
/// The address dictionary of the location. A reference to `MKMapItem` object's property `placemark.addressDictionary`
/// - Note: This dictionary along with a coordinate can be used to create a `MKPlacemark` object which can create a `MKMapItem` object.
public var addressDictionary: [AnyHashable: Any]? {
get {
return mapItem.placemark.addressDictionary
}
}

/// The address of the location. This is the value to the key _"FormattedAddressLines"_ in `addressDictionary`. It is the address text formatted according to user's region.
/// - Note: If you would like to format the address yourself, you can use `addressDictionary` property to create one.
/// The address of the location. This is the value to the key _"FormattedAddressLines"_ in `addressDictionary`. It is the address text formatted according to user's region.
/// - Note: If you would like to format the address yourself, you can use `addressDictionary` property to create one.

public var formattedAddressString: String? {
get {
let addressParts = (addressDictionary?["FormattedAddressLines"] as? [String])
return addressParts?.count > 1 ? addressParts?[1] : addressParts?[0]
guard let addressParts = (addressDictionary?["FormattedAddressLines"] as? [String]) else { return nil }
return addressParts.count > 1 ? addressParts[1] : addressParts[0]
}
}



public override var hashValue: Int {
get {
if let coordinate = coordinate {
Expand All @@ -114,14 +113,12 @@ public class LocationItem: NSObject, NSCoding {
}



public init(mapItem: MKMapItem) {
self.mapItem = mapItem
}

public init(coordinate: (latitude: Double, longitude: Double), addressDictionary: [String: AnyObject]) {
let coordinateObject = coordinateObjectFromTuple(coordinate)
let placeMark = MKPlacemark(coordinate: coordinateObject, addressDictionary: addressDictionary)
let placeMark = MKPlacemark(coordinate: coordinateObject(fromTuple: coordinate), addressDictionary: addressDictionary)
self.mapItem = MKMapItem(placemark: placeMark)
}

Expand All @@ -132,23 +129,23 @@ public class LocationItem: NSObject, NSCoding {
self.mapItem.name = locationName
}

public override func isEqual(object: AnyObject?) -> Bool {
return object?.hashValue == hashValue
public override func isEqual(_ object: Any?) -> Bool {
guard let object = object else { return false }
return (object as AnyObject).hashValue == hashValue
}



public required convenience init(coder decoder: NSCoder) {
let latitude = decoder.decodeDoubleForKey("latitude")
let longitude = decoder.decodeDoubleForKey("longitude")
let addressDictionary = decoder.decodeObjectForKey("addressDictionary") as! [String: AnyObject]
public required convenience init(coder aDecoder: NSCoder) {
let latitude = aDecoder.decodeDouble(forKey: "latitude")
let longitude = aDecoder.decodeDouble(forKey: "longitude")
let addressDictionary = aDecoder.decodeObject(forKey: "addressDictionary") as! [String: AnyObject]
self.init(coordinate: (latitude, longitude), addressDictionary: addressDictionary)
}

public func encodeWithCoder(coder: NSCoder) {
coder.encodeDouble(mapItem.placemark.coordinate.latitude, forKey: "latitude")
coder.encodeDouble(mapItem.placemark.coordinate.longitude, forKey: "longitude")
coder.encodeObject(addressDictionary, forKey: "addressDictionary")
public func encode(with aCoder: NSCoder) {
aCoder.encode(mapItem.placemark.coordinate.latitude, forKey: "latitude")
aCoder.encode(mapItem.placemark.coordinate.longitude, forKey: "longitude")
aCoder.encode(addressDictionary, forKey: "addressDictionary")
}

}

0 comments on commit 2ad2165

Please sign in to comment.