diff --git a/.gitignore b/.gitignore index a0b5f67..6fa01b2 100644 --- a/.gitignore +++ b/.gitignore @@ -82,11 +82,4 @@ fastlane/Preview.html fastlane/screenshots/**/*.png fastlane/test_output -# Code Injection -# -# After new code Injection tools there's a generated folder /iOSInjectionProject -# https://github.com/johnno1962/injectionforxcode - -iOSInjectionProject/ - -/NavigineDemo/NavigineDemo/Frameworks/ \ No newline at end of file +.DS_Store diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..5916704 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,6 @@ +# Change Log +All notable changes to this project will be documented in this file. +`navigine.framework` adheres to [Semantic Versioning](http://semver.org/). + +## [2.0.0](https://github.com/Navigine/navigine_ios_framework/releases/tag/v.2.0.0) / 2021-11-14 +* Initial version diff --git a/Frameworks/navigine.framework/.DS_Store b/Frameworks/navigine.framework/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/Frameworks/navigine.framework/.DS_Store and /dev/null differ diff --git a/Frameworks/navigine.framework/Headers/NCAnimationType.h b/Frameworks/navigine.framework/Headers/NCAnimationType.h new file mode 100644 index 0000000..54694c7 --- /dev/null +++ b/Frameworks/navigine.framework/Headers/NCAnimationType.h @@ -0,0 +1,10 @@ +#import + +typedef NS_ENUM(NSInteger, NCAnimationType) +{ + NCAnimationTypeNone, + NCAnimationTypeLinear, + NCAnimationTypeCubic, + NCAnimationTypeQuint, + NCAnimationTypeSine, +}; diff --git a/Frameworks/navigine.framework/Headers/NCAsyncRouteListener.h b/Frameworks/navigine.framework/Headers/NCAsyncRouteListener.h new file mode 100644 index 0000000..174f585 --- /dev/null +++ b/Frameworks/navigine.framework/Headers/NCAsyncRouteListener.h @@ -0,0 +1,16 @@ +#import "NCExport.h" +#import "NCLocationPoint.h" +#import +@class NCRoutePath; + + +NAVIGINE_EXPORT +@protocol NCAsyncRouteListener + +- (void)onRouteChanged:(nullable NCRoutePath *)currentPath + pendingPaths:(nonnull NSArray *)pendingPaths; + +- (void)onRouteAdvanced:(float)distance + point:(nonnull NCLocationPoint *)point; + +@end diff --git a/Frameworks/navigine.framework/Headers/NCAsyncRouteManager.h b/Frameworks/navigine.framework/Headers/NCAsyncRouteManager.h new file mode 100644 index 0000000..33206f5 --- /dev/null +++ b/Frameworks/navigine.framework/Headers/NCAsyncRouteManager.h @@ -0,0 +1,14 @@ +#import "NCExport.h" +#import "NCLocationPoint.h" +#import +@class NCRouteSession; + + +NAVIGINE_EXPORT +@interface NCAsyncRouteManager : NSObject + +- (nullable NCRouteSession *)createRouteSession:(nonnull NSArray *)wayPoints; + +- (void)cancelRouteSession:(nullable NCRouteSession *)session; + +@end diff --git a/Frameworks/navigine.framework/Headers/NCBeacon.h b/Frameworks/navigine.framework/Headers/NCBeacon.h index 082e4ca..3252ca7 100644 --- a/Frameworks/navigine.framework/Headers/NCBeacon.h +++ b/Frameworks/navigine.framework/Headers/NCBeacon.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import "NCPoint.h" #import +NAVIGINE_EXPORT @interface NCBeacon : NSObject @property (nonatomic, nonnull, readonly) NCPoint * point; diff --git a/Frameworks/navigine.framework/Headers/NCBitmapRegionDecoder.h b/Frameworks/navigine.framework/Headers/NCBitmapRegionDecoder.h index cffcaef..b58086f 100644 --- a/Frameworks/navigine.framework/Headers/NCBitmapRegionDecoder.h +++ b/Frameworks/navigine.framework/Headers/NCBitmapRegionDecoder.h @@ -1,9 +1,11 @@ +#import "NCExport.h" #import "NCRectangle.h" #import #import @class NCBitmapRegionDecoder; +NAVIGINE_EXPORT @interface NCBitmapRegionDecoder : NSObject + (nullable NCBitmapRegionDecoder *)newInstance:(nonnull NSData *)data diff --git a/Frameworks/navigine.framework/Headers/NCCategory.h b/Frameworks/navigine.framework/Headers/NCCategory.h index 0f59846..5a5521e 100644 --- a/Frameworks/navigine.framework/Headers/NCCategory.h +++ b/Frameworks/navigine.framework/Headers/NCCategory.h @@ -1,5 +1,7 @@ +#import "NCExport.h" #import +NAVIGINE_EXPORT @interface NCCategory : NSObject - (nonnull instancetype)initWithId:(int32_t)id name:(nonnull NSString *)name diff --git a/Frameworks/navigine.framework/Headers/NCCircleMapObject.h b/Frameworks/navigine.framework/Headers/NCCircleMapObject.h index 771eea2..de42b17 100644 --- a/Frameworks/navigine.framework/Headers/NCCircleMapObject.h +++ b/Frameworks/navigine.framework/Headers/NCCircleMapObject.h @@ -1,25 +1,23 @@ -#import "NCMapObjectData.h" -#import "NCPoint.h" +#import "NCAnimationType.h" +#import "NCExport.h" +#import "NCLocationPoint.h" #import +NAVIGINE_EXPORT @interface NCCircleMapObject : NSObject -- (void)setPosition:(nonnull NCPoint *)point; +- (BOOL)setPosition:(nonnull NCLocationPoint *)point; -- (nonnull NCPoint *)getPosition; +- (BOOL)setPositionAnimated:(nonnull NCLocationPoint *)point + duration:(float)duration + type:(NCAnimationType)type; -- (void)setRadius:(float)radius; +- (BOOL)setRadius:(float)radius; -- (float)getRadius; +- (BOOL)setVisible:(BOOL)visible; -- (void)setData:(nonnull NCMapObjectData *)data; - -- (nonnull NCMapObjectData *)getData; - -- (void)setEnabled:(BOOL)visibility; - -- (void)setColor:(float)red +- (BOOL)setColor:(float)red green:(float)green blue:(float)blue alpha:(float)alpha; diff --git a/Frameworks/navigine.framework/Headers/NCEddystone.h b/Frameworks/navigine.framework/Headers/NCEddystone.h index 7ec1651..ae99a76 100644 --- a/Frameworks/navigine.framework/Headers/NCEddystone.h +++ b/Frameworks/navigine.framework/Headers/NCEddystone.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import "NCPoint.h" #import +NAVIGINE_EXPORT @interface NCEddystone : NSObject @property (nonatomic, nonnull, readonly) NCPoint * point; diff --git a/Frameworks/navigine.framework/Headers/NCElevationGraph.h b/Frameworks/navigine.framework/Headers/NCElevationGraph.h index e085f4c..90c13ca 100644 --- a/Frameworks/navigine.framework/Headers/NCElevationGraph.h +++ b/Frameworks/navigine.framework/Headers/NCElevationGraph.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import @class NCGraphEdge; +NAVIGINE_EXPORT @interface NCElevationGraph : NSObject @property (nonatomic, nonnull, readonly) NSArray * edges; diff --git a/Frameworks/navigine.framework/Headers/NCExport.h b/Frameworks/navigine.framework/Headers/NCExport.h new file mode 100644 index 0000000..4cd50db --- /dev/null +++ b/Frameworks/navigine.framework/Headers/NCExport.h @@ -0,0 +1,2 @@ +#pragma once +#define NAVIGINE_EXPORT __attribute__((visibility("default"))) diff --git a/Frameworks/navigine.framework/Headers/NCGeometryUtils.h b/Frameworks/navigine.framework/Headers/NCGeometryUtils.h index d256b3e..ec35201 100644 --- a/Frameworks/navigine.framework/Headers/NCGeometryUtils.h +++ b/Frameworks/navigine.framework/Headers/NCGeometryUtils.h @@ -1,3 +1,4 @@ +#import "NCExport.h" #import "NCGlobalPoint.h" #import "NCPoint.h" #import "NCPolygon.h" @@ -5,6 +6,7 @@ #import +NAVIGINE_EXPORT @interface NCGeometryUtils : NSObject /** Get distance between GPS points */ @@ -45,11 +47,11 @@ segment2:(nonnull NCSegment *)segment2; /** Calculate projection point on a segment */ -+ (nonnull NCPoint *)projectionPoint:(nonnull NCSegment *)segment - point:(nonnull NCPoint *)point; ++ (nonnull NCPoint *)getRatioPoint:(nonnull NCSegment *)segment + r:(double)r; /** Calculate the division ratio of a segment by a given point */ -+ (float)divisionRatioByPoint:(nonnull NCSegment *)segment - point:(nonnull NCPoint *)point; ++ (double)getProjectionRatio:(nonnull NCSegment *)segment + point:(nonnull NCPoint *)point; @end diff --git a/Frameworks/navigine.framework/Headers/NCGestureRecognizerDelegate.h b/Frameworks/navigine.framework/Headers/NCGestureRecognizerDelegate.h new file mode 100644 index 0000000..112e222 --- /dev/null +++ b/Frameworks/navigine.framework/Headers/NCGestureRecognizerDelegate.h @@ -0,0 +1,182 @@ +#import +#import + +@class NCLocationView; + +/** + The `NCGestureRecognizerDelegate` protocol can be implemented to receive gesture events from the map view. The map view will + first check whether a gestureDelegate is set, then check whether it responds to any `shouldRecognize*` method: + - If the delegate responds to `shouldRecognize*`, the map view only performs its default handling of the gesture if + `shouldRecognize*` returns `YES`. + - If the delegate doesn't respond to `shouldRecognize*`, the map view performs its default handling of the gesture. + Finally, if the delegate implements `didRecognize*` then the map view calls this method after the gesture is handled. + @note These methods are all **optional**. All the screen positions in this interface are in _logical pixels_ or + _drawing coordinate system_ (based on a `UIKit` coordinate system) which is independent of the phone pixel density. + Refer to the + + Apple documentation regarding _Coordinate Systems and Drawing in iOS_ for more informations. + */ +@protocol NCGestureRecognizerDelegate +@optional + +/** + Whether the map view should handle a single tap gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` that recognized the gesture. + @param location The location of the recognized gesture in the view. + @return `YES` if the map view should handle this gesture, otherwise `NO`. + */ +- (BOOL)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +shouldRecognizeSingleTapGesture:(CGPoint)location; + +/** + Whether the map view should handle a double tap gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` that recognized the gesture. + @param location The location of the recognized gesture in the view. + @return `YES` if the map view should handle this gesture, otherwise `NO`. + */ +- (BOOL)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +shouldRecognizeDoubleTapGesture:(CGPoint)location; + +/** + Whether the map view should handle a long press gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` that recognized the gesture. + @param location The location of the recognized gesture in the view. + @return `YES` if the map view should handle this gesture, otherwise `NO`. + */ +- (BOOL)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +shouldRecognizeLongPressGesture:(CGPoint)location; + +/** + Whether the map view should handle a pan gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` that recognized the gesture. + @param displacement The displacement of the recognized gesture in the view. + @return `YES` if the map view should handle this gesture, otherwise `NO`. + */ +- (BOOL)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +shouldRecognizePanGesture:(CGPoint)displacement; + +/** + Whether the map view should handle a pinch gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` that recognized the gesture. + @param location The position of the recognized gesture in the view. + @return `YES` if the map view should handle this gesture, otherwise `NO`. + */ +- (BOOL)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +shouldRecognizePinchGesture:(CGPoint)location; + +/** + Whether the map view should handle a rotation gesture. + + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` that recognized the gesture. + @param location The position of the recognized gesture in the view. + @return `YES` if the map view should handle this gesture, otherwise `NO`. + */ +// - (BOOL)locationView:(NCLocationView *)view +// recognizer:(UIGestureRecognizer *)recognizer +// shouldRecognizeRotationGesture:(CGPoint)location; + +/** + Whether the map view should handle a shove gesture. + + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` that recognized the gesture. + @param displacement The displacement of the recognized gesture in the view. + @return `YES` if the map view should handle this gesture, otherwise `NO`. + */ +// - (BOOL)locationView:(NCLocationView *)view +// recognizer:(UIGestureRecognizer *)recognizer +// shouldRecognizeShoveGesture:(CGPoint)displacement; + +/** + Called when the map view just handled a single tap gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` the recognized the gesture. + @param location The position of the recognized gesture in the view. + */ +- (void)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +didRecognizeSingleTapGesture:(CGPoint)location; + +/** + Called when the map view just handled a single double tap gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` the recognized the gesture. + @param location The position of the recognized gesture in the view. + */ +- (void)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +didRecognizeDoubleTapGesture:(CGPoint)location; + +/** + Called when the map view just handled a long press gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` the recognized the gesture. + @param location The position of the recognized gesture in the view. + */ +- (void)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +didRecognizeLongPressGesture:(CGPoint)location; + +/** + Called when the map view just handled a pan gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` the recognized the gesture. + @param displacement The displacement of the recognized gesture in the view. + */ +- (void)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +didRecognizePanGesture:(CGPoint)displacement; + +/** + Called when the map view just handled a pinch gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` the recognized the gesture. + @param location The position of the recognized gesture in the view. + */ +- (void)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +didRecognizePinchGesture:(CGPoint)location; + +/** + Called when the map view just handled a rotation gesture. + + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` the recognized the gesture. + @param location The position of the recognized gesture in the view. + */ +// - (void)locationView:(NCLocationView *)view +// recognizer:(UIGestureRecognizer *)recognizer +// didRecognizeRotationGesture:(CGPoint)location; + +/** + Called when the map view just handled a shove gesture. + + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` the recognized the gesture. + @param displacement The displacement of the recognized gesture in the view. + */ +// - (void)locationView:(NCLocationView *)view +// recognizer:(UIGestureRecognizer *)recognizer +// didRecognizeShoveGesture:(CGPoint)displacement; + +/** + If implemented, the returned value will be the focus for the pinch gesture. + + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` that recognized the gesture. + @return The screen position the pinch gesture should focus to. + */ +- (CGPoint)pinchFocus:(NCLocationView *)view recognizer:(UIGestureRecognizer *)recognizer; + +@end diff --git a/Frameworks/navigine.framework/Headers/NCGlobalPoint.h b/Frameworks/navigine.framework/Headers/NCGlobalPoint.h index a922f0a..3007c44 100644 --- a/Frameworks/navigine.framework/Headers/NCGlobalPoint.h +++ b/Frameworks/navigine.framework/Headers/NCGlobalPoint.h @@ -1,5 +1,7 @@ +#import "NCExport.h" #import +NAVIGINE_EXPORT @interface NCGlobalPoint : NSObject - (nonnull instancetype)initWithLatitude:(float)latitude longitude:(float)longitude; diff --git a/Frameworks/navigine.framework/Headers/NCGraph.h b/Frameworks/navigine.framework/Headers/NCGraph.h index 7139ef3..c8f5b7b 100644 --- a/Frameworks/navigine.framework/Headers/NCGraph.h +++ b/Frameworks/navigine.framework/Headers/NCGraph.h @@ -1,8 +1,10 @@ +#import "NCExport.h" #import @class NCGraphEdge; @class NCGraphVertex; +NAVIGINE_EXPORT @interface NCGraph : NSObject @property (nonatomic, nonnull, readonly) NSArray * vertexes; diff --git a/Frameworks/navigine.framework/Headers/NCGraphEdge.h b/Frameworks/navigine.framework/Headers/NCGraphEdge.h index 86e6cf1..3ba0e5f 100644 --- a/Frameworks/navigine.framework/Headers/NCGraphEdge.h +++ b/Frameworks/navigine.framework/Headers/NCGraphEdge.h @@ -1,6 +1,8 @@ +#import "NCExport.h" #import +NAVIGINE_EXPORT @interface NCGraphEdge : NSObject @property (nonatomic, readonly) float weight; diff --git a/Frameworks/navigine.framework/Headers/NCGraphVertex.h b/Frameworks/navigine.framework/Headers/NCGraphVertex.h index 00954c1..18ebaac 100644 --- a/Frameworks/navigine.framework/Headers/NCGraphVertex.h +++ b/Frameworks/navigine.framework/Headers/NCGraphVertex.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import "NCPoint.h" #import +NAVIGINE_EXPORT @interface NCGraphVertex : NSObject @property (nonatomic, readonly) int32_t id; diff --git a/Frameworks/navigine.framework/Headers/NCIconMapObject.h b/Frameworks/navigine.framework/Headers/NCIconMapObject.h new file mode 100644 index 0000000..3f142f3 --- /dev/null +++ b/Frameworks/navigine.framework/Headers/NCIconMapObject.h @@ -0,0 +1,26 @@ +#import "NCAnimationType.h" +#import "NCExport.h" +#import "NCLocationPoint.h" +#import +#import + + +NAVIGINE_EXPORT +@interface NCIconMapObject : NSObject + +- (BOOL)setPosition:(nonnull NCLocationPoint *)point; + +- (BOOL)setPositionAnimated:(nonnull NCLocationPoint *)point + duration:(float)duration + type:(NCAnimationType)type; + +- (BOOL)setBitmap:(nullable UIImage *)bitmap; + +- (BOOL)setSize:(float)width + height:(float)height; + +- (BOOL)setVisible:(BOOL)visible; + +- (BOOL)setInteractive:(BOOL)interactive; + +@end diff --git a/Frameworks/navigine.framework/Headers/NCImage.h b/Frameworks/navigine.framework/Headers/NCImage.h index e44ce29..5d04f46 100644 --- a/Frameworks/navigine.framework/Headers/NCImage.h +++ b/Frameworks/navigine.framework/Headers/NCImage.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import "NCImageType.h" #import +NAVIGINE_EXPORT @interface NCImage : NSObject @property (nonatomic, nonnull, readonly) NSData * data; diff --git a/Frameworks/navigine.framework/Headers/NCLine.h b/Frameworks/navigine.framework/Headers/NCLine.h index dd0dca9..adcc936 100644 --- a/Frameworks/navigine.framework/Headers/NCLine.h +++ b/Frameworks/navigine.framework/Headers/NCLine.h @@ -1,6 +1,8 @@ +#import "NCExport.h" #import "NCSegment.h" #import +NAVIGINE_EXPORT @interface NCLine : NSObject - (nonnull instancetype)initWithSegments:(nonnull NSArray *)segments; + (nonnull instancetype)lineWithSegments:(nonnull NSArray *)segments; diff --git a/Frameworks/navigine.framework/Headers/NCLocation.h b/Frameworks/navigine.framework/Headers/NCLocation.h index 6c28457..ac6f250 100644 --- a/Frameworks/navigine.framework/Headers/NCLocation.h +++ b/Frameworks/navigine.framework/Headers/NCLocation.h @@ -1,9 +1,11 @@ #import "NCCategory.h" +#import "NCExport.h" #import @class NCElevationGraph; @class NCSublocation; +NAVIGINE_EXPORT @interface NCLocation : NSObject - (nullable NCElevationGraph *)getElevationGraph:(nonnull NSString *)tag; diff --git a/Frameworks/navigine.framework/Headers/NCLocationEditListener.h b/Frameworks/navigine.framework/Headers/NCLocationEditListener.h index f8830d0..a755fcf 100644 --- a/Frameworks/navigine.framework/Headers/NCLocationEditListener.h +++ b/Frameworks/navigine.framework/Headers/NCLocationEditListener.h @@ -1,6 +1,8 @@ +#import "NCExport.h" #import +NAVIGINE_EXPORT @protocol NCLocationEditListener - (void)onLocationUploaded; diff --git a/Frameworks/navigine.framework/Headers/NCLocationEditManager.h b/Frameworks/navigine.framework/Headers/NCLocationEditManager.h index b4c3182..36c2f7f 100644 --- a/Frameworks/navigine.framework/Headers/NCLocationEditManager.h +++ b/Frameworks/navigine.framework/Headers/NCLocationEditManager.h @@ -1,8 +1,10 @@ +#import "NCExport.h" #import "NCPoint.h" #import @protocol NCLocationEditListener; +NAVIGINE_EXPORT @interface NCLocationEditManager : NSObject - (void)addBeacon:(int32_t)subLocId diff --git a/Frameworks/navigine.framework/Headers/NCLocationInfo.h b/Frameworks/navigine.framework/Headers/NCLocationInfo.h index 15859ca..d814271 100644 --- a/Frameworks/navigine.framework/Headers/NCLocationInfo.h +++ b/Frameworks/navigine.framework/Headers/NCLocationInfo.h @@ -1,5 +1,7 @@ +#import "NCExport.h" #import +NAVIGINE_EXPORT @interface NCLocationInfo : NSObject - (nonnull instancetype)initWithId:(int32_t)id version:(int32_t)version diff --git a/Frameworks/navigine.framework/Headers/NCLocationLine.h b/Frameworks/navigine.framework/Headers/NCLocationLine.h deleted file mode 100644 index e9d27a3..0000000 --- a/Frameworks/navigine.framework/Headers/NCLocationLine.h +++ /dev/null @@ -1,18 +0,0 @@ -#import "NCLine.h" -#import - -@interface NCLocationLine : NSObject -- (nonnull instancetype)initWithLine:(nonnull NCLine *)line - locationId:(int32_t)locationId - sublocationId:(int32_t)sublocationId; -+ (nonnull instancetype)locationLineWithLine:(nonnull NCLine *)line - locationId:(int32_t)locationId - sublocationId:(int32_t)sublocationId; - -@property (nonatomic, readonly, nonnull) NCLine * line; - -@property (nonatomic, readonly) int32_t locationId; - -@property (nonatomic, readonly) int32_t sublocationId; - -@end diff --git a/Frameworks/navigine.framework/Headers/NCLocationListListener.h b/Frameworks/navigine.framework/Headers/NCLocationListListener.h index e71e2c7..dcc9fab 100644 --- a/Frameworks/navigine.framework/Headers/NCLocationListListener.h +++ b/Frameworks/navigine.framework/Headers/NCLocationListListener.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import "NCLocationInfo.h" #import +NAVIGINE_EXPORT @protocol NCLocationListListener - (void)onLocationListLoaded:(nonnull NSDictionary *)locationInfos; diff --git a/Frameworks/navigine.framework/Headers/NCLocationListManager.h b/Frameworks/navigine.framework/Headers/NCLocationListManager.h index 455076d..8c16626 100644 --- a/Frameworks/navigine.framework/Headers/NCLocationListManager.h +++ b/Frameworks/navigine.framework/Headers/NCLocationListManager.h @@ -1,7 +1,10 @@ +#import "NCExport.h" +#import "NCLocationInfo.h" #import @protocol NCLocationListListener; +NAVIGINE_EXPORT @interface NCLocationListManager : NSObject - (void)addLocationListListener:(nullable id)listener; @@ -10,4 +13,6 @@ - (void)updateLocationList; +- (nonnull NSDictionary *)getLocationList; + @end diff --git a/Frameworks/navigine.framework/Headers/NCLocationListener.h b/Frameworks/navigine.framework/Headers/NCLocationListener.h index db1f45f..290c018 100644 --- a/Frameworks/navigine.framework/Headers/NCLocationListener.h +++ b/Frameworks/navigine.framework/Headers/NCLocationListener.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import @class NCLocation; +NAVIGINE_EXPORT @protocol NCLocationListener - (void)onLocationLoaded:(nullable NCLocation *)location; diff --git a/Frameworks/navigine.framework/Headers/NCLocationManager.h b/Frameworks/navigine.framework/Headers/NCLocationManager.h index 140b4cd..ebbf7b2 100644 --- a/Frameworks/navigine.framework/Headers/NCLocationManager.h +++ b/Frameworks/navigine.framework/Headers/NCLocationManager.h @@ -1,14 +1,16 @@ +#import "NCExport.h" #import @protocol NCLocationListener; +NAVIGINE_EXPORT @interface NCLocationManager : NSObject - (void)addLocationListener:(nullable id)listener; - (void)removeLocationListener:(nullable id)listener; -- (void)setLocation:(int32_t)locationId; +- (void)setLocationId:(int32_t)locationId; - (int32_t)getLocationId; diff --git a/Frameworks/navigine.framework/Headers/NCLocationPoint.h b/Frameworks/navigine.framework/Headers/NCLocationPoint.h index 9817d1c..319e209 100644 --- a/Frameworks/navigine.framework/Headers/NCLocationPoint.h +++ b/Frameworks/navigine.framework/Headers/NCLocationPoint.h @@ -1,6 +1,8 @@ +#import "NCExport.h" #import "NCPoint.h" #import +NAVIGINE_EXPORT @interface NCLocationPoint : NSObject - (nonnull instancetype)initWithPoint:(nonnull NCPoint *)point locationId:(int32_t)locationId diff --git a/Frameworks/navigine.framework/Headers/NCLocationPolygon.h b/Frameworks/navigine.framework/Headers/NCLocationPolygon.h index 2030876..c56fb0b 100644 --- a/Frameworks/navigine.framework/Headers/NCLocationPolygon.h +++ b/Frameworks/navigine.framework/Headers/NCLocationPolygon.h @@ -1,6 +1,8 @@ +#import "NCExport.h" #import "NCPolygon.h" #import +NAVIGINE_EXPORT @interface NCLocationPolygon : NSObject - (nonnull instancetype)initWithPolygon:(nonnull NCPolygon *)polygon locationId:(int32_t)locationId diff --git a/Frameworks/navigine.framework/Headers/NCLocationPolyline.h b/Frameworks/navigine.framework/Headers/NCLocationPolyline.h new file mode 100644 index 0000000..db3f937 --- /dev/null +++ b/Frameworks/navigine.framework/Headers/NCLocationPolyline.h @@ -0,0 +1,20 @@ +#import "NCExport.h" +#import "NCPolyline.h" +#import + +NAVIGINE_EXPORT +@interface NCLocationPolyline : NSObject +- (nonnull instancetype)initWithPolyline:(nonnull NCPolyline *)polyline + locationId:(int32_t)locationId + sublocationId:(int32_t)sublocationId; ++ (nonnull instancetype)locationPolylineWithPolyline:(nonnull NCPolyline *)polyline + locationId:(int32_t)locationId + sublocationId:(int32_t)sublocationId; + +@property (nonatomic, readonly, nonnull) NCPolyline * polyline; + +@property (nonatomic, readonly) int32_t locationId; + +@property (nonatomic, readonly) int32_t sublocationId; + +@end diff --git a/Frameworks/navigine.framework/Headers/NCLocationView.h b/Frameworks/navigine.framework/Headers/NCLocationView.h index ab632d2..416578f 100644 --- a/Frameworks/navigine.framework/Headers/NCLocationView.h +++ b/Frameworks/navigine.framework/Headers/NCLocationView.h @@ -1,62 +1,51 @@ #import +#import "NCExport.h" NS_ASSUME_NONNULL_BEGIN @class NCCircleMapObject; -@class NCLineMapObject; -@class NCTextureMapObject; +@class NCIconMapObject; +@class NCPolylineMapObject; @class NCPoint; @class NCSublocation; @protocol NCGestureRecognizerDelegate; +@protocol NCLocationViewDelegate; +NAVIGINE_EXPORT @interface NCLocationView : UIView - (instancetype)initWithFrame:(CGRect)frame; -- (NCCircleMapObject *) createCircleMapObject; +- (void) setSublocationId: (int) sublocationId; -- (void)addCircleMapObject: (NCCircleMapObject *)mapObject; +- (NCCircleMapObject *) addCircleMapObject; -- (void)setCircleMapObjects: (NSArray *)mapObjects withVisibility: (bool) visibility; +- (bool) removeCircleMapObject: (NCCircleMapObject *) circleMapObject; -- (nullable NCCircleMapObject *) getObjectAt: (NCPoint *)point; +- (NCIconMapObject *) addIconMapObject; -- (NCLineMapObject *) createLineMapObject; +- (bool) removeIconMapObject: (NCIconMapObject *) iconMapObject; -- (void)addLineMapObject: (NCLineMapObject *)mapObject; +- (NCPolylineMapObject *) addPolylineMapObject; -- (void)setLineMapObjects: (NSArray *)mapObjects withVisibility: (bool) visibility; +- (bool) removePolylineMapObject: (NCPolylineMapObject *) polylineMapObject; -- (NCTextureMapObject *) createTextureMapObject; +- (void) requestRender; -- (void) addTextureMapObject: (NCTextureMapObject *)mapObject; +- (void)pickMapObjectAt:(CGPoint)viewPosition; -- (void)setTextureMapObjects: (NSArray *)mapObjects withVisibility: (bool) visibility; +@property (assign, nonatomic) CGFloat minZoomFactor; -- (NCPoint *) screenToMetricCoordinates: (NCPoint *) point; +@property (assign, nonatomic) CGFloat maxZoomFactor; -- (void) setSublocation: (int) sublocationId; +@property (assign, nonatomic) CGFloat zoomFactor; -- (void) setTargetPoint: (NCPoint *) point; +@property (strong, nonatomic, readonly) CADisplayLink *displayLink; -- (void) showBeacons: (bool) visibility; +@property (assign, nonatomic) NSInteger preferredFramesPerSecond; -- (void) showEddystones: (bool) visibility; - -- (void) showWifis: (bool) visibility; - -- (void) showVenues: (bool) visibility; - -- (void) setBackgroundColor: (float) red green: (float) green blue: (float) blue alpha: (float) alpha; - -- (void) setMaxScale: (float) scale; - -- (void) setMinScale: (float) scale; - -- (void) setZoomScale: (float) scale; - -- (void) attachToPosition: (bool) status; +@property (weak, nonatomic, nullable) id locationViewDelegate; #pragma mark Gesture Recognizers @@ -82,11 +71,28 @@ NS_ASSUME_NONNULL_BEGIN */ @property (strong, nonatomic) UIPinchGestureRecognizer* pinchGestureRecognizer; +/** + Replaces the rotation gesture recognizer used by the map view and adds it to the UIView. + */ +// @property (strong, nonatomic) UIRotationGestureRecognizer* rotationGestureRecognizer; + +/** + Replaces the shove gesture recognizer used by the map view and adds it to the UIView. + */ +// @property (strong, nonatomic) UIPanGestureRecognizer* shoveGestureRecognizer; + /** Replaces the long press gesture recognizer used by the map view and adds it to the UIView. */ @property (strong, nonatomic) UILongPressGestureRecognizer* longPressGestureRecognizer; +#pragma mark Memory Management + +/** + Reduce memory usage by freeing currently unused resources. + */ +- (void)didReceiveMemoryWarning; + @end NS_ASSUME_NONNULL_END diff --git a/Frameworks/navigine.framework/Headers/NCLocationViewDelegate.h b/Frameworks/navigine.framework/Headers/NCLocationViewDelegate.h new file mode 100644 index 0000000..007ff97 --- /dev/null +++ b/Frameworks/navigine.framework/Headers/NCLocationViewDelegate.h @@ -0,0 +1,26 @@ +#import +#import + +@class NCLocationView; +@class NCMapObjectPickResult; + +/** + A map view delegate can receive various map events. + + @note All of these methods are called from main thread, these methods are all **optional**. + */ +@protocol NCLocationViewDelegate +@optional + +/** + Receive the result from `-[NCLocationView pickMapObjectAt:]`. + + @param locationView The location view instance. + @param pickResult A result object with information about the picked object or `nil` if no object was found. + @param position The view position where object was picked. + */ +- (void)locationView:(nonnull NCLocationView *)mapView +didSelectMapObject:(nullable NCMapObjectPickResult *)markerPickResult +atScreenPosition:(CGPoint)position; + +@end // protocol NCLocationViewDelegate diff --git a/Frameworks/navigine.framework/Headers/NCMapObjectData.h b/Frameworks/navigine.framework/Headers/NCMapObjectData.h index 79fa5e4..7bd9c8b 100644 --- a/Frameworks/navigine.framework/Headers/NCMapObjectData.h +++ b/Frameworks/navigine.framework/Headers/NCMapObjectData.h @@ -1,6 +1,8 @@ +#import "NCExport.h" #import "NCMapObjectType.h" #import +NAVIGINE_EXPORT @interface NCMapObjectData : NSObject - (nonnull instancetype)initWithId:(nonnull NSString *)id sublocationId:(int32_t)sublocationId diff --git a/Frameworks/navigine.framework/Headers/NCMapObjectPickResult.h b/Frameworks/navigine.framework/Headers/NCMapObjectPickResult.h new file mode 100644 index 0000000..f8ea276 --- /dev/null +++ b/Frameworks/navigine.framework/Headers/NCMapObjectPickResult.h @@ -0,0 +1,23 @@ +#import +#import +#import "NCExport.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + Data structure holding the result of a marker selection that occured on the location view. + + See `-[NCLocationView pickMapObjectAt:]` and `[NCLocationViewDelegate locationView:didSelectMapObject:atScreenPosition:]`. + */ +NAVIGINE_EXPORT +@interface NCMapObjectPickResult : NSObject + +/// The geographic coordinates of the selected label +@property (readonly, nonatomic) CLLocationCoordinate2D coordinates; + +/// The selected marker +@property (readonly, nonatomic) NSObject* mapObject; + +NS_ASSUME_NONNULL_END + +@end diff --git a/Frameworks/navigine.framework/Headers/NCMeasurementListener.h b/Frameworks/navigine.framework/Headers/NCMeasurementListener.h index 9bbcaa2..fcc555e 100644 --- a/Frameworks/navigine.framework/Headers/NCMeasurementListener.h +++ b/Frameworks/navigine.framework/Headers/NCMeasurementListener.h @@ -1,9 +1,11 @@ +#import "NCExport.h" #import "NCSensorMeasurement.h" #import "NCSensorType.h" #import "NCSignalMeasurement.h" #import +NAVIGINE_EXPORT @protocol NCMeasurementListener - (void)onSensorMeasurementDetected:(nonnull NSDictionary *)sensors; diff --git a/Frameworks/navigine.framework/Headers/NCMeasurementManager.h b/Frameworks/navigine.framework/Headers/NCMeasurementManager.h index 6a16fd6..4b81dad 100644 --- a/Frameworks/navigine.framework/Headers/NCMeasurementManager.h +++ b/Frameworks/navigine.framework/Headers/NCMeasurementManager.h @@ -1,7 +1,10 @@ +#import "NCExport.h" +#import "NCSensorMeasurement.h" #import @protocol NCMeasurementListener; +NAVIGINE_EXPORT @interface NCMeasurementManager : NSObject - (void)addMeasurementListener:(nullable id)listener; @@ -50,4 +53,6 @@ - (void)removeWifiRttGenerators; +- (void)addExternalSensorMeasurement:(nonnull NCSensorMeasurement *)measurement; + @end diff --git a/Frameworks/navigine.framework/Headers/NCMultiLineMapObject.h b/Frameworks/navigine.framework/Headers/NCMultiLineMapObject.h index ffbea54..a70b06e 100644 --- a/Frameworks/navigine.framework/Headers/NCMultiLineMapObject.h +++ b/Frameworks/navigine.framework/Headers/NCMultiLineMapObject.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import "NCPoint.h" #import +NAVIGINE_EXPORT @interface NCMultiLineMapObject : NSObject - (void)setLines:(nonnull NSArray *> *)lines; diff --git a/Frameworks/navigine.framework/Headers/NCNavigationManager.h b/Frameworks/navigine.framework/Headers/NCNavigationManager.h index 9eb8ed1..f8e2eb8 100644 --- a/Frameworks/navigine.framework/Headers/NCNavigationManager.h +++ b/Frameworks/navigine.framework/Headers/NCNavigationManager.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import @protocol NCPositionListener; +NAVIGINE_EXPORT @interface NCNavigationManager : NSObject - (void)addPositionListener:(nullable id)listener; diff --git a/Frameworks/navigine.framework/Headers/NCNavigineSdk.h b/Frameworks/navigine.framework/Headers/NCNavigineSdk.h index f8407dc..92268cd 100644 --- a/Frameworks/navigine.framework/Headers/NCNavigineSdk.h +++ b/Frameworks/navigine.framework/Headers/NCNavigineSdk.h @@ -1,4 +1,6 @@ +#import "NCExport.h" #import +@class NCAsyncRouteManager; @class NCLocationEditManager; @class NCLocationListManager; @class NCLocationManager; @@ -11,6 +13,7 @@ @class NCZoneManager; +NAVIGINE_EXPORT @interface NCNavigineSdk : NSObject + (void)setUserHash:(nonnull NSString *)userHash; @@ -19,6 +22,8 @@ + (nullable NCNavigineSdk *)getInstance; ++ (nonnull NSString *)getVersion; + - (nullable NCLocationManager *)getLocationManager; - (nullable NCNavigationManager *)getNavigationManager:(nullable NCLocationManager *)locationManager; @@ -29,6 +34,9 @@ - (nullable NCRouteManager *)getRouteManager:(nullable NCLocationManager *)locationManager navigationManager:(nullable NCNavigationManager *)navigationManager; +- (nullable NCAsyncRouteManager *)getAsyncRouteManager:(nullable NCLocationManager *)locationManager + navigationManager:(nullable NCNavigationManager *)navigationManager; + - (nullable NCResourceManager *)getResourceManager:(nullable NCLocationManager *)locationManager; - (nullable NCNotificationManager *)getNotificationManager:(nullable NCLocationManager *)locationManager; diff --git a/Frameworks/navigine.framework/Headers/NCNotification.h b/Frameworks/navigine.framework/Headers/NCNotification.h index 91c3b3d..a5155d2 100644 --- a/Frameworks/navigine.framework/Headers/NCNotification.h +++ b/Frameworks/navigine.framework/Headers/NCNotification.h @@ -1,6 +1,8 @@ +#import "NCExport.h" #import +NAVIGINE_EXPORT @interface NCNotification : NSObject @property (nonatomic, readonly) int32_t id; diff --git a/Frameworks/navigine.framework/Headers/NCNotificationListener.h b/Frameworks/navigine.framework/Headers/NCNotificationListener.h index be98df2..daab6aa 100644 --- a/Frameworks/navigine.framework/Headers/NCNotificationListener.h +++ b/Frameworks/navigine.framework/Headers/NCNotificationListener.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import @class NCNotification; +NAVIGINE_EXPORT @protocol NCNotificationListener - (void)onNotificationLoaded:(nullable NCNotification *)notification; diff --git a/Frameworks/navigine.framework/Headers/NCNotificationManager.h b/Frameworks/navigine.framework/Headers/NCNotificationManager.h index ef7f5bf..e1e1616 100644 --- a/Frameworks/navigine.framework/Headers/NCNotificationManager.h +++ b/Frameworks/navigine.framework/Headers/NCNotificationManager.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import @protocol NCNotificationListener; +NAVIGINE_EXPORT @interface NCNotificationManager : NSObject - (void)addNotificationListener:(nullable id)listener; diff --git a/Frameworks/navigine.framework/Headers/NCPoint.h b/Frameworks/navigine.framework/Headers/NCPoint.h index 8642a7d..f650f21 100644 --- a/Frameworks/navigine.framework/Headers/NCPoint.h +++ b/Frameworks/navigine.framework/Headers/NCPoint.h @@ -1,5 +1,7 @@ +#import "NCExport.h" #import +NAVIGINE_EXPORT @interface NCPoint : NSObject - (nonnull instancetype)initWithX:(float)x y:(float)y; diff --git a/Frameworks/navigine.framework/Headers/NCPolygon.h b/Frameworks/navigine.framework/Headers/NCPolygon.h index 9d6b54e..cde7fc0 100644 --- a/Frameworks/navigine.framework/Headers/NCPolygon.h +++ b/Frameworks/navigine.framework/Headers/NCPolygon.h @@ -1,6 +1,8 @@ +#import "NCExport.h" #import "NCPoint.h" #import +NAVIGINE_EXPORT @interface NCPolygon : NSObject - (nonnull instancetype)initWithPoints:(nonnull NSArray *)points; + (nonnull instancetype)polygonWithPoints:(nonnull NSArray *)points; diff --git a/Frameworks/navigine.framework/Headers/NCPolyline.h b/Frameworks/navigine.framework/Headers/NCPolyline.h new file mode 100644 index 0000000..7b82995 --- /dev/null +++ b/Frameworks/navigine.framework/Headers/NCPolyline.h @@ -0,0 +1,12 @@ +#import "NCExport.h" +#import "NCPoint.h" +#import + +NAVIGINE_EXPORT +@interface NCPolyline : NSObject +- (nonnull instancetype)initWithPoints:(nonnull NSArray *)points; ++ (nonnull instancetype)polylineWithPoints:(nonnull NSArray *)points; + +@property (nonatomic, readonly, nonnull) NSArray * points; + +@end diff --git a/Frameworks/navigine.framework/Headers/NCPolylineMapObject.h b/Frameworks/navigine.framework/Headers/NCPolylineMapObject.h new file mode 100644 index 0000000..74daa52 --- /dev/null +++ b/Frameworks/navigine.framework/Headers/NCPolylineMapObject.h @@ -0,0 +1,20 @@ +#import "NCExport.h" +#import "NCLocationPolyline.h" +#import + + +NAVIGINE_EXPORT +@interface NCPolylineMapObject : NSObject + +- (BOOL)setPolyLine:(nonnull NCLocationPolyline *)polyline; + +- (BOOL)setWidth:(float)width; + +- (BOOL)setVisible:(BOOL)visible; + +- (BOOL)setColor:(float)red + green:(float)green + blue:(float)blue + alpha:(float)alpha; + +@end diff --git a/Frameworks/navigine.framework/Headers/NCPosition.h b/Frameworks/navigine.framework/Headers/NCPosition.h index a9a39a0..835dd17 100644 --- a/Frameworks/navigine.framework/Headers/NCPosition.h +++ b/Frameworks/navigine.framework/Headers/NCPosition.h @@ -1,6 +1,8 @@ +#import "NCExport.h" #import "NCPoint.h" #import +NAVIGINE_EXPORT @interface NCPosition : NSObject - (nonnull instancetype)initWithPoint:(nonnull NCPoint *)point locationId:(int32_t)locationId diff --git a/Frameworks/navigine.framework/Headers/NCPositionListener.h b/Frameworks/navigine.framework/Headers/NCPositionListener.h index 9fc2ce7..f449d62 100644 --- a/Frameworks/navigine.framework/Headers/NCPositionListener.h +++ b/Frameworks/navigine.framework/Headers/NCPositionListener.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import "NCPosition.h" #import +NAVIGINE_EXPORT @protocol NCPositionListener - (void)onPositionUpdated:(nonnull NCPosition *)position; diff --git a/Frameworks/navigine.framework/Headers/NCRectangle.h b/Frameworks/navigine.framework/Headers/NCRectangle.h index cc73f02..100013c 100644 --- a/Frameworks/navigine.framework/Headers/NCRectangle.h +++ b/Frameworks/navigine.framework/Headers/NCRectangle.h @@ -1,5 +1,7 @@ +#import "NCExport.h" #import +NAVIGINE_EXPORT @interface NCRectangle : NSObject - (nonnull instancetype)initWithX:(float)x y:(float)y diff --git a/Frameworks/navigine.framework/Headers/NCReferenceEntry.h b/Frameworks/navigine.framework/Headers/NCReferenceEntry.h index b83da8b..07e9c8f 100644 --- a/Frameworks/navigine.framework/Headers/NCReferenceEntry.h +++ b/Frameworks/navigine.framework/Headers/NCReferenceEntry.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import "NCReferenceEntryType.h" #import +NAVIGINE_EXPORT @interface NCReferenceEntry : NSObject @property (nonatomic, readonly) NCReferenceEntryType type; diff --git a/Frameworks/navigine.framework/Headers/NCReferencePoint.h b/Frameworks/navigine.framework/Headers/NCReferencePoint.h index ecfda6a..c44e3a4 100644 --- a/Frameworks/navigine.framework/Headers/NCReferencePoint.h +++ b/Frameworks/navigine.framework/Headers/NCReferencePoint.h @@ -1,8 +1,10 @@ +#import "NCExport.h" #import "NCPoint.h" #import @class NCReferenceEntry; +NAVIGINE_EXPORT @interface NCReferencePoint : NSObject @property (nonatomic, readonly) int32_t locationId; diff --git a/Frameworks/navigine.framework/Headers/NCResourceListener.h b/Frameworks/navigine.framework/Headers/NCResourceListener.h index 9e82826..f4d6e00 100644 --- a/Frameworks/navigine.framework/Headers/NCResourceListener.h +++ b/Frameworks/navigine.framework/Headers/NCResourceListener.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import @class NCImage; +NAVIGINE_EXPORT @protocol NCResourceListener - (void)onLoaded:(nonnull NSString *)imageId diff --git a/Frameworks/navigine.framework/Headers/NCResourceManager.h b/Frameworks/navigine.framework/Headers/NCResourceManager.h index 0a2ace9..25eb674 100644 --- a/Frameworks/navigine.framework/Headers/NCResourceManager.h +++ b/Frameworks/navigine.framework/Headers/NCResourceManager.h @@ -1,8 +1,10 @@ +#import "NCExport.h" #import @protocol NCResourceListener; @protocol NCResourceUploadListener; +NAVIGINE_EXPORT @interface NCResourceManager : NSObject - (void)loadImage:(nonnull NSString *)imageId diff --git a/Frameworks/navigine.framework/Headers/NCResourceUploadListener.h b/Frameworks/navigine.framework/Headers/NCResourceUploadListener.h index db00cd0..11da891 100644 --- a/Frameworks/navigine.framework/Headers/NCResourceUploadListener.h +++ b/Frameworks/navigine.framework/Headers/NCResourceUploadListener.h @@ -1,6 +1,8 @@ +#import "NCExport.h" #import +NAVIGINE_EXPORT @protocol NCResourceUploadListener - (void)onUploaded; diff --git a/Frameworks/navigine.framework/Headers/NCRouteEvent.h b/Frameworks/navigine.framework/Headers/NCRouteEvent.h index 438ce4c..7566c6d 100644 --- a/Frameworks/navigine.framework/Headers/NCRouteEvent.h +++ b/Frameworks/navigine.framework/Headers/NCRouteEvent.h @@ -1,6 +1,8 @@ +#import "NCExport.h" #import "NCRouteEventType.h" #import +NAVIGINE_EXPORT @interface NCRouteEvent : NSObject - (nonnull instancetype)initWithType:(NCRouteEventType)type value:(int32_t)value diff --git a/Frameworks/navigine.framework/Headers/NCRouteListener.h b/Frameworks/navigine.framework/Headers/NCRouteListener.h index 9b4884d..a1b9648 100644 --- a/Frameworks/navigine.framework/Headers/NCRouteListener.h +++ b/Frameworks/navigine.framework/Headers/NCRouteListener.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import @class NCRoutePath; +NAVIGINE_EXPORT @protocol NCRouteListener - (void)onPathsUpdated:(nonnull NSArray *)paths; diff --git a/Frameworks/navigine.framework/Headers/NCRouteManager.h b/Frameworks/navigine.framework/Headers/NCRouteManager.h index 77509d0..f065eea 100644 --- a/Frameworks/navigine.framework/Headers/NCRouteManager.h +++ b/Frameworks/navigine.framework/Headers/NCRouteManager.h @@ -1,14 +1,19 @@ +#import "NCExport.h" #import "NCLocationPoint.h" #import @class NCRoutePath; @protocol NCRouteListener; +NAVIGINE_EXPORT @interface NCRouteManager : NSObject - (nullable NCRoutePath *)makeRoute:(nonnull NCLocationPoint *)from to:(nonnull NCLocationPoint *)to; +- (nonnull NSArray *)arrangePoints:(nonnull NCLocationPoint *)startPoint + checkPoints:(nonnull NSArray *)checkPoints; + - (void)setTarget:(nonnull NCLocationPoint *)target; - (void)addTarget:(nonnull NCLocationPoint *)target; diff --git a/Frameworks/navigine.framework/Headers/NCRoutePath.h b/Frameworks/navigine.framework/Headers/NCRoutePath.h index 3936b0b..cac12d6 100644 --- a/Frameworks/navigine.framework/Headers/NCRoutePath.h +++ b/Frameworks/navigine.framework/Headers/NCRoutePath.h @@ -1,8 +1,10 @@ +#import "NCExport.h" #import "NCLocationPoint.h" #import "NCRouteEvent.h" #import +NAVIGINE_EXPORT @interface NCRoutePath : NSObject @property (nonatomic, readonly) float length; diff --git a/Frameworks/navigine.framework/Headers/NCRouteSession.h b/Frameworks/navigine.framework/Headers/NCRouteSession.h new file mode 100644 index 0000000..3d70a2e --- /dev/null +++ b/Frameworks/navigine.framework/Headers/NCRouteSession.h @@ -0,0 +1,16 @@ +#import "NCExport.h" +#import "NCLocationPoint.h" +#import +@protocol NCAsyncRouteListener; + + +NAVIGINE_EXPORT +@interface NCRouteSession : NSObject + +- (void)addRouteListener:(nullable id)listener; + +- (void)removeRouteListener:(nullable id)listener; + +- (void)checkIn:(nonnull NCLocationPoint *)point; + +@end diff --git a/Frameworks/navigine.framework/Headers/NCSegment.h b/Frameworks/navigine.framework/Headers/NCSegment.h index 5f25258..7e0b157 100644 --- a/Frameworks/navigine.framework/Headers/NCSegment.h +++ b/Frameworks/navigine.framework/Headers/NCSegment.h @@ -1,6 +1,8 @@ +#import "NCExport.h" #import "NCPoint.h" #import +NAVIGINE_EXPORT @interface NCSegment : NSObject - (nonnull instancetype)initWithStart:(nonnull NCPoint *)start end:(nonnull NCPoint *)end; diff --git a/Frameworks/navigine.framework/Headers/NCSensorMeasurement.h b/Frameworks/navigine.framework/Headers/NCSensorMeasurement.h index 762ffa3..a75b46a 100644 --- a/Frameworks/navigine.framework/Headers/NCSensorMeasurement.h +++ b/Frameworks/navigine.framework/Headers/NCSensorMeasurement.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import "NCSensorType.h" #import "NCVector3d.h" #import +NAVIGINE_EXPORT @interface NCSensorMeasurement : NSObject - (nonnull instancetype)initWithType:(NCSensorType)type values:(nonnull NCVector3d *)values; diff --git a/Frameworks/navigine.framework/Headers/NCSignalMeasurement.h b/Frameworks/navigine.framework/Headers/NCSignalMeasurement.h index ee8bda5..bd7fa9e 100644 --- a/Frameworks/navigine.framework/Headers/NCSignalMeasurement.h +++ b/Frameworks/navigine.framework/Headers/NCSignalMeasurement.h @@ -1,6 +1,8 @@ +#import "NCExport.h" #import "NCSignalType.h" #import +NAVIGINE_EXPORT @interface NCSignalMeasurement : NSObject - (nonnull instancetype)initWithType:(NCSignalType)type id:(nonnull NSString *)id diff --git a/Frameworks/navigine.framework/Headers/NCSublocation.h b/Frameworks/navigine.framework/Headers/NCSublocation.h index 68c6d96..d4320f5 100644 --- a/Frameworks/navigine.framework/Headers/NCSublocation.h +++ b/Frameworks/navigine.framework/Headers/NCSublocation.h @@ -1,3 +1,4 @@ +#import "NCExport.h" #import "NCGlobalPoint.h" #import "NCLocationPoint.h" #import @@ -10,6 +11,7 @@ @class NCZone; +NAVIGINE_EXPORT @interface NCSublocation : NSObject - (nonnull NCLocationPoint *)globalToLocal:(nonnull NCGlobalPoint *)globalPoint; diff --git a/Frameworks/navigine.framework/Headers/NCTextureMapObject.h b/Frameworks/navigine.framework/Headers/NCTextureMapObject.h index 596e6be..9a26b0b 100644 --- a/Frameworks/navigine.framework/Headers/NCTextureMapObject.h +++ b/Frameworks/navigine.framework/Headers/NCTextureMapObject.h @@ -1,8 +1,10 @@ +#import "NCExport.h" #import "NCMapObjectData.h" #import "NCPoint.h" #import +NAVIGINE_EXPORT @interface NCTextureMapObject : NSObject - (void)setPosition:(nonnull NCPoint *)point; diff --git a/Frameworks/navigine.framework/Headers/NCVector3d.h b/Frameworks/navigine.framework/Headers/NCVector3d.h index e48d303..f6863ba 100644 --- a/Frameworks/navigine.framework/Headers/NCVector3d.h +++ b/Frameworks/navigine.framework/Headers/NCVector3d.h @@ -1,5 +1,7 @@ +#import "NCExport.h" #import +NAVIGINE_EXPORT @interface NCVector3d : NSObject - (nonnull instancetype)initWithX:(float)x y:(float)y diff --git a/Frameworks/navigine.framework/Headers/NCVenue.h b/Frameworks/navigine.framework/Headers/NCVenue.h index 6c25d28..41d6a16 100644 --- a/Frameworks/navigine.framework/Headers/NCVenue.h +++ b/Frameworks/navigine.framework/Headers/NCVenue.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import "NCPoint.h" #import +NAVIGINE_EXPORT @interface NCVenue : NSObject @property (nonatomic, nonnull, readonly) NCPoint * point; diff --git a/Frameworks/navigine.framework/Headers/NCWifi.h b/Frameworks/navigine.framework/Headers/NCWifi.h index 93d7bb3..c8b64aa 100644 --- a/Frameworks/navigine.framework/Headers/NCWifi.h +++ b/Frameworks/navigine.framework/Headers/NCWifi.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import "NCPoint.h" #import +NAVIGINE_EXPORT @interface NCWifi : NSObject @property (nonatomic, nonnull, readonly) NCPoint * point; diff --git a/Frameworks/navigine.framework/Headers/NCZone.h b/Frameworks/navigine.framework/Headers/NCZone.h index ff4289a..4e72a43 100644 --- a/Frameworks/navigine.framework/Headers/NCZone.h +++ b/Frameworks/navigine.framework/Headers/NCZone.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import "NCPolygon.h" #import +NAVIGINE_EXPORT @interface NCZone : NSObject @property (nonatomic, nonnull, readonly) NCPolygon * polygon; diff --git a/Frameworks/navigine.framework/Headers/NCZoneListener.h b/Frameworks/navigine.framework/Headers/NCZoneListener.h index d396e35..9703528 100644 --- a/Frameworks/navigine.framework/Headers/NCZoneListener.h +++ b/Frameworks/navigine.framework/Headers/NCZoneListener.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import @class NCZone; +NAVIGINE_EXPORT @protocol NCZoneListener - (void)onEnterZone:(nullable NCZone *)zone; diff --git a/Frameworks/navigine.framework/Headers/NCZoneManager.h b/Frameworks/navigine.framework/Headers/NCZoneManager.h index b252534..df71fcd 100644 --- a/Frameworks/navigine.framework/Headers/NCZoneManager.h +++ b/Frameworks/navigine.framework/Headers/NCZoneManager.h @@ -1,7 +1,9 @@ +#import "NCExport.h" #import @protocol NCZoneListener; +NAVIGINE_EXPORT @interface NCZoneManager : NSObject - (void)addZoneListener:(nullable id)listener; diff --git a/Frameworks/navigine.framework/Headers/navigine.h b/Frameworks/navigine.framework/Headers/navigine.h index 292e306..60c6e3d 100644 --- a/Frameworks/navigine.framework/Headers/navigine.h +++ b/Frameworks/navigine.framework/Headers/navigine.h @@ -8,28 +8,31 @@ #import "NCSignalMeasurement.h" #import "NCLocationEditManager.h" #import "NCMeasurementManager.h" -#import "NCLineMapObject.h" +#import "NCAsyncRouteManager.h" #import "NCMapObjectType.h" #import "NCSensorMeasurement.h" #import "NCRouteManager.h" #import "NCImageType.h" +#import "NCPolyline.h" #import "NCNavigationManager.h" #import "NCImage.h" #import "NCPolygon.h" #import "NCElevationGraph.h" #import "NCSignalType.h" #import "NCVenue.h" +#import "NCAnimationType.h" #import "NCMultiLineMapObject.h" +#import "NCAsyncRouteListener.h" #import "NCMapObjectData.h" #import "NCRouteEvent.h" #import "NCLocationPoint.h" -#import "NCLocationLine.h" #import "NCPositionListener.h" #import "NCLocationInfo.h" #import "NCSegment.h" #import "NCTextureMapObject.h" #import "NCBitmapRegionDecoder.h" #import "NCResourceUploadListener.h" +#import "NCPolylineMapObject.h" #import "NCLocation.h" #import "NCLocationListManager.h" #import "NCGeometryUtils.h" @@ -59,8 +62,15 @@ #import "NCRectangle.h" #import "NCGraphVertex.h" #import "NCResourceListener.h" +#import "NCRouteSession.h" +#import "NCIconMapObject.h" #import "NCNavigineSdk.h" #import "NCCategory.h" #import "NCReferenceEntryType.h" #import "NCGraphEdge.h" +#import "NCLocationPolyline.h" +#import "NCExport.h" #import "NCLocationView.h" +#import "NCMapObjectPickResult.h" +#import "NCLocationViewDelegate.h" +#import "NCGestureRecognizerDelegate.h" diff --git a/Frameworks/navigine.framework/Info.plist b/Frameworks/navigine.framework/Info.plist index 1205c2b..97f77bd 100644 Binary files a/Frameworks/navigine.framework/Info.plist and b/Frameworks/navigine.framework/Info.plist differ diff --git a/Frameworks/navigine.framework/navigine b/Frameworks/navigine.framework/navigine index cfa6e46..72d770b 100755 Binary files a/Frameworks/navigine.framework/navigine and b/Frameworks/navigine.framework/navigine differ diff --git a/Navigine.podspec b/Navigine.podspec new file mode 100644 index 0000000..2a36c4d --- /dev/null +++ b/Navigine.podspec @@ -0,0 +1,19 @@ +Pod::Spec.new do |spec| + spec.name = 'Navigine' + spec.version = '2.0.0' + spec.license = { :type => 'Custom', :text => 'Navigine Licence'} + spec.summary = "iOS SDK for performing indoor navigation" + spec.platform = :ios, "9.0" + spec.homepage = 'https://github.com/Navigine/Indoor-Navigation-iOS-Mobile-SDK-2.0' + spec.authors = { 'Pavel Tychinin' => 'p.tychinin@navigine.com' } + spec.source = { :git => 'https://github.com/Navigine/Indoor-Navigation-iOS-Mobile-SDK-2.0.git', :tag => 'v.2.0.0' } + spec.documentation_url = 'https://github.com/Navigine/Indoor-Navigation-iOS-Mobile-SDK-2.0/wiki/Getting-Started' + spec.vendored_frameworks = 'Frameworks/navigine.framework' +# spec.vendored_libraries = 'Frameworks/navigine.framework/Navigine' + spec.public_header_files = 'Frameworks/navigine.framework/Headers/*.h' + spec.source_files = 'Frameworks/navigine.framework/Headers' + spec.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' } + spec.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' } + spec.exclude_files = "Classes/Exclude" + spec.requires_arc = true +end diff --git a/NavigineDemo/NavigineDemo.xcodeproj/project.pbxproj b/NavigineDemo/NavigineDemo.xcodeproj/project.pbxproj old mode 100644 new mode 100755 index 5a39da8..a525fa8 --- a/NavigineDemo/NavigineDemo.xcodeproj/project.pbxproj +++ b/NavigineDemo/NavigineDemo.xcodeproj/project.pbxproj @@ -7,25 +7,61 @@ objects = { /* Begin PBXBuildFile section */ - 8628213D25274774007546DA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8628213C25274774007546DA /* AppDelegate.swift */; }; - 8628214125274774007546DA /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8628214025274774007546DA /* ViewController.swift */; }; - 8628214425274774007546DA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8628214225274774007546DA /* Main.storyboard */; }; - 8628214625274775007546DA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8628214525274775007546DA /* Assets.xcassets */; }; - 8628214925274775007546DA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8628214725274775007546DA /* LaunchScreen.storyboard */; }; - 8628215A25274C0E007546DA /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8628215925274C0E007546DA /* SceneDelegate.swift */; }; - 8628215C25274E42007546DA /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8628215B25274E42007546DA /* Constants.swift */; }; - 866AA0D5261376BA002BD2F7 /* navigine.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 866AA0D02613487A002BD2F7 /* navigine.framework */; }; - 866AA0D6261376BA002BD2F7 /* navigine.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 866AA0D02613487A002BD2F7 /* navigine.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 62157CD326D15EB7008D2ED2 /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8601653E24C88F2100509D5E /* GLKit.framework */; }; + 62A7FC7B27073861002D1C18 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8601653F24C88F2100509D5E /* OpenGLES.framework */; }; + 62A7FC7D27073882002D1C18 /* navigine.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 860164FD24C745BA00509D5E /* navigine.framework */; }; + 62A7FC7E27073882002D1C18 /* navigine.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 860164FD24C745BA00509D5E /* navigine.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 62AEFF562732B9D0000223D5 /* blue_dot.png in Resources */ = {isa = PBXBuildFile; fileRef = 62AEFF552732B9D0000223D5 /* blue_dot.png */; }; + 860164E924C7456900509D5E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 860164E824C7456900509D5E /* AppDelegate.swift */; }; + 860164EB24C7456900509D5E /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 860164EA24C7456900509D5E /* SceneDelegate.swift */; }; + 860164F224C7456900509D5E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 860164F124C7456900509D5E /* Assets.xcassets */; }; + 8601650F24C8567C00509D5E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8601650D24C8567C00509D5E /* LaunchScreen.storyboard */; }; + 8601651324C8575900509D5E /* LocationsList.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8601651224C8575900509D5E /* LocationsList.storyboard */; }; + 8601651724C8581500509D5E /* AddBeacon.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8601651624C8581500509D5E /* AddBeacon.storyboard */; }; + 8601651924C8582800509D5E /* Debug.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8601651824C8582800509D5E /* Debug.storyboard */; }; + 8601651B24C8583600509D5E /* Profile.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8601651A24C8583600509D5E /* Profile.storyboard */; }; + 8601651E24C85AD900509D5E /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8601651D24C85AD900509D5E /* TabBarController.swift */; }; + 8601652824C85D5C00509D5E /* Circe-ExtraLight.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 8601652024C85D5C00509D5E /* Circe-ExtraLight.ttf */; }; + 8601652924C85D5C00509D5E /* Circe-ExtraBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 8601652124C85D5C00509D5E /* Circe-ExtraBold.ttf */; }; + 8601652A24C85D5C00509D5E /* Circe-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 8601652224C85D5C00509D5E /* Circe-Bold.ttf */; }; + 8601653124C867FC00509D5E /* LocationsListController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8601653024C867FC00509D5E /* LocationsListController.swift */; }; + 8601653524C86DAD00509D5E /* LocationSearchController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8601653424C86DAD00509D5E /* LocationSearchController.swift */; }; + 8601653824C87FC600509D5E /* NavigineApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8601653724C87FC600509D5E /* NavigineApp.swift */; }; + 8601654024C88F2100509D5E /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8601653E24C88F2100509D5E /* GLKit.framework */; }; + 8601654724C9C39C00509D5E /* NavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8601654624C9C39C00509D5E /* NavigationController.swift */; }; + 86016BBF24C9D00B00509D5E /* Circe-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 8601652624C85D5C00509D5E /* Circe-Thin.ttf */; }; + 86016BC024C9D00B00509D5E /* Circe-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 8601652724C85D5C00509D5E /* Circe-Regular.ttf */; }; + 86016BC124C9D00B00509D5E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8601650C24C8567C00509D5E /* Main.storyboard */; }; + 86016BC224C9D00B00509D5E /* Navigation.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8601651424C857F400509D5E /* Navigation.storyboard */; }; + 8610E3A924E536E0002BED87 /* AddBeaconController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8610E3A824E536E0002BED87 /* AddBeaconController.swift */; }; + 861E3D8F24E1A9F4008DD348 /* LocationItemCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 861E3D8E24E1A9F4008DD348 /* LocationItemCell.swift */; }; + 861E3D9724E2D0E2008DD348 /* CircularLoaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 861E3D9624E2D0E2008DD348 /* CircularLoaderView.swift */; }; + 8676DD5B24DC3CE200325212 /* DebugController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8676DD5A24DC3CE200325212 /* DebugController.swift */; }; + 8695E0D824F3DA19005D738C /* VenueDetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8695E0D724F3DA19005D738C /* VenueDetailsViewController.swift */; }; + 8695E0E724F3DAF8005D738C /* FloatingPanelCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8695E0DB24F3DAF8005D738C /* FloatingPanelCore.swift */; }; + 8695E0E824F3DAF8005D738C /* FloatingPanelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8695E0DC24F3DAF8005D738C /* FloatingPanelController.swift */; }; + 8695E0E924F3DAF8005D738C /* FloatingPanelSurfaceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8695E0DD24F3DAF8005D738C /* FloatingPanelSurfaceView.swift */; }; + 8695E0EA24F3DAF8005D738C /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8695E0DE24F3DAF8005D738C /* Logger.swift */; }; + 8695E0EB24F3DAF8005D738C /* FloatingPanelBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8695E0DF24F3DAF8005D738C /* FloatingPanelBehavior.swift */; }; + 8695E0EC24F3DAF8005D738C /* FloatingPanelTransitioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8695E0E124F3DAF8005D738C /* FloatingPanelTransitioning.swift */; }; + 8695E0ED24F3DAF8005D738C /* FloatingPanelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8695E0E224F3DAF8005D738C /* FloatingPanelView.swift */; }; + 8695E0EE24F3DAF8005D738C /* GrabberHandleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8695E0E324F3DAF8005D738C /* GrabberHandleView.swift */; }; + 8695E0EF24F3DAF8005D738C /* FloatingPanelLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8695E0E424F3DAF8005D738C /* FloatingPanelLayout.swift */; }; + 8695E0F024F3DAF8005D738C /* FloatingPanelBackdropView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8695E0E524F3DAF8005D738C /* FloatingPanelBackdropView.swift */; }; + 8695E0F124F3DAF8005D738C /* UIExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8695E0E624F3DAF8005D738C /* UIExtensions.swift */; }; + 86F43C4524E3E1080084C2D3 /* MyCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86F43C4424E3E1080084C2D3 /* MyCollectionViewCell.swift */; }; + 86F43C4924E418CC0084C2D3 /* ProfileController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86F43C4824E418CC0084C2D3 /* ProfileController.swift */; }; + 86F43C4B24E419B90084C2D3 /* LogsItemCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86F43C4A24E419B90084C2D3 /* LogsItemCell.swift */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ - 866AA0D7261376BA002BD2F7 /* Embed Frameworks */ = { + 62A7FC7F27073882002D1C18 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( - 866AA0D6261376BA002BD2F7 /* navigine.framework in Embed Frameworks */, + 62A7FC7E27073882002D1C18 /* navigine.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -33,83 +69,230 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 8628213925274774007546DA /* NavigineDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NavigineDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 8628213C25274774007546DA /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 8628214025274774007546DA /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - 8628214325274774007546DA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 8628214525274775007546DA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 8628214825274775007546DA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 8628214A25274775007546DA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 8628215325274945007546DA /* BridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BridgingHeader.h; sourceTree = ""; }; - 8628215925274C0E007546DA /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - 8628215B25274E42007546DA /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; - 866AA0D02613487A002BD2F7 /* navigine.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = navigine.framework; sourceTree = ""; }; + 62AEFF552732B9D0000223D5 /* blue_dot.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = blue_dot.png; sourceTree = ""; }; + 860164E524C7456900509D5E /* NavigineDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NavigineDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 860164E824C7456900509D5E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 860164EA24C7456900509D5E /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 860164F124C7456900509D5E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 860164F624C7456900509D5E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 860164FD24C745BA00509D5E /* navigine.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = navigine.framework; sourceTree = ""; }; + 8601650224C7479700509D5E /* BridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BridgingHeader.h; sourceTree = ""; }; + 8601650C24C8567C00509D5E /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; + 8601650D24C8567C00509D5E /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; + 8601651224C8575900509D5E /* LocationsList.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LocationsList.storyboard; sourceTree = ""; }; + 8601651424C857F400509D5E /* Navigation.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Navigation.storyboard; sourceTree = ""; }; + 8601651624C8581500509D5E /* AddBeacon.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = AddBeacon.storyboard; sourceTree = ""; }; + 8601651824C8582800509D5E /* Debug.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Debug.storyboard; sourceTree = ""; }; + 8601651A24C8583600509D5E /* Profile.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Profile.storyboard; sourceTree = ""; }; + 8601651D24C85AD900509D5E /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; + 8601652024C85D5C00509D5E /* Circe-ExtraLight.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Circe-ExtraLight.ttf"; sourceTree = ""; }; + 8601652124C85D5C00509D5E /* Circe-ExtraBold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Circe-ExtraBold.ttf"; sourceTree = ""; }; + 8601652224C85D5C00509D5E /* Circe-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Circe-Bold.ttf"; sourceTree = ""; }; + 8601652624C85D5C00509D5E /* Circe-Thin.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Circe-Thin.ttf"; sourceTree = ""; }; + 8601652724C85D5C00509D5E /* Circe-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Circe-Regular.ttf"; sourceTree = ""; }; + 8601653024C867FC00509D5E /* LocationsListController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationsListController.swift; sourceTree = ""; }; + 8601653424C86DAD00509D5E /* LocationSearchController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationSearchController.swift; sourceTree = ""; }; + 8601653724C87FC600509D5E /* NavigineApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigineApp.swift; sourceTree = ""; }; + 8601653E24C88F2100509D5E /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; }; + 8601653F24C88F2100509D5E /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + 8601654624C9C39C00509D5E /* NavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationController.swift; sourceTree = ""; }; + 8610E3A824E536E0002BED87 /* AddBeaconController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddBeaconController.swift; sourceTree = ""; }; + 861E3D8E24E1A9F4008DD348 /* LocationItemCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationItemCell.swift; sourceTree = ""; }; + 861E3D9624E2D0E2008DD348 /* CircularLoaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircularLoaderView.swift; sourceTree = ""; }; + 8676DD5A24DC3CE200325212 /* DebugController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugController.swift; sourceTree = ""; }; + 8695E0D724F3DA19005D738C /* VenueDetailsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VenueDetailsViewController.swift; sourceTree = ""; }; + 8695E0DB24F3DAF8005D738C /* FloatingPanelCore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatingPanelCore.swift; sourceTree = ""; }; + 8695E0DC24F3DAF8005D738C /* FloatingPanelController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatingPanelController.swift; sourceTree = ""; }; + 8695E0DD24F3DAF8005D738C /* FloatingPanelSurfaceView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatingPanelSurfaceView.swift; sourceTree = ""; }; + 8695E0DE24F3DAF8005D738C /* Logger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = ""; }; + 8695E0DF24F3DAF8005D738C /* FloatingPanelBehavior.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatingPanelBehavior.swift; sourceTree = ""; }; + 8695E0E024F3DAF8005D738C /* FloatingPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FloatingPanel.h; sourceTree = ""; }; + 8695E0E124F3DAF8005D738C /* FloatingPanelTransitioning.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatingPanelTransitioning.swift; sourceTree = ""; }; + 8695E0E224F3DAF8005D738C /* FloatingPanelView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatingPanelView.swift; sourceTree = ""; }; + 8695E0E324F3DAF8005D738C /* GrabberHandleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GrabberHandleView.swift; sourceTree = ""; }; + 8695E0E424F3DAF8005D738C /* FloatingPanelLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatingPanelLayout.swift; sourceTree = ""; }; + 8695E0E524F3DAF8005D738C /* FloatingPanelBackdropView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatingPanelBackdropView.swift; sourceTree = ""; }; + 8695E0E624F3DAF8005D738C /* UIExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIExtensions.swift; sourceTree = ""; }; + 86F43C4424E3E1080084C2D3 /* MyCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyCollectionViewCell.swift; sourceTree = ""; }; + 86F43C4824E418CC0084C2D3 /* ProfileController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileController.swift; sourceTree = ""; }; + 86F43C4A24E419B90084C2D3 /* LogsItemCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogsItemCell.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 8628213625274774007546DA /* Frameworks */ = { + 860164E224C7456900509D5E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 866AA0D5261376BA002BD2F7 /* navigine.framework in Frameworks */, + 8601654024C88F2100509D5E /* GLKit.framework in Frameworks */, + 62157CD326D15EB7008D2ED2 /* GLKit.framework in Frameworks */, + 62A7FC7B27073861002D1C18 /* OpenGLES.framework in Frameworks */, + 62A7FC7D27073882002D1C18 /* navigine.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 8628213025274774007546DA = { + 62C796BB2678F91E005FEB09 /* Resources */ = { isa = PBXGroup; children = ( - 8628213B25274774007546DA /* NavigineDemo */, - 8628213A25274774007546DA /* Products */, + 62C796BC2678F91E005FEB09 /* img */, ); + path = Resources; sourceTree = ""; }; - 8628213A25274774007546DA /* Products */ = { + 62C796BC2678F91E005FEB09 /* img */ = { isa = PBXGroup; children = ( - 8628213925274774007546DA /* NavigineDemo.app */, + 62AEFF552732B9D0000223D5 /* blue_dot.png */, + ); + path = img; + sourceTree = ""; + }; + 860164DC24C7456900509D5E = { + isa = PBXGroup; + children = ( + 860164E724C7456900509D5E /* NavigineDemo */, + 860164E624C7456900509D5E /* Products */, + 8601653D24C88F2100509D5E /* Frameworks */, + ); + sourceTree = ""; + }; + 860164E624C7456900509D5E /* Products */ = { + isa = PBXGroup; + children = ( + 860164E524C7456900509D5E /* NavigineDemo.app */, ); name = Products; sourceTree = ""; }; - 8628213B25274774007546DA /* NavigineDemo */ = { + 860164E724C7456900509D5E /* NavigineDemo */ = { isa = PBXGroup; children = ( - 8628215025274907007546DA /* Frameworks */, - 8628215925274C0E007546DA /* SceneDelegate.swift */, - 8628213C25274774007546DA /* AppDelegate.swift */, - 8628214025274774007546DA /* ViewController.swift */, - 8628214225274774007546DA /* Main.storyboard */, - 8628214525274775007546DA /* Assets.xcassets */, - 8628214725274775007546DA /* LaunchScreen.storyboard */, - 8628214A25274775007546DA /* Info.plist */, - 8628215325274945007546DA /* BridgingHeader.h */, - 8628215B25274E42007546DA /* Constants.swift */, + 62C796BB2678F91E005FEB09 /* Resources */, + 8695E0D924F3DAD9005D738C /* Libs */, + 8601653624C87FA900509D5E /* Helpers */, + 8601651F24C85D5C00509D5E /* Fonts */, + 8601651C24C85AC100509D5E /* ViewControllers */, + 8601650624C8558300509D5E /* Storyboards */, + 860164FC24C7458200509D5E /* Frameworks */, + 860164E824C7456900509D5E /* AppDelegate.swift */, + 860164EA24C7456900509D5E /* SceneDelegate.swift */, + 860164F124C7456900509D5E /* Assets.xcassets */, + 860164F624C7456900509D5E /* Info.plist */, + 8601650224C7479700509D5E /* BridgingHeader.h */, ); path = NavigineDemo; sourceTree = ""; }; - 8628215025274907007546DA /* Frameworks */ = { + 860164FC24C7458200509D5E /* Frameworks */ = { isa = PBXGroup; children = ( - 866AA0D02613487A002BD2F7 /* navigine.framework */, + 860164FD24C745BA00509D5E /* navigine.framework */, ); path = Frameworks; sourceTree = ""; }; + 8601650624C8558300509D5E /* Storyboards */ = { + isa = PBXGroup; + children = ( + 8601650D24C8567C00509D5E /* LaunchScreen.storyboard */, + 8601650C24C8567C00509D5E /* Main.storyboard */, + 8601651224C8575900509D5E /* LocationsList.storyboard */, + 8601651424C857F400509D5E /* Navigation.storyboard */, + 8601651624C8581500509D5E /* AddBeacon.storyboard */, + 8601651824C8582800509D5E /* Debug.storyboard */, + 8601651A24C8583600509D5E /* Profile.storyboard */, + ); + path = Storyboards; + sourceTree = ""; + }; + 8601651C24C85AC100509D5E /* ViewControllers */ = { + isa = PBXGroup; + children = ( + 8601651D24C85AD900509D5E /* TabBarController.swift */, + 8601653024C867FC00509D5E /* LocationsListController.swift */, + 8601653424C86DAD00509D5E /* LocationSearchController.swift */, + 8601654624C9C39C00509D5E /* NavigationController.swift */, + 8676DD5A24DC3CE200325212 /* DebugController.swift */, + 86F43C4824E418CC0084C2D3 /* ProfileController.swift */, + 8610E3A824E536E0002BED87 /* AddBeaconController.swift */, + ); + path = ViewControllers; + sourceTree = ""; + }; + 8601651F24C85D5C00509D5E /* Fonts */ = { + isa = PBXGroup; + children = ( + 8601652024C85D5C00509D5E /* Circe-ExtraLight.ttf */, + 8601652124C85D5C00509D5E /* Circe-ExtraBold.ttf */, + 8601652224C85D5C00509D5E /* Circe-Bold.ttf */, + 8601652624C85D5C00509D5E /* Circe-Thin.ttf */, + 8601652724C85D5C00509D5E /* Circe-Regular.ttf */, + ); + path = Fonts; + sourceTree = ""; + }; + 8601653624C87FA900509D5E /* Helpers */ = { + isa = PBXGroup; + children = ( + 8601653724C87FC600509D5E /* NavigineApp.swift */, + 861E3D8E24E1A9F4008DD348 /* LocationItemCell.swift */, + 861E3D9624E2D0E2008DD348 /* CircularLoaderView.swift */, + 86F43C4424E3E1080084C2D3 /* MyCollectionViewCell.swift */, + 86F43C4A24E419B90084C2D3 /* LogsItemCell.swift */, + 8695E0D724F3DA19005D738C /* VenueDetailsViewController.swift */, + ); + path = Helpers; + sourceTree = ""; + }; + 8601653D24C88F2100509D5E /* Frameworks */ = { + isa = PBXGroup; + children = ( + 8601653E24C88F2100509D5E /* GLKit.framework */, + 8601653F24C88F2100509D5E /* OpenGLES.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 8695E0D924F3DAD9005D738C /* Libs */ = { + isa = PBXGroup; + children = ( + 8695E0DA24F3DAF8005D738C /* FloatingPanel */, + ); + path = Libs; + sourceTree = ""; + }; + 8695E0DA24F3DAF8005D738C /* FloatingPanel */ = { + isa = PBXGroup; + children = ( + 8695E0DB24F3DAF8005D738C /* FloatingPanelCore.swift */, + 8695E0DC24F3DAF8005D738C /* FloatingPanelController.swift */, + 8695E0DD24F3DAF8005D738C /* FloatingPanelSurfaceView.swift */, + 8695E0DE24F3DAF8005D738C /* Logger.swift */, + 8695E0DF24F3DAF8005D738C /* FloatingPanelBehavior.swift */, + 8695E0E024F3DAF8005D738C /* FloatingPanel.h */, + 8695E0E124F3DAF8005D738C /* FloatingPanelTransitioning.swift */, + 8695E0E224F3DAF8005D738C /* FloatingPanelView.swift */, + 8695E0E324F3DAF8005D738C /* GrabberHandleView.swift */, + 8695E0E424F3DAF8005D738C /* FloatingPanelLayout.swift */, + 8695E0E524F3DAF8005D738C /* FloatingPanelBackdropView.swift */, + 8695E0E624F3DAF8005D738C /* UIExtensions.swift */, + ); + path = FloatingPanel; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 8628213825274774007546DA /* NavigineDemo */ = { + 860164E424C7456900509D5E /* NavigineDemo */ = { isa = PBXNativeTarget; - buildConfigurationList = 8628214D25274775007546DA /* Build configuration list for PBXNativeTarget "NavigineDemo" */; + buildConfigurationList = 860164F924C7456900509D5E /* Build configuration list for PBXNativeTarget "NavigineDemo" */; buildPhases = ( - 8628213525274774007546DA /* Sources */, - 8628213625274774007546DA /* Frameworks */, - 8628213725274774007546DA /* Resources */, - 866AA0D7261376BA002BD2F7 /* Embed Frameworks */, + 860164E124C7456900509D5E /* Sources */, + 860164E224C7456900509D5E /* Frameworks */, + 860164E324C7456900509D5E /* Resources */, + 62A7FC7F27073882002D1C18 /* Embed Frameworks */, ); buildRules = ( ); @@ -117,25 +300,26 @@ ); name = NavigineDemo; productName = NavigineDemo; - productReference = 8628213925274774007546DA /* NavigineDemo.app */; + productReference = 860164E524C7456900509D5E /* NavigineDemo.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ - 8628213125274774007546DA /* Project object */ = { + 860164DD24C7456900509D5E /* Project object */ = { isa = PBXProject; attributes = { LastSwiftUpdateCheck = 1120; LastUpgradeCheck = 1120; ORGANIZATIONNAME = navigine; TargetAttributes = { - 8628213825274774007546DA = { + 860164E424C7456900509D5E = { CreatedOnToolsVersion = 11.2; + LastSwiftMigration = 1120; }; }; }; - buildConfigurationList = 8628213425274774007546DA /* Build configuration list for PBXProject "NavigineDemo" */; + buildConfigurationList = 860164E024C7456900509D5E /* Build configuration list for PBXProject "NavigineDemo" */; compatibilityVersion = "Xcode 9.3"; developmentRegion = en; hasScannedForEncodings = 0; @@ -143,64 +327,78 @@ en, Base, ); - mainGroup = 8628213025274774007546DA; - productRefGroup = 8628213A25274774007546DA /* Products */; + mainGroup = 860164DC24C7456900509D5E; + productRefGroup = 860164E624C7456900509D5E /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - 8628213825274774007546DA /* NavigineDemo */, + 860164E424C7456900509D5E /* NavigineDemo */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - 8628213725274774007546DA /* Resources */ = { + 860164E324C7456900509D5E /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8628214925274775007546DA /* LaunchScreen.storyboard in Resources */, - 8628214625274775007546DA /* Assets.xcassets in Resources */, - 8628214425274774007546DA /* Main.storyboard in Resources */, + 86016BBF24C9D00B00509D5E /* Circe-Thin.ttf in Resources */, + 62AEFF562732B9D0000223D5 /* blue_dot.png in Resources */, + 86016BC024C9D00B00509D5E /* Circe-Regular.ttf in Resources */, + 86016BC124C9D00B00509D5E /* Main.storyboard in Resources */, + 86016BC224C9D00B00509D5E /* Navigation.storyboard in Resources */, + 8601651324C8575900509D5E /* LocationsList.storyboard in Resources */, + 8601652A24C85D5C00509D5E /* Circe-Bold.ttf in Resources */, + 8601650F24C8567C00509D5E /* LaunchScreen.storyboard in Resources */, + 8601651724C8581500509D5E /* AddBeacon.storyboard in Resources */, + 8601652924C85D5C00509D5E /* Circe-ExtraBold.ttf in Resources */, + 8601651B24C8583600509D5E /* Profile.storyboard in Resources */, + 8601651924C8582800509D5E /* Debug.storyboard in Resources */, + 860164F224C7456900509D5E /* Assets.xcassets in Resources */, + 8601652824C85D5C00509D5E /* Circe-ExtraLight.ttf in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 8628213525274774007546DA /* Sources */ = { + 860164E124C7456900509D5E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8628214125274774007546DA /* ViewController.swift in Sources */, - 8628213D25274774007546DA /* AppDelegate.swift in Sources */, - 8628215A25274C0E007546DA /* SceneDelegate.swift in Sources */, - 8628215C25274E42007546DA /* Constants.swift in Sources */, + 8695E0EA24F3DAF8005D738C /* Logger.swift in Sources */, + 86F43C4524E3E1080084C2D3 /* MyCollectionViewCell.swift in Sources */, + 8695E0E824F3DAF8005D738C /* FloatingPanelController.swift in Sources */, + 8601651E24C85AD900509D5E /* TabBarController.swift in Sources */, + 8695E0E924F3DAF8005D738C /* FloatingPanelSurfaceView.swift in Sources */, + 8601654724C9C39C00509D5E /* NavigationController.swift in Sources */, + 8601653524C86DAD00509D5E /* LocationSearchController.swift in Sources */, + 8676DD5B24DC3CE200325212 /* DebugController.swift in Sources */, + 861E3D8F24E1A9F4008DD348 /* LocationItemCell.swift in Sources */, + 860164E924C7456900509D5E /* AppDelegate.swift in Sources */, + 86F43C4B24E419B90084C2D3 /* LogsItemCell.swift in Sources */, + 8695E0EE24F3DAF8005D738C /* GrabberHandleView.swift in Sources */, + 8695E0ED24F3DAF8005D738C /* FloatingPanelView.swift in Sources */, + 861E3D9724E2D0E2008DD348 /* CircularLoaderView.swift in Sources */, + 8695E0EC24F3DAF8005D738C /* FloatingPanelTransitioning.swift in Sources */, + 8695E0F124F3DAF8005D738C /* UIExtensions.swift in Sources */, + 860164EB24C7456900509D5E /* SceneDelegate.swift in Sources */, + 8601653824C87FC600509D5E /* NavigineApp.swift in Sources */, + 86F43C4924E418CC0084C2D3 /* ProfileController.swift in Sources */, + 8695E0D824F3DA19005D738C /* VenueDetailsViewController.swift in Sources */, + 8601653124C867FC00509D5E /* LocationsListController.swift in Sources */, + 8695E0F024F3DAF8005D738C /* FloatingPanelBackdropView.swift in Sources */, + 8610E3A924E536E0002BED87 /* AddBeaconController.swift in Sources */, + 8695E0EB24F3DAF8005D738C /* FloatingPanelBehavior.swift in Sources */, + 8695E0EF24F3DAF8005D738C /* FloatingPanelLayout.swift in Sources */, + 8695E0E724F3DAF8005D738C /* FloatingPanelCore.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXVariantGroup section */ - 8628214225274774007546DA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 8628214325274774007546DA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 8628214725274775007546DA /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 8628214825274775007546DA /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - /* Begin XCBuildConfiguration section */ - 8628214B25274775007546DA /* Debug */ = { + 860164F724C7456900509D5E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -252,7 +450,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/NavigineDemo/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 13.2; + IPHONEOS_DEPLOYMENT_TARGET = 14.5; LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/NavigineDemo/Frameworks"; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -261,11 +459,10 @@ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OBJC_BRIDGING_HEADER = NavigineDemo/BridgingHeader.h; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SYSTEM_FRAMEWORK_SEARCH_PATHS = ""; }; name = Debug; }; - 8628214C25274775007546DA /* Release */ = { + 860164F824C7456900509D5E /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -311,7 +508,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/NavigineDemo/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 13.2; + IPHONEOS_DEPLOYMENT_TARGET = 14.5; LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/NavigineDemo/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; @@ -319,77 +516,83 @@ SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OBJC_BRIDGING_HEADER = NavigineDemo/BridgingHeader.h; SWIFT_OPTIMIZATION_LEVEL = "-O"; - SYSTEM_FRAMEWORK_SEARCH_PATHS = ""; VALIDATE_PRODUCT = YES; }; name = Release; }; - 8628214E25274775007546DA /* Debug */ = { + 860164FA24C7456900509D5E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = 9L9SSEDTLA; - EXCLUDED_ARCHS = ""; - FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/NavigineDemo/Frameworks", + ); INFOPLIST_FILE = NavigineDemo/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 14.5; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.navigine.NavigineDemo; + PRODUCT_BUNDLE_IDENTIFIER = "com.navigine.Navigine-iOS"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = NavigineDemo/BridgingHeader.h; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 1; - VALIDATE_WORKSPACE = NO; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 8628214F25274775007546DA /* Release */ = { + 860164FB24C7456900509D5E /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = 9L9SSEDTLA; - EXCLUDED_ARCHS = ""; - FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/NavigineDemo/Frameworks", + ); INFOPLIST_FILE = NavigineDemo/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 14.5; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.navigine.NavigineDemo; + PRODUCT_BUNDLE_IDENTIFIER = "com.navigine.Navigine-iOS"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = NavigineDemo/BridgingHeader.h; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 1; - VALIDATE_WORKSPACE = NO; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 8628213425274774007546DA /* Build configuration list for PBXProject "NavigineDemo" */ = { + 860164E024C7456900509D5E /* Build configuration list for PBXProject "NavigineDemo" */ = { isa = XCConfigurationList; buildConfigurations = ( - 8628214B25274775007546DA /* Debug */, - 8628214C25274775007546DA /* Release */, + 860164F724C7456900509D5E /* Debug */, + 860164F824C7456900509D5E /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 8628214D25274775007546DA /* Build configuration list for PBXNativeTarget "NavigineDemo" */ = { + 860164F924C7456900509D5E /* Build configuration list for PBXNativeTarget "NavigineDemo" */ = { isa = XCConfigurationList; buildConfigurations = ( - 8628214E25274775007546DA /* Debug */, - 8628214F25274775007546DA /* Release */, + 860164FA24C7456900509D5E /* Debug */, + 860164FB24C7456900509D5E /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; - rootObject = 8628213125274774007546DA /* Project object */; + rootObject = 860164DD24C7456900509D5E /* Project object */; } diff --git a/NavigineDemo/NavigineDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/NavigineDemo/NavigineDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata old mode 100644 new mode 100755 diff --git a/NavigineDemo/NavigineDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/NavigineDemo/NavigineDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist old mode 100644 new mode 100755 diff --git a/NavigineDemo/NavigineDemo/AppDelegate.swift b/NavigineDemo/NavigineDemo/AppDelegate.swift old mode 100644 new mode 100755 index 99f1cf6..6b5aa59 --- a/NavigineDemo/NavigineDemo/AppDelegate.swift +++ b/NavigineDemo/NavigineDemo/AppDelegate.swift @@ -1,49 +1,49 @@ -// -// AppDelegate.swift -// NavigineDemo -// -// Created by mrcrambo on 02/10/2020. -// Copyright © 2020 navigine. All rights reserved. -// - import UIKit +struct AppInitializer { + static func setupAppearance() -> Void { + UINavigationBar.appearance().isTranslucent = false + UINavigationBar.appearance().titleTextAttributes = + [NSAttributedString.Key.foregroundColor: UIColor.white, + NSAttributedString.Key.font : {() -> UIFont in + return UIFont.init(name: "Circe-Bold", size: 16.0) ?? UIFont() + }()] + } +} + @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { - + var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - NCNavigineSdk.setUserHash(Constants.USER_HASH) - NCNavigineSdk.setServer(Constants.SERVER_URL) + if #available(iOS 13.0, *) { // In iOS 13 setup is done in SceneDelegate } else { let window = UIWindow(frame: UIScreen.main.bounds) self.window = window let sb = UIStoryboard.init(name: "Main", bundle: Bundle.main) + AppInitializer.setupAppearance() window.rootViewController = sb.instantiateViewController(withIdentifier: "initial") window.makeKeyAndVisible() } return true } - + // MARK: UISceneSession Lifecycle - + @available(iOS 13.0, *) func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { // Called when a new scene session is being created. // Use this method to select a configuration to create the new scene with. return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) } - + @available(iOS 13.0, *) func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { // Called when the user discards a scene session. // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. // Use this method to release any resources that were specific to the discarded scenes, as they will not return. } - - } - diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Contents.json b/NavigineDemo/NavigineDemo/Assets.xcassets/Contents.json old mode 100644 new mode 100755 diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Contents.json b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Contents.json new file mode 100755 index 0000000..da4a164 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Debug Tab.imageset/Contents.json b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Debug Tab.imageset/Contents.json new file mode 100755 index 0000000..a388a55 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Debug Tab.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "filename" : "Debug.png", + "scale" : "1x" + }, + { + "idiom" : "iphone", + "filename" : "Debug@2x.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "filename" : "Debug@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Debug Tab.imageset/Debug.png b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Debug Tab.imageset/Debug.png new file mode 100755 index 0000000..91744dd Binary files /dev/null and b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Debug Tab.imageset/Debug.png differ diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Debug Tab.imageset/Debug@2x.png b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Debug Tab.imageset/Debug@2x.png new file mode 100755 index 0000000..7f431b6 Binary files /dev/null and b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Debug Tab.imageset/Debug@2x.png differ diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Debug Tab.imageset/Debug@3x.png b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Debug Tab.imageset/Debug@3x.png new file mode 100755 index 0000000..5216006 Binary files /dev/null and b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Debug Tab.imageset/Debug@3x.png differ diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Locations Tab.imageset/Contents.json b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Locations Tab.imageset/Contents.json new file mode 100755 index 0000000..04a3ed6 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Locations Tab.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "filename" : "Locations.png", + "scale" : "1x" + }, + { + "idiom" : "iphone", + "filename" : "Locations@2x.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "filename" : "Locations@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Locations Tab.imageset/Locations.png b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Locations Tab.imageset/Locations.png new file mode 100755 index 0000000..b1f35e1 Binary files /dev/null and b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Locations Tab.imageset/Locations.png differ diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Locations Tab.imageset/Locations@2x.png b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Locations Tab.imageset/Locations@2x.png new file mode 100755 index 0000000..a9ffab2 Binary files /dev/null and b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Locations Tab.imageset/Locations@2x.png differ diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Locations Tab.imageset/Locations@3x.png b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Locations Tab.imageset/Locations@3x.png new file mode 100755 index 0000000..506ea97 Binary files /dev/null and b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Locations Tab.imageset/Locations@3x.png differ diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Measuring Tab.imageset/1x_Groupmenu_measuring.png b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Measuring Tab.imageset/1x_Groupmenu_measuring.png new file mode 100755 index 0000000..da56b30 Binary files /dev/null and b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Measuring Tab.imageset/1x_Groupmenu_measuring.png differ diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Measuring Tab.imageset/2x_Groupmenu_measuring.png b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Measuring Tab.imageset/2x_Groupmenu_measuring.png new file mode 100755 index 0000000..267407d Binary files /dev/null and b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Measuring Tab.imageset/2x_Groupmenu_measuring.png differ diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Measuring Tab.imageset/3x_Groupmenu_measuring.png b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Measuring Tab.imageset/3x_Groupmenu_measuring.png new file mode 100755 index 0000000..197769b Binary files /dev/null and b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Measuring Tab.imageset/3x_Groupmenu_measuring.png differ diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Measuring Tab.imageset/Contents.json b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Measuring Tab.imageset/Contents.json new file mode 100755 index 0000000..fa219a6 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Measuring Tab.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "filename" : "1x_Groupmenu_measuring.png", + "scale" : "1x" + }, + { + "idiom" : "iphone", + "filename" : "2x_Groupmenu_measuring.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "filename" : "3x_Groupmenu_measuring.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Navigation Tab.imageset/Contents.json b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Navigation Tab.imageset/Contents.json new file mode 100755 index 0000000..1c2c6f9 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Navigation Tab.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "filename" : "Navigation.png", + "scale" : "1x" + }, + { + "idiom" : "iphone", + "filename" : "Navigation@2x.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "filename" : "Navigation@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Navigation Tab.imageset/Navigation.png b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Navigation Tab.imageset/Navigation.png new file mode 100755 index 0000000..9b50da0 Binary files /dev/null and b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Navigation Tab.imageset/Navigation.png differ diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Navigation Tab.imageset/Navigation@2x.png b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Navigation Tab.imageset/Navigation@2x.png new file mode 100755 index 0000000..f971537 Binary files /dev/null and b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Navigation Tab.imageset/Navigation@2x.png differ diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Navigation Tab.imageset/Navigation@3x.png b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Navigation Tab.imageset/Navigation@3x.png new file mode 100755 index 0000000..5036844 Binary files /dev/null and b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Navigation Tab.imageset/Navigation@3x.png differ diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Profile Tab.imageset/Contents.json b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Profile Tab.imageset/Contents.json new file mode 100755 index 0000000..cbd027b --- /dev/null +++ b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Profile Tab.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Profile.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Profile@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "Profile@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Profile Tab.imageset/Profile.png b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Profile Tab.imageset/Profile.png new file mode 100755 index 0000000..93d7ccd Binary files /dev/null and b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Profile Tab.imageset/Profile.png differ diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Profile Tab.imageset/Profile@2x.png b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Profile Tab.imageset/Profile@2x.png new file mode 100755 index 0000000..cd8351a Binary files /dev/null and b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Profile Tab.imageset/Profile@2x.png differ diff --git a/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Profile Tab.imageset/Profile@3x.png b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Profile Tab.imageset/Profile@3x.png new file mode 100755 index 0000000..72669e8 Binary files /dev/null and b/NavigineDemo/NavigineDemo/Assets.xcassets/Tab bar/Profile Tab.imageset/Profile@3x.png differ diff --git a/NavigineDemo/NavigineDemo/Base.lproj/Main.storyboard b/NavigineDemo/NavigineDemo/Base.lproj/Main.storyboard deleted file mode 100644 index 2f95836..0000000 --- a/NavigineDemo/NavigineDemo/Base.lproj/Main.storyboard +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/NavigineDemo/NavigineDemo/BridgingHeader.h b/NavigineDemo/NavigineDemo/BridgingHeader.h old mode 100644 new mode 100755 index ee91d12..1bab2a4 --- a/NavigineDemo/NavigineDemo/BridgingHeader.h +++ b/NavigineDemo/NavigineDemo/BridgingHeader.h @@ -1,11 +1,3 @@ -// -// BridgingHeader.h -// Navigine_iOS -// -// Created by mrcrambo on 21/07/2020. -// Copyright © 2020 mrcrambo. All rights reserved. -// - #ifndef BridgingHeader_h #define BridgingHeader_h diff --git a/NavigineDemo/NavigineDemo/Constants.swift b/NavigineDemo/NavigineDemo/Constants.swift deleted file mode 100644 index 1e85629..0000000 --- a/NavigineDemo/NavigineDemo/Constants.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// Constants.swift -// NavigineDemo -// -// Created by mrcrambo on 02/10/2020. -// Copyright © 2020 navigine. All rights reserved. -// - -import Foundation - -struct Constants { - static let USER_HASH = "0000-0000-0000-0000" - static let SERVER_URL = "https://api.navigine.com" - static let LOCATION_ID = 2475 - static let SUBLOCATION_ID = 4158 -} diff --git a/NavigineDemo/NavigineDemo/Fonts/Circe-Bold.ttf b/NavigineDemo/NavigineDemo/Fonts/Circe-Bold.ttf new file mode 100755 index 0000000..d8542ff Binary files /dev/null and b/NavigineDemo/NavigineDemo/Fonts/Circe-Bold.ttf differ diff --git a/NavigineDemo/NavigineDemo/Fonts/Circe-ExtraBold.ttf b/NavigineDemo/NavigineDemo/Fonts/Circe-ExtraBold.ttf new file mode 100755 index 0000000..461e327 Binary files /dev/null and b/NavigineDemo/NavigineDemo/Fonts/Circe-ExtraBold.ttf differ diff --git a/NavigineDemo/NavigineDemo/Fonts/Circe-ExtraLight.ttf b/NavigineDemo/NavigineDemo/Fonts/Circe-ExtraLight.ttf new file mode 100755 index 0000000..9b67900 Binary files /dev/null and b/NavigineDemo/NavigineDemo/Fonts/Circe-ExtraLight.ttf differ diff --git a/NavigineDemo/NavigineDemo/Fonts/Circe-Regular.ttf b/NavigineDemo/NavigineDemo/Fonts/Circe-Regular.ttf new file mode 100755 index 0000000..d100c5b Binary files /dev/null and b/NavigineDemo/NavigineDemo/Fonts/Circe-Regular.ttf differ diff --git a/NavigineDemo/NavigineDemo/Fonts/Circe-Thin.ttf b/NavigineDemo/NavigineDemo/Fonts/Circe-Thin.ttf new file mode 100755 index 0000000..4c63328 Binary files /dev/null and b/NavigineDemo/NavigineDemo/Fonts/Circe-Thin.ttf differ diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCAnimationType.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCAnimationType.h new file mode 100644 index 0000000..54694c7 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCAnimationType.h @@ -0,0 +1,10 @@ +#import + +typedef NS_ENUM(NSInteger, NCAnimationType) +{ + NCAnimationTypeNone, + NCAnimationTypeLinear, + NCAnimationTypeCubic, + NCAnimationTypeQuint, + NCAnimationTypeSine, +}; diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCAsyncRouteListener.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCAsyncRouteListener.h new file mode 100644 index 0000000..174f585 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCAsyncRouteListener.h @@ -0,0 +1,16 @@ +#import "NCExport.h" +#import "NCLocationPoint.h" +#import +@class NCRoutePath; + + +NAVIGINE_EXPORT +@protocol NCAsyncRouteListener + +- (void)onRouteChanged:(nullable NCRoutePath *)currentPath + pendingPaths:(nonnull NSArray *)pendingPaths; + +- (void)onRouteAdvanced:(float)distance + point:(nonnull NCLocationPoint *)point; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCAsyncRouteManager.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCAsyncRouteManager.h new file mode 100644 index 0000000..33206f5 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCAsyncRouteManager.h @@ -0,0 +1,14 @@ +#import "NCExport.h" +#import "NCLocationPoint.h" +#import +@class NCRouteSession; + + +NAVIGINE_EXPORT +@interface NCAsyncRouteManager : NSObject + +- (nullable NCRouteSession *)createRouteSession:(nonnull NSArray *)wayPoints; + +- (void)cancelRouteSession:(nullable NCRouteSession *)session; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCBeacon.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCBeacon.h new file mode 100644 index 0000000..3252ca7 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCBeacon.h @@ -0,0 +1,25 @@ +#import "NCExport.h" +#import "NCPoint.h" +#import + + +NAVIGINE_EXPORT +@interface NCBeacon : NSObject + +@property (nonatomic, nonnull, readonly) NCPoint * point; + +@property (nonatomic, readonly) int32_t locationId; + +@property (nonatomic, readonly) int32_t sublocationId; + +@property (nonatomic, nonnull, readonly) NSString * name; + +@property (nonatomic, readonly) int32_t major; + +@property (nonatomic, readonly) int32_t minor; + +@property (nonatomic, nonnull, readonly) NSString * uuid; + +@property (nonatomic, readonly) int32_t power; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCBitmapRegionDecoder.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCBitmapRegionDecoder.h new file mode 100644 index 0000000..b58086f --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCBitmapRegionDecoder.h @@ -0,0 +1,17 @@ +#import "NCExport.h" +#import "NCRectangle.h" +#import +#import +@class NCBitmapRegionDecoder; + + +NAVIGINE_EXPORT +@interface NCBitmapRegionDecoder : NSObject + ++ (nullable NCBitmapRegionDecoder *)newInstance:(nonnull NSData *)data + length:(int32_t)length; + +- (nullable UIImage *)decodeRegion:(nonnull NCRectangle *)rect + sampleSize:(int32_t)sampleSize; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCCategory.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCCategory.h new file mode 100644 index 0000000..5a5521e --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCCategory.h @@ -0,0 +1,19 @@ +#import "NCExport.h" +#import + +NAVIGINE_EXPORT +@interface NCCategory : NSObject +- (nonnull instancetype)initWithId:(int32_t)id + name:(nonnull NSString *)name + imageId:(nullable NSString *)imageId; ++ (nonnull instancetype)categoryWithId:(int32_t)id + name:(nonnull NSString *)name + imageId:(nullable NSString *)imageId; + +@property (nonatomic, readonly) int32_t id; + +@property (nonatomic, readonly, nonnull) NSString * name; + +@property (nonatomic, readonly, nullable) NSString * imageId; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCCircleMapObject.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCCircleMapObject.h new file mode 100644 index 0000000..de42b17 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCCircleMapObject.h @@ -0,0 +1,25 @@ +#import "NCAnimationType.h" +#import "NCExport.h" +#import "NCLocationPoint.h" +#import + + +NAVIGINE_EXPORT +@interface NCCircleMapObject : NSObject + +- (BOOL)setPosition:(nonnull NCLocationPoint *)point; + +- (BOOL)setPositionAnimated:(nonnull NCLocationPoint *)point + duration:(float)duration + type:(NCAnimationType)type; + +- (BOOL)setRadius:(float)radius; + +- (BOOL)setVisible:(BOOL)visible; + +- (BOOL)setColor:(float)red + green:(float)green + blue:(float)blue + alpha:(float)alpha; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCEddystone.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCEddystone.h new file mode 100644 index 0000000..ae99a76 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCEddystone.h @@ -0,0 +1,23 @@ +#import "NCExport.h" +#import "NCPoint.h" +#import + + +NAVIGINE_EXPORT +@interface NCEddystone : NSObject + +@property (nonatomic, nonnull, readonly) NCPoint * point; + +@property (nonatomic, readonly) int32_t locationId; + +@property (nonatomic, readonly) int32_t sublocationId; + +@property (nonatomic, nonnull, readonly) NSString * name; + +@property (nonatomic, nonnull, readonly) NSString * namespaceId; + +@property (nonatomic, nonnull, readonly) NSString * instanceId; + +@property (nonatomic, readonly) int32_t power; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCElevationGraph.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCElevationGraph.h new file mode 100644 index 0000000..90c13ca --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCElevationGraph.h @@ -0,0 +1,11 @@ +#import "NCExport.h" +#import +@class NCGraphEdge; + + +NAVIGINE_EXPORT +@interface NCElevationGraph : NSObject + +@property (nonatomic, nonnull, readonly) NSArray * edges; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCExport.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCExport.h new file mode 100644 index 0000000..4cd50db --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCExport.h @@ -0,0 +1,2 @@ +#pragma once +#define NAVIGINE_EXPORT __attribute__((visibility("default"))) diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGeometryUtils.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGeometryUtils.h new file mode 100644 index 0000000..ec35201 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGeometryUtils.h @@ -0,0 +1,57 @@ +#import "NCExport.h" +#import "NCGlobalPoint.h" +#import "NCPoint.h" +#import "NCPolygon.h" +#import "NCSegment.h" +#import + + +NAVIGINE_EXPORT +@interface NCGeometryUtils : NSObject + +/** Get distance between GPS points */ ++ (float)distanceBetweenGlobalPoints:(nonnull NCGlobalPoint *)from + to:(nonnull NCGlobalPoint *)to; + +/** Get distance between points */ ++ (float)distanceBetweenPoints:(nonnull NCPoint *)from + to:(nonnull NCPoint *)to; + +/** Get length of segment */ ++ (float)segmentLength:(nonnull NCSegment *)segment; + +/** Get polygon area */ ++ (float)polygonArea:(nonnull NCPolygon *)polygon; + +/** Get polygon geometric centre */ ++ (nonnull NCPoint *)polygonCenter:(nonnull NCPolygon *)polygon; + +/** Checks that polygon contains point */ ++ (BOOL)polygonContainsPoint:(nonnull NCPolygon *)polygon + point:(nonnull NCPoint *)point; + +/** Get distance from segment to point */ ++ (float)segmentPointDistance:(nonnull NCSegment *)segment + point:(nonnull NCPoint *)point; + +/** Checks the intersection of two segments */ ++ (BOOL)segmentIntersectsSegment:(nonnull NCSegment *)segment1 + segment2:(nonnull NCSegment *)segment2; + +/** Calculate the intersection point of two segments */ ++ (nonnull NCPoint *)segmentIntersectionSegment:(nonnull NCSegment *)segment1 + segment2:(nonnull NCSegment *)segment2; + +/** Calculate the division ratio of a segment by a given segment(if intersects) */ ++ (float)divisionRatioBySegment:(nonnull NCSegment *)segment1 + segment2:(nonnull NCSegment *)segment2; + +/** Calculate projection point on a segment */ ++ (nonnull NCPoint *)getRatioPoint:(nonnull NCSegment *)segment + r:(double)r; + +/** Calculate the division ratio of a segment by a given point */ ++ (double)getProjectionRatio:(nonnull NCSegment *)segment + point:(nonnull NCPoint *)point; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGestureRecognizerDelegate.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGestureRecognizerDelegate.h new file mode 100644 index 0000000..112e222 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGestureRecognizerDelegate.h @@ -0,0 +1,182 @@ +#import +#import + +@class NCLocationView; + +/** + The `NCGestureRecognizerDelegate` protocol can be implemented to receive gesture events from the map view. The map view will + first check whether a gestureDelegate is set, then check whether it responds to any `shouldRecognize*` method: + - If the delegate responds to `shouldRecognize*`, the map view only performs its default handling of the gesture if + `shouldRecognize*` returns `YES`. + - If the delegate doesn't respond to `shouldRecognize*`, the map view performs its default handling of the gesture. + Finally, if the delegate implements `didRecognize*` then the map view calls this method after the gesture is handled. + @note These methods are all **optional**. All the screen positions in this interface are in _logical pixels_ or + _drawing coordinate system_ (based on a `UIKit` coordinate system) which is independent of the phone pixel density. + Refer to the + + Apple documentation regarding _Coordinate Systems and Drawing in iOS_ for more informations. + */ +@protocol NCGestureRecognizerDelegate +@optional + +/** + Whether the map view should handle a single tap gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` that recognized the gesture. + @param location The location of the recognized gesture in the view. + @return `YES` if the map view should handle this gesture, otherwise `NO`. + */ +- (BOOL)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +shouldRecognizeSingleTapGesture:(CGPoint)location; + +/** + Whether the map view should handle a double tap gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` that recognized the gesture. + @param location The location of the recognized gesture in the view. + @return `YES` if the map view should handle this gesture, otherwise `NO`. + */ +- (BOOL)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +shouldRecognizeDoubleTapGesture:(CGPoint)location; + +/** + Whether the map view should handle a long press gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` that recognized the gesture. + @param location The location of the recognized gesture in the view. + @return `YES` if the map view should handle this gesture, otherwise `NO`. + */ +- (BOOL)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +shouldRecognizeLongPressGesture:(CGPoint)location; + +/** + Whether the map view should handle a pan gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` that recognized the gesture. + @param displacement The displacement of the recognized gesture in the view. + @return `YES` if the map view should handle this gesture, otherwise `NO`. + */ +- (BOOL)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +shouldRecognizePanGesture:(CGPoint)displacement; + +/** + Whether the map view should handle a pinch gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` that recognized the gesture. + @param location The position of the recognized gesture in the view. + @return `YES` if the map view should handle this gesture, otherwise `NO`. + */ +- (BOOL)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +shouldRecognizePinchGesture:(CGPoint)location; + +/** + Whether the map view should handle a rotation gesture. + + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` that recognized the gesture. + @param location The position of the recognized gesture in the view. + @return `YES` if the map view should handle this gesture, otherwise `NO`. + */ +// - (BOOL)locationView:(NCLocationView *)view +// recognizer:(UIGestureRecognizer *)recognizer +// shouldRecognizeRotationGesture:(CGPoint)location; + +/** + Whether the map view should handle a shove gesture. + + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` that recognized the gesture. + @param displacement The displacement of the recognized gesture in the view. + @return `YES` if the map view should handle this gesture, otherwise `NO`. + */ +// - (BOOL)locationView:(NCLocationView *)view +// recognizer:(UIGestureRecognizer *)recognizer +// shouldRecognizeShoveGesture:(CGPoint)displacement; + +/** + Called when the map view just handled a single tap gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` the recognized the gesture. + @param location The position of the recognized gesture in the view. + */ +- (void)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +didRecognizeSingleTapGesture:(CGPoint)location; + +/** + Called when the map view just handled a single double tap gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` the recognized the gesture. + @param location The position of the recognized gesture in the view. + */ +- (void)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +didRecognizeDoubleTapGesture:(CGPoint)location; + +/** + Called when the map view just handled a long press gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` the recognized the gesture. + @param location The position of the recognized gesture in the view. + */ +- (void)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +didRecognizeLongPressGesture:(CGPoint)location; + +/** + Called when the map view just handled a pan gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` the recognized the gesture. + @param displacement The displacement of the recognized gesture in the view. + */ +- (void)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +didRecognizePanGesture:(CGPoint)displacement; + +/** + Called when the map view just handled a pinch gesture. + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` the recognized the gesture. + @param location The position of the recognized gesture in the view. + */ +- (void)locationView:(NCLocationView *)view + recognizer:(UIGestureRecognizer *)recognizer +didRecognizePinchGesture:(CGPoint)location; + +/** + Called when the map view just handled a rotation gesture. + + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` the recognized the gesture. + @param location The position of the recognized gesture in the view. + */ +// - (void)locationView:(NCLocationView *)view +// recognizer:(UIGestureRecognizer *)recognizer +// didRecognizeRotationGesture:(CGPoint)location; + +/** + Called when the map view just handled a shove gesture. + + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` the recognized the gesture. + @param displacement The displacement of the recognized gesture in the view. + */ +// - (void)locationView:(NCLocationView *)view +// recognizer:(UIGestureRecognizer *)recognizer +// didRecognizeShoveGesture:(CGPoint)displacement; + +/** + If implemented, the returned value will be the focus for the pinch gesture. + + @param view The map view instance. + @param recognizer The `UIGestureRecognizer` that recognized the gesture. + @return The screen position the pinch gesture should focus to. + */ +- (CGPoint)pinchFocus:(NCLocationView *)view recognizer:(UIGestureRecognizer *)recognizer; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGlobalPoint.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGlobalPoint.h new file mode 100644 index 0000000..3007c44 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGlobalPoint.h @@ -0,0 +1,15 @@ +#import "NCExport.h" +#import + +NAVIGINE_EXPORT +@interface NCGlobalPoint : NSObject +- (nonnull instancetype)initWithLatitude:(float)latitude + longitude:(float)longitude; ++ (nonnull instancetype)globalPointWithLatitude:(float)latitude + longitude:(float)longitude; + +@property (nonatomic, readonly) float latitude; + +@property (nonatomic, readonly) float longitude; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGraph.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGraph.h new file mode 100644 index 0000000..c8f5b7b --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGraph.h @@ -0,0 +1,14 @@ +#import "NCExport.h" +#import +@class NCGraphEdge; +@class NCGraphVertex; + + +NAVIGINE_EXPORT +@interface NCGraph : NSObject + +@property (nonatomic, nonnull, readonly) NSArray * vertexes; + +@property (nonatomic, nonnull, readonly) NSArray * edges; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGraphEdge.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGraphEdge.h new file mode 100644 index 0000000..3ba0e5f --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGraphEdge.h @@ -0,0 +1,16 @@ +#import "NCExport.h" +#import + + +NAVIGINE_EXPORT +@interface NCGraphEdge : NSObject + +@property (nonatomic, readonly) float weight; + +@property (nonatomic, readonly) int32_t dst; + +@property (nonatomic, readonly) int32_t src; + +@property (nonatomic, readonly) int32_t weightCoef; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGraphVertex.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGraphVertex.h new file mode 100644 index 0000000..18ebaac --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCGraphVertex.h @@ -0,0 +1,19 @@ +#import "NCExport.h" +#import "NCPoint.h" +#import + + +NAVIGINE_EXPORT +@interface NCGraphVertex : NSObject + +@property (nonatomic, readonly) int32_t id; + +@property (nonatomic, nonnull, readonly) NCPoint * point; + +@property (nonatomic, nonnull, readonly) NSString * name; + +@property (nonatomic, readonly) BOOL isExternal; + +@property (nonatomic, readonly) BOOL isElevation; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCIconMapObject.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCIconMapObject.h new file mode 100644 index 0000000..3f142f3 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCIconMapObject.h @@ -0,0 +1,26 @@ +#import "NCAnimationType.h" +#import "NCExport.h" +#import "NCLocationPoint.h" +#import +#import + + +NAVIGINE_EXPORT +@interface NCIconMapObject : NSObject + +- (BOOL)setPosition:(nonnull NCLocationPoint *)point; + +- (BOOL)setPositionAnimated:(nonnull NCLocationPoint *)point + duration:(float)duration + type:(NCAnimationType)type; + +- (BOOL)setBitmap:(nullable UIImage *)bitmap; + +- (BOOL)setSize:(float)width + height:(float)height; + +- (BOOL)setVisible:(BOOL)visible; + +- (BOOL)setInteractive:(BOOL)interactive; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCImage.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCImage.h new file mode 100644 index 0000000..5d04f46 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCImage.h @@ -0,0 +1,17 @@ +#import "NCExport.h" +#import "NCImageType.h" +#import + + +NAVIGINE_EXPORT +@interface NCImage : NSObject + +@property (nonatomic, nonnull, readonly) NSData * data; + +@property (nonatomic, readonly) int32_t width; + +@property (nonatomic, readonly) int32_t height; + +@property (nonatomic, readonly) NCImageType type; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCImageType.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCImageType.h new file mode 100644 index 0000000..9f114e7 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCImageType.h @@ -0,0 +1,8 @@ +#import + +typedef NS_ENUM(NSInteger, NCImageType) +{ + NCImageTypePNG, + NCImageTypeSVG, + NCImageTypeJPG, +}; diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLine.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLine.h new file mode 100644 index 0000000..adcc936 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLine.h @@ -0,0 +1,12 @@ +#import "NCExport.h" +#import "NCSegment.h" +#import + +NAVIGINE_EXPORT +@interface NCLine : NSObject +- (nonnull instancetype)initWithSegments:(nonnull NSArray *)segments; ++ (nonnull instancetype)lineWithSegments:(nonnull NSArray *)segments; + +@property (nonatomic, readonly, nonnull) NSArray * segments; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocation.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocation.h new file mode 100644 index 0000000..ac6f250 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocation.h @@ -0,0 +1,31 @@ +#import "NCCategory.h" +#import "NCExport.h" +#import +@class NCElevationGraph; +@class NCSublocation; + + +NAVIGINE_EXPORT +@interface NCLocation : NSObject + +- (nullable NCElevationGraph *)getElevationGraph:(nonnull NSString *)tag; + +- (nonnull NSArray *)getGraphTags; + +- (nullable NCSublocation *)getSublocationById:(int32_t)id; + +- (nullable NCCategory *)getCategoryById:(int32_t)id; + +@property (nonatomic, readonly) int32_t id; + +@property (nonatomic, readonly) int32_t version; + +@property (nonatomic, nonnull, readonly) NSString * name; + +@property (nonatomic, nonnull, readonly) NSString * descript; + +@property (nonatomic, nonnull, readonly) NSArray * categories; + +@property (nonatomic, nonnull, readonly) NSArray * sublocations; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationEditListener.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationEditListener.h new file mode 100644 index 0000000..a755fcf --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationEditListener.h @@ -0,0 +1,15 @@ +#import "NCExport.h" +#import + + +NAVIGINE_EXPORT +@protocol NCLocationEditListener + +- (void)onLocationUploaded; + +- (void)onUploadProgress:(int32_t)received + total:(int32_t)total; + +- (void)onLocationEditError:(nullable NSError *)error; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationEditManager.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationEditManager.h new file mode 100644 index 0000000..36c2f7f --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationEditManager.h @@ -0,0 +1,75 @@ +#import "NCExport.h" +#import "NCPoint.h" +#import +@protocol NCLocationEditListener; + + +NAVIGINE_EXPORT +@interface NCLocationEditManager : NSObject + +- (void)addBeacon:(int32_t)subLocId + uuid:(nonnull NSString *)uuid + major:(int32_t)major + minor:(int32_t)minor + point:(nonnull NCPoint *)point + name:(nonnull NSString *)name + power:(int32_t)power; + +- (void)editBeacon:(int32_t)subLocId + uuid:(nonnull NSString *)uuid + major:(int32_t)major + minor:(int32_t)minor + point:(nonnull NCPoint *)point + name:(nonnull NSString *)name + power:(int32_t)power; + +- (void)removeBeacon:(int32_t)subLocId + uuid:(nonnull NSString *)uuid + major:(int32_t)major + minor:(int32_t)minor; + +- (void)addEddystone:(int32_t)subLocId + namespaceId:(nonnull NSString *)namespaceId + instanceId:(nonnull NSString *)instanceId + point:(nonnull NCPoint *)point + name:(nonnull NSString *)name + power:(int32_t)power; + +- (void)editEddystone:(int32_t)subLocId + namespaceId:(nonnull NSString *)namespaceId + instanceId:(nonnull NSString *)instanceId + point:(nonnull NCPoint *)point + name:(nonnull NSString *)name + power:(int32_t)power; + +- (void)removeEddystone:(int32_t)subLocId + namespaceId:(nonnull NSString *)namespaceId + instanceId:(nonnull NSString *)instanceId; + +- (void)addWifi:(int32_t)subLocId + mac:(nonnull NSString *)mac + point:(nonnull NCPoint *)point + name:(nonnull NSString *)name; + +- (void)editWifi:(int32_t)subLocId + mac:(nonnull NSString *)mac + point:(nonnull NCPoint *)point + name:(nonnull NSString *)name; + +- (void)removeWifi:(int32_t)subLocId + mac:(nonnull NSString *)mac; + +- (void)addWifiRtt; + +- (void)editWifiRtt; + +- (void)removeWifiRtt:(int32_t)subLocId + mac:(nonnull NSString *)mac; + +- (void)addLocationEditListener:(nullable id)locationEditListener; + +- (void)removeLocationEditListener:(nullable id)locationEditListener; + +- (void)commitChanges; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationInfo.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationInfo.h new file mode 100644 index 0000000..d814271 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationInfo.h @@ -0,0 +1,19 @@ +#import "NCExport.h" +#import + +NAVIGINE_EXPORT +@interface NCLocationInfo : NSObject +- (nonnull instancetype)initWithId:(int32_t)id + version:(int32_t)version + name:(nonnull NSString *)name; ++ (nonnull instancetype)locationInfoWithId:(int32_t)id + version:(int32_t)version + name:(nonnull NSString *)name; + +@property (nonatomic, readonly) int32_t id; + +@property (nonatomic, readonly) int32_t version; + +@property (nonatomic, readonly, nonnull) NSString * name; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationListListener.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationListListener.h new file mode 100644 index 0000000..dcc9fab --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationListListener.h @@ -0,0 +1,13 @@ +#import "NCExport.h" +#import "NCLocationInfo.h" +#import + + +NAVIGINE_EXPORT +@protocol NCLocationListListener + +- (void)onLocationListLoaded:(nonnull NSDictionary *)locationInfos; + +- (void)onLocationListFailed:(nullable NSError *)error; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationListManager.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationListManager.h new file mode 100644 index 0000000..8c16626 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationListManager.h @@ -0,0 +1,18 @@ +#import "NCExport.h" +#import "NCLocationInfo.h" +#import +@protocol NCLocationListListener; + + +NAVIGINE_EXPORT +@interface NCLocationListManager : NSObject + +- (void)addLocationListListener:(nullable id)listener; + +- (void)removeLocationListListener:(nullable id)listener; + +- (void)updateLocationList; + +- (nonnull NSDictionary *)getLocationList; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationListener.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationListener.h new file mode 100644 index 0000000..290c018 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationListener.h @@ -0,0 +1,16 @@ +#import "NCExport.h" +#import +@class NCLocation; + + +NAVIGINE_EXPORT +@protocol NCLocationListener + +- (void)onLocationLoaded:(nullable NCLocation *)location; + +- (void)onDownloadProgress:(int32_t)received + total:(int32_t)total; + +- (void)onLocationFailed:(nullable NSError *)error; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationManager.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationManager.h new file mode 100644 index 0000000..ebbf7b2 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationManager.h @@ -0,0 +1,17 @@ +#import "NCExport.h" +#import +@protocol NCLocationListener; + + +NAVIGINE_EXPORT +@interface NCLocationManager : NSObject + +- (void)addLocationListener:(nullable id)listener; + +- (void)removeLocationListener:(nullable id)listener; + +- (void)setLocationId:(int32_t)locationId; + +- (int32_t)getLocationId; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationPoint.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationPoint.h new file mode 100644 index 0000000..319e209 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationPoint.h @@ -0,0 +1,20 @@ +#import "NCExport.h" +#import "NCPoint.h" +#import + +NAVIGINE_EXPORT +@interface NCLocationPoint : NSObject +- (nonnull instancetype)initWithPoint:(nonnull NCPoint *)point + locationId:(int32_t)locationId + sublocationId:(int32_t)sublocationId; ++ (nonnull instancetype)locationPointWithPoint:(nonnull NCPoint *)point + locationId:(int32_t)locationId + sublocationId:(int32_t)sublocationId; + +@property (nonatomic, readonly, nonnull) NCPoint * point; + +@property (nonatomic, readonly) int32_t locationId; + +@property (nonatomic, readonly) int32_t sublocationId; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationPolygon.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationPolygon.h new file mode 100644 index 0000000..c56fb0b --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationPolygon.h @@ -0,0 +1,20 @@ +#import "NCExport.h" +#import "NCPolygon.h" +#import + +NAVIGINE_EXPORT +@interface NCLocationPolygon : NSObject +- (nonnull instancetype)initWithPolygon:(nonnull NCPolygon *)polygon + locationId:(int32_t)locationId + sublocationId:(int32_t)sublocationId; ++ (nonnull instancetype)locationPolygonWithPolygon:(nonnull NCPolygon *)polygon + locationId:(int32_t)locationId + sublocationId:(int32_t)sublocationId; + +@property (nonatomic, readonly, nonnull) NCPolygon * polygon; + +@property (nonatomic, readonly) int32_t locationId; + +@property (nonatomic, readonly) int32_t sublocationId; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationPolyline.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationPolyline.h new file mode 100644 index 0000000..db3f937 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationPolyline.h @@ -0,0 +1,20 @@ +#import "NCExport.h" +#import "NCPolyline.h" +#import + +NAVIGINE_EXPORT +@interface NCLocationPolyline : NSObject +- (nonnull instancetype)initWithPolyline:(nonnull NCPolyline *)polyline + locationId:(int32_t)locationId + sublocationId:(int32_t)sublocationId; ++ (nonnull instancetype)locationPolylineWithPolyline:(nonnull NCPolyline *)polyline + locationId:(int32_t)locationId + sublocationId:(int32_t)sublocationId; + +@property (nonatomic, readonly, nonnull) NCPolyline * polyline; + +@property (nonatomic, readonly) int32_t locationId; + +@property (nonatomic, readonly) int32_t sublocationId; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationView.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationView.h new file mode 100644 index 0000000..416578f --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationView.h @@ -0,0 +1,98 @@ +#import +#import "NCExport.h" + +NS_ASSUME_NONNULL_BEGIN + +@class NCCircleMapObject; +@class NCIconMapObject; +@class NCPolylineMapObject; +@class NCPoint; +@class NCSublocation; + +@protocol NCGestureRecognizerDelegate; +@protocol NCLocationViewDelegate; + +NAVIGINE_EXPORT +@interface NCLocationView : UIView + +- (instancetype)initWithFrame:(CGRect)frame; + +- (void) setSublocationId: (int) sublocationId; + +- (NCCircleMapObject *) addCircleMapObject; + +- (bool) removeCircleMapObject: (NCCircleMapObject *) circleMapObject; + +- (NCIconMapObject *) addIconMapObject; + +- (bool) removeIconMapObject: (NCIconMapObject *) iconMapObject; + +- (NCPolylineMapObject *) addPolylineMapObject; + +- (bool) removePolylineMapObject: (NCPolylineMapObject *) polylineMapObject; + +- (void) requestRender; + +- (void)pickMapObjectAt:(CGPoint)viewPosition; + +@property (assign, nonatomic) CGFloat minZoomFactor; + +@property (assign, nonatomic) CGFloat maxZoomFactor; + +@property (assign, nonatomic) CGFloat zoomFactor; + +@property (strong, nonatomic, readonly) CADisplayLink *displayLink; + +@property (assign, nonatomic) NSInteger preferredFramesPerSecond; + +@property (weak, nonatomic, nullable) id locationViewDelegate; + +#pragma mark Gesture Recognizers + +@property (weak, nonatomic, nullable) id gestureDelegate; + +/** + Replaces the tap gesture recognizer used by the map view and adds it to the UIView. + */ +@property (strong, nonatomic) UITapGestureRecognizer* tapGestureRecognizer; + +/** + Replaces the double tap gesture recognizer used by the map view and adds it to the UIView. + */ +@property (strong, nonatomic) UITapGestureRecognizer* doubleTapGestureRecognizer; + +/** + Replaces the pan gesture recognizer used by the map view and adds it to the UIView. + */ +@property (strong, nonatomic) UIPanGestureRecognizer* panGestureRecognizer; + +/** + Replaces the pinch gesture recognizer used by the map view and adds it to the UIView. + */ +@property (strong, nonatomic) UIPinchGestureRecognizer* pinchGestureRecognizer; + +/** + Replaces the rotation gesture recognizer used by the map view and adds it to the UIView. + */ +// @property (strong, nonatomic) UIRotationGestureRecognizer* rotationGestureRecognizer; + +/** + Replaces the shove gesture recognizer used by the map view and adds it to the UIView. + */ +// @property (strong, nonatomic) UIPanGestureRecognizer* shoveGestureRecognizer; + +/** + Replaces the long press gesture recognizer used by the map view and adds it to the UIView. + */ +@property (strong, nonatomic) UILongPressGestureRecognizer* longPressGestureRecognizer; + +#pragma mark Memory Management + +/** + Reduce memory usage by freeing currently unused resources. + */ +- (void)didReceiveMemoryWarning; + +@end + +NS_ASSUME_NONNULL_END diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationViewDelegate.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationViewDelegate.h new file mode 100644 index 0000000..007ff97 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCLocationViewDelegate.h @@ -0,0 +1,26 @@ +#import +#import + +@class NCLocationView; +@class NCMapObjectPickResult; + +/** + A map view delegate can receive various map events. + + @note All of these methods are called from main thread, these methods are all **optional**. + */ +@protocol NCLocationViewDelegate +@optional + +/** + Receive the result from `-[NCLocationView pickMapObjectAt:]`. + + @param locationView The location view instance. + @param pickResult A result object with information about the picked object or `nil` if no object was found. + @param position The view position where object was picked. + */ +- (void)locationView:(nonnull NCLocationView *)mapView +didSelectMapObject:(nullable NCMapObjectPickResult *)markerPickResult +atScreenPosition:(CGPoint)position; + +@end // protocol NCLocationViewDelegate diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMapObjectData.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMapObjectData.h new file mode 100644 index 0000000..7bd9c8b --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMapObjectData.h @@ -0,0 +1,24 @@ +#import "NCExport.h" +#import "NCMapObjectType.h" +#import + +NAVIGINE_EXPORT +@interface NCMapObjectData : NSObject +- (nonnull instancetype)initWithId:(nonnull NSString *)id + sublocationId:(int32_t)sublocationId + type:(NCMapObjectType)type + extraValues:(nonnull NSDictionary *)extraValues; ++ (nonnull instancetype)mapObjectDataWithId:(nonnull NSString *)id + sublocationId:(int32_t)sublocationId + type:(NCMapObjectType)type + extraValues:(nonnull NSDictionary *)extraValues; + +@property (nonatomic, readonly, nonnull) NSString * id; + +@property (nonatomic, readonly) int32_t sublocationId; + +@property (nonatomic, readonly) NCMapObjectType type; + +@property (nonatomic, readonly, nonnull) NSDictionary * extraValues; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMapObjectPickResult.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMapObjectPickResult.h new file mode 100644 index 0000000..f8ea276 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMapObjectPickResult.h @@ -0,0 +1,23 @@ +#import +#import +#import "NCExport.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + Data structure holding the result of a marker selection that occured on the location view. + + See `-[NCLocationView pickMapObjectAt:]` and `[NCLocationViewDelegate locationView:didSelectMapObject:atScreenPosition:]`. + */ +NAVIGINE_EXPORT +@interface NCMapObjectPickResult : NSObject + +/// The geographic coordinates of the selected label +@property (readonly, nonatomic) CLLocationCoordinate2D coordinates; + +/// The selected marker +@property (readonly, nonatomic) NSObject* mapObject; + +NS_ASSUME_NONNULL_END + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMapObjectType.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMapObjectType.h new file mode 100644 index 0000000..48b835b --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMapObjectType.h @@ -0,0 +1,10 @@ +#import + +typedef NS_ENUM(NSInteger, NCMapObjectType) +{ + NCMapObjectTypeBEACON, + NCMapObjectTypeEDDYSTONE, + NCMapObjectTypeWIFI, + NCMapObjectTypeVENUE, + NCMapObjectTypeOTHER, +}; diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMeasurementListener.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMeasurementListener.h new file mode 100644 index 0000000..fcc555e --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMeasurementListener.h @@ -0,0 +1,15 @@ +#import "NCExport.h" +#import "NCSensorMeasurement.h" +#import "NCSensorType.h" +#import "NCSignalMeasurement.h" +#import + + +NAVIGINE_EXPORT +@protocol NCMeasurementListener + +- (void)onSensorMeasurementDetected:(nonnull NSDictionary *)sensors; + +- (void)onSignalMeasurementDetected:(nonnull NSDictionary *)signals; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMeasurementManager.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMeasurementManager.h new file mode 100644 index 0000000..4b81dad --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMeasurementManager.h @@ -0,0 +1,58 @@ +#import "NCExport.h" +#import "NCSensorMeasurement.h" +#import +@protocol NCMeasurementListener; + + +NAVIGINE_EXPORT +@interface NCMeasurementManager : NSObject + +- (void)addMeasurementListener:(nullable id)listener; + +- (void)removeMeasurementListener:(nullable id)listener; + +- (int32_t)addBeaconGenerator:(nonnull NSString *)uuid + major:(int32_t)major + minor:(int32_t)minor + power:(int32_t)power + timeout:(int32_t)timeout + rssiMin:(int32_t)rssiMin + rssiMax:(int32_t)rssiMax; + +- (void)removeBeaconGenerator:(int32_t)hash; + +- (void)removeBeaconGenerators; + +- (int32_t)addEddystoneGenerator:(nonnull NSString *)namespaceId + instanceId:(nonnull NSString *)instanceId + power:(int32_t)power + timeout:(int32_t)timeout + rssiMin:(int32_t)rssiMin + rssiMax:(int32_t)rssiMax; + +- (void)removeEddystoneGenerator:(int32_t)hash; + +- (void)removeEddystoneGenerators; + +- (int32_t)addWifiGenerator:(nonnull NSString *)mac + timeout:(int32_t)timeout + rssiMin:(int32_t)rssiMin + rssiMax:(int32_t)rssiMax; + +- (void)removeWifiGenerator:(int32_t)hash; + +- (void)removeWifiGenerators; + +- (int32_t)addWifiRttGenerator:(nonnull NSString *)mac + distance:(float)distance + timeout:(int32_t)timeout + rssiMin:(int32_t)rssiMin + rssiMax:(int32_t)rssiMax; + +- (void)removeWifiRttGenerator:(int32_t)hash; + +- (void)removeWifiRttGenerators; + +- (void)addExternalSensorMeasurement:(nonnull NCSensorMeasurement *)measurement; + +@end diff --git a/Frameworks/navigine.framework/Headers/NCLineMapObject.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMultiLineMapObject.h similarity index 56% rename from Frameworks/navigine.framework/Headers/NCLineMapObject.h rename to NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMultiLineMapObject.h index 3cc774f..a70b06e 100644 --- a/Frameworks/navigine.framework/Headers/NCLineMapObject.h +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCMultiLineMapObject.h @@ -1,19 +1,20 @@ -#import "NCMapObjectData.h" +#import "NCExport.h" #import "NCPoint.h" #import -@interface NCLineMapObject : NSObject +NAVIGINE_EXPORT +@interface NCMultiLineMapObject : NSObject -- (void)setPoints:(nonnull NSArray *)points; +- (void)setLines:(nonnull NSArray *> *)lines; - (void)setWidth:(float)width; - (float)getWidth; -- (void)setData:(nonnull NCMapObjectData *)data; +- (void)setData:(nonnull NSData *)data; -- (nonnull NCMapObjectData *)getData; +- (nonnull NSData *)getData; - (void)setEnabled:(BOOL)visibility; diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCNavigationManager.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCNavigationManager.h new file mode 100644 index 0000000..f8e2eb8 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCNavigationManager.h @@ -0,0 +1,17 @@ +#import "NCExport.h" +#import +@protocol NCPositionListener; + + +NAVIGINE_EXPORT +@interface NCNavigationManager : NSObject + +- (void)addPositionListener:(nullable id)listener; + +- (void)removePositionListener:(nullable id)listener; + +- (void)startLogRecording; + +- (void)stopLogRecording; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCNavigineSdk.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCNavigineSdk.h new file mode 100644 index 0000000..92268cd --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCNavigineSdk.h @@ -0,0 +1,52 @@ +#import "NCExport.h" +#import +@class NCAsyncRouteManager; +@class NCLocationEditManager; +@class NCLocationListManager; +@class NCLocationManager; +@class NCMeasurementManager; +@class NCNavigationManager; +@class NCNavigineSdk; +@class NCNotificationManager; +@class NCResourceManager; +@class NCRouteManager; +@class NCZoneManager; + + +NAVIGINE_EXPORT +@interface NCNavigineSdk : NSObject + ++ (void)setUserHash:(nonnull NSString *)userHash; + ++ (void)setServer:(nonnull NSString *)server; + ++ (nullable NCNavigineSdk *)getInstance; + ++ (nonnull NSString *)getVersion; + +- (nullable NCLocationManager *)getLocationManager; + +- (nullable NCNavigationManager *)getNavigationManager:(nullable NCLocationManager *)locationManager; + +- (nullable NCZoneManager *)getZoneManager:(nullable NCLocationManager *)locationManager + navigationManager:(nullable NCNavigationManager *)navigationManager; + +- (nullable NCRouteManager *)getRouteManager:(nullable NCLocationManager *)locationManager + navigationManager:(nullable NCNavigationManager *)navigationManager; + +- (nullable NCAsyncRouteManager *)getAsyncRouteManager:(nullable NCLocationManager *)locationManager + navigationManager:(nullable NCNavigationManager *)navigationManager; + +- (nullable NCResourceManager *)getResourceManager:(nullable NCLocationManager *)locationManager; + +- (nullable NCNotificationManager *)getNotificationManager:(nullable NCLocationManager *)locationManager; + +- (nullable NCLocationEditManager *)getLocationEditManager:(nullable NCLocationManager *)locationManager; + +- (nullable NCMeasurementManager *)getMeasurementManager; + +- (nonnull NSString *)getErrorDescription:(int32_t)errorCode; + +- (nullable NCLocationListManager *)getLocationListManager; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCNotification.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCNotification.h new file mode 100644 index 0000000..a5155d2 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCNotification.h @@ -0,0 +1,16 @@ +#import "NCExport.h" +#import + + +NAVIGINE_EXPORT +@interface NCNotification : NSObject + +@property (nonatomic, readonly) int32_t id; + +@property (nonatomic, nonnull, readonly) NSString * title; + +@property (nonatomic, nonnull, readonly) NSString * content; + +@property (nonatomic, nullable, readonly) NSString * imageId; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCNotificationListener.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCNotificationListener.h new file mode 100644 index 0000000..daab6aa --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCNotificationListener.h @@ -0,0 +1,13 @@ +#import "NCExport.h" +#import +@class NCNotification; + + +NAVIGINE_EXPORT +@protocol NCNotificationListener + +- (void)onNotificationLoaded:(nullable NCNotification *)notification; + +- (void)onNotificationFailed:(nullable NSError *)error; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCNotificationManager.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCNotificationManager.h new file mode 100644 index 0000000..e1e1616 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCNotificationManager.h @@ -0,0 +1,13 @@ +#import "NCExport.h" +#import +@protocol NCNotificationListener; + + +NAVIGINE_EXPORT +@interface NCNotificationManager : NSObject + +- (void)addNotificationListener:(nullable id)listener; + +- (void)removeNotificationListener:(nullable id)listener; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPoint.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPoint.h new file mode 100644 index 0000000..f650f21 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPoint.h @@ -0,0 +1,15 @@ +#import "NCExport.h" +#import + +NAVIGINE_EXPORT +@interface NCPoint : NSObject +- (nonnull instancetype)initWithX:(float)x + y:(float)y; ++ (nonnull instancetype)pointWithX:(float)x + y:(float)y; + +@property (nonatomic, readonly) float x; + +@property (nonatomic, readonly) float y; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPolygon.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPolygon.h new file mode 100644 index 0000000..cde7fc0 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPolygon.h @@ -0,0 +1,12 @@ +#import "NCExport.h" +#import "NCPoint.h" +#import + +NAVIGINE_EXPORT +@interface NCPolygon : NSObject +- (nonnull instancetype)initWithPoints:(nonnull NSArray *)points; ++ (nonnull instancetype)polygonWithPoints:(nonnull NSArray *)points; + +@property (nonatomic, readonly, nonnull) NSArray * points; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPolyline.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPolyline.h new file mode 100644 index 0000000..7b82995 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPolyline.h @@ -0,0 +1,12 @@ +#import "NCExport.h" +#import "NCPoint.h" +#import + +NAVIGINE_EXPORT +@interface NCPolyline : NSObject +- (nonnull instancetype)initWithPoints:(nonnull NSArray *)points; ++ (nonnull instancetype)polylineWithPoints:(nonnull NSArray *)points; + +@property (nonatomic, readonly, nonnull) NSArray * points; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPolylineMapObject.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPolylineMapObject.h new file mode 100644 index 0000000..74daa52 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPolylineMapObject.h @@ -0,0 +1,20 @@ +#import "NCExport.h" +#import "NCLocationPolyline.h" +#import + + +NAVIGINE_EXPORT +@interface NCPolylineMapObject : NSObject + +- (BOOL)setPolyLine:(nonnull NCLocationPolyline *)polyline; + +- (BOOL)setWidth:(float)width; + +- (BOOL)setVisible:(BOOL)visible; + +- (BOOL)setColor:(float)red + green:(float)green + blue:(float)blue + alpha:(float)alpha; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPosition.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPosition.h new file mode 100644 index 0000000..835dd17 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPosition.h @@ -0,0 +1,28 @@ +#import "NCExport.h" +#import "NCPoint.h" +#import + +NAVIGINE_EXPORT +@interface NCPosition : NSObject +- (nonnull instancetype)initWithPoint:(nonnull NCPoint *)point + locationId:(int32_t)locationId + sublocationId:(int32_t)sublocationId + accuracy:(float)accuracy + azimuth:(float)azimuth; ++ (nonnull instancetype)positionWithPoint:(nonnull NCPoint *)point + locationId:(int32_t)locationId + sublocationId:(int32_t)sublocationId + accuracy:(float)accuracy + azimuth:(float)azimuth; + +@property (nonatomic, readonly, nonnull) NCPoint * point; + +@property (nonatomic, readonly) int32_t locationId; + +@property (nonatomic, readonly) int32_t sublocationId; + +@property (nonatomic, readonly) float accuracy; + +@property (nonatomic, readonly) float azimuth; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPositionListener.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPositionListener.h new file mode 100644 index 0000000..f449d62 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCPositionListener.h @@ -0,0 +1,13 @@ +#import "NCExport.h" +#import "NCPosition.h" +#import + + +NAVIGINE_EXPORT +@protocol NCPositionListener + +- (void)onPositionUpdated:(nonnull NCPosition *)position; + +- (void)onPositionError:(nullable NSError *)error; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRectangle.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRectangle.h new file mode 100644 index 0000000..100013c --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRectangle.h @@ -0,0 +1,23 @@ +#import "NCExport.h" +#import + +NAVIGINE_EXPORT +@interface NCRectangle : NSObject +- (nonnull instancetype)initWithX:(float)x + y:(float)y + width:(float)width + height:(float)height; ++ (nonnull instancetype)rectangleWithX:(float)x + y:(float)y + width:(float)width + height:(float)height; + +@property (nonatomic, readonly) float x; + +@property (nonatomic, readonly) float y; + +@property (nonatomic, readonly) float width; + +@property (nonatomic, readonly) float height; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCReferenceEntry.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCReferenceEntry.h new file mode 100644 index 0000000..07e9c8f --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCReferenceEntry.h @@ -0,0 +1,15 @@ +#import "NCExport.h" +#import "NCReferenceEntryType.h" +#import + + +NAVIGINE_EXPORT +@interface NCReferenceEntry : NSObject + +@property (nonatomic, readonly) NCReferenceEntryType type; + +@property (nonatomic, nonnull, readonly) NSString * bssid; + +@property (nonatomic, nonnull, readonly) NSString * value; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCReferenceEntryType.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCReferenceEntryType.h new file mode 100644 index 0000000..3d0617d --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCReferenceEntryType.h @@ -0,0 +1,10 @@ +#import + +typedef NS_ENUM(NSInteger, NCReferenceEntryType) +{ + NCReferenceEntryTypeBEACON, + NCReferenceEntryTypeWIFI, + NCReferenceEntryTypeBLE, + NCReferenceEntryTypeEDDYSTONE, + NCReferenceEntryTypeMAGNET, +}; diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCReferencePoint.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCReferencePoint.h new file mode 100644 index 0000000..c44e3a4 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCReferencePoint.h @@ -0,0 +1,32 @@ +#import "NCExport.h" +#import "NCPoint.h" +#import +@class NCReferenceEntry; + + +NAVIGINE_EXPORT +@interface NCReferencePoint : NSObject + +@property (nonatomic, readonly) int32_t locationId; + +@property (nonatomic, readonly) int32_t sublocationId; + +@property (nonatomic, nonnull, readonly) NSString * name; + +@property (nonatomic, nonnull, readonly) NSString * uuid; + +@property (nonatomic, nonnull, readonly) NCPoint * point; + +@property (nonatomic, readonly) int32_t quality; + +@property (nonatomic, readonly) int64_t duration; + +@property (nonatomic, nonnull, readonly) NSString * deviceId; + +@property (nonatomic, nonnull, readonly) NSString * deviceModel; + +@property (nonatomic, nonnull, readonly) NSString * timeLabel; + +@property (nonatomic, nonnull, readonly) NSArray * entries; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCResourceListener.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCResourceListener.h new file mode 100644 index 0000000..f4d6e00 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCResourceListener.h @@ -0,0 +1,15 @@ +#import "NCExport.h" +#import +@class NCImage; + + +NAVIGINE_EXPORT +@protocol NCResourceListener + +- (void)onLoaded:(nonnull NSString *)imageId + image:(nullable NCImage *)image; + +- (void)onFailed:(nonnull NSString *)imageId + error:(nullable NSError *)error; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCResourceManager.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCResourceManager.h new file mode 100644 index 0000000..25eb674 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCResourceManager.h @@ -0,0 +1,26 @@ +#import "NCExport.h" +#import +@protocol NCResourceListener; +@protocol NCResourceUploadListener; + + +NAVIGINE_EXPORT +@interface NCResourceManager : NSObject + +- (void)loadImage:(nonnull NSString *)imageId + listener:(nullable id)listener; + +- (nonnull NSString *)publishUserEvent:(nonnull NSString *)content; + +- (void)uploadUserFile:(nonnull NSString *)filePath + listener:(nullable id)listener; + +/** working with logs */ +- (nonnull NSArray *)getLogsList; + +- (void)removeLogFile:(nonnull NSString *)fileName; + +- (void)uploadLogFile:(nonnull NSString *)fileName + listener:(nullable id)listener; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCResourceUploadListener.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCResourceUploadListener.h new file mode 100644 index 0000000..11da891 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCResourceUploadListener.h @@ -0,0 +1,12 @@ +#import "NCExport.h" +#import + + +NAVIGINE_EXPORT +@protocol NCResourceUploadListener + +- (void)onUploaded; + +- (void)onFailed:(nullable NSError *)error; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRouteEvent.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRouteEvent.h new file mode 100644 index 0000000..7566c6d --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRouteEvent.h @@ -0,0 +1,20 @@ +#import "NCExport.h" +#import "NCRouteEventType.h" +#import + +NAVIGINE_EXPORT +@interface NCRouteEvent : NSObject +- (nonnull instancetype)initWithType:(NCRouteEventType)type + value:(int32_t)value + distance:(float)distance; ++ (nonnull instancetype)routeEventWithType:(NCRouteEventType)type + value:(int32_t)value + distance:(float)distance; + +@property (nonatomic, readonly) NCRouteEventType type; + +@property (nonatomic, readonly) int32_t value; + +@property (nonatomic, readonly) float distance; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRouteEventType.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRouteEventType.h new file mode 100644 index 0000000..2f89471 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRouteEventType.h @@ -0,0 +1,8 @@ +#import + +typedef NS_ENUM(NSInteger, NCRouteEventType) +{ + NCRouteEventTypeTURNLEFT, + NCRouteEventTypeTURNRIGHT, + NCRouteEventTypeTRANSITION, +}; diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRouteListener.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRouteListener.h new file mode 100644 index 0000000..a1b9648 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRouteListener.h @@ -0,0 +1,11 @@ +#import "NCExport.h" +#import +@class NCRoutePath; + + +NAVIGINE_EXPORT +@protocol NCRouteListener + +- (void)onPathsUpdated:(nonnull NSArray *)paths; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRouteManager.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRouteManager.h new file mode 100644 index 0000000..f065eea --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRouteManager.h @@ -0,0 +1,37 @@ +#import "NCExport.h" +#import "NCLocationPoint.h" +#import +@class NCRoutePath; +@protocol NCRouteListener; + + +NAVIGINE_EXPORT +@interface NCRouteManager : NSObject + +- (nullable NCRoutePath *)makeRoute:(nonnull NCLocationPoint *)from + to:(nonnull NCLocationPoint *)to; + +- (nonnull NSArray *)arrangePoints:(nonnull NCLocationPoint *)startPoint + checkPoints:(nonnull NSArray *)checkPoints; + +- (void)setTarget:(nonnull NCLocationPoint *)target; + +- (void)addTarget:(nonnull NCLocationPoint *)target; + +- (void)cancelTarget; + +- (void)clearTargets; + +- (void)setGraphTag:(nonnull NSString *)tag; + +- (nonnull NSString *)getGraphTag; + +- (nonnull NSArray *)getGraphTags; + +- (nonnull NSString *)getGraphDescription; + +- (void)addRouteListener:(nullable id)listener; + +- (void)removeRouteListener:(nullable id)listener; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRoutePath.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRoutePath.h new file mode 100644 index 0000000..cac12d6 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRoutePath.h @@ -0,0 +1,16 @@ +#import "NCExport.h" +#import "NCLocationPoint.h" +#import "NCRouteEvent.h" +#import + + +NAVIGINE_EXPORT +@interface NCRoutePath : NSObject + +@property (nonatomic, readonly) float length; + +@property (nonatomic, nonnull, readonly) NSArray * events; + +@property (nonatomic, nonnull, readonly) NSArray * points; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRouteSession.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRouteSession.h new file mode 100644 index 0000000..3d70a2e --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCRouteSession.h @@ -0,0 +1,16 @@ +#import "NCExport.h" +#import "NCLocationPoint.h" +#import +@protocol NCAsyncRouteListener; + + +NAVIGINE_EXPORT +@interface NCRouteSession : NSObject + +- (void)addRouteListener:(nullable id)listener; + +- (void)removeRouteListener:(nullable id)listener; + +- (void)checkIn:(nonnull NCLocationPoint *)point; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSegment.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSegment.h new file mode 100644 index 0000000..7e0b157 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSegment.h @@ -0,0 +1,16 @@ +#import "NCExport.h" +#import "NCPoint.h" +#import + +NAVIGINE_EXPORT +@interface NCSegment : NSObject +- (nonnull instancetype)initWithStart:(nonnull NCPoint *)start + end:(nonnull NCPoint *)end; ++ (nonnull instancetype)segmentWithStart:(nonnull NCPoint *)start + end:(nonnull NCPoint *)end; + +@property (nonatomic, readonly, nonnull) NCPoint * start; + +@property (nonatomic, readonly, nonnull) NCPoint * end; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSensorMeasurement.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSensorMeasurement.h new file mode 100644 index 0000000..a75b46a --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSensorMeasurement.h @@ -0,0 +1,19 @@ +#import "NCExport.h" +#import "NCSensorType.h" +#import "NCVector3d.h" +#import + +NAVIGINE_EXPORT +@interface NCSensorMeasurement : NSObject +- (nonnull instancetype)initWithType:(NCSensorType)type + values:(nonnull NCVector3d *)values; ++ (nonnull instancetype)sensorMeasurementWithType:(NCSensorType)type + values:(nonnull NCVector3d *)values; + +@property (nonatomic, readonly) NCSensorType type; + +@property (nonatomic, readonly, nonnull) NCVector3d * values; + +- (NSComparisonResult)compare:(nonnull NCSensorMeasurement *)other; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSensorType.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSensorType.h new file mode 100644 index 0000000..9b1d37d --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSensorType.h @@ -0,0 +1,11 @@ +#import + +typedef NS_ENUM(NSInteger, NCSensorType) +{ + NCSensorTypeACCELEROMETER, + NCSensorTypeMAGNETOMETER, + NCSensorTypeGYROSCOPE, + NCSensorTypeBAROMETER, + NCSensorTypeLOCATION, + NCSensorTypeORIENTATION, +}; diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSignalMeasurement.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSignalMeasurement.h new file mode 100644 index 0000000..bd7fa9e --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSignalMeasurement.h @@ -0,0 +1,26 @@ +#import "NCExport.h" +#import "NCSignalType.h" +#import + +NAVIGINE_EXPORT +@interface NCSignalMeasurement : NSObject +- (nonnull instancetype)initWithType:(NCSignalType)type + id:(nonnull NSString *)id + rssi:(float)rssi + distance:(float)distance; ++ (nonnull instancetype)signalMeasurementWithType:(NCSignalType)type + id:(nonnull NSString *)id + rssi:(float)rssi + distance:(float)distance; + +@property (nonatomic, readonly) NCSignalType type; + +@property (nonatomic, readonly, nonnull) NSString * id; + +@property (nonatomic, readonly) float rssi; + +@property (nonatomic, readonly) float distance; + +- (NSComparisonResult)compare:(nonnull NCSignalMeasurement *)other; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSignalType.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSignalType.h new file mode 100644 index 0000000..5495124 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSignalType.h @@ -0,0 +1,10 @@ +#import + +typedef NS_ENUM(NSInteger, NCSignalType) +{ + NCSignalTypeWIFI, + NCSignalTypeBEACON, + NCSignalTypeBLUETOOTH, + NCSignalTypeEDDYSTONE, + NCSignalTypeWIFIRTT, +}; diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSublocation.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSublocation.h new file mode 100644 index 0000000..d4320f5 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCSublocation.h @@ -0,0 +1,55 @@ +#import "NCExport.h" +#import "NCGlobalPoint.h" +#import "NCLocationPoint.h" +#import +@class NCBeacon; +@class NCEddystone; +@class NCGraph; +@class NCReferencePoint; +@class NCVenue; +@class NCWifi; +@class NCZone; + + +NAVIGINE_EXPORT +@interface NCSublocation : NSObject + +- (nonnull NCLocationPoint *)globalToLocal:(nonnull NCGlobalPoint *)globalPoint; + +- (nonnull NCGlobalPoint *)localToGlobal:(nonnull NCLocationPoint *)localPoint; + +- (nullable NCGraph *)getGraph:(nonnull NSString *)tag; + +- (nullable NCVenue *)getVenueById:(int32_t)id; + +- (nullable NCZone *)getZoneById:(int32_t)id; + +@property (nonatomic, readonly) int32_t id; + +@property (nonatomic, readonly) int32_t location; + +@property (nonatomic, nonnull, readonly) NSString * name; + +@property (nonatomic, nonnull, readonly) NSString * imageId; + +@property (nonatomic, readonly) float width; + +@property (nonatomic, readonly) float height; + +@property (nonatomic, readonly) float azimuth; + +@property (nonatomic, nonnull, readonly) NCGlobalPoint * originPoint; + +@property (nonatomic, nonnull, readonly) NSArray * beacons; + +@property (nonatomic, nonnull, readonly) NSArray * eddystones; + +@property (nonatomic, nonnull, readonly) NSArray * wifis; + +@property (nonatomic, nonnull, readonly) NSArray * referencePoints; + +@property (nonatomic, nonnull, readonly) NSArray * venues; + +@property (nonatomic, nonnull, readonly) NSArray * zones; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCTextureMapObject.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCTextureMapObject.h new file mode 100644 index 0000000..9a26b0b --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCTextureMapObject.h @@ -0,0 +1,31 @@ +#import "NCExport.h" +#import "NCMapObjectData.h" +#import "NCPoint.h" +#import + + +NAVIGINE_EXPORT +@interface NCTextureMapObject : NSObject + +- (void)setPosition:(nonnull NCPoint *)point; + +- (nonnull NCPoint *)getPosition; + +- (void)setSize:(float)width + height:(float)height; + +- (float)getWidth; + +- (float)getHeight; + +- (void)setData:(nonnull NCMapObjectData *)data; + +- (nonnull NCMapObjectData *)getData; + +- (void)setEnabled:(BOOL)status; + +- (void)setTexture:(nonnull NSData *)data + imageWidth:(int32_t)imageWidth + imageHeight:(int32_t)imageHeight; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCVector3d.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCVector3d.h new file mode 100644 index 0000000..f6863ba --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCVector3d.h @@ -0,0 +1,21 @@ +#import "NCExport.h" +#import + +NAVIGINE_EXPORT +@interface NCVector3d : NSObject +- (nonnull instancetype)initWithX:(float)x + y:(float)y + z:(float)z; ++ (nonnull instancetype)vector3dWithX:(float)x + y:(float)y + z:(float)z; + +@property (nonatomic, readonly) float x; + +@property (nonatomic, readonly) float y; + +@property (nonatomic, readonly) float z; + +- (NSComparisonResult)compare:(nonnull NCVector3d *)other; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCVenue.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCVenue.h new file mode 100644 index 0000000..41d6a16 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCVenue.h @@ -0,0 +1,29 @@ +#import "NCExport.h" +#import "NCPoint.h" +#import + + +NAVIGINE_EXPORT +@interface NCVenue : NSObject + +@property (nonatomic, nonnull, readonly) NCPoint * point; + +@property (nonatomic, readonly) int32_t locationId; + +@property (nonatomic, readonly) int32_t sublocationId; + +@property (nonatomic, readonly) int32_t id; + +@property (nonatomic, nonnull, readonly) NSString * name; + +@property (nonatomic, nonnull, readonly) NSString * phone; + +@property (nonatomic, nonnull, readonly) NSString * descript; + +@property (nonatomic, nonnull, readonly) NSString * alias; + +@property (nonatomic, readonly) int32_t categoryId; + +@property (nonatomic, nullable, readonly) NSString * imageId; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCWifi.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCWifi.h new file mode 100644 index 0000000..c8b64aa --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCWifi.h @@ -0,0 +1,19 @@ +#import "NCExport.h" +#import "NCPoint.h" +#import + + +NAVIGINE_EXPORT +@interface NCWifi : NSObject + +@property (nonatomic, nonnull, readonly) NCPoint * point; + +@property (nonatomic, readonly) int32_t locationId; + +@property (nonatomic, readonly) int32_t sublocationId; + +@property (nonatomic, nonnull, readonly) NSString * name; + +@property (nonatomic, nonnull, readonly) NSString * mac; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCZone.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCZone.h new file mode 100644 index 0000000..4e72a43 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCZone.h @@ -0,0 +1,23 @@ +#import "NCExport.h" +#import "NCPolygon.h" +#import + + +NAVIGINE_EXPORT +@interface NCZone : NSObject + +@property (nonatomic, nonnull, readonly) NCPolygon * polygon; + +@property (nonatomic, readonly) int32_t locationId; + +@property (nonatomic, readonly) int32_t sublocationId; + +@property (nonatomic, readonly) int32_t id; + +@property (nonatomic, nonnull, readonly) NSString * name; + +@property (nonatomic, nonnull, readonly) NSString * color; + +@property (nonatomic, nonnull, readonly) NSString * alias; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCZoneListener.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCZoneListener.h new file mode 100644 index 0000000..9703528 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCZoneListener.h @@ -0,0 +1,13 @@ +#import "NCExport.h" +#import +@class NCZone; + + +NAVIGINE_EXPORT +@protocol NCZoneListener + +- (void)onEnterZone:(nullable NCZone *)zone; + +- (void)onLeaveZone:(nullable NCZone *)zone; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCZoneManager.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCZoneManager.h new file mode 100644 index 0000000..df71fcd --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/NCZoneManager.h @@ -0,0 +1,13 @@ +#import "NCExport.h" +#import +@protocol NCZoneListener; + + +NAVIGINE_EXPORT +@interface NCZoneManager : NSObject + +- (void)addZoneListener:(nullable id)listener; + +- (void)removeZoneListener:(nullable id)listener; + +@end diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/navigine.h b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/navigine.h new file mode 100644 index 0000000..60c6e3d --- /dev/null +++ b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Headers/navigine.h @@ -0,0 +1,76 @@ +#import "NCLocationListListener.h" +#import "NCLine.h" +#import "NCNotificationManager.h" +#import "NCZoneListener.h" +#import "NCGlobalPoint.h" +#import "NCMeasurementListener.h" +#import "NCEddystone.h" +#import "NCSignalMeasurement.h" +#import "NCLocationEditManager.h" +#import "NCMeasurementManager.h" +#import "NCAsyncRouteManager.h" +#import "NCMapObjectType.h" +#import "NCSensorMeasurement.h" +#import "NCRouteManager.h" +#import "NCImageType.h" +#import "NCPolyline.h" +#import "NCNavigationManager.h" +#import "NCImage.h" +#import "NCPolygon.h" +#import "NCElevationGraph.h" +#import "NCSignalType.h" +#import "NCVenue.h" +#import "NCAnimationType.h" +#import "NCMultiLineMapObject.h" +#import "NCAsyncRouteListener.h" +#import "NCMapObjectData.h" +#import "NCRouteEvent.h" +#import "NCLocationPoint.h" +#import "NCPositionListener.h" +#import "NCLocationInfo.h" +#import "NCSegment.h" +#import "NCTextureMapObject.h" +#import "NCBitmapRegionDecoder.h" +#import "NCResourceUploadListener.h" +#import "NCPolylineMapObject.h" +#import "NCLocation.h" +#import "NCLocationListManager.h" +#import "NCGeometryUtils.h" +#import "NCPoint.h" +#import "NCLocationPolygon.h" +#import "NCVector3d.h" +#import "NCRoutePath.h" +#import "NCRouteListener.h" +#import "NCLocationListener.h" +#import "NCReferenceEntry.h" +#import "NCPosition.h" +#import "NCLocationEditListener.h" +#import "NCResourceManager.h" +#import "NCZoneManager.h" +#import "NCSublocation.h" +#import "NCLocationManager.h" +#import "NCNotificationListener.h" +#import "NCCircleMapObject.h" +#import "NCWifi.h" +#import "NCSensorType.h" +#import "NCZone.h" +#import "NCNotification.h" +#import "NCGraph.h" +#import "NCBeacon.h" +#import "NCReferencePoint.h" +#import "NCRouteEventType.h" +#import "NCRectangle.h" +#import "NCGraphVertex.h" +#import "NCResourceListener.h" +#import "NCRouteSession.h" +#import "NCIconMapObject.h" +#import "NCNavigineSdk.h" +#import "NCCategory.h" +#import "NCReferenceEntryType.h" +#import "NCGraphEdge.h" +#import "NCLocationPolyline.h" +#import "NCExport.h" +#import "NCLocationView.h" +#import "NCMapObjectPickResult.h" +#import "NCLocationViewDelegate.h" +#import "NCGestureRecognizerDelegate.h" diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Info.plist b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Info.plist new file mode 100644 index 0000000..97f77bd Binary files /dev/null and b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/Info.plist differ diff --git a/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/navigine b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/navigine new file mode 100755 index 0000000..e6b3648 Binary files /dev/null and b/NavigineDemo/NavigineDemo/Frameworks/navigine.framework/navigine differ diff --git a/NavigineDemo/NavigineDemo/Helpers/CircularLoaderView.swift b/NavigineDemo/NavigineDemo/Helpers/CircularLoaderView.swift new file mode 100755 index 0000000..3a9aef4 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Helpers/CircularLoaderView.swift @@ -0,0 +1,129 @@ +import UIKit + +class CircularLoaderView: UIView { + + let circleRadius: CGFloat = 14.0 + let loadCircleStrokeColor: UIColor = + UIColor(red: 0.129, green: 0.698, blue: 0.255, alpha: 1) + let backingCircleStrokeColor: UIColor = + UIColor(red: 0.818, green: 0.82, blue: 0.822, alpha: 1) + + + let percentLabel: UILabel = UILabel.init(frame: .zero) + let circlePathLayer = CAShapeLayer() + let circleBackingLayer = CAShapeLayer() + var progress: CGFloat { + get { + return circlePathLayer.strokeEnd + } + set { + if newValue > 1 { + circlePathLayer.strokeEnd = 1 + percentLabel.text = "100%" + } else if newValue < 0 { + circlePathLayer.strokeEnd = 0 + } else { + circlePathLayer.strokeEnd = newValue + percentLabel.text = String(Int(newValue * 100)) + "%" + } + } + } + + // MARK:- Initializers + override init(frame: CGRect) { + super.init(frame: frame) + configure() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + configure() + } + + override func layoutSubviews() { + super.layoutSubviews() + circlePathLayer.frame = bounds + circlePathLayer.path = circlePath().cgPath + + circleBackingLayer.frame = bounds + circleBackingLayer.path = circlePath().cgPath + + percentLabel.sizeToFit() + } + + override func updateConstraints() { + addConstraintsForPercentLabel() + super.updateConstraints() + } + + // MARK:- Setup + private func configure() { + progress = 0 + backgroundColor = .clear + setupBackingCircle() + setupLoadingCircle() + setupPercentLabel() + self.setNeedsUpdateConstraints() + } + + private func setupLoadingCircle() { + circlePathLayer.frame = bounds + circlePathLayer.lineWidth = 1.5 + circlePathLayer.fillColor = UIColor.clear.cgColor + circlePathLayer.strokeColor = loadCircleStrokeColor.cgColor + layer.addSublayer(circlePathLayer) + } + + private func setupBackingCircle() { + circleBackingLayer.frame = bounds + circleBackingLayer.lineWidth = 1.5 + circleBackingLayer.fillColor = UIColor.clear.cgColor + circleBackingLayer.strokeColor = backingCircleStrokeColor.cgColor + circleBackingLayer.strokeEnd = 1 + layer.addSublayer(circleBackingLayer) + } + + private func setupPercentLabel() { + // Setup percent label + percentLabel.font = UIFont(name: "Circe-Bold", size: 9) + percentLabel.textAlignment = .center + percentLabel.textColor = loadCircleStrokeColor + percentLabel.sizeToFit() + percentLabel.translatesAutoresizingMaskIntoConstraints = false + + addSubview(percentLabel) + } + + private func addConstraintsForPercentLabel() { + let constraints = [ + percentLabel.centerXAnchor.constraint(equalTo: centerXAnchor), + percentLabel.centerYAnchor.constraint(equalTo: centerYAnchor)] + NSLayoutConstraint.activate(constraints) + } + + private func circlePath() -> UIBezierPath { + let circlePathBounds = circlePathLayer.bounds + let arcCentre = + CGPoint.init(x: circlePathBounds.midX, + y: circlePathBounds.midY) + + return UIBezierPath(arcCenter: arcCentre, + radius: circleRadius, + startAngle: -.pi / 2, + endAngle: 3 * .pi / 2, + clockwise: true) + } +} + +// MARK:- Unused +extension CircularLoaderView { + func circleFrame() -> CGRect { + var circleFrame = + CGRect(x: 0, y: 0, width: 2 * circleRadius, height: 2 * circleRadius) + let circlePathBounds = circlePathLayer.bounds + circleFrame.origin.x = circlePathBounds.midX - circleFrame.midX + circleFrame.origin.y = circlePathBounds.midY - circleFrame.midY + + return circleFrame + } +} diff --git a/NavigineDemo/NavigineDemo/Helpers/LocationItemCell.swift b/NavigineDemo/NavigineDemo/Helpers/LocationItemCell.swift new file mode 100755 index 0000000..3e86897 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Helpers/LocationItemCell.swift @@ -0,0 +1,14 @@ +import Foundation +import UIKit + +class LocationItemCell: UITableViewCell { + + @IBOutlet weak var nameView: UILabel! + @IBOutlet weak var versionView: UILabel! + @IBOutlet weak var progressBar: CircularLoaderView! + + override func prepareForReuse() { + super.prepareForReuse() + self.progressBar.isHidden = false + } +} diff --git a/NavigineDemo/NavigineDemo/Helpers/LogsItemCell.swift b/NavigineDemo/NavigineDemo/Helpers/LogsItemCell.swift new file mode 100755 index 0000000..a2db7c1 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Helpers/LogsItemCell.swift @@ -0,0 +1,12 @@ +import Foundation +import UIKit + +class LogsItemCell: UITableViewCell { + + + @IBOutlet weak var mLogName: UILabel! + + override func prepareForReuse() { + super.prepareForReuse() + } +} diff --git a/NavigineDemo/NavigineDemo/Helpers/MyCollectionViewCell.swift b/NavigineDemo/NavigineDemo/Helpers/MyCollectionViewCell.swift new file mode 100755 index 0000000..400ebbc --- /dev/null +++ b/NavigineDemo/NavigineDemo/Helpers/MyCollectionViewCell.swift @@ -0,0 +1,4 @@ +import UIKit +class MyCollectionViewCell: UICollectionViewCell { + @IBOutlet weak var mLabel: UILabel! +} diff --git a/NavigineDemo/NavigineDemo/Helpers/NavigineApp.swift b/NavigineDemo/NavigineDemo/Helpers/NavigineApp.swift new file mode 100755 index 0000000..b9570f3 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Helpers/NavigineApp.swift @@ -0,0 +1,27 @@ +import Foundation + +class NavigineApp { + static var mNavigineSdk: NCNavigineSdk? + static var mLocationListManager: NCLocationListManager? + static var mLocationManager: NCLocationManager? + static var mNavigationManager: NCNavigationManager? + static var mZoneManager: NCZoneManager? + static var mResourceManager: NCResourceManager? + static var mMeasurementManager: NCMeasurementManager? + static var mInspectManager: NCLocationEditManager? + static var mRouteManager: NCRouteManager? + + static func initWith(userHash: String, serverUrl: String) { + NCNavigineSdk.setServer(serverUrl) + NCNavigineSdk.setUserHash(userHash) + mNavigineSdk = NCNavigineSdk.getInstance() + mLocationListManager = mNavigineSdk?.getLocationListManager() + mLocationManager = mNavigineSdk?.getLocationManager() + mNavigationManager = mNavigineSdk?.getNavigationManager(mLocationManager) + mResourceManager = mNavigineSdk?.getResourceManager(mLocationManager) + mMeasurementManager = mNavigineSdk?.getMeasurementManager() + mInspectManager = mNavigineSdk?.getLocationEdit(mLocationManager) + mRouteManager = mNavigineSdk?.getRouteManager(mLocationManager, navigationManager: mNavigationManager) + mZoneManager = mNavigineSdk?.getZoneManager(mLocationManager, navigationManager: mNavigationManager) + } +} diff --git a/NavigineDemo/NavigineDemo/Helpers/ProgressBar.swift b/NavigineDemo/NavigineDemo/Helpers/ProgressBar.swift new file mode 100755 index 0000000..53c451d --- /dev/null +++ b/NavigineDemo/NavigineDemo/Helpers/ProgressBar.swift @@ -0,0 +1,26 @@ +import Foundation +import SwiftUI + +@available(iOS 13.0, *) +struct ProgressBar: View { + @Binding var progress: Float + + var body: some View { + ZStack { + Circle() + .stroke(lineWidth: 20.0) + .opacity(0.3) + .foregroundColor(Color.red) + + Circle() + .trim(from: 0.0, to: CGFloat(min(self.progress, 1.0))) + .stroke(style: StrokeStyle(lineWidth: 20.0, lineCap: .round, lineJoin: .round)) + .foregroundColor(Color.red) + .rotationEffect(Angle(degrees: 270.0)) + .animation(.linear) + Text(String(format: "%.0f %%", min(self.progress, 1.0)*100.0)) + .font(.largeTitle) + .bold() + } + } +} diff --git a/NavigineDemo/NavigineDemo/Helpers/VenueDetailsViewController.swift b/NavigineDemo/NavigineDemo/Helpers/VenueDetailsViewController.swift new file mode 100755 index 0000000..08132e8 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Helpers/VenueDetailsViewController.swift @@ -0,0 +1,76 @@ +import UIKit + +class VenueDetailsViewController: UIViewController { + public var didDismiss: ((VenueDetailsViewController) -> Void)? + + @IBOutlet weak var mVenueTitle: UILabel! + @IBOutlet weak var mVenueContent: UILabel! + @IBOutlet weak var mVenueImage: UIImageView! + @IBOutlet weak var mBottomConstraint: NSLayoutConstraint! + + private var mVenue = NCVenue() + + override func viewDidLoad() { + super.viewDidLoad() + + mVenueTitle.text = mVenue.name + mVenueContent.text = mVenue.descript + + mVenueImage.alpha = 0.0 + mBottomConstraint.constant = 224 + } + + static func instantiate() -> VenueDetailsViewController { + return UIStoryboard(name: "Navigation", bundle: nil).instantiateViewController(withIdentifier: "VenueDetailsVC") as! VenueDetailsViewController + } + + func setVenueMapObject(venue: NCVenue) { + mVenue = venue; + } + + func setPosition(position: FloatingPanelPosition) { + DispatchQueue.main.async { + UIView.animate(withDuration: 0.3, animations: { + switch position { + case .full: + self.mVenueImage.alpha = 1.0 + self.mBottomConstraint.constant = 40 + break + default: + self.mVenueImage.alpha = 0.0 + self.mBottomConstraint.constant = 224 + } + }) + } + } + + @IBAction func closeButtonAction(_ sender: Any) { + didDismiss!(self) + } +} + +extension VenueDetailsViewController { + /** + - Attention: `FloatingPanelLayout` must not be applied by the parent view + controller of a floating panel. But here `SampleListViewController` adopts it + purposely to check if the library prints an appropriate warning. + */ + + class VenueDetailsSheetLayout: FloatingPanelLayout { + var supportedPositions: Set { + return [.full, .half] + } + + public var initialPosition: FloatingPanelPosition { + return .half + } + + public func insetFor(position: FloatingPanelPosition) -> CGFloat? { + switch position { + case .full: return 18.0 + case .half: return 243.0 + default: return nil + } + } + } +} diff --git a/NavigineDemo/NavigineDemo/Info.plist b/NavigineDemo/NavigineDemo/Info.plist old mode 100644 new mode 100755 index 3d41f79..3f430f8 --- a/NavigineDemo/NavigineDemo/Info.plist +++ b/NavigineDemo/NavigineDemo/Info.plist @@ -21,15 +21,23 @@ LSRequiresIPhoneOS NSBluetoothAlwaysUsageDescription - 5 + 4 NSBluetoothPeripheralUsageDescription - 1 + 4 NSLocationAlwaysAndWhenInUseUsageDescription 2 NSLocationWhenInUseUsageDescription 3 NSMotionUsageDescription - 4 + 1 + UIAppFonts + + Circe-ExtraLight.ttf + Circe-ExtraBold.ttf + Circe-Bold.ttf + Circe-Thin.ttf + Circe-Regular.ttf + UIApplicationSceneManifest UIApplicationSupportsMultipleScenes @@ -50,7 +58,7 @@ UILaunchStoryboardName - Main + LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities @@ -60,8 +68,6 @@ UISupportedInterfaceOrientations UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad diff --git a/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanel.h b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanel.h new file mode 100755 index 0000000..bf3dd58 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanel.h @@ -0,0 +1,9 @@ +// +// Created by Shin Yamamoto on 2018/09/18. +// Copyright © 2018 Shin Yamamoto. All rights reserved. +// + +#import + +FOUNDATION_EXPORT double FloatingPanelVersionNumber; +FOUNDATION_EXPORT const unsigned char FloatingPanelVersionString[]; diff --git a/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelBackdropView.swift b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelBackdropView.swift new file mode 100755 index 0000000..7d0ef3c --- /dev/null +++ b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelBackdropView.swift @@ -0,0 +1,11 @@ +// +// Created by Shin Yamamoto on 2018/09/26. +// Copyright © 2018 Shin Yamamoto. All rights reserved. +// + +import UIKit + +/// A view that presents a backdrop interface behind a floating panel. +public class FloatingPanelBackdropView: UIView { + public var dismissalTapGestureRecognizer: UITapGestureRecognizer! +} diff --git a/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelBehavior.swift b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelBehavior.swift new file mode 100755 index 0000000..ee709d1 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelBehavior.swift @@ -0,0 +1,156 @@ +// +// Created by Shin Yamamoto on 2018/10/03. +// Copyright © 2018 Shin Yamamoto. All rights reserved. +// + +import UIKit + +public protocol FloatingPanelBehavior { + /// Asks the behavior if the floating panel should project a momentum of a user interaction to move the proposed position. + /// + /// The default implementation of this method returns true. This method is called for a layout to support all positions(tip, half and full). + /// Therefore, `proposedTargetPosition` can only be `FloatingPanelPosition.tip` or `FloatingPanelPosition.full`. + func shouldProjectMomentum(_ fpc: FloatingPanelController, for proposedTargetPosition: FloatingPanelPosition) -> Bool + + /// Returns a deceleration rate to calculate a target position projected a dragging momentum. + /// + /// The default implementation of this method returns the normal deceleration rate of UIScrollView. + func momentumProjectionRate(_ fpc: FloatingPanelController) -> CGFloat + + /// Returns the progress to redirect to the previous position. + /// + /// The progress is represented by a floating-point value between 0.0 and 1.0, inclusive, where 1.0 indicates the floating panel is impossible to move to the next position. The default value is 0.5. Values less than 0.0 and greater than 1.0 are pinned to those limits. + func redirectionalProgress(_ fpc: FloatingPanelController, from: FloatingPanelPosition, to: FloatingPanelPosition) -> CGFloat + + /// Returns a UIViewPropertyAnimator object to project a floating panel to a position on finger up if the user dragged. + /// + /// - Attention: + /// By default, it returns a non-interruptible animator to prevent a propagation of the animation to a content view. + /// However returning an interruptible animator is working well depending on a content view and it can be better + /// than using a non-interruptible one. + func interactionAnimator(_ fpc: FloatingPanelController, to targetPosition: FloatingPanelPosition, with velocity: CGVector) -> UIViewPropertyAnimator + + /// Returns a UIViewPropertyAnimator object to add a floating panel to a position. + /// + /// Its animator instance will be used to animate the surface view in `FloatingPanelController.addPanel(toParent:belowView:animated:)`. + /// Default is an animator with ease-in-out curve and 0.25 sec duration. + func addAnimator(_ fpc: FloatingPanelController, to: FloatingPanelPosition) -> UIViewPropertyAnimator + + /// Returns a UIViewPropertyAnimator object to remove a floating panel from a position. + /// + /// Its animator instance will be used to animate the surface view in `FloatingPanelController.removePanelFromParent(animated:completion:)`. + /// Default is an animator with ease-in-out curve and 0.25 sec duration. + func removeAnimator(_ fpc: FloatingPanelController, from: FloatingPanelPosition) -> UIViewPropertyAnimator + + /// Returns a UIViewPropertyAnimator object to move a floating panel from a position to a position. + /// + /// Its animator instance will be used to animate the surface view in `FloatingPanelController.move(to:animated:completion:)`. + /// Default is an animator with ease-in-out curve and 0.25 sec duration. + func moveAnimator(_ fpc: FloatingPanelController, from: FloatingPanelPosition, to: FloatingPanelPosition) -> UIViewPropertyAnimator + + /// Returns a y-axis velocity to invoke a removal interaction at the bottom position. + /// + /// Default is 10.0. This method is called when FloatingPanelController.isRemovalInteractionEnabled is true. + var removalVelocity: CGFloat { get } + + /// Returns the threshold of the transition to invoke a removal interaction at the bottom position. + /// + /// The progress is represented by a floating-point value between 0.0 and 1.0, inclusive, where 1.0 indicates the floating panel is impossible to invoke the removal interaction. The default value is 0.5. Values less than 0.0 and greater than 1.0 are pinned to those limits. This method is called when FloatingPanelController.isRemovalInteractionEnabled is true. + var removalProgress: CGFloat { get } + + /// Returns a UIViewPropertyAnimator object to remove a floating panel with a velocity interactively at the bottom position. + /// + /// Default is a spring animator with 1.0 damping ratio. This method is called when FloatingPanelController.isRemovalInteractionEnabled is true. + func removalInteractionAnimator(_ fpc: FloatingPanelController, with velocity: CGVector) -> UIViewPropertyAnimator + + + /// Asks the behavior whether the rubber band effect is enabled in moving over a given edge of the surface view. + /// + /// This method allows the behavior to activate the rubber band effect to a given edge of the surface view. By default, the effect is disabled. + func allowsRubberBanding(for edge: UIRectEdge) -> Bool +} + +public extension FloatingPanelBehavior { + func shouldProjectMomentum(_ fpc: FloatingPanelController, for proposedTargetPosition: FloatingPanelPosition) -> Bool { + return false + } + + func momentumProjectionRate(_ fpc: FloatingPanelController) -> CGFloat { + #if swift(>=4.2) + return UIScrollView.DecelerationRate.normal.rawValue + #else + return UIScrollViewDecelerationRateNormal + #endif + } + + func redirectionalProgress(_ fpc: FloatingPanelController, from: FloatingPanelPosition, to: FloatingPanelPosition) -> CGFloat { + return 0.5 + } + + func interactionAnimator(_ fpc: FloatingPanelController, to targetPosition: FloatingPanelPosition, with velocity: CGVector) -> UIViewPropertyAnimator { + return defaultBehavior.interactionAnimator(fpc, to: targetPosition, with: velocity) + } + + func addAnimator(_ fpc: FloatingPanelController, to: FloatingPanelPosition) -> UIViewPropertyAnimator { + return UIViewPropertyAnimator(duration: 0.25, curve: .easeInOut) + } + + func removeAnimator(_ fpc: FloatingPanelController, from: FloatingPanelPosition) -> UIViewPropertyAnimator { + return UIViewPropertyAnimator(duration: 0.25, curve: .easeInOut) + } + + func moveAnimator(_ fpc: FloatingPanelController, from: FloatingPanelPosition, to: FloatingPanelPosition) -> UIViewPropertyAnimator { + return UIViewPropertyAnimator(duration: 0.25, curve: .easeInOut) + } + + var removalVelocity: CGFloat { + return 10.0 + } + + var removalProgress: CGFloat { + return 0.5 + } + + func removalInteractionAnimator(_ fpc: FloatingPanelController, with velocity: CGVector) -> UIViewPropertyAnimator { + log.debug("velocity", velocity) + let timing = UISpringTimingParameters(dampingRatio: 1.0, + frequencyResponse: 0.3, + initialVelocity: velocity) + return UIViewPropertyAnimator(duration: 0, timingParameters: timing) + } + + func allowsRubberBanding(for edge: UIRectEdge) -> Bool { + return false + } +} + +private let defaultBehavior = FloatingPanelDefaultBehavior() + +public class FloatingPanelDefaultBehavior: FloatingPanelBehavior { + public init() { } + + public func interactionAnimator(_ fpc: FloatingPanelController, to targetPosition: FloatingPanelPosition, with velocity: CGVector) -> UIViewPropertyAnimator { + let timing = timeingCurve(with: velocity) + let animator = UIViewPropertyAnimator(duration: 0, timingParameters: timing) + animator.isInterruptible = false // Prevent a propagation of the animation(spring etc) to a content view + return animator + } + + private func timeingCurve(with velocity: CGVector) -> UITimingCurveProvider { + log.debug("velocity", velocity) + let damping = self.getDamping(with: velocity) + return UISpringTimingParameters(dampingRatio: damping, + frequencyResponse: 0.3, + initialVelocity: velocity) + } + + private let velocityThreshold: CGFloat = 8.0 + private func getDamping(with velocity: CGVector) -> CGFloat { + let dy = abs(velocity.dy) + if dy > velocityThreshold { + return 0.7 + } else { + return 1.0 + } + } +} diff --git a/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelController.swift b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelController.swift new file mode 100755 index 0000000..ff6fef5 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelController.swift @@ -0,0 +1,685 @@ +// +// Created by Shin Yamamoto on 2018/09/18. +// Copyright © 2018 Shin Yamamoto. All rights reserved. +// + +import UIKit + +public protocol FloatingPanelControllerDelegate: class { + // if it returns nil, FloatingPanelController uses the default layout + func floatingPanel(_ vc: FloatingPanelController, layoutFor newCollection: UITraitCollection) -> FloatingPanelLayout? + + // if it returns nil, FloatingPanelController uses the default behavior + func floatingPanel(_ vc: FloatingPanelController, behaviorFor newCollection: UITraitCollection) -> FloatingPanelBehavior? + + /// Called when the floating panel has changed to a new position. Can be called inside an animation block, so any + /// view properties set inside this function will be automatically animated alongside the panel. + func floatingPanelDidChangePosition(_ vc: FloatingPanelController) + + /// Asks the delegate if dragging should begin by the pan gesture recognizer. + func floatingPanelShouldBeginDragging(_ vc: FloatingPanelController) -> Bool + + func floatingPanelDidMove(_ vc: FloatingPanelController) // any surface frame changes in dragging + + // called on start of dragging (may require some time and or distance to move) + func floatingPanelWillBeginDragging(_ vc: FloatingPanelController) + // called on finger up if the user dragged. velocity is in points/second. + func floatingPanelDidEndDragging(_ vc: FloatingPanelController, withVelocity velocity: CGPoint, targetPosition: FloatingPanelPosition) + func floatingPanelWillBeginDecelerating(_ vc: FloatingPanelController) // called on finger up as we are moving + func floatingPanelDidEndDecelerating(_ vc: FloatingPanelController) // called when scroll view grinds to a halt + + // called on start of dragging to remove its views from a parent view controller + func floatingPanelDidEndDraggingToRemove(_ vc: FloatingPanelController, withVelocity velocity: CGPoint) + // called when its views are removed from a parent view controller + func floatingPanelDidEndRemove(_ vc: FloatingPanelController) + + /// Asks the delegate if the other gesture recognizer should be allowed to recognize the gesture in parallel. + /// + /// By default, any tap and long gesture recognizers are allowed to recognize gestures simultaneously. + func floatingPanel(_ vc: FloatingPanelController, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool + + /// Asks the delegate for a content offset of the tracked scroll view to be pinned when a floating panel moves + /// + /// If you do not implement this method, the controller uses a value of the content offset plus the content insets + /// of the tracked scroll view. Your implementation of this method can return a value for a navigation bar with a large + /// title, for example. + /// + /// This method will not be called if the controller doesn't track any scroll view. + func floatingPanel(_ vc: FloatingPanelController, contentOffsetForPinning trackedScrollView: UIScrollView) -> CGPoint +} + +public extension FloatingPanelControllerDelegate { + func floatingPanel(_ vc: FloatingPanelController, layoutFor newCollection: UITraitCollection) -> FloatingPanelLayout? { + return nil + } + func floatingPanel(_ vc: FloatingPanelController, behaviorFor newCollection: UITraitCollection) -> FloatingPanelBehavior? { + return nil + } + func floatingPanelDidChangePosition(_ vc: FloatingPanelController) {} + func floatingPanelShouldBeginDragging(_ vc: FloatingPanelController) -> Bool { + return true + } + func floatingPanelDidMove(_ vc: FloatingPanelController) {} + func floatingPanelWillBeginDragging(_ vc: FloatingPanelController) {} + func floatingPanelDidEndDragging(_ vc: FloatingPanelController, withVelocity velocity: CGPoint, targetPosition: FloatingPanelPosition) {} + func floatingPanelWillBeginDecelerating(_ vc: FloatingPanelController) {} + func floatingPanelDidEndDecelerating(_ vc: FloatingPanelController) {} + + func floatingPanelDidEndDraggingToRemove(_ vc: FloatingPanelController, withVelocity velocity: CGPoint) {} + func floatingPanelDidEndRemove(_ vc: FloatingPanelController) {} + + func floatingPanel(_ vc: FloatingPanelController, shouldRecognizeSimultaneouslyWith gestureRecognizer: UIGestureRecognizer) -> Bool { + return false + } + func floatingPanel(_ vc: FloatingPanelController, contentOffsetForPinning trackedScrollView: UIScrollView) -> CGPoint { + return CGPoint(x: 0.0, y: 0.0 - trackedScrollView.contentInset.top) + } +} + + +public enum FloatingPanelPosition: Int { + case full + case half + case tip + case hidden + + static var allCases: [FloatingPanelPosition] { + return [.full, .half, .tip, .hidden] + } + + func next(in positions: [FloatingPanelPosition]) -> FloatingPanelPosition { + #if swift(>=4.2) + guard + let index = positions.firstIndex(of: self), + positions.indices.contains(index + 1) + else { return self } + #else + guard + let index = positions.index(of: self), + positions.indices.contains(index + 1) + else { return self } + #endif + return positions[index + 1] + } + + func pre(in positions: [FloatingPanelPosition]) -> FloatingPanelPosition { + #if swift(>=4.2) + guard + let index = positions.firstIndex(of: self), + positions.indices.contains(index - 1) + else { return self } + #else + guard + let index = positions.index(of: self), + positions.indices.contains(index - 1) + else { return self } + #endif + return positions[index - 1] + } +} + +/// +/// A container view controller to display a floating panel to present contents in parallel as a user wants. +/// +open class FloatingPanelController: UIViewController { + /// Constants indicating how safe area insets are added to the adjusted content inset. + public enum ContentInsetAdjustmentBehavior: Int { + case always + case never + } + + /// A flag used to determine how the controller object lays out the content view when the surface position changes. + public enum ContentMode: Int { + /// The option to fix the content to keep the height of the top most position. + case `static` + /// The option to scale the content to fit the bounds of the root view by changing the surface position. + case fitToBounds + } + + /// The delegate of the floating panel controller object. + public weak var delegate: FloatingPanelControllerDelegate?{ + didSet{ + didUpdateDelegate() + } + } + + /// Returns the surface view managed by the controller object. It's the same as `self.view`. + public var surfaceView: FloatingPanelSurfaceView! { + return floatingPanel.surfaceView + } + + /// Returns the backdrop view managed by the controller object. + public var backdropView: FloatingPanelBackdropView! { + return floatingPanel.backdropView + } + + /// Returns the scroll view that the controller tracks. + public weak var scrollView: UIScrollView? { + return floatingPanel.scrollView + } + + // The underlying gesture recognizer for pan gestures + public var panGestureRecognizer: UIPanGestureRecognizer { + return floatingPanel.panGestureRecognizer + } + + /// The current position of the floating panel controller's contents. + public var position: FloatingPanelPosition { + return floatingPanel.state + } + + /// The layout object managed by the controller + public var layout: FloatingPanelLayout { + return floatingPanel.layoutAdapter.layout + } + + /// The behavior object managed by the controller + public var behavior: FloatingPanelBehavior { + return floatingPanel.behavior + } + + /// The content insets of the tracking scroll view derived from this safe area + public var adjustedContentInsets: UIEdgeInsets { + return floatingPanel.layoutAdapter.adjustedContentInsets + } + + /// The behavior for determining the adjusted content offsets. + /// + /// This property specifies how the content area of the tracking scroll view is modified using `adjustedContentInsets`. The default value of this property is FloatingPanelController.ContentInsetAdjustmentBehavior.always. + public var contentInsetAdjustmentBehavior: ContentInsetAdjustmentBehavior = .always + + /// A Boolean value that determines whether the removal interaction is enabled. + public var isRemovalInteractionEnabled: Bool { + set { floatingPanel.isRemovalInteractionEnabled = newValue } + get { return floatingPanel.isRemovalInteractionEnabled } + } + + /// The view controller responsible for the content portion of the floating panel. + public var contentViewController: UIViewController? { + set { set(contentViewController: newValue) } + get { return _contentViewController } + } + + /// The NearbyPosition determines that finger's nearby position. + public var nearbyPosition: FloatingPanelPosition { + let currentY = surfaceView.frame.minY + return floatingPanel.targetPosition(from: currentY, with: .zero) + } + + public var contentMode: ContentMode = .static { + didSet { + guard position != .hidden else { return } + activateLayout() + } + } + + private var _contentViewController: UIViewController? + + private(set) var floatingPanel: FloatingPanelCore! + private var preSafeAreaInsets: UIEdgeInsets = .zero // Capture the latest one + private var safeAreaInsetsObservation: NSKeyValueObservation? + private let modalTransition = FloatingPanelModalTransition() + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setUp() + } + + /// Initialize a newly created floating panel controller. + public init(delegate: FloatingPanelControllerDelegate? = nil) { + super.init(nibName: nil, bundle: nil) + self.delegate = delegate + setUp() + } + + private func setUp() { + _ = FloatingPanelController.dismissSwizzling + + modalPresentationStyle = .custom + transitioningDelegate = modalTransition + + floatingPanel = FloatingPanelCore(self, + layout: fetchLayout(for: self.traitCollection), + behavior: fetchBehavior(for: self.traitCollection)) + } + + private func didUpdateDelegate(){ + floatingPanel.layoutAdapter.layout = fetchLayout(for: traitCollection) + floatingPanel.behavior = fetchBehavior(for: self.traitCollection) + } + + // MARK:- Overrides + + /// Creates the view that the controller manages. + open override func loadView() { + assert(self.storyboard == nil, "Storyboard isn't supported") + + let view = FloatingPanelPassThroughView() + view.backgroundColor = .clear + + backdropView.frame = view.bounds + view.addSubview(backdropView) + + surfaceView.frame = view.bounds + view.addSubview(surfaceView) + + self.view = view as UIView + } + + open override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + if #available(iOS 11.0, *) {} + else { + // Because {top,bottom}LayoutGuide is managed as a view + if preSafeAreaInsets != layoutInsets, + floatingPanel.isDecelerating == false { + self.update(safeAreaInsets: layoutInsets) + } + } + } + + open override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransition(to: size, with: coordinator) + + if view.translatesAutoresizingMaskIntoConstraints { + view.frame.size = size + view.layoutIfNeeded() + } + } + + open override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) { + super.willTransition(to: newCollection, with: coordinator) + self.prepare(for: newCollection) + } + + open override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + safeAreaInsetsObservation = nil + } + + // MARK:- Child view controller to consult + #if swift(>=4.2) + open override var childForStatusBarStyle: UIViewController? { + return contentViewController + } + + open override var childForStatusBarHidden: UIViewController? { + return contentViewController + } + + open override var childForScreenEdgesDeferringSystemGestures: UIViewController? { + return contentViewController + } + + open override var childForHomeIndicatorAutoHidden: UIViewController? { + return contentViewController + } + #else + open override var childViewControllerForStatusBarStyle: UIViewController? { + return contentViewController + } + + open override var childViewControllerForStatusBarHidden: UIViewController? { + return contentViewController + } + + open override func childViewControllerForScreenEdgesDeferringSystemGestures() -> UIViewController? { + return contentViewController + } + + open override func childViewControllerForHomeIndicatorAutoHidden() -> UIViewController? { + return contentViewController + } + #endif + + // MARK:- Internals + func prepare(for newCollection: UITraitCollection) { + guard newCollection.shouldUpdateLayout(from: traitCollection) else { return } + // Change a layout & behavior for a new trait collection + reloadLayout(for: newCollection) + activateLayout() + floatingPanel.behavior = fetchBehavior(for: newCollection) + } + + // MARK:- Privates + + private func fetchLayout(for traitCollection: UITraitCollection) -> FloatingPanelLayout { + switch traitCollection.verticalSizeClass { + case .compact: + return self.delegate?.floatingPanel(self, layoutFor: traitCollection) ?? FloatingPanelDefaultLandscapeLayout() + default: + return self.delegate?.floatingPanel(self, layoutFor: traitCollection) ?? FloatingPanelDefaultLayout() + } + } + + private func fetchBehavior(for traitCollection: UITraitCollection) -> FloatingPanelBehavior { + return self.delegate?.floatingPanel(self, behaviorFor: traitCollection) ?? FloatingPanelDefaultBehavior() + } + + private func update(safeAreaInsets: UIEdgeInsets) { + guard + preSafeAreaInsets != safeAreaInsets + else { return } + + log.debug("Update safeAreaInsets", safeAreaInsets) + + // Prevent an infinite loop on iOS 10: setUpLayout() -> viewDidLayoutSubviews() -> setUpLayout() + preSafeAreaInsets = safeAreaInsets + + activateLayout() + + switch contentInsetAdjustmentBehavior { + case .always: + scrollView?.contentInset = adjustedContentInsets + default: + break + } + } + + private func reloadLayout(for traitCollection: UITraitCollection) { + floatingPanel.layoutAdapter.layout = fetchLayout(for: traitCollection) + + if let parent = self.parent { + if let layout = layout as? UIViewController, layout == parent { + log.warning("A memory leak will occur by a retain cycle because \(self) owns the parent view controller(\(parent)) as the layout object. Don't let the parent adopt FloatingPanelLayout.") + } + if let behavior = behavior as? UIViewController, behavior == parent { + log.warning("A memory leak will occur by a retain cycle because \(self) owns the parent view controller(\(parent)) as the behavior object. Don't let the parent adopt FloatingPanelBehavior.") + } + } + } + + private func activateLayout() { + floatingPanel.layoutAdapter.prepareLayout(in: self) + + // preserve the current content offset if contentInsetAdjustmentBehavior is `.always` + var contentOffset: CGPoint? + if contentInsetAdjustmentBehavior == .always { + contentOffset = scrollView?.contentOffset + } + + floatingPanel.layoutAdapter.updateHeight() + floatingPanel.layoutAdapter.activateLayout(of: floatingPanel.state) + + if let contentOffset = contentOffset { + scrollView?.contentOffset = contentOffset + } + } + + // MARK: - Container view controller interface + + /// Shows the surface view at the initial position defined by the current layout + public func show(animated: Bool = false, completion: (() -> Void)? = nil) { + // Must apply the current layout here + reloadLayout(for: traitCollection) + activateLayout() + + if #available(iOS 11.0, *) { + // Must track the safeAreaInsets of `self.view` to update the layout. + // There are 2 reasons. + // 1. This or the parent VC doesn't call viewSafeAreaInsetsDidChange() on the bottom + // inset's update expectedly. + // 2. The safe area top inset can be variable on the large title navigation bar(iOS11+). + // That's why it needs the observation to keep `adjustedContentInsets` correct. + safeAreaInsetsObservation = self.view.observe(\.safeAreaInsets, options: [.initial, .new, .old]) { [weak self] (_, change) in + // Use `self.view.safeAreaInsets` becauese `change.newValue` can be nil in particular case when + // is reported in https://github.com/SCENEE/FloatingPanel/issues/330 + guard let `self` = self, change.oldValue != self.view.safeAreaInsets else { return } + self.update(safeAreaInsets: self.view.safeAreaInsets) + } + } else { + // KVOs for topLayoutGuide & bottomLayoutGuide are not effective. + // Instead, update(safeAreaInsets:) is called at `viewDidLayoutSubviews()` + } + + move(to: floatingPanel.layoutAdapter.layout.initialPosition, + animated: animated, + completion: completion) + } + + /// Hides the surface view to the hidden position + public func hide(animated: Bool = false, completion: (() -> Void)? = nil) { + move(to: .hidden, + animated: animated, + completion: completion) + } + + /// Adds the view managed by the controller as a child of the specified view controller. + /// - Parameters: + /// - parent: A parent view controller object that displays FloatingPanelController's view. A container view controller object isn't applicable. + /// - belowView: Insert the surface view managed by the controller below the specified view. By default, the surface view will be added to the end of the parent list of subviews. + /// - animated: Pass true to animate the presentation; otherwise, pass false. + public func addPanel(toParent parent: UIViewController, belowView: UIView? = nil, animated: Bool = false) { + guard self.parent == nil else { + log.warning("Already added to a parent(\(parent))") + return + } + precondition((parent is UINavigationController) == false, "UINavigationController displays only one child view controller at a time.") + precondition((parent is UITabBarController) == false, "UITabBarController displays child view controllers with a radio-style selection interface") + precondition((parent is UISplitViewController) == false, "UISplitViewController manages two child view controllers in a master-detail interface") + precondition((parent is UITableViewController) == false, "UITableViewController should not be the parent because the view is a table view so that a floating panel doens't work well") + precondition((parent is UICollectionViewController) == false, "UICollectionViewController should not be the parent because the view is a collection view so that a floating panel doens't work well") + + if let belowView = belowView { + parent.view.insertSubview(self.view, belowSubview: belowView) + } else { + parent.view.addSubview(self.view) + } + + #if swift(>=4.2) + parent.addChild(self) + #else + parent.addChildViewController(self) + #endif + + view.frame = parent.view.bounds // Needed for a correct safe area configuration + view.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + self.view.topAnchor.constraint(equalTo: parent.view.topAnchor, constant: 0.0), + self.view.leftAnchor.constraint(equalTo: parent.view.leftAnchor, constant: 0.0), + self.view.rightAnchor.constraint(equalTo: parent.view.rightAnchor, constant: 0.0), + self.view.bottomAnchor.constraint(equalTo: parent.view.bottomAnchor, constant: 0.0), + ]) + + show(animated: animated) { [weak self] in + guard let `self` = self else { return } + #if swift(>=4.2) + self.didMove(toParent: parent) + #else + self.didMove(toParentViewController: parent) + #endif + } + } + + /// Removes the controller and the managed view from its parent view controller + /// - Parameters: + /// - animated: Pass true to animate the presentation; otherwise, pass false. + /// - completion: The block to execute after the view controller is dismissed. This block has no return value and takes no parameters. You may specify nil for this parameter. + public func removePanelFromParent(animated: Bool, completion: (() -> Void)? = nil) { + guard self.parent != nil else { + completion?() + return + } + + hide(animated: animated) { [weak self] in + guard let `self` = self else { return } + #if swift(>=4.2) + self.willMove(toParent: nil) + #else + self.willMove(toParentViewController: nil) + #endif + + self.view.removeFromSuperview() + + #if swift(>=4.2) + self.removeFromParent() + #else + self.removeFromParentViewController() + #endif + + completion?() + } + } + + /// Moves the position to the specified position. + /// - Parameters: + /// - to: Pass a FloatingPanelPosition value to move the surface view to the position. + /// - animated: Pass true to animate the presentation; otherwise, pass false. + /// - completion: The block to execute after the view controller has finished moving. This block has no return value and takes no parameters. You may specify nil for this parameter. + public func move(to: FloatingPanelPosition, animated: Bool, completion: (() -> Void)? = nil) { + precondition(floatingPanel.layoutAdapter.vc != nil, "Use show(animated:completion)") + floatingPanel.move(to: to, animated: animated, completion: completion) + } + + /// Sets the view controller responsible for the content portion of the floating panel. + public func set(contentViewController: UIViewController?) { + if let vc = _contentViewController { + #if swift(>=4.2) + vc.willMove(toParent: nil) + #else + vc.willMove(toParentViewController: nil) + #endif + + vc.view.removeFromSuperview() + + #if swift(>=4.2) + vc.removeFromParent() + #else + vc.removeFromParentViewController() + #endif + } + + if let vc = contentViewController { + #if swift(>=4.2) + addChild(vc) + #else + addChildViewController(vc) + #endif + + let surfaceView = floatingPanel.surfaceView + surfaceView.add(contentView: vc.view) + + #if swift(>=4.2) + vc.didMove(toParent: self) + #else + vc.didMove(toParentViewController: self) + #endif + } + + _contentViewController = contentViewController + } + + @available(*, unavailable, renamed: "set(contentViewController:)") + open override func show(_ vc: UIViewController, sender: Any?) { + if let target = self.parent?.targetViewController(forAction: #selector(UIViewController.show(_:sender:)), sender: sender) { + target.show(vc, sender: sender) + } + } + + @available(*, unavailable, renamed: "set(contentViewController:)") + open override func showDetailViewController(_ vc: UIViewController, sender: Any?) { + if let target = self.parent?.targetViewController(forAction: #selector(UIViewController.showDetailViewController(_:sender:)), sender: sender) { + target.showDetailViewController(vc, sender: sender) + } + } + + // MARK: - Scroll view tracking + + /// Tracks the specified scroll view to correspond with the scroll. + /// + /// - Parameters: + /// - scrollView: Specify a scroll view to continuously and seamlessly work in concert with interactions of the surface view or nil to cancel it. + public func track(scrollView: UIScrollView?) { + guard let scrollView = scrollView else { + floatingPanel.scrollView = nil + return + } + + floatingPanel.scrollView = scrollView + + switch contentInsetAdjustmentBehavior { + case .always: + if #available(iOS 11.0, *) { + scrollView.contentInsetAdjustmentBehavior = .never + } else { + #if swift(>=4.2) + children.forEach { (vc) in + vc.automaticallyAdjustsScrollViewInsets = false + } + #else + childViewControllers.forEach { (vc) in + vc.automaticallyAdjustsScrollViewInsets = false + } + #endif + } + default: + break + } + } + + // MARK: - Utilities + + /// Updates the layout object from the delegate and lays out the views managed + /// by the controller immediately. + /// + /// This method updates the `FloatingPanelLayout` object from the delegate and + /// then it calls `layoutIfNeeded()` of the root view to force the view + /// to update the floating panel's layout immediately. It can be called in an + /// animation block. + public func updateLayout() { + reloadLayout(for: traitCollection) + activateLayout() + } + + /// Returns the y-coordinate of the point at the origin of the surface view. + public func originYOfSurface(for pos: FloatingPanelPosition) -> CGFloat { + return floatingPanel.layoutAdapter.positionY(for: pos) + } +} + +extension FloatingPanelController { + private static let dismissSwizzling: Any? = { + let aClass: AnyClass! = UIViewController.self //object_getClass(vc) + if let imp = class_getMethodImplementation(aClass, #selector(dismiss(animated:completion:))), + let originalAltMethod = class_getInstanceMethod(aClass, #selector(fp_original_dismiss(animated:completion:))) { + method_setImplementation(originalAltMethod, imp) + } + let originalMethod = class_getInstanceMethod(aClass, #selector(dismiss(animated:completion:))) + let swizzledMethod = class_getInstanceMethod(aClass, #selector(fp_dismiss(animated:completion:))) + if let originalMethod = originalMethod, let swizzledMethod = swizzledMethod { + // switch implementation.. + method_exchangeImplementations(originalMethod, swizzledMethod) + } + return nil + }() +} + +public extension UIViewController { + @objc func fp_original_dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { + // Implementation will be replaced by IMP of self.dismiss(animated:completion:) + } + @objc func fp_dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { + // Call dismiss(animated:completion:) to a content view controller + if let fpc = parent as? FloatingPanelController { + if fpc.presentingViewController != nil { + self.fp_original_dismiss(animated: flag, completion: completion) + } else { + fpc.removePanelFromParent(animated: flag, completion: completion) + } + return + } + // Call dismiss(animated:completion:) to FloatingPanelController directly + if let fpc = self as? FloatingPanelController { + // When a panel is presented modally and it's not a child view controller of the presented view controller. + if fpc.presentingViewController != nil, fpc.parent == nil { + self.fp_original_dismiss(animated: flag, completion: completion) + } else { + fpc.removePanelFromParent(animated: flag, completion: completion) + } + return + } + + // For other view controllers + self.fp_original_dismiss(animated: flag, completion: completion) + } +} diff --git a/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelCore.swift b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelCore.swift new file mode 100755 index 0000000..06e2fce --- /dev/null +++ b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelCore.swift @@ -0,0 +1,956 @@ +// +// Copyright © 2018 Shin Yamamoto. All rights reserved. +// + +import UIKit +import UIKit.UIGestureRecognizerSubclass // For Xcode 9.4.1 + +/// +/// FloatingPanel presentation model +/// +class FloatingPanelCore: NSObject, UIGestureRecognizerDelegate { + // MUST be a weak reference to prevent UI freeze on the presentation modally + weak var viewcontroller: FloatingPanelController? + + let surfaceView: FloatingPanelSurfaceView + let backdropView: FloatingPanelBackdropView + var layoutAdapter: FloatingPanelLayoutAdapter + var behavior: FloatingPanelBehavior + + weak var scrollView: UIScrollView? { + didSet { + oldValue?.panGestureRecognizer.removeTarget(self, action: nil) + scrollView?.panGestureRecognizer.addTarget(self, action: #selector(handle(panGesture:))) + } + } + + private(set) var state: FloatingPanelPosition = .hidden { + didSet { + if let vc = viewcontroller { + vc.delegate?.floatingPanelDidChangePosition(vc) + } + } + } + + private var isBottomState: Bool { + let remains = layoutAdapter.supportedPositions.filter { $0.rawValue > state.rawValue } + return remains.count == 0 + } + + let panGestureRecognizer: FloatingPanelPanGestureRecognizer + var isRemovalInteractionEnabled: Bool = false + + fileprivate var animator: UIViewPropertyAnimator? + + private var initialFrame: CGRect = .zero + private var initialTranslationY: CGFloat = 0 + private var initialLocation: CGPoint = .nan + + var interactionInProgress: Bool = false + var isDecelerating: Bool = false + + // Scroll handling + private var initialScrollOffset: CGPoint = .zero + private var stopScrollDeceleration: Bool = false + private var scrollBouncable = false + private var scrollIndictorVisible = false + + // MARK: - Interface + + init(_ vc: FloatingPanelController, layout: FloatingPanelLayout, behavior: FloatingPanelBehavior) { + viewcontroller = vc + + surfaceView = FloatingPanelSurfaceView() + surfaceView.backgroundColor = .white + + backdropView = FloatingPanelBackdropView() + backdropView.backgroundColor = .black + backdropView.alpha = 0.0 + + self.layoutAdapter = FloatingPanelLayoutAdapter(surfaceView: surfaceView, + backdropView: backdropView, + layout: layout) + self.behavior = behavior + + panGestureRecognizer = FloatingPanelPanGestureRecognizer() + + if #available(iOS 11.0, *) { + panGestureRecognizer.name = "FloatingPanelSurface" + } + + super.init() + + panGestureRecognizer.floatingPanel = self + surfaceView.addGestureRecognizer(panGestureRecognizer) + panGestureRecognizer.addTarget(self, action: #selector(handle(panGesture:))) + panGestureRecognizer.delegate = self + + // Set tap-to-dismiss in the backdrop view + let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleBackdrop(tapGesture:))) + tapGesture.isEnabled = false + backdropView.dismissalTapGestureRecognizer = tapGesture + backdropView.addGestureRecognizer(tapGesture) + } + + func move(to: FloatingPanelPosition, animated: Bool, completion: (() -> Void)? = nil) { + move(from: state, to: to, animated: animated, completion: completion) + } + + private func move(from: FloatingPanelPosition, to: FloatingPanelPosition, animated: Bool, completion: (() -> Void)? = nil) { + assert(layoutAdapter.validPositions.contains(to), "Can't move to '\(to)' position because it's not valid in the layout") + guard let vc = viewcontroller else { + completion?() + return + } + if state != layoutAdapter.topMostState { + lockScrollView() + } + tearDownActiveInteraction() + + if animated { + let animator: UIViewPropertyAnimator + switch (from, to) { + case (.hidden, let to): + animator = behavior.addAnimator(vc, to: to) + case (let from, .hidden): + animator = behavior.removeAnimator(vc, from: from) + case (let from, let to): + animator = behavior.moveAnimator(vc, from: from, to: to) + } + + animator.addAnimations { [weak self] in + guard let `self` = self else { return } + + self.state = to + self.updateLayout(to: to) + } + animator.addCompletion { [weak self] _ in + guard let `self` = self else { return } + self.animator = nil + if self.state == self.layoutAdapter.topMostState { + self.unlockScrollView() + } else { + self.lockScrollView() + } + completion?() + } + self.animator = animator + animator.startAnimation() + } else { + self.state = to + self.updateLayout(to: to) + if self.state == self.layoutAdapter.topMostState { + self.unlockScrollView() + } else { + self.lockScrollView() + } + completion?() + } + } + + // MARK: - Layout update + + private func updateLayout(to target: FloatingPanelPosition) { + self.layoutAdapter.activateFixedLayout() + self.layoutAdapter.activateInteractiveLayout(of: target) + } + + func getBackdropAlpha(at currentY: CGFloat, with translation: CGPoint) -> CGFloat { + let forwardY = (translation.y >= 0) + let segment = layoutAdapter.segument(at: currentY, forward: forwardY) + let lowerPos = segment.lower ?? layoutAdapter.topMostState + let upperPos = segment.upper ?? layoutAdapter.bottomMostState + + let pre = forwardY ? lowerPos : upperPos + let next = forwardY ? upperPos : lowerPos + + let nextY = layoutAdapter.positionY(for: next) + let preY = layoutAdapter.positionY(for: pre) + + let nextAlpha = layoutAdapter.layout.backdropAlphaFor(position: next) + let preAlpha = layoutAdapter.layout.backdropAlphaFor(position: pre) + + if preY == nextY { + return preAlpha + } else { + return preAlpha + max(min(1.0, 1.0 - (nextY - currentY) / (nextY - preY) ), 0.0) * (nextAlpha - preAlpha) + } + } + + // MARK: - UIGestureRecognizerDelegate + + public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, + shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { + guard gestureRecognizer == panGestureRecognizer else { return false } + + /* log.debug("shouldRecognizeSimultaneouslyWith", otherGestureRecognizer) */ + + if let vc = viewcontroller, + vc.delegate?.floatingPanel(vc, shouldRecognizeSimultaneouslyWith: otherGestureRecognizer) ?? false { + return true + } + + switch otherGestureRecognizer { + case is FloatingPanelPanGestureRecognizer: + // All visiable panels' pan gesture should be recognized simultaneously. + return true + case is UIPanGestureRecognizer, + is UISwipeGestureRecognizer, + is UIRotationGestureRecognizer, + is UIScreenEdgePanGestureRecognizer, + is UIPinchGestureRecognizer: + // all gestures of the tracking scroll view should be recognized in parallel + // and handle them in self.handle(panGesture:) + return scrollView?.gestureRecognizers?.contains(otherGestureRecognizer) ?? false + default: + // Should recognize tap/long press gestures in parallel when the surface view is at an anchor position. + let surfaceFrame = surfaceView.layer.presentation()?.frame ?? surfaceView.frame + let surfaceY = surfaceFrame.minY + let adapterY = layoutAdapter.positionY(for: state) + + return abs(surfaceY - adapterY) < (1.0 / surfaceView.traitCollection.displayScale) + } + } + + public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool { + /* log.debug("shouldBeRequiredToFailBy", otherGestureRecognizer) */ + if otherGestureRecognizer is FloatingPanelPanGestureRecognizer { + // If this panel is the farthest descendant of visiable panels, + // its ancestors' pan gesture must wait for its pan gesture to fail + if let view = otherGestureRecognizer.view, surfaceView.isDescendant(of: view) { + return true + } + } + if #available(iOS 11.0, *), + otherGestureRecognizer.name == "_UISheetInteractionBackgroundDismissRecognizer" { + // The dismiss gesture of a sheet modal should not begin until the pan gesture fails. + return true + } + return false + } + + public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool { + guard gestureRecognizer == panGestureRecognizer else { return false } + + /* log.debug("shouldRequireFailureOf", otherGestureRecognizer) */ + + // Should begin the pan gesture without waiting for the tracking scroll view's gestures. + // `scrollView.gestureRecognizers` can contains the following gestures + // * UIScrollViewDelayedTouchesBeganGestureRecognizer + // * UIScrollViewPanGestureRecognizer (scrollView.panGestureRecognizer) + // * _UIDragAutoScrollGestureRecognizer + // * _UISwipeActionPanGestureRecognizer + // * UISwipeDismissalGestureRecognizer + if let scrollView = scrollView { + // On short contents scroll, `_UISwipeActionPanGestureRecognizer` blocks + // the panel's pan gesture if not returns false + if let scrollGestureRecognizers = scrollView.gestureRecognizers, + scrollGestureRecognizers.contains(otherGestureRecognizer) { + switch otherGestureRecognizer { + case scrollView.panGestureRecognizer: + if grabberAreaFrame.contains(gestureRecognizer.location(in: gestureRecognizer.view)) { + return false + } + return allowScrollPanGesture(for: scrollView) + default: + return false + } + } + } + + if let vc = viewcontroller, + vc.delegate?.floatingPanel(vc, shouldRecognizeSimultaneouslyWith: otherGestureRecognizer) ?? false { + return false + } + + switch otherGestureRecognizer { + case is FloatingPanelPanGestureRecognizer: + // If this panel is the farthest descendant of visiable panels, + // its pan gesture does not require its ancestors' pan gesture to fail + if let view = otherGestureRecognizer.view, surfaceView.isDescendant(of: view) { + return false + } + return true + case is UIPanGestureRecognizer, + is UISwipeGestureRecognizer, + is UIRotationGestureRecognizer, + is UIScreenEdgePanGestureRecognizer, + is UIPinchGestureRecognizer: + if #available(iOS 11.0, *), + otherGestureRecognizer.name == "_UISheetInteractionBackgroundDismissRecognizer" { + // Should begin the pan gesture without waiting the dismiss gesture of a sheet modal. + return false + } + // Do not begin the pan gesture until these gestures fail + return true + default: + // Should begin the pan gesture without waiting tap/long press gestures fail + return false + } + } + + var grabberAreaFrame: CGRect { + let grabberAreaFrame = CGRect(x: surfaceView.bounds.origin.x, + y: surfaceView.bounds.origin.y, + width: surfaceView.bounds.width, + height: surfaceView.topGrabberBarHeight * 2) + return grabberAreaFrame + } + + // MARK: - Gesture handling + + @objc func handleBackdrop(tapGesture: UITapGestureRecognizer) { + viewcontroller?.dismiss(animated: true) { [weak self] in + guard let vc = self?.viewcontroller else { return } + vc.delegate?.floatingPanelDidEndRemove(vc) + } + } + + @objc func handle(panGesture: UIPanGestureRecognizer) { + let velocity = panGesture.velocity(in: panGesture.view) + + switch panGesture { + case scrollView?.panGestureRecognizer: + guard let scrollView = scrollView else { return } + + let location = panGesture.location(in: surfaceView) + + let surfaceMinY = surfaceView.presentationFrame.minY + let adapterTopY = layoutAdapter.topY + let belowTop = surfaceMinY > (adapterTopY + (1.0 / surfaceView.traitCollection.displayScale)) + log.debug("scroll gesture(\(state):\(panGesture.state)) --", + "belowTop = \(belowTop),", + "interactionInProgress = \(interactionInProgress),", + "scroll offset = \(scrollView.contentOffset.y),", + "location = \(location.y), velocity = \(velocity.y)") + + let offset = scrollView.contentOffset.y - contentOrigin(of: scrollView).y + + if belowTop { + // Scroll offset pinning + if state == layoutAdapter.topMostState { + if interactionInProgress { + log.debug("settle offset --", initialScrollOffset.y) + scrollView.setContentOffset(initialScrollOffset, animated: false) + } else { + if grabberAreaFrame.contains(location) { + // Preserve the current content offset in moving from full. + scrollView.setContentOffset(initialScrollOffset, animated: false) + } + } + } else { + scrollView.setContentOffset(initialScrollOffset, animated: false) + } + + // Hide a scroll indicator at the non-top in dragging. + if interactionInProgress { + lockScrollView() + } else { + if state == layoutAdapter.topMostState, self.animator == nil, + offset > 0, velocity.y < 0 { + unlockScrollView() + } + } + } else { + if interactionInProgress { + // Show a scroll indicator at the top in dragging. + if offset >= 0, velocity.y <= 0 { + unlockScrollView() + } else { + if state == layoutAdapter.topMostState { + // Adjust a small gap of the scroll offset just after swiping down starts in the grabber area. + if grabberAreaFrame.contains(location), grabberAreaFrame.contains(initialLocation) { + scrollView.setContentOffset(initialScrollOffset, animated: false) + } + } + } + } else { + if state == layoutAdapter.topMostState { + // Hide a scroll indicator just before starting an interaction by swiping a panel down. + if velocity.y > 0, !allowScrollPanGesture(for: scrollView) { + lockScrollView() + } + // Show a scroll indicator when an animation is interrupted at the top and content is scrolled up + if velocity.y < 0, allowScrollPanGesture(for: scrollView) { + unlockScrollView() + } + + // Adjust a small gap of the scroll offset just before swiping down starts in the grabber area, + if grabberAreaFrame.contains(location), grabberAreaFrame.contains(initialLocation) { + scrollView.setContentOffset(initialScrollOffset, animated: false) + } + } + } + } + case panGestureRecognizer: + let translation = panGesture.translation(in: panGestureRecognizer.view!.superview) + let location = panGesture.location(in: panGesture.view) + + log.debug("panel gesture(\(state):\(panGesture.state)) --", + "translation = \(translation.y), location = \(location.y), velocity = \(velocity.y)") + + if interactionInProgress == false, isDecelerating == false, + let vc = viewcontroller, vc.delegate?.floatingPanelShouldBeginDragging(vc) == false { + return + } + + if let animator = self.animator { + guard surfaceView.presentationFrame.minY >= layoutAdapter.topMaxY else { return } + log.debug("panel animation(interruptible: \(animator.isInterruptible)) interrupted!!!") + if animator.isInterruptible { + animator.stopAnimation(false) + // A user can stop a panel at the nearest Y of a target position so this fine-tunes + // the a small gap between the presentation layer frame and model layer frame + // to unlock scroll view properly at finishAnimation(at:) + if abs(surfaceView.frame.minY - layoutAdapter.topY) <= 1.0 { + surfaceView.frame.origin.y = layoutAdapter.topY + } + animator.finishAnimation(at: .current) + } else { + self.endAnimation(false) // Must call it manually + } + } + + if panGesture.state == .began { + panningBegan(at: location) + return + } + + if shouldScrollViewHandleTouch(scrollView, point: location, velocity: velocity) { + return + } + + switch panGesture.state { + case .changed: + if interactionInProgress == false { + startInteraction(with: translation, at: location) + } + panningChange(with: translation) + case .ended, .cancelled, .failed: + if interactionInProgress == false { + startInteraction(with: translation, at: location) + // Workaround: Prevent stopping the surface view b/w anchors if the pan gesture + // doesn't pass through .changed state after an interruptible animator is interrupted. + let dy = translation.y - .leastNonzeroMagnitude + layoutAdapter.updateInteractiveTopConstraint(diff: dy, + allowsTopBuffer: true, + with: behavior) + } + panningEnd(with: translation, velocity: velocity) + default: + break + } + default: + return + } + } + + private func shouldScrollViewHandleTouch(_ scrollView: UIScrollView?, point: CGPoint, velocity: CGPoint) -> Bool { + // When no scrollView, nothing to handle. + guard let scrollView = scrollView else { return false } + + // For _UISwipeActionPanGestureRecognizer + if let scrollGestureRecognizers = scrollView.gestureRecognizers { + for gesture in scrollGestureRecognizers { + guard gesture.state == .began || gesture.state == .changed + else { continue } + + if gesture != scrollView.panGestureRecognizer { + return true + } + } + } + + guard + state == layoutAdapter.topMostState, // When not top most(i.e. .full), don't scroll. + interactionInProgress == false, // When interaction already in progress, don't scroll. + surfaceView.frame.minY == layoutAdapter.topY + else { + return false + } + + // When the current and initial point within grabber area, do scroll. + if grabberAreaFrame.contains(point), !grabberAreaFrame.contains(initialLocation) { + return true + } + + let scrollViewFrame = scrollView.convert(scrollView.bounds, to: surfaceView) + guard + scrollViewFrame.contains(initialLocation), // When initialLocation not in scrollView, don't scroll. + !grabberAreaFrame.contains(point) // When point within grabber area, don't scroll. + else { + return false + } + + let offset = scrollView.contentOffset.y - contentOrigin(of: scrollView).y + // The zero offset must be excluded because the offset is usually zero + // after a panel moves from half/tip to full. + if offset > 0.0 { + return true + } + if scrollView.isDecelerating { + return true + } + if velocity.y <= 0 { + return true + } + + return false + } + + private func panningBegan(at location: CGPoint) { + // A user interaction does not always start from Began state of the pan gesture + // because it can be recognized in scrolling a content in a content view controller. + // So here just preserve the current state if needed. + log.debug("panningBegan -- location = \(location.y)") + initialLocation = location + + guard let scrollView = scrollView else { return } + if state == layoutAdapter.topMostState { + if grabberAreaFrame.contains(location) { + initialScrollOffset = scrollView.contentOffset + } + } else { + initialScrollOffset = scrollView.contentOffset + } + } + + private func panningChange(with translation: CGPoint) { + log.debug("panningChange -- translation = \(translation.y)") + let preY = surfaceView.frame.minY + let dy = translation.y - initialTranslationY + + layoutAdapter.updateInteractiveTopConstraint(diff: dy, + allowsTopBuffer: allowsTopBuffer(for: dy), + with: behavior) + + let currentY = surfaceView.frame.minY + backdropView.alpha = getBackdropAlpha(at: currentY, with: translation) + preserveContentVCLayoutIfNeeded() + + let didMove = (preY != currentY) + guard didMove else { return } + + if let vc = viewcontroller { + vc.delegate?.floatingPanelDidMove(vc) + } + } + + private func allowsTopBuffer(for translationY: CGFloat) -> Bool { + let preY = surfaceView.frame.minY + let nextY = initialFrame.offsetBy(dx: 0.0, dy: translationY).minY + if let scrollView = scrollView, scrollView.panGestureRecognizer.state == .changed, + preY > 0 && preY > nextY { + return false + } else { + return true + } + } + + private var disabledBottomAutoLayout = false + private var disabledAutoLayoutItems: Set = [] + // Prevent stretching a view having a constraint to SafeArea.bottom in an overflow + // from the full position because SafeArea is global in a screen. + private func preserveContentVCLayoutIfNeeded() { + guard let vc = viewcontroller else { return } + guard vc.contentMode != .fitToBounds else { return } + + // Must include topY + if (surfaceView.frame.minY <= layoutAdapter.topY) { + if !disabledBottomAutoLayout { + disabledAutoLayoutItems.removeAll() + vc.contentViewController?.view?.constraints.forEach({ (const) in + switch vc.contentViewController?.layoutGuide.bottomAnchor { + case const.firstAnchor: + (const.secondItem as? UIView)?.disableAutoLayout() + const.isActive = false + disabledAutoLayoutItems.insert(const) + case const.secondAnchor: + (const.firstItem as? UIView)?.disableAutoLayout() + const.isActive = false + disabledAutoLayoutItems.insert(const) + default: + break + } + }) + } + disabledBottomAutoLayout = true + } else { + if disabledBottomAutoLayout { + disabledAutoLayoutItems.forEach({ (const) in + switch vc.contentViewController?.layoutGuide.bottomAnchor { + case const.firstAnchor: + (const.secondItem as? UIView)?.enableAutoLayout() + const.isActive = true + case const.secondAnchor: + (const.firstItem as? UIView)?.enableAutoLayout() + const.isActive = true + default: + break + } + }) + disabledAutoLayoutItems.removeAll() + } + disabledBottomAutoLayout = false + } + } + + private func panningEnd(with translation: CGPoint, velocity: CGPoint) { + log.debug("panningEnd -- translation = \(translation.y), velocity = \(velocity.y)") + + if state == .hidden { + log.debug("Already hidden") + return + } + + stopScrollDeceleration = surfaceView.frame.minY > (layoutAdapter.topY + (1.0 / surfaceView.traitCollection.displayScale)) // Projecting the dragging to the scroll dragging or not + if stopScrollDeceleration { + DispatchQueue.main.async { [weak self] in + guard let `self` = self else { return } + self.stopScrollingWithDeceleration(at: self.initialScrollOffset) + } + } + + let currentY = surfaceView.frame.minY + let targetPosition = self.targetPosition(from: currentY, with: velocity) + let distance = self.distance(to: targetPosition) + + endInteraction(for: targetPosition) + + if isRemovalInteractionEnabled, isBottomState { + let velocityVector = (distance != 0) ? CGVector(dx: 0, dy: min(velocity.y/distance, behavior.removalVelocity)) : .zero + // `velocityVector` will be replaced by just a velocity(not vector) when FloatingPanelRemovalInteraction will be added. + if shouldStartRemovalAnimation(with: velocityVector), let vc = viewcontroller { + vc.delegate?.floatingPanelDidEndDraggingToRemove(vc, withVelocity: velocity) + let animationVector = CGVector(dx: abs(velocityVector.dx), dy: abs(velocityVector.dy)) + startRemovalAnimation(vc, with: animationVector) { [weak self] in + self?.finishRemovalAnimation() + } + return + } + } + + if scrollView != nil, !stopScrollDeceleration, + surfaceView.frame.minY == layoutAdapter.topY, + targetPosition == layoutAdapter.topMostState { + self.state = targetPosition + self.updateLayout(to: targetPosition) + self.unlockScrollView() + if let vc = viewcontroller { + vc.delegate?.floatingPanelDidEndDragging(vc, withVelocity: .zero, targetPosition: targetPosition) + } + return + } + + if let vc = viewcontroller { + vc.delegate?.floatingPanelDidEndDragging(vc, withVelocity: velocity, targetPosition: targetPosition) + } + + // Workaround: Disable a tracking scroll to prevent bouncing a scroll content in a panel animating + let isScrollEnabled = scrollView?.isScrollEnabled + if let scrollView = scrollView, targetPosition != .full { + scrollView.isScrollEnabled = false + } + + startAnimation(to: targetPosition, at: distance, with: velocity) + + // Workaround: Reset `self.scrollView.isScrollEnabled` + if let scrollView = scrollView, targetPosition != .full, + let isScrollEnabled = isScrollEnabled { + scrollView.isScrollEnabled = isScrollEnabled + } + } + + private func shouldStartRemovalAnimation(with velocityVector: CGVector) -> Bool { + let posY = layoutAdapter.positionY(for: state) + let currentY = surfaceView.frame.minY + let hiddenY = layoutAdapter.positionY(for: .hidden) + let vth = behavior.removalVelocity + let pth = max(min(behavior.removalProgress, 1.0), 0.0) + + let num = (currentY - posY) + let den = (hiddenY - posY) + + guard num >= 0, den != 0, (num / den >= pth || velocityVector.dy == vth) + else { return false } + + return true + } + + private func startRemovalAnimation(_ vc: FloatingPanelController, with velocityVector: CGVector, completion: (() -> Void)?) { + let animator = behavior.removalInteractionAnimator(vc, with: velocityVector) + + animator.addAnimations { [weak self] in + self?.state = .hidden + self?.updateLayout(to: .hidden) + } + animator.addCompletion({ _ in + self.animator = nil + completion?() + }) + self.animator = animator + animator.startAnimation() + } + + private func finishRemovalAnimation() { + viewcontroller?.dismiss(animated: false) { [weak self] in + guard let vc = self?.viewcontroller else { return } + vc.delegate?.floatingPanelDidEndRemove(vc) + } + } + + private func startInteraction(with translation: CGPoint, at location: CGPoint) { + /* Don't lock a scroll view to show a scroll indicator after hitting the top */ + log.debug("startInteraction -- translation = \(translation.y), location = \(location.y)") + guard interactionInProgress == false else { return } + + var offset: CGPoint = .zero + + initialFrame = surfaceView.frame + if state == layoutAdapter.topMostState, let scrollView = scrollView { + if grabberAreaFrame.contains(location) { + initialScrollOffset = scrollView.contentOffset + } else { + initialScrollOffset = contentOrigin(of: scrollView) + // Fit the surface bounds to a scroll offset content by startInteraction(at:offset:) + let scrollOffsetY = (scrollView.contentOffset.y - contentOrigin(of: scrollView).y) + if scrollOffsetY < 0 { + offset = CGPoint(x: -scrollView.contentOffset.x, y: -scrollOffsetY) + } + } + log.debug("initial scroll offset --", initialScrollOffset) + } + + initialTranslationY = translation.y + + if let vc = viewcontroller { + vc.delegate?.floatingPanelWillBeginDragging(vc) + } + + layoutAdapter.startInteraction(at: state, offset: offset) + + interactionInProgress = true + + lockScrollView() + } + + private func endInteraction(for targetPosition: FloatingPanelPosition) { + log.debug("endInteraction to \(targetPosition)") + + if let scrollView = scrollView { + log.debug("endInteraction -- scroll offset = \(scrollView.contentOffset)") + } + + interactionInProgress = false + + // Prevent to keep a scroll view indicator visible at the half/tip position + if targetPosition != layoutAdapter.topMostState { + lockScrollView() + } + + layoutAdapter.endInteraction(at: targetPosition) + } + + private func tearDownActiveInteraction() { + // Cancel the pan gesture so that panningEnd(with:velocity:) is called + panGestureRecognizer.isEnabled = false + panGestureRecognizer.isEnabled = true + } + + private func startAnimation(to targetPosition: FloatingPanelPosition, at distance: CGFloat, with velocity: CGPoint) { + log.debug("startAnimation to \(targetPosition) -- distance = \(distance), velocity = \(velocity.y)") + guard let vc = viewcontroller else { return } + + isDecelerating = true + + vc.delegate?.floatingPanelWillBeginDecelerating(vc) + + let velocityVector = (distance != 0) ? CGVector(dx: 0, dy: velocity.y / distance) : .zero + let animator = behavior.interactionAnimator(vc, to: targetPosition, with: velocityVector) + animator.addAnimations { [weak self] in + guard let `self` = self, let vc = self.viewcontroller else { return } + self.state = targetPosition + if animator.isInterruptible { + switch vc.contentMode { + case .fitToBounds: + UIView.performWithLinear(startTime: 0.0, relativeDuration: 0.75) { + self.layoutAdapter.activateFixedLayout() + self.surfaceView.superview!.layoutIfNeeded() + } + case .static: + self.layoutAdapter.activateFixedLayout() + } + } else { + self.layoutAdapter.activateFixedLayout() + } + self.layoutAdapter.activateInteractiveLayout(of: targetPosition) + } + animator.addCompletion { [weak self] pos in + // Prevent calling `finishAnimation(at:)` by the old animator whose `isInterruptive` is false + // when a new animator has been started after the old one is interrupted. + guard let `self` = self, self.animator == animator else { return } + log.debug("finishAnimation to \(targetPosition)") + self.endAnimation(pos == .end) + } + self.animator = animator + animator.startAnimation() + } + + private func endAnimation(_ finished: Bool) { + self.isDecelerating = false + self.animator = nil + + if let vc = viewcontroller { + vc.delegate?.floatingPanelDidEndDecelerating(vc) + } + + if let scrollView = scrollView { + log.debug("finishAnimation -- scroll offset = \(scrollView.contentOffset)") + } + + stopScrollDeceleration = false + + log.debug("finishAnimation -- state = \(state) surface.minY = \(surfaceView.presentationFrame.minY) topY = \(layoutAdapter.topY)") + if finished, state == layoutAdapter.topMostState, abs(surfaceView.presentationFrame.minY - layoutAdapter.topY) <= 1.0 { + unlockScrollView() + } + } + + private func distance(to targetPosition: FloatingPanelPosition) -> CGFloat { + let currentY = surfaceView.frame.minY + let targetY = layoutAdapter.positionY(for: targetPosition) + return CGFloat(targetY - currentY) + } + + // Distance travelled after decelerating to zero velocity at a constant rate. + // Refer to the slides p176 of [Designing Fluid Interfaces](https://developer.apple.com/videos/play/wwdc2018/803/) + private func project(initialVelocity: CGFloat, decelerationRate: CGFloat) -> CGFloat { + return (initialVelocity / 1000.0) * decelerationRate / (1.0 - decelerationRate) + } + + func targetPosition(from currentY: CGFloat, with velocity: CGPoint) -> (FloatingPanelPosition) { + guard let vc = viewcontroller else { return state } + let supportedPositions = layoutAdapter.supportedPositions + + guard supportedPositions.count > 1 else { + return state + } + + let sortedPositions = Array(supportedPositions).sorted(by: { $0.rawValue < $1.rawValue }) + + // Projection + let decelerationRate = behavior.momentumProjectionRate(vc) + let baseY = abs(layoutAdapter.positionY(for: layoutAdapter.bottomMostState) - layoutAdapter.positionY(for: layoutAdapter.topMostState)) + let vecY = velocity.y / baseY + var pY = project(initialVelocity: vecY, decelerationRate: decelerationRate) * baseY + currentY + + let forwardY = velocity.y == 0 ? (currentY - layoutAdapter.positionY(for: state) > 0) : velocity.y > 0 + + let segment = layoutAdapter.segument(at: pY, forward: forwardY) + + var fromPos: FloatingPanelPosition + var toPos: FloatingPanelPosition + + let (lowerPos, upperPos) = (segment.lower ?? sortedPositions.first!, segment.upper ?? sortedPositions.last!) + (fromPos, toPos) = forwardY ? (lowerPos, upperPos) : (upperPos, lowerPos) + + if behavior.shouldProjectMomentum(vc, for: toPos) == false { + let segment = layoutAdapter.segument(at: currentY, forward: forwardY) + var (lowerPos, upperPos) = (segment.lower ?? sortedPositions.first!, segment.upper ?? sortedPositions.last!) + // Equate the segment out of {top,bottom} most state to the {top,bottom} most segment + if lowerPos == upperPos { + if forwardY { + upperPos = lowerPos.next(in: sortedPositions) + } else { + lowerPos = upperPos.pre(in: sortedPositions) + } + } + (fromPos, toPos) = forwardY ? (lowerPos, upperPos) : (upperPos, lowerPos) + // Block a projection to a segment over the next from the current segment + // (= Trim pY with the current segment) + if forwardY { + pY = max(min(pY, layoutAdapter.positionY(for: toPos.next(in: sortedPositions))), layoutAdapter.positionY(for: fromPos)) + } else { + pY = max(min(pY, layoutAdapter.positionY(for: fromPos)), layoutAdapter.positionY(for: toPos.pre(in: sortedPositions))) + } + } + + // Redirection + let redirectionalProgress = max(min(behavior.redirectionalProgress(vc, from: fromPos, to: toPos), 1.0), 0.0) + let progress = abs(pY - layoutAdapter.positionY(for: fromPos)) / abs(layoutAdapter.positionY(for: fromPos) - layoutAdapter.positionY(for: toPos)) + return progress > redirectionalProgress ? toPos : fromPos + } + + // MARK: - ScrollView handling + + private func lockScrollView() { + guard let scrollView = scrollView else { return } + + if scrollView.isLocked { + log.debug("Already scroll locked.") + return + } + log.debug("lock scroll view") + + scrollBouncable = scrollView.bounces + scrollIndictorVisible = scrollView.showsVerticalScrollIndicator + + scrollView.isDirectionalLockEnabled = true + scrollView.bounces = false + scrollView.showsVerticalScrollIndicator = false + } + + private func unlockScrollView() { + guard let scrollView = scrollView, scrollView.isLocked else { return } + log.debug("unlock scroll view") + + scrollView.isDirectionalLockEnabled = false + scrollView.bounces = scrollBouncable + scrollView.showsVerticalScrollIndicator = scrollIndictorVisible + } + + private func stopScrollingWithDeceleration(at contentOffset: CGPoint) { + // Must use setContentOffset(_:animated) to force-stop deceleration + scrollView?.setContentOffset(contentOffset, animated: false) + } + + private func contentOrigin(of scrollView: UIScrollView) -> CGPoint { + if let vc = viewcontroller, let origin = vc.delegate?.floatingPanel(vc, contentOffsetForPinning: scrollView) { + return origin + } + return CGPoint(x: 0.0, y: 0.0 - scrollView.contentInset.top) + } + + private func allowScrollPanGesture(for scrollView: UIScrollView) -> Bool { + let contentOffset = scrollView.contentOffset - contentOrigin(of: scrollView) + if state == layoutAdapter.topMostState { + return contentOffset.y <= -30.0 || contentOffset.y > 0 + } + return false + } +} + +class FloatingPanelPanGestureRecognizer: UIPanGestureRecognizer { + fileprivate weak var floatingPanel: FloatingPanelCore? + override func touchesBegan(_ touches: Set, with event: UIEvent) { + super.touchesBegan(touches, with: event) + if floatingPanel?.animator != nil { + self.state = .began + } + } + override weak var delegate: UIGestureRecognizerDelegate? { + get { + return super.delegate + } + set { + guard newValue is FloatingPanelCore else { + let exception = NSException(name: .invalidArgumentException, + reason: "FloatingPanelController's built-in pan gesture recognizer must have its controller as its delegate.", + userInfo: nil) + exception.raise() + return + } + super.delegate = newValue + } + } +} diff --git a/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelLayout.swift b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelLayout.swift new file mode 100755 index 0000000..c89fe79 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelLayout.swift @@ -0,0 +1,616 @@ +// +// Created by Shin Yamamoto on 2018/09/27. +// Copyright © 2018 Shin Yamamoto. All rights reserved. +// + +import UIKit + +/// FloatingPanelFullScreenLayout +/// +/// Use the layout protocol if you configure full, half and tip insets from the superview, not the safe area. +/// It can't be used with FloatingPanelIntrinsicLayout. +public protocol FloatingPanelFullScreenLayout: FloatingPanelLayout { } + +public extension FloatingPanelFullScreenLayout { + var positionReference: FloatingPanelLayoutReference { + return .fromSuperview + } +} + +/// FloatingPanelIntrinsicLayout +/// +/// Use the layout protocol if you want to layout a panel using the intrinsic height. +/// It can't be used with `FloatingPanelFullScreenLayout`. +/// +/// - Attention: +/// `insetFor(position:)` must return `nil` for the full position. Because +/// the inset is determined automatically by the intrinsic height. +/// You can customize insets only for the half, tip and hidden positions. +/// +/// - Note: +/// By default, the `positionReference` is set to `.fromSafeArea`. +public protocol FloatingPanelIntrinsicLayout: FloatingPanelLayout { } + +public extension FloatingPanelIntrinsicLayout { + var initialPosition: FloatingPanelPosition { + return .full + } + + var supportedPositions: Set { + return [.full] + } + + func insetFor(position: FloatingPanelPosition) -> CGFloat? { + return nil + } + + var positionReference: FloatingPanelLayoutReference { + return .fromSafeArea + } +} + +public enum FloatingPanelLayoutReference: Int { + case fromSafeArea = 0 + case fromSuperview = 1 +} + +public protocol FloatingPanelLayout: class { + /// Returns the initial position of a floating panel. + var initialPosition: FloatingPanelPosition { get } + + /// Returns a set of FloatingPanelPosition objects to tell the applicable + /// positions of the floating panel controller. + /// + /// By default, it returns full, half and tip positions. + var supportedPositions: Set { get } + + /// Return the interaction buffer to the top from the top position. Default is 6.0. + var topInteractionBuffer: CGFloat { get } + + /// Return the interaction buffer to the bottom from the bottom position. Default is 6.0. + /// + /// - Important: + /// The specified buffer is ignored when `FloatingPanelController.isRemovalInteractionEnabled` is set to true. + var bottomInteractionBuffer: CGFloat { get } + + /// Returns a CGFloat value to determine a Y coordinate of a floating panel for each position(full, half, tip and hidden). + /// + /// Its returning value indicates a different inset for each position. + /// For full position, a top inset from a safe area in `FloatingPanelController.view`. + /// For half or tip position, a bottom inset from the safe area. + /// For hidden position, a bottom inset from `FloatingPanelController.view`. + /// If a position isn't supported or the default value is used, return nil. + func insetFor(position: FloatingPanelPosition) -> CGFloat? + + /// Returns X-axis and width layout constraints of the surface view of a floating panel. + /// You must not include any Y-axis and height layout constraints of the surface view + /// because their constraints will be configured by the floating panel controller. + /// By default, the width of a surface view fits a safe area. + func prepareLayout(surfaceView: UIView, in view: UIView) -> [NSLayoutConstraint] + + /// Returns a CGFloat value to determine the backdrop view's alpha for a position. + /// + /// Default is 0.3 at full position, otherwise 0.0. + func backdropAlphaFor(position: FloatingPanelPosition) -> CGFloat + + var positionReference: FloatingPanelLayoutReference { get } + +} + +public extension FloatingPanelLayout { + var topInteractionBuffer: CGFloat { return 6.0 } + var bottomInteractionBuffer: CGFloat { return 6.0 } + + var supportedPositions: Set { + return Set([.full, .half, .tip]) + } + + func prepareLayout(surfaceView: UIView, in view: UIView) -> [NSLayoutConstraint] { + return [ + surfaceView.leftAnchor.constraint(equalTo: view.sideLayoutGuide.leftAnchor, constant: 0.0), + surfaceView.rightAnchor.constraint(equalTo: view.sideLayoutGuide.rightAnchor, constant: 0.0), + ] + } + + func backdropAlphaFor(position: FloatingPanelPosition) -> CGFloat { + return position == .full ? 0.3 : 0.0 + } + + var positionReference: FloatingPanelLayoutReference { + return .fromSafeArea + } +} + +public class FloatingPanelDefaultLayout: FloatingPanelLayout { + public init() { } + + public var initialPosition: FloatingPanelPosition { + return .half + } + + public func insetFor(position: FloatingPanelPosition) -> CGFloat? { + switch position { + case .full: return 18.0 + case .half: return 262.0 + case .tip: return 69.0 + case .hidden: return nil + } + } +} + +public class FloatingPanelDefaultLandscapeLayout: FloatingPanelLayout { + public init() { } + + public var initialPosition: FloatingPanelPosition { + return .tip + } + public var supportedPositions: Set { + return [.full, .tip] + } + + public func insetFor(position: FloatingPanelPosition) -> CGFloat? { + switch position { + case .full: return 16.0 + case .tip: return 69.0 + default: return nil + } + } +} + +struct LayoutSegment { + let lower: FloatingPanelPosition? + let upper: FloatingPanelPosition? +} + +class FloatingPanelLayoutAdapter { + weak var vc: FloatingPanelController! + private weak var surfaceView: FloatingPanelSurfaceView! + private weak var backdropView: FloatingPanelBackdropView! + + var layout: FloatingPanelLayout { + didSet { + checkLayoutConsistance() + } + } + + private var safeAreaInsets: UIEdgeInsets { + return vc?.layoutInsets ?? .zero + } + + private var initialConst: CGFloat = 0.0 + + private var fixedConstraints: [NSLayoutConstraint] = [] + private var fullConstraints: [NSLayoutConstraint] = [] + private var halfConstraints: [NSLayoutConstraint] = [] + private var tipConstraints: [NSLayoutConstraint] = [] + private var offConstraints: [NSLayoutConstraint] = [] + private var interactiveTopConstraint: NSLayoutConstraint? + private var bottomConstraint: NSLayoutConstraint? + + + private var heightConstraint: NSLayoutConstraint? + + private var fullInset: CGFloat { + if layout is FloatingPanelIntrinsicLayout { + return intrinsicHeight + } else { + return layout.insetFor(position: .full) ?? 0.0 + } + } + private var halfInset: CGFloat { + return layout.insetFor(position: .half) ?? 0.0 + } + private var tipInset: CGFloat { + return layout.insetFor(position: .tip) ?? 0.0 + } + private var hiddenInset: CGFloat { + return layout.insetFor(position: .hidden) ?? 0.0 + } + + var supportedPositions: Set { + return layout.supportedPositions + } + + var validPositions: Set { + return supportedPositions.union([.hidden]) + } + + var topMostState: FloatingPanelPosition { + return supportedPositions.sorted(by: { $0.rawValue < $1.rawValue }).first ?? .hidden + } + + var bottomMostState: FloatingPanelPosition { + return supportedPositions.sorted(by: { $0.rawValue < $1.rawValue }).last ?? .hidden + } + + var topY: CGFloat { + return positionY(for: topMostState) + } + + var bottomY: CGFloat { + return positionY(for: bottomMostState) + } + + var topMaxY: CGFloat { + return topY - layout.topInteractionBuffer + } + + var bottomMaxY: CGFloat { + return bottomY + layout.bottomInteractionBuffer + } + + var adjustedContentInsets: UIEdgeInsets { + return UIEdgeInsets(top: 0.0, + left: 0.0, + bottom: safeAreaInsets.bottom, + right: 0.0) + } + + func positionY(for pos: FloatingPanelPosition) -> CGFloat { + switch pos { + case .full: + if layout is FloatingPanelIntrinsicLayout { + return surfaceView.superview!.bounds.height - surfaceView.bounds.height + } + switch layout.positionReference { + case .fromSafeArea: + return (safeAreaInsets.top + fullInset) + case .fromSuperview: + return fullInset + } + case .half: + switch layout.positionReference { + case .fromSafeArea: + return surfaceView.superview!.bounds.height - (safeAreaInsets.bottom + halfInset) + case .fromSuperview: + return surfaceView.superview!.bounds.height - halfInset + } + case .tip: + switch layout.positionReference { + case .fromSafeArea: + return surfaceView.superview!.bounds.height - (safeAreaInsets.bottom + tipInset) + case .fromSuperview: + return surfaceView.superview!.bounds.height - tipInset + } + case .hidden: + return surfaceView.superview!.bounds.height - hiddenInset + } + } + + var intrinsicHeight: CGFloat = 0.0 + + init(surfaceView: FloatingPanelSurfaceView, backdropView: FloatingPanelBackdropView, layout: FloatingPanelLayout) { + self.layout = layout + self.surfaceView = surfaceView + self.backdropView = backdropView + } + + func updateIntrinsicHeight() { + #if swift(>=4.2) + let fittingSize = UIView.layoutFittingCompressedSize + #else + let fittingSize = UILayoutFittingCompressedSize + #endif + var intrinsicHeight = surfaceView.contentView?.systemLayoutSizeFitting(fittingSize).height ?? 0.0 + var safeAreaBottom: CGFloat = 0.0 + if #available(iOS 11.0, *) { + safeAreaBottom = surfaceView.contentView?.safeAreaInsets.bottom ?? 0.0 + if safeAreaBottom > 0 { + intrinsicHeight -= safeAreaInsets.bottom + } + } + self.intrinsicHeight = max(intrinsicHeight, 0.0) + + log.debug("Update intrinsic height =", intrinsicHeight, + ", surface(height) =", surfaceView.frame.height, + ", content(height) =", surfaceView.contentView?.frame.height ?? 0.0, + ", content safe area(bottom) =", safeAreaBottom) + } + + func prepareLayout(in vc: FloatingPanelController) { + self.vc = vc + + NSLayoutConstraint.deactivate(fixedConstraints + fullConstraints + halfConstraints + tipConstraints + offConstraints) + NSLayoutConstraint.deactivate(constraint: self.heightConstraint) + self.heightConstraint = nil + NSLayoutConstraint.deactivate(constraint: self.bottomConstraint) + self.bottomConstraint = nil + + surfaceView.translatesAutoresizingMaskIntoConstraints = false + backdropView.translatesAutoresizingMaskIntoConstraints = false + + // Fixed constraints of surface and backdrop views + let surfaceConstraints = layout.prepareLayout(surfaceView: surfaceView, in: vc.view!) + let backdropConstraints = [ + backdropView.topAnchor.constraint(equalTo: vc.view.topAnchor, constant: 0.0), + backdropView.leftAnchor.constraint(equalTo: vc.view.leftAnchor,constant: 0.0), + backdropView.rightAnchor.constraint(equalTo: vc.view.rightAnchor, constant: 0.0), + backdropView.bottomAnchor.constraint(equalTo: vc.view.bottomAnchor, constant: 0.0), + ] + + fixedConstraints = surfaceConstraints + backdropConstraints + + if vc.contentMode == .fitToBounds { + bottomConstraint = surfaceView.bottomAnchor.constraint(equalTo: vc.view.bottomAnchor, + constant: 0.0) + } + + // Flexible surface constraints for full, half, tip and off + let topAnchor: NSLayoutYAxisAnchor = { + if layout.positionReference == .fromSuperview { + return vc.view.topAnchor + } else { + return vc.layoutGuide.topAnchor + } + }() + + switch layout { + case is FloatingPanelIntrinsicLayout: + // Set up on updateHeight() + break + default: + fullConstraints = [ + surfaceView.topAnchor.constraint(equalTo: topAnchor, + constant: fullInset), + ] + } + + let bottomAnchor: NSLayoutYAxisAnchor = { + if layout.positionReference == .fromSuperview { + return vc.view.bottomAnchor + } else { + return vc.layoutGuide.bottomAnchor + } + }() + + halfConstraints = [ + surfaceView.topAnchor.constraint(equalTo: bottomAnchor, + constant: -halfInset), + ] + tipConstraints = [ + surfaceView.topAnchor.constraint(equalTo: bottomAnchor, + constant: -tipInset), + ] + + offConstraints = [ + surfaceView.topAnchor.constraint(equalTo:vc.view.bottomAnchor, + constant: -hiddenInset), + ] + } + + func startInteraction(at state: FloatingPanelPosition, offset: CGPoint = .zero) { + guard self.interactiveTopConstraint == nil else { return } + NSLayoutConstraint.deactivate(fullConstraints + halfConstraints + tipConstraints + offConstraints) + + let interactiveTopConstraint: NSLayoutConstraint + switch layout.positionReference { + case .fromSafeArea: + initialConst = surfaceView.frame.minY - safeAreaInsets.top + offset.y + interactiveTopConstraint = surfaceView.topAnchor.constraint(equalTo: vc.layoutGuide.topAnchor, + constant: initialConst) + case .fromSuperview: + initialConst = surfaceView.frame.minY + offset.y + interactiveTopConstraint = surfaceView.topAnchor.constraint(equalTo: vc.view.topAnchor, + constant: initialConst) + } + NSLayoutConstraint.activate([interactiveTopConstraint]) + self.interactiveTopConstraint = interactiveTopConstraint + } + + func endInteraction(at state: FloatingPanelPosition) { + // Don't deactivate `interactiveTopConstraint` here because it leads to + // unsatisfiable constraints + + if self.interactiveTopConstraint == nil { + // Activate `interactiveTopConstraint` for `fitToBounds` mode. + // It goes through this path when the pan gesture state jumps + // from .begin to .end. + startInteraction(at: state) + } + } + + // The method is separated from prepareLayout(to:) for the rotation support + // It must be called in FloatingPanelController.traitCollectionDidChange(_:) + func updateHeight() { + guard let vc = vc else { return } + NSLayoutConstraint.deactivate(constraint: heightConstraint) + heightConstraint = nil + + if layout is FloatingPanelIntrinsicLayout { + updateIntrinsicHeight() + } + defer { + if layout is FloatingPanelIntrinsicLayout { + NSLayoutConstraint.deactivate(fullConstraints) + fullConstraints = [ + surfaceView.topAnchor.constraint(equalTo: vc.layoutGuide.bottomAnchor, + constant: -fullInset), + ] + } + } + + guard vc.contentMode != .fitToBounds else { return } + + switch layout { + case is FloatingPanelIntrinsicLayout: + heightConstraint = surfaceView.heightAnchor.constraint(equalToConstant: intrinsicHeight + safeAreaInsets.bottom) + default: + let const = -(positionY(for: topMostState)) + heightConstraint = surfaceView.heightAnchor.constraint(equalTo: vc.view.heightAnchor, + constant: const) + } + NSLayoutConstraint.activate(constraint: heightConstraint) + + surfaceView.bottomOverflow = vc.view.bounds.height + layout.topInteractionBuffer + } + + func updateInteractiveTopConstraint(diff: CGFloat, allowsTopBuffer: Bool, with behavior: FloatingPanelBehavior) { + defer { + layoutSurfaceIfNeeded() // MUST be called to update `surfaceView.frame` + } + + let topMostConst: CGFloat = { + var ret: CGFloat = 0.0 + switch layout.positionReference { + case .fromSafeArea: + ret = topY - safeAreaInsets.top + case .fromSuperview: + ret = topY + } + return ret + }() + let bottomMostConst: CGFloat = { + var ret: CGFloat = 0.0 + let _bottomY = vc.isRemovalInteractionEnabled ? positionY(for: .hidden) : bottomY + switch layout.positionReference { + case .fromSafeArea: + ret = _bottomY - safeAreaInsets.top + case .fromSuperview: + ret = _bottomY + } + return ret + }() + let minConst = allowsTopBuffer ? topMostConst - layout.topInteractionBuffer : topMostConst + let maxConst = bottomMostConst + layout.bottomInteractionBuffer + + var const = initialConst + diff + + // Rubberbanding top buffer + if behavior.allowsRubberBanding(for: .top), const < topMostConst { + let buffer = topMostConst - const + const = topMostConst - rubberbandEffect(for: buffer, base: vc.view.bounds.height) + } + + // Rubberbanding bottom buffer + if behavior.allowsRubberBanding(for: .bottom), const > bottomMostConst { + let buffer = const - bottomMostConst + const = bottomMostConst + rubberbandEffect(for: buffer, base: vc.view.bounds.height) + } + + interactiveTopConstraint?.constant = max(minConst, min(maxConst, const)) + } + + // According to @chpwn's tweet: https://twitter.com/chpwn/status/285540192096497664 + // x = distance from the edge + // c = constant value, UIScrollView uses 0.55 + // d = dimension, either width or height + private func rubberbandEffect(for buffer: CGFloat, base: CGFloat) -> CGFloat { + return (1.0 - (1.0 / ((buffer * 0.55 / base) + 1.0))) * base + } + + func activateFixedLayout() { + // Must deactivate `interactiveTopConstraint` here + NSLayoutConstraint.deactivate(constraint: self.interactiveTopConstraint) + self.interactiveTopConstraint = nil + + NSLayoutConstraint.activate(fixedConstraints) + + if vc.contentMode == .fitToBounds { + NSLayoutConstraint.activate(constraint: self.bottomConstraint) + } + } + + func activateInteractiveLayout(of state: FloatingPanelPosition) { + defer { + layoutSurfaceIfNeeded() + log.debug("activateLayout -- surface.presentation = \(self.surfaceView.presentationFrame) surface.frame = \(self.surfaceView.frame)") + } + + var state = state + + setBackdropAlpha(of: state) + + if validPositions.contains(state) == false { + state = layout.initialPosition + } + + NSLayoutConstraint.deactivate(fullConstraints + halfConstraints + tipConstraints + offConstraints) + switch state { + case .full: + NSLayoutConstraint.activate(fullConstraints) + case .half: + NSLayoutConstraint.activate(halfConstraints) + case .tip: + NSLayoutConstraint.activate(tipConstraints) + case .hidden: + NSLayoutConstraint.activate(offConstraints) + } + } + + func activateLayout(of state: FloatingPanelPosition) { + activateFixedLayout() + activateInteractiveLayout(of: state) + } + + private func layoutSurfaceIfNeeded() { + #if !TEST + guard surfaceView.window != nil else { return } + #endif + surfaceView.superview?.layoutIfNeeded() + } + + private func setBackdropAlpha(of target: FloatingPanelPosition) { + if target == .hidden { + self.backdropView.alpha = 0.0 + } else { + self.backdropView.alpha = layout.backdropAlphaFor(position: target) + } + } + + private func checkLayoutConsistance() { + // Verify layout configurations + assert(supportedPositions.count > 0) + assert(validPositions.contains(layout.initialPosition), + "Does not include an initial position (\(layout.initialPosition)) in (\(validPositions))") + + if layout is FloatingPanelIntrinsicLayout { + assert(layout.insetFor(position: .full) == nil, "Return `nil` for full position on FloatingPanelIntrinsicLayout") + } + + if halfInset > 0 { + assert(halfInset > tipInset, "Invalid half and tip insets") + } + // The verification isn't working on orientation change(portrait -> landscape) + // of a floating panel in tab bar. Because the `safeAreaInsets.bottom` is + // updated in delay so that it can be 83.0(not 53.0) even after the surface + // and the super view's frame is fit to landscape already. + /*if fullInset > 0 { + assert(middleY > topY, "Invalid insets { topY: \(topY), middleY: \(middleY) }") + assert(bottomY > topY, "Invalid insets { topY: \(topY), bottomY: \(bottomY) }") + }*/ + } + + func segument(at posY: CGFloat, forward: Bool) -> LayoutSegment { + /// ----------------------->Y + /// --> forward <-- backward + /// |-------|===o===|-------| |-------|-------|===o===| + /// |-------|-------x=======| |-------|=======x-------| + /// |-------|-------|===o===| |-------|===o===|-------| + /// pos: o/x, seguement: = + let sortedPositions = supportedPositions.sorted(by: { $0.rawValue < $1.rawValue }) + + let upperIndex: Int? + if forward { + #if swift(>=4.2) + upperIndex = sortedPositions.firstIndex(where: { posY < positionY(for: $0) }) + #else + upperIndex = sortedPositions.index(where: { posY < positionY(for: $0) }) + #endif + } else { + #if swift(>=4.2) + upperIndex = sortedPositions.firstIndex(where: { posY <= positionY(for: $0) }) + #else + upperIndex = sortedPositions.index(where: { posY <= positionY(for: $0) }) + #endif + } + + switch upperIndex { + case 0: + return LayoutSegment(lower: nil, upper: sortedPositions.first) + case let upperIndex?: + return LayoutSegment(lower: sortedPositions[upperIndex - 1], upper: sortedPositions[upperIndex]) + default: + return LayoutSegment(lower: sortedPositions[sortedPositions.endIndex - 1], upper: nil) + } + } +} diff --git a/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelSurfaceView.swift b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelSurfaceView.swift new file mode 100755 index 0000000..20ee97b --- /dev/null +++ b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelSurfaceView.swift @@ -0,0 +1,243 @@ +// +// Created by Shin Yamamoto on 2018/09/26. +// Copyright © 2018 Shin Yamamoto. All rights reserved. +// + +import UIKit + +/// A view that presents a surface interface in a floating panel. +public class FloatingPanelSurfaceView: UIView { + + /// A GrabberHandleView object displayed at the top of the surface view. + /// + /// To use a custom grabber handle, hide this and then add the custom one + /// to the surface view at appropriate coordinates. + public let grabberHandle: GrabberHandleView = GrabberHandleView() + + /// Offset of the grabber handle from the top + public var grabberTopPadding: CGFloat = 6.0 { didSet { + setNeedsUpdateConstraints() + } } + + /// The height of the grabber bar area + public var topGrabberBarHeight: CGFloat { + return grabberTopPadding * 2 + grabberHandleHeight + } + + /// Grabber view width and height + public var grabberHandleWidth: CGFloat = 36.0 { didSet { + setNeedsUpdateConstraints() + } } + public var grabberHandleHeight: CGFloat = 5.0 { didSet { + setNeedsUpdateConstraints() + } } + + /// A root view of a content view controller + public weak var contentView: UIView! + + /// The content insets specifying the insets around the content view. + public var contentInsets: UIEdgeInsets = .zero { + didSet { + // Needs update constraints + self.setNeedsUpdateConstraints() + } + } + + private var color: UIColor? = .white { didSet { setNeedsLayout() } } + var bottomOverflow: CGFloat = 0.0 // Must not call setNeedsLayout() + + public override var backgroundColor: UIColor? { + get { return color } + set { color = newValue } + } + + /// The radius to use when drawing top rounded corners. + /// + /// `self.contentView` is masked with the top rounded corners automatically on iOS 11 and later. + /// On iOS 10, they are not automatically masked because of a UIVisualEffectView issue. See https://forums.developer.apple.com/thread/50854 + public var cornerRadius: CGFloat { + set { containerView.layer.cornerRadius = newValue; setNeedsLayout() } + get { return containerView.layer.cornerRadius } + } + + /// A Boolean indicating whether the surface shadow is displayed. + public var shadowHidden: Bool = false { didSet { setNeedsLayout() } } + + /// The color of the surface shadow. + public var shadowColor: UIColor = .black { didSet { setNeedsLayout() } } + + /// The offset (in points) of the surface shadow. + public var shadowOffset: CGSize = CGSize(width: 0.0, height: 1.0) { didSet { setNeedsLayout() } } + + /// The opacity of the surface shadow. + public var shadowOpacity: Float = 0.2 { didSet { setNeedsLayout() } } + + /// The blur radius (in points) used to render the surface shadow. + public var shadowRadius: CGFloat = 3 { didSet { setNeedsLayout() } } + + /// The width of the surface border. + public var borderColor: UIColor? { didSet { setNeedsLayout() } } + + /// The color of the surface border. + public var borderWidth: CGFloat = 0.0 { didSet { setNeedsLayout() } } + + /// The margins to use when laying out the container view wrapping content. + public var containerMargins: UIEdgeInsets = .zero { didSet { + setNeedsUpdateConstraints() + } } + + /// The view presents an actual surface shape. + /// + /// It renders the background color, border line and top rounded corners, + /// specified by other properties. The reason why they're not be applied to + /// a content view directly is because it avoids any side-effects to the + /// content view. + public let containerView: UIView = UIView() + + @available(*, unavailable, renamed: "containerView") + public var backgroundView: UIView! + + private lazy var containerViewTopConstraint = containerView.topAnchor.constraint(equalTo: topAnchor, constant: containerMargins.top) + private lazy var containerViewHeightConstraint = containerView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 1.0) + private lazy var containerViewLeftConstraint = containerView.leftAnchor.constraint(equalTo: leftAnchor, constant: 0.0) + private lazy var containerViewRightConstraint = containerView.rightAnchor.constraint(equalTo: rightAnchor, constant: 0.0) + + /// The content view top constraint + private var contentViewTopConstraint: NSLayoutConstraint? + /// The content view left constraint + private var contentViewLeftConstraint: NSLayoutConstraint? + /// The content right constraint + private var contentViewRightConstraint: NSLayoutConstraint? + /// The content height constraint + private var contentViewHeightConstraint: NSLayoutConstraint? + + private lazy var grabberHandleWidthConstraint = grabberHandle.widthAnchor.constraint(equalToConstant: grabberHandleWidth) + private lazy var grabberHandleHeightConstraint = grabberHandle.heightAnchor.constraint(equalToConstant: grabberHandleHeight) + private lazy var grabberHandleTopConstraint = grabberHandle.topAnchor.constraint(equalTo: topAnchor, constant: grabberTopPadding) + + public override class var requiresConstraintBasedLayout: Bool { return true } + + override init(frame: CGRect) { + super.init(frame: frame) + addSubViews() + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + addSubViews() + } + + private func addSubViews() { + super.backgroundColor = .clear + self.clipsToBounds = false + + addSubview(containerView) + containerView.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + containerViewTopConstraint, + containerViewLeftConstraint, + containerViewRightConstraint, + containerViewHeightConstraint, + ]) + + addSubview(grabberHandle) + grabberHandle.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + grabberHandleWidthConstraint, + grabberHandleHeightConstraint, + grabberHandleTopConstraint, + grabberHandle.centerXAnchor.constraint(equalTo: centerXAnchor), + ]) + } + + public override func updateConstraints() { + containerViewTopConstraint.constant = containerMargins.top + containerViewLeftConstraint.constant = containerMargins.left + containerViewRightConstraint.constant = -containerMargins.right + containerViewHeightConstraint.constant = (containerMargins.bottom == 0) ? bottomOverflow : -(containerMargins.top + containerMargins.bottom) + + contentViewTopConstraint?.constant = containerMargins.top + contentInsets.top + contentViewLeftConstraint?.constant = containerMargins.left + contentInsets.left + contentViewRightConstraint?.constant = containerMargins.right + contentInsets.right + contentViewHeightConstraint?.constant = -(containerMargins.top + containerMargins.bottom + contentInsets.top + contentInsets.bottom) + + grabberHandleTopConstraint.constant = grabberTopPadding + grabberHandleWidthConstraint.constant = grabberHandleWidth + grabberHandleHeightConstraint.constant = grabberHandleHeight + + super.updateConstraints() + } + + public override func layoutSubviews() { + super.layoutSubviews() + log.debug("surface view frame = \(frame)") + + containerView.backgroundColor = color + + updateShadow() + updateCornerRadius() + updateBorder() + } + + private func updateShadow() { + if shadowHidden == false { + if #available(iOS 11, *) { + // For clear background. See also, https://github.com/SCENEE/FloatingPanel/pull/51. + layer.shadowColor = shadowColor.cgColor + layer.shadowOffset = shadowOffset + layer.shadowOpacity = shadowOpacity + layer.shadowRadius = shadowRadius + } else { + // Can't update `layer.shadow*` directly because of a UIVisualEffectView issue in iOS 10, https://forums.developer.apple.com/thread/50854 + // Instead, a user should display shadow appropriately. + } + } + } + + private func updateCornerRadius() { + guard containerView.layer.cornerRadius != 0.0 else { + containerView.layer.masksToBounds = false + return + } + containerView.layer.masksToBounds = true + guard containerMargins.bottom == 0 else { return } + if #available(iOS 11, *) { + // Don't use `contentView.clipToBounds` because it prevents content view from expanding the height of a subview of it + // for the bottom overflow like Auto Layout settings of UIVisualEffectView in Main.storyboard of Example/Maps. + // Because the bottom of contentView must be fit to the bottom of a screen to work the `safeLayoutGuide` of a content VC. + containerView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] + } else { + // Can't use `containerView.layer.mask` because of a UIVisualEffectView issue in iOS 10, https://forums.developer.apple.com/thread/50854 + // Instead, a user should display rounding corners appropriately. + } + } + + private func updateBorder() { + containerView.layer.borderColor = borderColor?.cgColor + containerView.layer.borderWidth = borderWidth + } + + func add(contentView: UIView) { + containerView.addSubview(contentView) + self.contentView = contentView + /* contentView.frame = bounds */ // MUST NOT: Because the top safe area inset of a content VC will be incorrect. + contentView.translatesAutoresizingMaskIntoConstraints = false + + let topConstraint = contentView.topAnchor.constraint(equalTo: topAnchor, constant: containerMargins.top + contentInsets.top) + let leftConstraint = contentView.leftAnchor.constraint(equalTo: leftAnchor, constant: containerMargins.left + contentInsets.left) + let rightConstraint = rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: containerMargins.right + contentInsets.right) + let heightPadding = containerMargins.top + containerMargins.bottom + contentInsets.top + contentInsets.bottom + let heightConstraint = contentView.heightAnchor.constraint(equalTo: heightAnchor, constant: -heightPadding) + heightConstraint.priority = UILayoutPriority(999) + NSLayoutConstraint.activate([ + topConstraint, + leftConstraint, + rightConstraint, + heightConstraint, + ]) + self.contentViewTopConstraint = topConstraint + self.contentViewLeftConstraint = leftConstraint + self.contentViewRightConstraint = rightConstraint + self.contentViewHeightConstraint = heightConstraint + } +} diff --git a/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelTransitioning.swift b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelTransitioning.swift new file mode 100755 index 0000000..e55798c --- /dev/null +++ b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelTransitioning.swift @@ -0,0 +1,122 @@ +// +// Created by Shin Yamamoto on 2018/11/21. +// Copyright © 2018 Shin Yamamoto. All rights reserved. +// + +import UIKit + +class FloatingPanelModalTransition: NSObject, UIViewControllerTransitioningDelegate { + func animationController(forPresented presented: UIViewController, + presenting: UIViewController, + source: UIViewController) -> UIViewControllerAnimatedTransitioning? { + return FloatingPanelModalPresentTransition() + } + + func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { + return FloatingPanelModalDismissTransition() + } + + func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { + return FloatingPanelPresentationController(presentedViewController: presented, presenting: presenting) + } +} + +class FloatingPanelPresentationController: UIPresentationController { + override func presentationTransitionWillBegin() { + // Must call here even if duplicating on in containerViewWillLayoutSubviews() + // Because it let the floating panel present correctly with the presentation animation + addFloatingPanel() + } + + override func presentationTransitionDidEnd(_ completed: Bool) { + // For non-animated presentation + if let fpc = presentedViewController as? FloatingPanelController, fpc.position == .hidden { + fpc.show(animated: false, completion: nil) + } + } + + override func dismissalTransitionDidEnd(_ completed: Bool) { + if let fpc = presentedViewController as? FloatingPanelController { + // For non-animated dismissal + if fpc.position != .hidden { + fpc.hide(animated: false, completion: nil) + } + fpc.view.removeFromSuperview() + } + } + + override func containerViewWillLayoutSubviews() { + guard + let fpc = presentedViewController as? FloatingPanelController + else { fatalError() } + + /* + * Layout the views managed by `FloatingPanelController` here for the + * sake of the presentation and dismissal modally from the controller. + */ + addFloatingPanel() + + // Forward touch events to the presenting view controller + (fpc.view as? FloatingPanelPassThroughView)?.eventForwardingView = presentingViewController.view + + fpc.backdropView.dismissalTapGestureRecognizer.isEnabled = true + } + + @objc func handleBackdrop(tapGesture: UITapGestureRecognizer) { + presentedViewController.dismiss(animated: true, completion: nil) + } + + private func addFloatingPanel() { + guard + let containerView = self.containerView, + let fpc = presentedViewController as? FloatingPanelController + else { fatalError() } + + containerView.addSubview(fpc.view) + fpc.view.frame = containerView.bounds + fpc.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] + } +} + +class FloatingPanelModalPresentTransition: NSObject, UIViewControllerAnimatedTransitioning { + func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { + guard + let fpc = transitionContext?.viewController(forKey: .to) as? FloatingPanelController + else { fatalError()} + + let animator = fpc.behavior.addAnimator(fpc, to: fpc.layout.initialPosition) + return TimeInterval(animator.duration) + } + + func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + guard + let fpc = transitionContext.viewController(forKey: .to) as? FloatingPanelController + else { fatalError() } + + fpc.show(animated: true) { + transitionContext.completeTransition(!transitionContext.transitionWasCancelled) + } + } +} + +class FloatingPanelModalDismissTransition: NSObject, UIViewControllerAnimatedTransitioning { + func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { + guard + let fpc = transitionContext?.viewController(forKey: .from) as? FloatingPanelController + else { fatalError()} + + let animator = fpc.behavior.removeAnimator(fpc, from: fpc.position) + return TimeInterval(animator.duration) + } + + func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + guard + let fpc = transitionContext.viewController(forKey: .from) as? FloatingPanelController + else { fatalError() } + + fpc.hide(animated: true) { + transitionContext.completeTransition(!transitionContext.transitionWasCancelled) + } + } +} + diff --git a/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelView.swift b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelView.swift new file mode 100755 index 0000000..39e599a --- /dev/null +++ b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/FloatingPanelView.swift @@ -0,0 +1,19 @@ +// +// Created by Shin Yamamoto on 2018/11/21. +// Copyright © 2018 Shin Yamamoto. All rights reserved. +// + +import UIKit + +class FloatingPanelPassThroughView: UIView { + public weak var eventForwardingView: UIView? + public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + let hitView = super.hitTest(point, with: event) + switch hitView { + case self: + return eventForwardingView?.hitTest(self.convert(point, to: eventForwardingView), with: event) + default: + return hitView + } + } +} diff --git a/NavigineDemo/NavigineDemo/Libs/FloatingPanel/GrabberHandleView.swift b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/GrabberHandleView.swift new file mode 100755 index 0000000..865eebf --- /dev/null +++ b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/GrabberHandleView.swift @@ -0,0 +1,35 @@ +// +// Created by Shin Yamamoto on 2018/09/19. +// Copyright © 2018 Shin Yamamoto. All rights reserved. +// + +import UIKit + +public class GrabberHandleView: UIView { + + public var barColor = UIColor(displayP3Red: 0.76, green: 0.77, blue: 0.76, alpha: 1.0) { didSet { backgroundColor = barColor } } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + init() { + super.init(frame: .zero) + backgroundColor = barColor + } + + public override func layoutSubviews() { + super.layoutSubviews() + render() + } + + public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + let view = super.hitTest(point, with: event) + return view == self ? nil : view + } + + private func render() { + self.layer.masksToBounds = true + self.layer.cornerRadius = frame.size.height * 0.5 + } +} diff --git a/NavigineDemo/NavigineDemo/Libs/FloatingPanel/Logger.swift b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/Logger.swift new file mode 100755 index 0000000..561c4c6 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/Logger.swift @@ -0,0 +1,101 @@ +// +// Created by Shin Yamamoto on 2018/10/09. +// Copyright © 2018 Shin Yamamoto. All rights reserved. +// + +import Foundation +import os.log + +var log = { + return Logger() +}() + +struct Logger { + private let osLog: OSLog + private let s = DispatchSemaphore(value: 1) + + enum Level: Int, Comparable { + case debug = 0 + case info = 1 + case warning = 2 + case error = 3 + + var displayName: String { + switch self { + case .debug: + return "D/" + case .info: + return "I/" + case .warning: + return "Warning:" + case .error: + return "Error:" + } + } + @available(iOS 10.0, *) + var osLogType: OSLogType { + switch self { + case .debug: return .debug + case .info: return .info + case .warning: return .default + case .error: return .error + } + } + + static func < (lhs: Logger.Level, rhs: Logger.Level) -> Bool { + return lhs.rawValue < rhs.rawValue + } + } + + typealias Hook = ((String, Level) -> Void) + var hook: Hook? + + fileprivate init() { + osLog = OSLog(subsystem: "com.scenee.FloatingPanel", category: "FloatingPanel") + } + + private func log(_ level: Level, _ message: Any, _ arguments: [Any], function: String, line: UInt) { + _ = s.wait(timeout: .now() + 0.033) + defer { s.signal() } + + let extraMessage: String = arguments.map({ String(describing: $0) }).joined(separator: " ") + let log: String = { + switch level { + case .debug: + return "\(level.displayName) \(message) \(extraMessage) (\(function):\(line))" + default: + return "\(level.displayName) \(message) \(extraMessage)" + } + }() + + hook?(log, level) + + os_log("%@", log: osLog, type: level.osLogType, log) + } + + private func getPrettyFunction(_ function: String, _ file: String) -> String { + if let filename = file.split(separator: "/").last { + return filename + ":" + function + } else { + return file + ":" + function + } + } + + func debug(_ log: Any, _ arguments: Any..., function: String = #function, file: String = #file, line: UInt = #line) { + #if __FP_LOG + self.log(.debug, log, arguments, function: getPrettyFunction(function, file), line: line) + #endif + } + + func info(_ log: Any, _ arguments: Any..., function: String = #function, file: String = #file, line: UInt = #line) { + self.log(.info, log, arguments, function: getPrettyFunction(function, file), line: line) + } + + func warning(_ log: Any, _ arguments: Any..., function: String = #function, file: String = #file, line: UInt = #line) { + self.log(.warning, log, arguments, function: getPrettyFunction(function, file), line: line) + } + + func error(_ log: Any, _ arguments: Any..., function: String = #function, file: String = #file, line: UInt = #line) { + self.log(.error, log, arguments, function: getPrettyFunction(function, file), line: line) + } +} diff --git a/NavigineDemo/NavigineDemo/Libs/FloatingPanel/UIExtensions.swift b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/UIExtensions.swift new file mode 100755 index 0000000..7880816 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Libs/FloatingPanel/UIExtensions.swift @@ -0,0 +1,158 @@ +// +// Created by Shin Yamamoto on 2018/09/18. +// Copyright © 2018 Shin Yamamoto. All rights reserved. +// + +import UIKit + +protocol LayoutGuideProvider { + var topAnchor: NSLayoutYAxisAnchor { get } + var bottomAnchor: NSLayoutYAxisAnchor { get } +} +extension UILayoutGuide: LayoutGuideProvider {} + +class CustomLayoutGuide: LayoutGuideProvider { + let topAnchor: NSLayoutYAxisAnchor + let bottomAnchor: NSLayoutYAxisAnchor + init(topAnchor: NSLayoutYAxisAnchor, bottomAnchor: NSLayoutYAxisAnchor) { + self.topAnchor = topAnchor + self.bottomAnchor = bottomAnchor + } +} + +extension UIViewController { + @objc var layoutInsets: UIEdgeInsets { + if #available(iOS 11.0, *) { + return view.safeAreaInsets + } else { + return UIEdgeInsets(top: topLayoutGuide.length, + left: 0.0, + bottom: bottomLayoutGuide.length, + right: 0.0) + } + } + + var layoutGuide: LayoutGuideProvider { + if #available(iOS 11.0, *) { + return view!.safeAreaLayoutGuide + } else { + return CustomLayoutGuide(topAnchor: topLayoutGuide.bottomAnchor, + bottomAnchor: bottomLayoutGuide.topAnchor) + } + } +} + +protocol SideLayoutGuideProvider { + var leftAnchor: NSLayoutXAxisAnchor { get } + var rightAnchor: NSLayoutXAxisAnchor { get } +} + +extension UIView: SideLayoutGuideProvider {} +extension UILayoutGuide: SideLayoutGuideProvider {} + +// The reason why UIView has no extensions of safe area insets and top/bottom guides +// is for iOS10 compat. +extension UIView { + var sideLayoutGuide: SideLayoutGuideProvider { + if #available(iOS 11.0, *) { + return safeAreaLayoutGuide + } else { + return self + } + } + + var presentationFrame: CGRect { + return layer.presentation()?.frame ?? frame + } +} + +extension UIView { + func disableAutoLayout() { + let frame = self.frame + translatesAutoresizingMaskIntoConstraints = true + self.frame = frame + } + func enableAutoLayout() { + translatesAutoresizingMaskIntoConstraints = false + } + + static func performWithLinear(startTime: Double = 0.0, relativeDuration: Double = 1.0, _ animations: @escaping (() -> Void)) { + UIView.animateKeyframes(withDuration: 0.0, delay: 0.0, options: [.calculationModeCubic], animations: { + UIView.addKeyframe(withRelativeStartTime: startTime, relativeDuration: relativeDuration, animations: animations) + }, completion: nil) + } +} + +#if __FP_LOG +#if swift(>=4.2) +extension UIGestureRecognizer.State: CustomDebugStringConvertible { + public var debugDescription: String { + switch self { + case .began: return "began" + case .changed: return "changed" + case .failed: return "failed" + case .cancelled: return "cancelled" + case .ended: return "endeded" + case .possible: return "possible" + } + } +} +#else +extension UIGestureRecognizerState: CustomDebugStringConvertible { + public var debugDescription: String { + switch self { + case .began: return "began" + case .changed: return "changed" + case .failed: return "failed" + case .cancelled: return "cancelled" + case .ended: return "endeded" + case .possible: return "possible" + } + } +} +#endif +#endif + +extension UIScrollView { + var isLocked: Bool { + return !showsVerticalScrollIndicator && !bounces && isDirectionalLockEnabled + } +} + +extension UISpringTimingParameters { + public convenience init(dampingRatio: CGFloat, frequencyResponse: CGFloat, initialVelocity: CGVector = .zero) { + let mass = 1 as CGFloat + let stiffness = pow(2 * .pi / frequencyResponse, 2) * mass + let damp = 4 * .pi * dampingRatio * mass / frequencyResponse + self.init(mass: mass, stiffness: stiffness, damping: damp, initialVelocity: initialVelocity) + } +} + +extension CGPoint { + static var nan: CGPoint { + return CGPoint(x: CGFloat.nan, y: CGFloat.nan) + } + static func - (left: CGPoint, right: CGPoint) -> CGPoint { + return CGPoint(x: left.x - right.x, y: left.y - right.y) + } +} + +extension UITraitCollection { + func shouldUpdateLayout(from previous: UITraitCollection) -> Bool { + return previous.horizontalSizeClass != horizontalSizeClass + || previous.verticalSizeClass != verticalSizeClass + || previous.preferredContentSizeCategory != preferredContentSizeCategory + || previous.layoutDirection != layoutDirection + } +} + +extension NSLayoutConstraint { + static func activate(constraint: NSLayoutConstraint?) { + guard let constraint = constraint else { return } + self.activate([constraint]) + } + static func deactivate(constraint: NSLayoutConstraint?) { + guard let constraint = constraint else { return } + self.deactivate([constraint]) + } +} diff --git a/NavigineDemo/NavigineDemo/Resources/img/blue_dot.png b/NavigineDemo/NavigineDemo/Resources/img/blue_dot.png new file mode 100644 index 0000000..5c94f7b Binary files /dev/null and b/NavigineDemo/NavigineDemo/Resources/img/blue_dot.png differ diff --git a/NavigineDemo/NavigineDemo/SceneDelegate.swift b/NavigineDemo/NavigineDemo/SceneDelegate.swift old mode 100644 new mode 100755 index 3a96415..637d99b --- a/NavigineDemo/NavigineDemo/SceneDelegate.swift +++ b/NavigineDemo/NavigineDemo/SceneDelegate.swift @@ -1,11 +1,3 @@ -// -// SceneDelegate.swift -// NavigineDemo -// -// Created by mrcrambo on 02/10/2020. -// Copyright © 2020 navigine. All rights reserved. -// - import UIKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { diff --git a/NavigineDemo/NavigineDemo/Storyboards/AddBeacon.storyboard b/NavigineDemo/NavigineDemo/Storyboards/AddBeacon.storyboard new file mode 100755 index 0000000..f0e0e72 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Storyboards/AddBeacon.storyboard @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NavigineDemo/NavigineDemo/Storyboards/Debug.storyboard b/NavigineDemo/NavigineDemo/Storyboards/Debug.storyboard new file mode 100755 index 0000000..2814910 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Storyboards/Debug.storyboard @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NavigineDemo/NavigineDemo/Base.lproj/LaunchScreen.storyboard b/NavigineDemo/NavigineDemo/Storyboards/LaunchScreen.storyboard old mode 100644 new mode 100755 similarity index 100% rename from NavigineDemo/NavigineDemo/Base.lproj/LaunchScreen.storyboard rename to NavigineDemo/NavigineDemo/Storyboards/LaunchScreen.storyboard diff --git a/NavigineDemo/NavigineDemo/Storyboards/LocationsList.storyboard b/NavigineDemo/NavigineDemo/Storyboards/LocationsList.storyboard new file mode 100755 index 0000000..de9f7bc --- /dev/null +++ b/NavigineDemo/NavigineDemo/Storyboards/LocationsList.storyboard @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NavigineDemo/NavigineDemo/Storyboards/Main.storyboard b/NavigineDemo/NavigineDemo/Storyboards/Main.storyboard new file mode 100755 index 0000000..36e34e8 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Storyboards/Main.storyboard @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NavigineDemo/NavigineDemo/Storyboards/Navigation.storyboard b/NavigineDemo/NavigineDemo/Storyboards/Navigation.storyboard new file mode 100755 index 0000000..2862698 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Storyboards/Navigation.storyboard @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + Circe-Bold + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NavigineDemo/NavigineDemo/Storyboards/Profile.storyboard b/NavigineDemo/NavigineDemo/Storyboards/Profile.storyboard new file mode 100755 index 0000000..c302cd1 --- /dev/null +++ b/NavigineDemo/NavigineDemo/Storyboards/Profile.storyboard @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NavigineDemo/NavigineDemo/ViewController.swift b/NavigineDemo/NavigineDemo/ViewController.swift old mode 100644 new mode 100755 index d9b4ff4..83cf95c --- a/NavigineDemo/NavigineDemo/ViewController.swift +++ b/NavigineDemo/NavigineDemo/ViewController.swift @@ -1,38 +1,50 @@ -// -// ViewController.swift -// NavigineDemo -// -// Created by mrcrambo on 02/10/2020. -// Copyright © 2020 navigine. All rights reserved. -// - import UIKit -class ViewController: UIViewController { - - var mNavigineSdk: NCNavigineSdk? - var mLocationManager: NCLocationManager? +class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { + + @IBOutlet weak var mTableView: UITableView! - @IBOutlet weak var mLocationView: NCLocationView! + var mLocationsList: [String] = [] + + var mNavigineSdk: NCNavigineSdk? + var mLocationListManager: NCLocationListManager? override func viewDidLoad() { super.viewDidLoad() + // Do any additional setup after loading the view. + + mNavigineSdk = NCNavigineSdk.createInstance("4EE6-9A3F-F126-5FE6", server: "https://api.navigine.com") + + mLocationListManager = mNavigineSdk?.getLocationListManager() - mNavigineSdk = NCNavigineSdk.getInstance()! + mLocationListManager?.add(self) - mLocationManager = mNavigineSdk?.getLocationManager()! - mLocationManager?.add(self) - mLocationManager?.setLocation(Int32(Constants.LOCATION_ID)) + self.mTableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") } + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return self.mLocationsList.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell:UITableViewCell = self.mTableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath as IndexPath) + + cell.textLabel?.text = self.mLocationsList[indexPath.row] + + return cell + } } -extension ViewController: NCLocationListener { - func onDownloadProgress(_ received: Int32, total: Int32) { } - - func onLocationLoaded(_ location: NCLocation?) { - mLocationView.setSublocation(Int32(Constants.SUBLOCATION_ID)) +extension ViewController: NCLocationListListener { + func onLocationListLoaded(_ locationInfos: [NSNumber : NCLocationInfo]) { + self.mLocationsList.removeAll() + for el in locationInfos { + self.mLocationsList.append(el.value.name) + } + self.mTableView.reloadData() } + + func onLocationListFailed(_ error: Error?) { - func onLocationFailed(_ error: Error?) { } + } } diff --git a/NavigineDemo/NavigineDemo/ViewControllers/AddBeaconController.swift b/NavigineDemo/NavigineDemo/ViewControllers/AddBeaconController.swift new file mode 100755 index 0000000..11ee4af --- /dev/null +++ b/NavigineDemo/NavigineDemo/ViewControllers/AddBeaconController.swift @@ -0,0 +1,7 @@ +import Foundation + +class AddBeaconController: UIViewController { + + override func viewDidLoad() { + } +} diff --git a/NavigineDemo/NavigineDemo/ViewControllers/DebugController.swift b/NavigineDemo/NavigineDemo/ViewControllers/DebugController.swift new file mode 100755 index 0000000..e9ad73f --- /dev/null +++ b/NavigineDemo/NavigineDemo/ViewControllers/DebugController.swift @@ -0,0 +1,85 @@ +import Foundation + +class DebugController: UIViewController { + + @IBOutlet weak var mUuid: UILabel! + @IBOutlet weak var mErrorCode: UILabel! + @IBOutlet weak var mNavResult: UILabel! + @IBOutlet weak var mAccellerometer: UILabel! + @IBOutlet weak var mMagnetometer: UILabel! + @IBOutlet weak var mGyro: UILabel! + @IBOutlet weak var mGps: UILabel! + @IBOutlet weak var mBleCount: UILabel! + + var textView: UITextView! + + override func viewDidLoad() { + textView = UITextView() + textView.translatesAutoresizingMaskIntoConstraints = false + self.view.addSubview(textView) + NavigineApp.mMeasurementManager?.add(self) + NavigineApp.mNavigationManager?.add(self) + + textView.topAnchor.constraint(equalTo: self.mBleCount.bottomAnchor).isActive = true + textView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true + textView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 20.0).isActive = true + textView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true + textView.font = .systemFont(ofSize: 8) + textView.isEditable = false + } +} + +extension DebugController: NCMeasurementListener { + func onSensorMeasurementDetected(_ sensors: [NSNumber : NCSensorMeasurement]) { + for el in sensors { + switch el.value.type { + case NCSensorType.ACCELEROMETER: + mAccellerometer.text = "Accelerometer: \(String(format: "%.2f", el.value.values.x)), \(String(format: "%.2f", el.value.values.y)), \(String(format: "%.2f", el.value.values.z))" + break + case NCSensorType.MAGNETOMETER: + mMagnetometer.text = "Magnetometer: \(String(format: "%.2f", el.value.values.x)), \(String(format: "%.2f", el.value.values.y)), \(String(format: "%.2f", el.value.values.z))" + break + case .GYROSCOPE: + mGyro.text = "Gyroscope: \(String(format: "%.2f", el.value.values.x)), \(String(format: "%.2f", el.value.values.y)), \(String(format: "%.2f", el.value.values.z))" + break + case .LOCATION: + mGps.text = "GPS: lat: \(String(format: "%.3f", el.value.values.x)) lon: \(String(format: "%.3f", el.value.values.y))" + break + case .BAROMETER: + break + case .ORIENTATION: + break + @unknown default: + break + } + } + } + + func onSignalMeasurementDetected(_ signals: [String : NCSignalMeasurement]){ + var signalsText: String = "" + var i = 1 + for item in signals { + let id = item.key.replacingOccurrences(of: "(", with: "").replacingOccurrences(of: ")", with: "").split(separator: ",") + if item.value.type == NCSignalType.BEACON { + signalsText += "\(String(format: "%02d", i))) \(item.value.rssi) \(String(format: "%05d", Int(String(id[0]))!)) \(String(format: "%05d", Int(String(id[1]))!)) \(id[2])\n" + } else if item.value.type == NCSignalType.EDDYSTONE { + signalsText += "\(String(format: "%02d", i))) \(item.value.rssi) \(id[0]) \(id[1])\n" + } + i += 1 + } + + textView.text = signalsText + } +} + +extension DebugController: NCPositionListener { + func onPositionUpdated(_ position: NCPosition) { + mErrorCode.text = "Error code: 0 Sublocation: \(position.sublocationId)" + mNavResult.text = "Result: x: \(position.point.x) y: \(position.point.y)" + } + + func onPositionError(_ error: Error?) { + mErrorCode.text = "Error code: Sublocation:" + mNavResult.text = "Result:" + } +} diff --git a/NavigineDemo/NavigineDemo/ViewControllers/LocationSearchController.swift b/NavigineDemo/NavigineDemo/ViewControllers/LocationSearchController.swift new file mode 100755 index 0000000..df2a05c --- /dev/null +++ b/NavigineDemo/NavigineDemo/ViewControllers/LocationSearchController.swift @@ -0,0 +1,61 @@ +import UIKit + +class LocationSearchController : UISearchController { + // MARK: - Properties + weak var dataSource: LocationListDataSource? + var filteredLocations: [NCLocationInfo] = [] + var isSearchBarEmpty: Bool { + return self.searchBar.text?.isEmpty ?? true + } + var isFiltering: Bool { + return self.isActive && !isSearchBarEmpty + } + + // MARK: Initializers + override init(searchResultsController: UIViewController?) { + super.init(searchResultsController: nil) + setup() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } + + override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + } + + private func setup() { + searchResultsUpdater = self + dimsBackgroundDuringPresentation = true + obscuresBackgroundDuringPresentation = false + hidesNavigationBarDuringPresentation = false + + searchBar.placeholder = "Search" + searchBar.searchBarStyle = .minimal + searchBar.sizeToFit() + } + + private func filterContentForSearchText() { + guard let dataSource = self.dataSource else { + return + } + + filteredLocations = + dataSource.mLocationsList.filter { (location: NCLocationInfo) -> Bool in + let searchText = searchBar.text! + return location.name.lowercased().contains(searchText.lowercased()) + } + + dataSource.didUpdateSearchResults() + } + +} + +// MARK: - UISearchResultsUpdating methods +extension LocationSearchController: UISearchResultsUpdating { + func updateSearchResults(for searchController: UISearchController) { + filterContentForSearchText() + } +} + diff --git a/NavigineDemo/NavigineDemo/ViewControllers/LocationsListController.swift b/NavigineDemo/NavigineDemo/ViewControllers/LocationsListController.swift new file mode 100755 index 0000000..486add0 --- /dev/null +++ b/NavigineDemo/NavigineDemo/ViewControllers/LocationsListController.swift @@ -0,0 +1,124 @@ +import Foundation + +protocol LocationListDataSource : class { + var mLocationsList: [NCLocationInfo] { get } + func didUpdateSearchResults() +} + +struct LoadProgress { + var currentLocationId: Int32 = -1 + var progress: CGFloat = 0.0 +} + +class LocationsListController: UIViewController { + + @IBOutlet weak var mTableView: UITableView! + + var mLocationsList: [NCLocationInfo] = [] + + let mSearchController = LocationSearchController(searchResultsController: nil) + + var currentProgress: LoadProgress! + + override func viewDidLoad() { + super.viewDidLoad() + + NavigineApp.mLocationListManager?.add(self) + NavigineApp.mLocationManager?.add(self) + + mSearchController.dataSource = self + mSearchController.searchBar.placeholder = "Search" + if #available(iOS 11.0, *) { + navigationItem.searchController = mSearchController + navigationItem.hidesSearchBarWhenScrolling = false + } else { } + + currentProgress = LoadProgress(currentLocationId: -1, progress: 0.0) + } +} + +extension LocationsListController: UITableViewDelegate, UITableViewDataSource{ + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if mSearchController.isFiltering { + return mSearchController.filteredLocations.count + } + + return self.mLocationsList.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let item: NCLocationInfo + if mSearchController.isFiltering { + item = mSearchController.filteredLocations[indexPath.row] + } else { + item = mLocationsList[indexPath.row] + } + + if let cell = tableView.dequeueReusableCell(withIdentifier:"cell", for: indexPath) as? LocationItemCell { + cell.nameView.text = item.name + cell.versionView.text = String(item.version) + + if item.id == currentProgress.currentLocationId { + cell.progressBar.progress = currentProgress.progress + } + + cell.progressBar.isHidden = item.id == currentProgress.currentLocationId ? false : true + + return cell + } + return UITableViewCell() + } + + func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { + return UIView() + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if currentProgress.currentLocationId == mLocationsList[indexPath.row].id { + return + } + NavigineApp.mLocationManager?.setLocationId(mLocationsList[indexPath.row].id) + currentProgress.currentLocationId = mLocationsList[indexPath.row].id + currentProgress.progress = 0.0 + self.mTableView.reloadData() + + NavigineApp.mLocationListManager?.updateLocationList() + } +} + +extension LocationsListController: NCLocationListListener { + func onLocationListLoaded(_ locationInfos: [NSNumber : NCLocationInfo]) { + self.mLocationsList.removeAll() + for el in locationInfos { + self.mLocationsList.append(el.value) + } + self.mTableView.reloadData() + } + + func onLocationListFailed(_ error: Error?) { + + } +} + +extension LocationsListController: LocationListDataSource { + func didUpdateSearchResults() { + self.mTableView.reloadData() + } +} + +extension LocationsListController: NCLocationListener { + func onLocationLoaded(_ location: NCLocation?) { + currentProgress.progress = 1.0 + self.mTableView.reloadData() + } + + func onDownloadProgress(_ received: Int32, total: Int32) { + let p = CGFloat(received) / CGFloat(total) + if (abs(p - currentProgress.progress) * 100 > 1) { + currentProgress.progress = p + self.mTableView.reloadData() + } + } + + func onLocationFailed(_ error: Error?) { } +} diff --git a/NavigineDemo/NavigineDemo/ViewControllers/NavigationController.swift b/NavigineDemo/NavigineDemo/ViewControllers/NavigationController.swift new file mode 100755 index 0000000..45d03a2 --- /dev/null +++ b/NavigineDemo/NavigineDemo/ViewControllers/NavigationController.swift @@ -0,0 +1,377 @@ +import Foundation + +class NavigationController: UIViewController { + + @IBOutlet weak var mLocationView: NCLocationView! + @IBOutlet weak var mCollectionView: UICollectionView! + @IBOutlet weak var mLevelsButton: UIButton! + @IBOutlet weak var mRecLogs: UIButton! + + @IBOutlet weak var mZoomInBtn: UIButton! + @IBOutlet weak var mZoomOutBtn: UIButton! + + var mBottomSheet: FloatingPanelController! + + var mLocation: NCLocation! + + var mRecording: Bool = false + + var mAttached: Bool = false + + let reuseIdentifier = "subloc" + + var subLoc: NCSublocation! + + var mSublocationsList: [NCSublocation] = [] + + var mVenuesMap = [String : [NCIconMapObject]]() + + var mPosition: NCIconMapObject! + var mCirclePosition: NCCircleMapObject! + var mPolyline: NCPolylineMapObject! + + override func viewDidLoad() { + NavigineApp.mLocationManager?.add(self) + NavigineApp.mNavigationManager?.add(self) + NavigineApp.mZoneManager?.add(self) + NavigineApp.mRouteManager?.add(self) + + mRecLogs.setTitleColor(UIColor.blue, for: .normal) + mLevelsButton.addTarget(self, action: #selector(levelsClicked), for: .touchUpInside) + mRecLogs.addTarget(self, action: #selector(recClicked), for: .touchUpInside) + + mLocationView.gestureDelegate = self + +// NavigineApp.mMeasurementManager?.addWifiGenerator("C83A353BFF20", timeout: 1000, rssiMin: -75, rssiMax: -55) +// +// NavigineApp.mMeasurementManager?.addBeaconGenerator( +// "F7826DA6-4FA2-4E98-8024-BC5B71E0893E", +// major: 1, +// minor: 1, +// power: 32, timeout: 100, rssiMin: -89, rssiMax: -55); +// +// NavigineApp.mMeasurementManager?.addBeaconGenerator( +// "00A10979-B448-3314-2059-DC5DEB6A1005", +// major: 2968, +// minor: 26457, +// power: 32, timeout: 100, rssiMin: -89, rssiMax: -55); + + mZoomInBtn.isHidden = true + mZoomOutBtn.isHidden = true + + mPosition = mLocationView.addIconMapObject() + mPosition.setBitmap(UIImage(named: "blue_dot.png")) + mPosition.setSize(Float(30), height: Float(30)) + mPosition.setVisible(false) + + mPolyline = mLocationView.addPolylineMapObject() + mPolyline.setColor(0.0, green: 0.5, blue: 0.5, alpha: 1) + mPolyline.setWidth(Float(0.1)) + mPolyline.setVisible(false) + } + + @objc func levelsClicked(_ sender: AnyObject?) { + mCollectionView.isHidden = !mCollectionView.isHidden + mZoomInBtn.isHidden = !mZoomInBtn.isHidden + mZoomOutBtn.isHidden = !mZoomOutBtn.isHidden + } + + @objc func recClicked(_ sender: AnyObject?) { + mAttached = !mAttached; + if !mRecording { + mRecLogs.setTitle("Stop", for: .normal) + mRecLogs.setTitleColor(UIColor.red, for: .normal) + NavigineApp.mNavigationManager?.startLogRecording() + } else { + mRecLogs.setTitle("Rec", for: .normal) + mRecLogs.setTitleColor(UIColor.blue, for: .normal) + NavigineApp.mNavigationManager?.stopLogRecording() + } + mRecording = !mRecording + } + + @IBAction func zoomIn(_ sender: Any) { + let zoomFactor = mLocationView.zoomFactor + mLocationView.zoomFactor = zoomFactor * 2 + } + + + @IBAction func zoomOut(_ sender: Any) { + let zoomFactor = mLocationView.zoomFactor + mLocationView.zoomFactor = zoomFactor / 2 + } +} + +extension NavigationController : NCGestureRecognizerDelegate { + func locationView(_ view: NCLocationView!, recognizer: UIGestureRecognizer!, didRecognizeSingleTapGesture location: CGPoint) { + view.pickMapObject(at: location) + } + + func locationView(_ view: NCLocationView!, recognizer: UIGestureRecognizer!, didRecognizeLongPressGesture location: CGPoint) { + NavigineApp.mRouteManager?.clearTargets() + + let point = NCLocationPoint(point: NCPoint.init(x: 0, y: 0), locationId: mLocation.id , sublocationId: subLoc.id) + NavigineApp.mRouteManager?.setTarget(point); + } +} + +extension NavigationController { + +} + +extension NavigationController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + self.mSublocationsList.count + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! MyCollectionViewCell + + cell.mLabel.text = self.mSublocationsList[indexPath.item].name + cell.backgroundColor = UIColor.white + cell.contentView.layer.cornerRadius = 6 + cell.contentView.layer.borderWidth = 0.5 + cell.contentView.layer.borderColor = UIColor.black.cgColor + + return cell + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + if subLoc != mSublocationsList[indexPath.row] { + subLoc = mSublocationsList[indexPath.row] + mLocationView.setSublocationId(subLoc.id) + + mLocationView.maxZoomFactor = mLocationView.frame.width * 2 / CGFloat(subLoc.width) + mLocationView.zoomFactor = mLocationView.frame.width / CGFloat(subLoc.width) + + collectionView.isHidden = true + mZoomInBtn.isHidden = false + mZoomOutBtn.isHidden = false + } + } + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + let yourWidth = (collectionView.bounds.width - 30) / 2.0 + let yourHeight = (collectionView.bounds.height - 20 - mLevelsButton.frame.size.height) / 4.0 + + return CGSize(width: yourWidth, height: yourHeight) + } + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { + return UIEdgeInsets.init(top: mLevelsButton.frame.size.height, left: 10, bottom: 10, right: 10) + } + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { + return 5 + } + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { + return 5 + } +} + +extension NavigationController: NCLocationListener { + func onDownloadProgress(_ received: Int32, total: Int32) { } + + func onLocationLoaded(_ location: NCLocation?) { + self.mSublocationsList.removeAll() + mLocation = location + mCirclePosition = mLocationView.addCircleMapObject(); + mCirclePosition.setColor(0.5, green: 0, blue: 0, alpha: 1) + mCirclePosition.setRadius(5) + + for subloc in location!.sublocations { + self.mSublocationsList.append(subloc) + for venue in subloc.venues { + let category = location?.getCategoryById(venue.categoryId) + let venueMapObject = mLocationView.addIconMapObject() + venueMapObject.setPosition(NCLocationPoint.init(point: venue.point, locationId: venue.locationId, sublocationId: venue.sublocationId)) + let cat = category + let imageId = cat?.imageId + if mVenuesMap[imageId!] == nil { + mVenuesMap[(category?.imageId!)!] = [NCIconMapObject](); + } + mVenuesMap[(category?.imageId!)!]!.append(venueMapObject) + } + } + + for imageId in mVenuesMap.keys { + NavigineApp.mResourceManager?.loadImage(imageId, listener: self) + } + self.mCollectionView.isHidden = false + self.mCollectionView.reloadData() + } + + func onLocationFailed(_ error: Error?) { + + } +} + +extension NavigationController: NCRouteListener { + func onPathsUpdated(_ paths: [NCRoutePath]) { + var points: [NCPoint] = [] + for point in paths[0].points { + points.append(point.point) + } + + let polyline = NCLocationPolyline.init(polyline: NCPolyline.init(points: points), locationId: subLoc.location, sublocationId: subLoc.id) + mPolyline.setPolyLine(polyline) + mPolyline.setVisible(true) + } +} + +extension NavigationController: NCPositionListener { + func onPositionUpdated(_ position: NCPosition) { + if (mPosition != nil) { + let locationPoint = NCLocationPoint.init(point: position.point, locationId: position.locationId, sublocationId: position.sublocationId) + mPosition.setPositionAnimated(locationPoint, duration: 1.0, type: NCAnimationType.cubic) + mPosition.setVisible(true) + } + } + + func onPositionError(_ error: Error?) { + mCirclePosition.setVisible(false) + } +} + +extension NavigationController: NCZoneListener { + func onEnter(_ zone: NCZone?) { + print("OnEnter zone \(String(describing: zone?.name))") + } + + func onLeave(_ zone: NCZone?) { + print("onLeave zone \(String(describing: zone?.name))") + } + + +} + +extension NavigationController: NCResourceListener { + func onLoaded(_ imageId: String, image: NCImage?) { + let decoder = NCBitmapRegionDecoder.newInstance(image!.data, length: image!.width * image!.height) + let bitmap = decoder?.decodeRegion(NCRectangle(x: 0, y: 0, width: Float(image!.width), height: Float(image!.height)), sampleSize: 1) + let venuesMapObjects = mVenuesMap[imageId] + for venueMapObject in venuesMapObjects! { + venueMapObject.setBitmap(bitmap) + venueMapObject.setSize(20, height: 20) + } + } + + func onFailed(_ imageId: String, error: Error?) { } +} + +extension NavigationController: FloatingPanelControllerDelegate { + func addMainPanel(with contentVC: UIViewController) { + + let oldBottomSheet = mBottomSheet + + mBottomSheet = FloatingPanelController() + mBottomSheet.set(contentViewController: contentVC) + + mBottomSheet.contentInsetAdjustmentBehavior = .always + + mBottomSheet.surfaceView.cornerRadius = 6.0 + mBottomSheet.surfaceView.shadowHidden = false + + mBottomSheet.isRemovalInteractionEnabled = true + mBottomSheet.delegate = self + + let backdropTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleBackdrop(tapGesture:))) + mBottomSheet.backdropView.addGestureRecognizer(backdropTapGesture) + + if let oldBottomSheet = oldBottomSheet { + oldBottomSheet.removePanelFromParent(animated: true, completion: { + self.mBottomSheet.addPanel(toParent: self, belowView: nil, animated: true) + }) + } else { + mBottomSheet.addPanel(toParent: self, belowView: nil, animated: true) + } + } + + + @objc + func handleBackdrop(tapGesture: UITapGestureRecognizer) { + switch tapGesture.view { + case mBottomSheet.backdropView: + mBottomSheet.hide(animated: true, completion: nil) + default: + break + } + } + + func floatingPanel(_ vc: FloatingPanelController, contentOffsetForPinning trackedScrollView: UIScrollView) -> CGPoint { + return CGPoint(x: 0.0, y: 0.0 - trackedScrollView.contentInset.top) + } + + func floatingPanel(_ vc: FloatingPanelController, layoutFor newCollection: UITraitCollection) -> FloatingPanelLayout? { + guard let viewController = vc.contentViewController else { + return RemovablePanelLayout() + } + + if (viewController.isKind(of: VenueDetailsViewController.self)) { + return VenueDetailsViewController.VenueDetailsSheetLayout() + } + + return RemovablePanelLayout() + } + + func floatingPanel(_ vc: FloatingPanelController, shouldRecognizeSimultaneouslyWith gestureRecognizer: UIGestureRecognizer) -> Bool { + return true + } + + func floatingPanelDidEndDraggingToRemove(_ vc: FloatingPanelController, withVelocity velocity: CGPoint) { + mBottomSheet.removePanelFromParent(animated: true) + mBottomSheet = nil + guard let viewController = vc.contentViewController else { + return + } + } + + func floatingPanelDidEndDragging(_ vc: FloatingPanelController, withVelocity velocity: CGPoint, targetPosition: FloatingPanelPosition) { + + } + + func floatingPanelDidMove(_ vc: FloatingPanelController) { + // guard let viewController = vc.contentViewController else { + // return + // } + // if (viewController.isKind(of: VenueDetailsViewController.self)) { + // let controller = viewController as! VenueDetailsViewController + // controller.setPosition(position: targetPosition) + // } + } + + func floatingPanelDidEndRemove(_ vc: FloatingPanelController) { + // switch vc { + // case settingsPanelVC: + // settingsPanelVC = nil + // default: + // break + // } + } +} + +/** + - Attention: `FloatingPanelLayout` must not be applied by the parent view + controller of a floating panel. But here `SampleListViewController` adopts it + purposely to check if the library prints an appropriate warning. + */ +class RemovablePanelLayout: FloatingPanelIntrinsicLayout { + var supportedPositions: Set { + return [.half] + } + var initialPosition: FloatingPanelPosition { + return .half + } + var topInteractionBuffer: CGFloat { + return 30.0 + } + + func insetFor(position: FloatingPanelPosition) -> CGFloat? { + switch position { + case .half: return 200.0 + default: return nil + } + } +} + diff --git a/NavigineDemo/NavigineDemo/ViewControllers/ProfileController.swift b/NavigineDemo/NavigineDemo/ViewControllers/ProfileController.swift new file mode 100755 index 0000000..266822a --- /dev/null +++ b/NavigineDemo/NavigineDemo/ViewControllers/ProfileController.swift @@ -0,0 +1,50 @@ +import Foundation + +class ProfileController: UIViewController { + + @IBOutlet weak var mLogsTable: UITableView! + @IBOutlet weak var mUpdate: UIButton! + + var mLogsList: [String] = [] + + override func viewDidLoad() { + mLogsList.removeAll() + for el in (NavigineApp.mResourceManager?.getLogsList())! { + mLogsList.append(el) + } + self.mLogsTable.reloadData() + + mUpdate.addTarget(self, action: #selector(update), for: .touchUpInside) + } + + @objc func update(_ sender: AnyObject?) { + mLogsList.removeAll() + for el in (NavigineApp.mResourceManager?.getLogsList())! { + mLogsList.append(el) + } + self.mLogsTable.reloadData() + } +} + +extension ProfileController: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return self.mLogsList.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + if let cell = tableView.dequeueReusableCell(withIdentifier:"logs", for: indexPath) as? LogsItemCell { + cell.mLogName.text = self.mLogsList[indexPath.row] + + return cell + } + return UITableViewCell() + } + + func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { + return UIView() + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + } +} diff --git a/NavigineDemo/NavigineDemo/ViewControllers/SearchLocationsController.swift b/NavigineDemo/NavigineDemo/ViewControllers/SearchLocationsController.swift new file mode 100755 index 0000000..550a5ec --- /dev/null +++ b/NavigineDemo/NavigineDemo/ViewControllers/SearchLocationsController.swift @@ -0,0 +1,62 @@ +import UIKit + +class SearchLocationsController : UISearchController { + // MARK: - Properties + var dataSource: LocationListDataSource? + var didUpdateSearchResults: ((_ for: UISearchController) -> Void)? + var filteredLocations: [NCLocationInfo] = [] + var isSearchBarEmpty: Bool { + return self.searchBar.text?.isEmpty ?? true + } + var isFiltering: Bool { + return self.isActive && !isSearchBarEmpty + } + + // MARK: Initializers + override init(searchResultsController: UIViewController?) { + super.init(searchResultsController: nil) + setup() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } + + override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + } + + private func setup() { + searchResultsUpdater = self + dimsBackgroundDuringPresentation = true + obscuresBackgroundDuringPresentation = false + hidesNavigationBarDuringPresentation = false + + searchBar.placeholder = "Search" + searchBar.searchBarStyle = .minimal + searchBar.sizeToFit() + } + + private func filterContentForSearchText() { + guard let dataSource = self.dataSource else { + return + } + + filteredLocations = + dataSource.locations.filter { (location: NCLocationInfo) -> Bool in + let searchText = searchBar.text! + return location.name.lowercased().contains(searchText.lowercased()) + } + } + +} + +// MARK: - UISearchResultsUpdating methods +extension SearchLocationsController: UISearchResultsUpdating { + func updateSearchResults(for searchController: UISearchController) { + filterContentForSearchText() + if let callback = self.didUpdateSearchResults { + callback(searchController) + } + } +} diff --git a/NavigineDemo/NavigineDemo/ViewControllers/TabBarController.swift b/NavigineDemo/NavigineDemo/ViewControllers/TabBarController.swift new file mode 100755 index 0000000..107aeb7 --- /dev/null +++ b/NavigineDemo/NavigineDemo/ViewControllers/TabBarController.swift @@ -0,0 +1,27 @@ +import UIKit + +class TabBarController: UITabBarController { + + override func viewDidLoad() { + + NavigineApp.initWith(userHash: "0000-0000-0000-0000", serverUrl: "https://api.navigine.com") + + let selectedColor = UIColor(red: 62.0 / 255.0, green: 157.0 / 255.0, blue: 202.0 / 255.0, alpha: 1.0) + + let normalColor = UIColor(red: 250 / 255.0, green: 250 / 255.0, blue: 250 / 255.0, alpha: 1.0) + + UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: selectedColor], for: .selected) + + UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: normalColor], for: .normal) + + tabBar.tintColor = selectedColor + tabBar.unselectedItemTintColor = normalColor + } + + override func viewWillLayoutSubviews() { + super.viewWillLayoutSubviews() + + tabBar.frame.size.height = 56 + tabBar.frame.origin.y = view.frame.height - 56 + } +} diff --git a/README.md b/README.md index 1fde552..e7a70e2 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ The NavigineDemo subfolder in this repository contains source files that you can To get the Navigine demo application for iOS, - Either find the [Navigine application in the Apple Store](https://itunes.apple.com/ru/app/navigine/id972099798) using your iOS device -- Or compile the application yourself [using source code, available at GitHub](https://github.com/Navigine/iOS-SDK-2.0). +- Or compile the application yourself [using source code, available at GitHub](https://github.com/Navigine/Indoor-Navigation-iOS-Mobile-SDK-2.0). For complete guidelines on using the Demo, refer to the [corresponding sections in the Navigine User Manual](http://docs.navigine.com/ud_ios_demo.html), or refer to the Help file incorporated into the application. @@ -32,15 +32,33 @@ For complete guidelines on using the Demo, refer to the [corresponding sections Navigine SDK for iOS applications enables you to develop your own indoor navigation apps using the well-developed methods, classes, and functions created by the Navigine team. The SDK file resides in the libs folder. -Find formal description of Navigine-SDK API including the list of classes and their public fields and methods at [Navigine SDK wiki](https://github.com/Navigine/iOS-SDK-2.0/wiki). +Find formal description of Navigine-SDK API including the list of classes and their public fields and methods at [Navigine SDK wiki](https://github.com/Navigine/Indoor-Navigation-iOS-Mobile-SDK-2.0/wiki). -### Using .framework file in XCode +## Installation with CocoaPods -- Download `navigine.framework.zip` file from current repositories `Frameworks` folder and unarchive it; -- In your project create `Frameworks` folder and move `navigine.framework` to there; -- Embed and sign it, add Bridging Headers file; -- Start using Navigine SDK. +[CocoaPods](http://cocoapods.org) is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like Navigine in your projects. See the ["Getting Started" guide for more information](https://github.com/Navigine/Indoor-Navigation-iOS-Mobile-SDK-2.0/Getting-Started). You can install it with the following command: -### Using with CocoaPods +```bash +$ gem install cocoapods +``` -Will be added soon... +> CocoaPods 0.39.0+ is required to build Navigine 2.0.0+. + +#### Podfile + +To integrate Navigine into your Xcode project using CocoaPods, specify it in your `Podfile`: + +```ruby +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, '9.0' + +target 'TargetName' do +pod 'Navigine' +end +``` + +Then, run the following command: + +```bash +$ pod install +```