forked from organicmaps/organicmaps
[ios] New Search
This commit is contained in:
parent
5f2284c113
commit
03da916506
16 changed files with 1512 additions and 901 deletions
|
@ -1,5 +1,4 @@
|
|||
#import "MapViewController.h"
|
||||
#import "SearchVC.h"
|
||||
#import "MapsAppDelegate.h"
|
||||
#import "EAGLView.h"
|
||||
#import "BookmarksRootVC.h"
|
||||
|
@ -19,6 +18,8 @@
|
|||
#import "InAppMessagesManager.h"
|
||||
#import "InterstitialView.h"
|
||||
#import "MoreAppsVC.h"
|
||||
#import "PlacePageView.h"
|
||||
#import "SearchView.h"
|
||||
|
||||
#import "../Settings/SettingsManager.h"
|
||||
#import "../../Common/CustomAlertView.h"
|
||||
|
@ -42,12 +43,13 @@
|
|||
const long long PRO_IDL = 510623322L;
|
||||
const long long LITE_IDL = 431183278L;
|
||||
|
||||
@interface MapViewController () <SideToolbarDelegate>
|
||||
@interface MapViewController () <SideToolbarDelegate, PlacePageViewDelegate, PlacePageVCDelegate>
|
||||
|
||||
@property (nonatomic) LocationButton * locationButton;
|
||||
@property (nonatomic) UINavigationBar * apiNavigationBar;
|
||||
@property (nonatomic) ShareActionSheet * shareActionSheet;
|
||||
@property (nonatomic) UIButton * buyButton;
|
||||
@property (nonatomic) PlacePageView * placePageView;
|
||||
@property (nonatomic) SearchView * searchView;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -142,18 +144,20 @@ const long long LITE_IDL = 431183278L;
|
|||
|
||||
#pragma mark - Map Navigation
|
||||
|
||||
- (void)positionBallonClickedLat:(double)lat lon:(double)lon
|
||||
- (void)poiBalloonClicked:(m2::PointD const &)point info:(search::AddressInfo const &)addressInfo
|
||||
{
|
||||
CGPoint const p = CGPointMake(MercatorBounds::LonToX(lon), MercatorBounds::LatToY(lat));
|
||||
PlacePreviewViewController * preview = [[PlacePreviewViewController alloc] initWithPoint:p];
|
||||
m_popoverPos = p;
|
||||
[self pushViewController:preview];
|
||||
[self showPlacePageWithPoint:point addressInfo:addressInfo];
|
||||
}
|
||||
|
||||
- (void)poiBalloonDismissed
|
||||
{
|
||||
[self.placePageView setState:PlacePageStateHidden animated:YES];
|
||||
}
|
||||
|
||||
- (void)additionalLayer:(size_t)index
|
||||
{
|
||||
Framework & framework = GetFramework();
|
||||
Bookmark const * bookmark = framework.AdditionalPoiLayerGetBookmark(index);
|
||||
Bookmark * bookmark = framework.AdditionalPoiLayerGetBookmark(index);
|
||||
|
||||
[self.placePageView showBookmark:*bookmark];
|
||||
[self.placePageView setState:PlacePageStateBitShown animated:YES];
|
||||
|
@ -165,12 +169,21 @@ const long long LITE_IDL = 431183278L;
|
|||
[self.placePageView setState:PlacePageStateBitShown animated:YES];
|
||||
}
|
||||
|
||||
- (void)bookmarkBalloonClicked:(BookmarkAndCategory const &)bmAndCat
|
||||
- (void)bookmarkBalloonClicked:(BookmarkAndCategory const &)bookmarkAndCategory
|
||||
{
|
||||
PlacePageVC * vc = [[PlacePageVC alloc] initWithBookmark:bmAndCat];
|
||||
Bookmark const * bm = GetFramework().GetBmCategory(bmAndCat.first)->GetBookmark(bmAndCat.second);
|
||||
m_popoverPos = CGPointMake(bm->GetOrg().x, bm->GetOrg().y);
|
||||
[self pushViewController:vc];
|
||||
[self showPlacePageWithBookmarkAndCategory:bookmarkAndCategory];
|
||||
}
|
||||
|
||||
- (void)showPlacePageWithPoint:(m2::PointD)point addressInfo:(search::AddressInfo)addressInfo
|
||||
{
|
||||
[self.placePageView showPoint:point addressInfo:addressInfo];
|
||||
[self.placePageView setState:PlacePageStateBitShown animated:YES];
|
||||
}
|
||||
|
||||
- (void)showPlacePageWithBookmarkAndCategory:(BookmarkAndCategory)bookmarkAndCategory
|
||||
{
|
||||
[self.placePageView showBookmarkAndCategory:bookmarkAndCategory];
|
||||
[self.placePageView setState:PlacePageStateBitShown animated:YES];
|
||||
}
|
||||
|
||||
- (void)onMyPositionClicked:(id)sender
|
||||
|
@ -281,26 +294,6 @@ const long long LITE_IDL = 431183278L;
|
|||
[self invalidate];
|
||||
}
|
||||
|
||||
- (void)showSearchResultAsBookmarkAtMercatorPoint:(const m2::PointD &)pt withInfo:(const search::AddressInfo &)info
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (void)showBalloonWithCategoryIndex:(int)cat andBookmarkIndex:(int)bm
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (void)poiBalloonDismissed
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (void)additionalLayer:(size_t)index
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (void)updatePointsFromEvent:(UIEvent *)event
|
||||
{
|
||||
NSSet * allTouches = [event allTouches];
|
||||
|
@ -388,6 +381,8 @@ const long long LITE_IDL = 431183278L;
|
|||
|
||||
if (!self.sideToolbar.isMenuHidden)
|
||||
[self.sideToolbar setMenuHidden:YES animated:YES];
|
||||
if (self.placePageView.state == PlacePageStateOpened)
|
||||
[self.placePageView setState:PlacePageStateBitShown animated:YES];
|
||||
}
|
||||
|
||||
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
|
@ -611,11 +606,21 @@ const long long LITE_IDL = 431183278L;
|
|||
}
|
||||
#endif
|
||||
|
||||
[self.view addSubview:self.apiNavigationBar];
|
||||
[self.view addSubview:self.locationButton];
|
||||
|
||||
[self.view addSubview:self.searchView];
|
||||
|
||||
[self.view addSubview:self.fadeView];
|
||||
|
||||
UIButton * slideView = [self slideView];
|
||||
[self.view addSubview:slideView];
|
||||
|
||||
[self.view addSubview:self.placePageView];
|
||||
|
||||
[self.view addSubview:self.sideToolbar];
|
||||
|
||||
self.sideToolbar.slideView = slideView;
|
||||
|
||||
[self.sideToolbar setMenuHidden:YES animated:NO];
|
||||
}
|
||||
|
||||
|
@ -650,10 +655,10 @@ const long long LITE_IDL = 431183278L;
|
|||
|
||||
typedef void (*POSITIONBalloonFnT)(id, SEL, double, double);
|
||||
typedef void (*POIBalloonFnT)(id, SEL, m2::PointD const &, search::AddressInfo const &);
|
||||
typedef void (*POIBalloonDismissedFnT)(id, SEL);
|
||||
typedef void (*APIPOINTBalloonFnT)(id, SEL, url_scheme::ApiPoint const &);
|
||||
typedef void (*BOOKMARKBalloonFnT)(id, SEL, BookmarkAndCategory const &);
|
||||
typedef void (*POIBalloonDismissedFnT)(id, SEL);
|
||||
typedef void (*ADDITIONALLayerFnT)(id, SEL, size_t);
|
||||
typedef void (*ADDITIONALLayerFnT)(id, SEL, size_t index);
|
||||
|
||||
PinClickManager & manager = f.GetBalloonManager();
|
||||
|
||||
|
@ -715,8 +720,8 @@ const long long LITE_IDL = 431183278L;
|
|||
{
|
||||
_placePageView = [[PlacePageView alloc] initWithFrame:CGRectMake(0, 0, self.view.width, 0)];
|
||||
_placePageView.minY = self.view.height;
|
||||
_placePageView.delegate = self;
|
||||
_placePageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
|
||||
_placePageView.delegate = self;
|
||||
[_placePageView addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:nil];
|
||||
}
|
||||
return _placePageView;
|
||||
|
@ -740,7 +745,7 @@ const long long LITE_IDL = 431183278L;
|
|||
if (!_locationButton)
|
||||
{
|
||||
_locationButton = [[LocationButton alloc] initWithFrame:CGRectMake(0, 0, 60, 60)];
|
||||
_locationButton.center = CGPointMake(28, self.view.height - 28);
|
||||
_locationButton.center = CGPointMake(28, LOCATION_BUTTON_MID_Y);
|
||||
_locationButton.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin;
|
||||
[_locationButton addTarget:self action:@selector(onMyPositionClicked:) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
|
@ -777,37 +782,44 @@ const long long LITE_IDL = 431183278L;
|
|||
}
|
||||
|
||||
#define SLIDE_VIEW_DARK_PART_TAG 1
|
||||
#define SLIDE_VIEW_MID_Y (self.view.height - 35)
|
||||
|
||||
- (SideToolbar *)sideToolbar
|
||||
{
|
||||
if (!_sideToolbar)
|
||||
{
|
||||
_sideToolbar = [[SideToolbar alloc] initWithFrame:CGRectMake(self.view.width, 0, 260, self.view.height)];
|
||||
_sideToolbar = [[SideToolbar alloc] initWithFrame:CGRectMake(self.view.width, 0, 310, self.view.height)];
|
||||
_sideToolbar.delegate = self;
|
||||
}
|
||||
return _sideToolbar;
|
||||
}
|
||||
|
||||
UIButton * toolbarButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 50, 70)];
|
||||
toolbarButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
|
||||
toolbarButton.maxX = self.view.width;
|
||||
toolbarButton.midY = self.view.height - 35;
|
||||
[toolbarButton addTarget:self action:@selector(toolbarButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
|
||||
- (UIButton *)slideView
|
||||
{
|
||||
UIButton * toolbarButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 50, 70)];
|
||||
toolbarButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
|
||||
toolbarButton.maxX = self.view.width;
|
||||
toolbarButton.midY = SLIDE_VIEW_MID_Y;
|
||||
[toolbarButton addTarget:self action:@selector(toolbarButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
CGFloat tailShift = 7;
|
||||
CGFloat tailShift = 7;
|
||||
|
||||
UIImageView * tailLight = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SlideViewLight"]];
|
||||
tailLight.maxX = toolbarButton.width;
|
||||
tailLight.midY = toolbarButton.height / 2 + tailShift;
|
||||
[toolbarButton addSubview:tailLight];
|
||||
UIImageView * tailLight = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SlideViewLight"]];
|
||||
tailLight.maxX = toolbarButton.width;
|
||||
tailLight.midY = toolbarButton.height / 2 + tailShift;
|
||||
[toolbarButton addSubview:tailLight];
|
||||
|
||||
UIImageView * tailDark = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SlideViewDark"]];
|
||||
tailDark.maxX = toolbarButton.width;
|
||||
tailDark.midY = toolbarButton.height / 2 + tailShift;
|
||||
tailDark.alpha = 0;
|
||||
tailDark.tag = SLIDE_VIEW_DARK_PART_TAG;
|
||||
[toolbarButton addSubview:tailDark];
|
||||
UIImageView * tailDark = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SlideViewDark"]];
|
||||
tailDark.maxX = toolbarButton.width;
|
||||
tailDark.midY = toolbarButton.height / 2 + tailShift;
|
||||
tailDark.alpha = 0;
|
||||
tailDark.tag = SLIDE_VIEW_DARK_PART_TAG;
|
||||
[toolbarButton addSubview:tailDark];
|
||||
|
||||
[self.view addSubview:toolbarButton];
|
||||
return toolbarButton;
|
||||
}
|
||||
|
||||
_sideToolbar.slideView = toolbarButton;
|
||||
#pragma mark - PlacePageViewDelegate
|
||||
|
||||
- (void)placePageView:(PlacePageView *)placePage willEditBookmarkAndCategory:(BookmarkAndCategory const &)bookmarkAndCategory
|
||||
{
|
||||
|
@ -819,17 +831,10 @@ const long long LITE_IDL = 431183278L;
|
|||
|
||||
- (void)placePageView:(PlacePageView *)placePage willEditBookmarkWithInfo:(search::AddressInfo const &)addressInfo point:(m2::PointD const &)point
|
||||
{
|
||||
if (!_apiNavigationBar)
|
||||
{
|
||||
CGFloat height = SYSTEM_VERSION_IS_LESS_THAN(@"7") ? 44 : 64;
|
||||
_apiNavigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, self.view.width, height)];
|
||||
UINavigationItem * item = [[UINavigationItem alloc] init];
|
||||
_apiNavigationBar.items = @[item];
|
||||
_apiNavigationBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
|
||||
_apiNavigationBar.topItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"back", nil) style: UIBarButtonItemStyleDone target:self action:@selector(returnToApiApp)];
|
||||
_apiNavigationBar.alpha = 0;
|
||||
}
|
||||
return _apiNavigationBar;
|
||||
PlacePageVC * vc = [[PlacePageVC alloc] initWithInfo:addressInfo point:CGPointMake(point.x, point.y)];
|
||||
vc.delegate = self;
|
||||
vc.mode = PlacePageVCModeEditing;
|
||||
[self pushViewController:vc];
|
||||
}
|
||||
|
||||
- (void)placePageView:(PlacePageView *)placePage willShareInfo:(search::AddressInfo const &)addressInfo point:(m2::PointD const &)point
|
||||
|
@ -847,26 +852,13 @@ const long long LITE_IDL = 431183278L;
|
|||
|
||||
#pragma mark - SideToolbarDelegate
|
||||
|
||||
- (void)sideToolbar:(SideToolbar *)toolbar didPressButtonAtIndex:(NSInteger)buttonIndex
|
||||
- (void)sideToolbar:(SideToolbar *)toolbar didPressItemWithName:(NSString *)itemName
|
||||
{
|
||||
if (buttonIndex == 0)
|
||||
{
|
||||
if (GetPlatform().IsPro())
|
||||
{
|
||||
SearchVC * vc = [[SearchVC alloc] init];
|
||||
[self.navigationController pushViewController:vc animated:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
[[Statistics instance] logProposalReason:@"Search Screen" withAnswer:@"YES"];
|
||||
[[UIApplication sharedApplication] openProVersion];
|
||||
}
|
||||
}
|
||||
else if (buttonIndex == 1)
|
||||
if ([itemName isEqualToString:@"Maps"])
|
||||
{
|
||||
[[[MapsAppDelegate theApp] settingsManager] show:self];
|
||||
}
|
||||
else if (buttonIndex == 2)
|
||||
else if ([itemName isEqualToString:@"Bookmarks"])
|
||||
{
|
||||
if (GetPlatform().IsPro())
|
||||
{
|
||||
|
@ -879,12 +871,12 @@ const long long LITE_IDL = 431183278L;
|
|||
[[UIApplication sharedApplication] openProVersion];
|
||||
}
|
||||
}
|
||||
else if (buttonIndex == 3)
|
||||
else if ([itemName isEqualToString:@"Settings"])
|
||||
{
|
||||
SettingsViewController * vc = [self.mainStoryboard instantiateViewControllerWithIdentifier:[SettingsViewController className]];
|
||||
[self.navigationController pushViewController:vc animated:YES];
|
||||
}
|
||||
else if (buttonIndex == 4)
|
||||
else if ([itemName isEqualToString:@"Share"])
|
||||
{
|
||||
CLLocation * location = [MapsAppDelegate theApp].m_locationManager.lastLocation;
|
||||
if (location)
|
||||
|
@ -901,13 +893,41 @@ const long long LITE_IDL = 431183278L;
|
|||
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"unknown_current_position", nil) message:nil delegate:nil cancelButtonTitle:NSLocalizedString(@"ok", nil) otherButtonTitles:nil] show];
|
||||
}
|
||||
}
|
||||
else if (buttonIndex == 5)
|
||||
else if ([itemName isEqualToString:@"MoreApps"])
|
||||
{
|
||||
MoreAppsVC * vc = [[MoreAppsVC alloc] init];
|
||||
[self.navigationController pushViewController:vc animated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)sideToolbarDidCloseMenu:(SideToolbar *)toolbar
|
||||
{
|
||||
[self.view bringSubviewToFront:self.placePageView];
|
||||
}
|
||||
|
||||
- (void)sideToolbarWillCloseMenu:(SideToolbar *)toolbar
|
||||
{
|
||||
[UIView animateWithDuration:0.25 animations:^{
|
||||
if ([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)])
|
||||
[self setNeedsStatusBarAppearanceUpdate];
|
||||
self.fadeView.alpha = 0;
|
||||
UIView * darkTail = [self.sideToolbar.slideView viewWithTag:SLIDE_VIEW_DARK_PART_TAG];
|
||||
darkTail.alpha = 0;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)sideToolbarWillOpenMenu:(SideToolbar *)toolbar
|
||||
{
|
||||
[UIView animateWithDuration:0.25 animations:^{
|
||||
if ([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)])
|
||||
[self setNeedsStatusBarAppearanceUpdate];
|
||||
self.fadeView.alpha = 1;
|
||||
UIView * darkTail = [self.sideToolbar.slideView viewWithTag:SLIDE_VIEW_DARK_PART_TAG];
|
||||
darkTail.alpha = 1;
|
||||
}];
|
||||
[self.view sendSubviewToBack:self.placePageView];
|
||||
}
|
||||
|
||||
- (void)sideToolbarDidUpdateShift:(SideToolbar *)toolbar
|
||||
{
|
||||
self.fadeView.alpha = toolbar.menuShift / (toolbar.maximumMenuShift - toolbar.minimumMenuShift);
|
||||
|
@ -955,15 +975,13 @@ const long long LITE_IDL = 431183278L;
|
|||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
|
||||
{
|
||||
if (object == self.sideToolbar && [keyPath isEqualToString:@"isMenuHidden"])
|
||||
if (object == self.searchView && [keyPath isEqualToString:@"active"])
|
||||
{
|
||||
[UIView animateWithDuration:0.25 animations:^{
|
||||
if ([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)])
|
||||
[self setNeedsStatusBarAppearanceUpdate];
|
||||
self.fadeView.alpha = self.sideToolbar.isMenuHidden ? 0 : 1;
|
||||
UIView * darkTail = [self.sideToolbar.slideView viewWithTag:SLIDE_VIEW_DARK_PART_TAG];
|
||||
darkTail.alpha = self.sideToolbar.isMenuHidden ? 0 : 1;
|
||||
[UIView animateWithDuration:0.2 animations:^{
|
||||
self.sideToolbar.slideView.maxX = self.searchView.active ? self.view.width + self.sideToolbar.slideView.width : self.view.width;
|
||||
}];
|
||||
if (self.searchView.active)
|
||||
[self.placePageView setState:PlacePageStateHidden animated:YES];
|
||||
}
|
||||
else if (object == self.placePageView && [keyPath isEqualToString:@"state"])
|
||||
{
|
||||
|
|
9
iphone/Maps/Classes/SearchActivityProtocol.h
Normal file
9
iphone/Maps/Classes/SearchActivityProtocol.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol SearchActivityProtocol <NSObject>
|
||||
|
||||
- (void)setActive:(BOOL)active animated:(BOOL)animated;
|
||||
@property (nonatomic, readonly) BOOL active;
|
||||
|
||||
@end
|
22
iphone/Maps/Classes/SearchBar.h
Normal file
22
iphone/Maps/Classes/SearchBar.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "SearchActivityProtocol.h"
|
||||
|
||||
@class SearchBar;
|
||||
@protocol SearchBarDelegate <NSObject>
|
||||
|
||||
- (void)searchBarDidPressCancelButton:(SearchBar *)searchBar;
|
||||
- (void)searchBarDidPressClearButton:(SearchBar *)searchBar;
|
||||
|
||||
@end
|
||||
|
||||
@interface SearchBar : UIView <SearchActivityProtocol>
|
||||
|
||||
@property (nonatomic, readonly) UITextField * textField;
|
||||
@property (nonatomic) BOOL isShowingResult;
|
||||
@property (nonatomic, weak) id <SearchBarDelegate> delegate;
|
||||
@property (nonatomic) NSString * apiText;
|
||||
|
||||
- (void)setSearching:(BOOL)searching;
|
||||
|
||||
@end
|
349
iphone/Maps/Classes/SearchBar.mm
Normal file
349
iphone/Maps/Classes/SearchBar.mm
Normal file
|
@ -0,0 +1,349 @@
|
|||
|
||||
#import "SearchBar.h"
|
||||
#import "UIKitCategories.h"
|
||||
#import "Framework.h"
|
||||
|
||||
@interface SearchSpotView : UIView
|
||||
|
||||
- (void)setAnimating:(BOOL)animating;
|
||||
|
||||
@end
|
||||
|
||||
@interface SearchSpotView ()
|
||||
|
||||
@property (nonatomic) UIImageView * spotImageView;
|
||||
@property (nonatomic) UIActivityIndicatorView * activityView;
|
||||
@property (nonatomic) NSTimer * timer;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SearchSpotView
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
|
||||
[self addSubview:self.activityView];
|
||||
[self addSubview:self.spotImageView];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setAnimating:(BOOL)animating
|
||||
{
|
||||
if (animating)
|
||||
{
|
||||
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.15 target:self selector:@selector(timerSelector) userInfo:nil repeats:NO];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self.activityView stopAnimating];
|
||||
self.spotImageView.hidden = NO;
|
||||
[self.timer invalidate];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)timerSelector
|
||||
{
|
||||
[self.activityView startAnimating];
|
||||
self.spotImageView.hidden = YES;
|
||||
}
|
||||
|
||||
- (UIActivityIndicatorView *)activityView
|
||||
{
|
||||
if (!_activityView)
|
||||
{
|
||||
_activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
_activityView.center = CGPointMake(self.width / 2, self.height / 2);
|
||||
}
|
||||
return _activityView;
|
||||
}
|
||||
|
||||
- (UIImageView *)spotImageView
|
||||
{
|
||||
if (!_spotImageView)
|
||||
{
|
||||
_spotImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SearchBarIcon"]];
|
||||
_spotImageView.center = CGPointMake(self.width / 2, self.height / 2);
|
||||
}
|
||||
return _spotImageView;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface SearchBar ()
|
||||
|
||||
@property (nonatomic) UITextField * textField;
|
||||
@property (nonatomic) SearchSpotView * searchImageView;
|
||||
@property (nonatomic) UILabel * searchLabel;
|
||||
@property (nonatomic) UIImageView * backgroundImageView;
|
||||
@property (nonatomic) UIButton * clearButton;
|
||||
@property (nonatomic) UIButton * cancelButton;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SearchBar
|
||||
@synthesize active = _active;
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
|
||||
[self addSubview:self.backgroundImageView];
|
||||
|
||||
self.clearButton.midY = self.backgroundImageView.height / 2;
|
||||
self.clearButton.maxX = self.backgroundImageView.width;
|
||||
[self.backgroundImageView addSubview:self.clearButton];
|
||||
|
||||
[self addSubview:self.searchImageView];
|
||||
[self addSubview:self.searchLabel];
|
||||
|
||||
self.textField.midY = self.backgroundImageView.height / 2;
|
||||
CGFloat fieldOffsetL = 39;
|
||||
CGFloat fieldOffsetR = 24;
|
||||
self.textField.frame = CGRectMake(fieldOffsetL, self.textField.origin.y, self.backgroundImageView.width - fieldOffsetL - fieldOffsetR, self.textField.height);
|
||||
[self.backgroundImageView addSubview:self.textField];
|
||||
|
||||
self.cancelButton.midY = self.backgroundImageView.height / 2;
|
||||
[self addSubview:self.cancelButton];
|
||||
|
||||
[self setActive:NO animated:NO];
|
||||
|
||||
if ([UITextField instancesRespondToSelector:@selector(setTintColor:)])
|
||||
[[UITextField appearance] setTintColor:[UIColor darkGrayColor]];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[self performAfterDelay:0 block:^{
|
||||
if (!self.active)
|
||||
[self layoutImageAndLabelInNonActiveState];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setSearching:(BOOL)searching
|
||||
{
|
||||
self.searchImageView.animating = searching;
|
||||
}
|
||||
|
||||
#define LABEL_MIN_X 23
|
||||
|
||||
- (void)setActive:(BOOL)active animated:(BOOL)animated
|
||||
{
|
||||
CGFloat backgroundImageOffset = 10;
|
||||
if (active)
|
||||
{
|
||||
[UIView animateWithDuration:(animated ? 0.1 : 0) delay:0.1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
||||
self.textField.alpha = 1;
|
||||
} completion:nil];
|
||||
|
||||
[UIView animateWithDuration:(animated ? 0.35 : 0) delay:0 damping:0.8 initialVelocity:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
||||
if (self.isShowingResult)
|
||||
{
|
||||
self.searchLabel.minX = 47;
|
||||
}
|
||||
else
|
||||
{
|
||||
CGFloat spaceBetween = self.searchLabel.minX - self.searchImageView.minX;
|
||||
self.searchImageView.minX = LABEL_MIN_X;
|
||||
self.searchLabel.minX = self.searchImageView.minX + spaceBetween;
|
||||
}
|
||||
|
||||
self.searchImageView.alpha = 1;
|
||||
self.searchLabel.alpha = 0;
|
||||
|
||||
self.backgroundImageView.frame = CGRectMake(backgroundImageOffset, 0, self.width - backgroundImageOffset - self.cancelButton.width, self.backgroundImageView.height);
|
||||
|
||||
self.cancelButton.alpha = 1;
|
||||
self.cancelButton.maxX = self.width;
|
||||
|
||||
self.clearButton.alpha = 1;
|
||||
|
||||
} completion:nil];
|
||||
|
||||
[self performAfterDelay:0.1 block:^{
|
||||
[self.textField becomeFirstResponder];
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
[UIView animateWithDuration:(animated ? 0.1 : 0) animations:^{
|
||||
self.textField.alpha = 0;
|
||||
}];
|
||||
|
||||
[UIView animateWithDuration:(animated ? 0.45 : 0) delay:0 damping:0.8 initialVelocity:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
||||
self.backgroundImageView.frame = CGRectMake(backgroundImageOffset, 0, self.width - 2 * backgroundImageOffset, self.backgroundImageView.height);
|
||||
|
||||
self.searchLabel.text = self.isShowingResult ? self.textField.text : NSLocalizedString(@"search", nil);
|
||||
[self.searchLabel sizeToFit];
|
||||
|
||||
[self layoutImageAndLabelInNonActiveState];
|
||||
|
||||
self.cancelButton.alpha = 0;
|
||||
self.cancelButton.minX = self.width;
|
||||
|
||||
if (!self.isShowingResult)
|
||||
self.clearButton.alpha = 0;
|
||||
|
||||
[self.textField resignFirstResponder];
|
||||
} completion:nil];
|
||||
}
|
||||
_active = active;
|
||||
}
|
||||
|
||||
- (void)layoutImageAndLabelInNonActiveState
|
||||
{
|
||||
self.searchLabel.alpha = 1;
|
||||
if (self.isShowingResult)
|
||||
{
|
||||
self.searchLabel.midX = self.searchLabel.superview.width / 2;
|
||||
self.searchImageView.alpha = 0;
|
||||
self.searchImageView.minX = LABEL_MIN_X;
|
||||
self.searchLabel.width = MIN(self.searchLabel.width, self.backgroundImageView.width - 54);
|
||||
}
|
||||
else
|
||||
{
|
||||
CGFloat width = self.searchImageView.width + 8 + self.searchLabel.width;
|
||||
self.searchImageView.midY = self.backgroundImageView.height / 2;
|
||||
self.searchImageView.minX = self.backgroundImageView.width / 2 - width / 2 + self.backgroundImageView.minX;
|
||||
self.searchImageView.alpha = 1;
|
||||
self.searchLabel.midY = self.backgroundImageView.height / 2;
|
||||
self.searchLabel.maxX = self.backgroundImageView.width / 2 + width / 2 + self.backgroundImageView.minX;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cancelButtonPressed:(id)sender
|
||||
{
|
||||
[self.delegate searchBarDidPressCancelButton:self];
|
||||
}
|
||||
|
||||
- (void)clearButtonPressed:(id)sender
|
||||
{
|
||||
Framework & framework = GetFramework();
|
||||
GetFramework().ClearMapApiPoints();
|
||||
if (self.active)
|
||||
{
|
||||
self.textField.text = nil;
|
||||
self.isShowingResult = NO;
|
||||
[self.textField becomeFirstResponder];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self hideSearchedText];
|
||||
}
|
||||
[self.delegate searchBarDidPressClearButton:self];
|
||||
|
||||
framework.GetBookmarkManager().AdditionalPoiLayerClear();
|
||||
framework.GetBalloonManager().RemovePin();
|
||||
framework.GetBalloonManager().Dismiss();
|
||||
framework.Invalidate();
|
||||
}
|
||||
|
||||
- (void)hideSearchedText
|
||||
{
|
||||
self.textField.text = nil;
|
||||
self.isShowingResult = NO;
|
||||
self.searchLabel.text = NSLocalizedString(@"search", nil);
|
||||
[self.searchLabel sizeToFit];
|
||||
[UIView animateWithDuration:0.4 delay:0 damping:0.8 initialVelocity:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
||||
[self layoutImageAndLabelInNonActiveState];
|
||||
self.clearButton.alpha = 0;
|
||||
} completion:nil];
|
||||
}
|
||||
|
||||
- (void)setApiText:(NSString *)apiText
|
||||
{
|
||||
if (apiText)
|
||||
{
|
||||
self.textField.text = apiText;
|
||||
self.isShowingResult = YES;
|
||||
[self setActive:NO animated:YES];
|
||||
self.clearButton.alpha = 1;
|
||||
}
|
||||
else if (_apiText)
|
||||
{
|
||||
[self hideSearchedText];
|
||||
GetFramework().ClearMapApiPoints();
|
||||
}
|
||||
_apiText = apiText;
|
||||
}
|
||||
|
||||
- (UILabel *)searchLabel
|
||||
{
|
||||
if (!_searchLabel)
|
||||
{
|
||||
_searchLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 25)];
|
||||
_searchLabel.textColor = [UIColor blackColor];
|
||||
_searchLabel.backgroundColor = [UIColor clearColor];
|
||||
_searchLabel.textAlignment = NSTextAlignmentLeft;
|
||||
_searchLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:15];
|
||||
}
|
||||
return _searchLabel;
|
||||
}
|
||||
|
||||
- (SearchSpotView *)searchImageView
|
||||
{
|
||||
if (!_searchImageView)
|
||||
{
|
||||
_searchImageView = [[SearchSpotView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
|
||||
_searchImageView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
|
||||
}
|
||||
return _searchImageView;
|
||||
}
|
||||
|
||||
- (UIButton *)cancelButton
|
||||
{
|
||||
if (!_cancelButton)
|
||||
{
|
||||
_cancelButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 64, 44)];
|
||||
_cancelButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin;
|
||||
_cancelButton.titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:15];
|
||||
[_cancelButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
|
||||
[_cancelButton setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
|
||||
[_cancelButton setTitle:NSLocalizedString(@"cancel", nil) forState:UIControlStateNormal];
|
||||
[_cancelButton addTarget:self action:@selector(cancelButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
return _cancelButton;
|
||||
}
|
||||
|
||||
- (UIButton *)clearButton
|
||||
{
|
||||
if (!_clearButton)
|
||||
{
|
||||
_clearButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 32, 44)];
|
||||
_clearButton.contentMode = UIViewContentModeCenter;
|
||||
_clearButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
|
||||
[_clearButton setImage:[UIImage imageNamed:@"SearchBarClearButton"] forState:UIControlStateNormal];
|
||||
[_clearButton addTarget:self action:@selector(clearButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
return _clearButton;
|
||||
}
|
||||
|
||||
- (UIImageView *)backgroundImageView
|
||||
{
|
||||
if (!_backgroundImageView)
|
||||
{
|
||||
UIImage * image = [[UIImage imageNamed:@"SearchBarInactiveBackground"] resizableImageWithCapInsets:UIEdgeInsetsMake(6, 6, 6, 6)];
|
||||
_backgroundImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.width, image.size.height)];
|
||||
_backgroundImageView.image = image;
|
||||
_backgroundImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
|
||||
_backgroundImageView.userInteractionEnabled = YES;
|
||||
}
|
||||
return _backgroundImageView;
|
||||
}
|
||||
|
||||
- (UITextField *)textField
|
||||
{
|
||||
if (!_textField)
|
||||
{
|
||||
_textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, self.width, 22)];
|
||||
_textField.autoresizingMask = UIViewAutoresizingFlexibleWidth;
|
||||
_textField.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:15];
|
||||
_textField.returnKeyType = UIReturnKeySearch;
|
||||
}
|
||||
return _textField;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,12 +1,15 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
typedef NS_ENUM(NSUInteger, SearchCellPosition) {
|
||||
SearchCellPositionFirst = 1,
|
||||
SearchCellPositionMiddle = 2,
|
||||
SearchCellPositionLast = 3,
|
||||
SearchCellPositionAlone = 4,
|
||||
};
|
||||
|
||||
@interface SearchCell : UITableViewCell
|
||||
|
||||
@property (nonatomic, readonly) UILabel * featureName;
|
||||
@property (nonatomic, readonly) UILabel * featureType;
|
||||
@property (nonatomic, readonly) UILabel * featureCountry;
|
||||
@property (nonatomic, readonly) UILabel * featureDistance;
|
||||
|
||||
- (id)initWithReuseIdentifier:(NSString *)identifier;
|
||||
@property (nonatomic) SearchCellPosition position;
|
||||
|
||||
@end
|
||||
|
|
99
iphone/Maps/Classes/SearchCell.m
Normal file
99
iphone/Maps/Classes/SearchCell.m
Normal file
|
@ -0,0 +1,99 @@
|
|||
|
||||
#import "SearchCell.h"
|
||||
#import "UIKitCategories.h"
|
||||
|
||||
@interface SearchCell ()
|
||||
|
||||
@property (nonatomic) UIImageView * separatorImageView;
|
||||
@property (nonatomic) UIImageView * backgroundImageView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SearchCell
|
||||
|
||||
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
|
||||
{
|
||||
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
|
||||
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
self.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
[self addSubview:self.backgroundImageView];
|
||||
[self.contentView addSubview:self.separatorImageView];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setPosition:(SearchCellPosition)position
|
||||
{
|
||||
if (position == _position)
|
||||
return;
|
||||
|
||||
UIImage * image;
|
||||
switch (position)
|
||||
{
|
||||
case SearchCellPositionFirst:
|
||||
image = [UIImage imageNamed:@"SearchCellBackgroundTop"];
|
||||
break;
|
||||
case SearchCellPositionMiddle:
|
||||
image = [UIImage imageNamed:@"SearchCellBackgroundMiddle"];
|
||||
break;
|
||||
case SearchCellPositionLast:
|
||||
image = [UIImage imageNamed:@"SearchCellBackgroundBottom"];
|
||||
break;
|
||||
case SearchCellPositionAlone:
|
||||
image = [UIImage imageNamed:@"SearchCellBackgroundAlone"];
|
||||
break;
|
||||
}
|
||||
self.backgroundImageView.image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(6, 6, 6, 6)];
|
||||
|
||||
_position = position;
|
||||
}
|
||||
|
||||
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
|
||||
{
|
||||
[super setHighlighted:highlighted animated:animated];
|
||||
self.backgroundImageView.alpha = highlighted ? 0.5 : 1;
|
||||
}
|
||||
|
||||
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
|
||||
{
|
||||
[super setSelected:selected animated:animated];
|
||||
self.backgroundImageView.alpha = selected ? 0.5 : 1;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
self.backgroundImageView.size = CGSizeMake(self.width - 28, self.height);
|
||||
self.backgroundImageView.midX = self.width / 2;
|
||||
[self sendSubviewToBack:self.backgroundImageView];
|
||||
|
||||
self.contentView.frame = self.backgroundImageView.frame;
|
||||
|
||||
self.separatorImageView.width = self.contentView.width;
|
||||
self.separatorImageView.maxY = self.contentView.height;
|
||||
self.separatorImageView.midX = self.contentView.width / 2;
|
||||
self.separatorImageView.hidden = (self.position == SearchCellPositionLast || self.position == SearchCellPositionAlone);
|
||||
}
|
||||
|
||||
- (UIImageView *)backgroundImageView
|
||||
{
|
||||
if (!_backgroundImageView)
|
||||
{
|
||||
_backgroundImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
|
||||
_backgroundImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
|
||||
}
|
||||
return _backgroundImageView;
|
||||
}
|
||||
|
||||
- (UIImageView *)separatorImageView
|
||||
{
|
||||
if (!_separatorImageView)
|
||||
{
|
||||
UIImage * image = [[UIImage imageNamed:@"SearchCellSeparator"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 40, 0, 40)];
|
||||
_separatorImageView = [[UIImageView alloc] initWithImage:image];
|
||||
_separatorImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
|
||||
}
|
||||
return _separatorImageView;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,79 +0,0 @@
|
|||
#import "SearchCell.h"
|
||||
|
||||
@implementation SearchCell
|
||||
|
||||
- (id)initWithReuseIdentifier:(NSString *)identifier
|
||||
{
|
||||
self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
|
||||
if (self)
|
||||
{
|
||||
// Fonts and sizes are hard-coded because they can't be easily retrieved
|
||||
UIFont * large = [UIFont fontWithName:@"Helvetica-Bold" size:[UIFont labelFontSize] + 1];
|
||||
UIFont * small = [UIFont fontWithName:@"Helvetica" size:[UIFont systemFontSize]];
|
||||
|
||||
_featureName = [[UILabel alloc] init];
|
||||
_featureName.font = large;
|
||||
_featureType = [[UILabel alloc] init];
|
||||
_featureType.font = small;
|
||||
_featureType.textColor = [UIColor grayColor];
|
||||
_featureType.textAlignment = UITextAlignmentRight;
|
||||
_featureCountry = [[UILabel alloc] init];
|
||||
_featureCountry.font = small;
|
||||
_featureCountry.textColor = [UIColor grayColor];
|
||||
_featureDistance = [[UILabel alloc] init];
|
||||
_featureDistance.font = small;
|
||||
_featureDistance.textColor = [UIColor grayColor];
|
||||
_featureDistance.textAlignment = UITextAlignmentRight;
|
||||
|
||||
[self.contentView addSubview:_featureName];
|
||||
[self.contentView addSubview:_featureType];
|
||||
[self.contentView addSubview:_featureCountry];
|
||||
[self.contentView addSubview:_featureDistance];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
CGRect r = self.contentView.bounds;
|
||||
// Leave some experimentally choosen paddings
|
||||
CGFloat const KPaddingX = 9.0;
|
||||
CGFloat const KPaddingBottom = 1.0;
|
||||
|
||||
r.origin.x += KPaddingX;
|
||||
r.size.width -= 2 * KPaddingX;
|
||||
r.size.height -= KPaddingBottom;
|
||||
|
||||
// Labels on the right should always fit and be visible, but not more than half of the cell
|
||||
CGFloat const w = r.size.width;
|
||||
CGFloat const h = r.size.height;
|
||||
CGFloat const yDelim = (int)(r.origin.y + h / 5 * 3);
|
||||
|
||||
CGFloat xTopDelim = (int)(r.origin.x + w / 2);
|
||||
CGFloat xBottomDelim = xTopDelim;
|
||||
if ([_featureDistance.text length])
|
||||
{
|
||||
CGSize const distanceTextSize = [_featureDistance.text sizeWithFont:_featureDistance.font];
|
||||
if (xTopDelim + distanceTextSize.width < r.origin.x + w)
|
||||
xTopDelim = r.origin.x + w - distanceTextSize.width - KPaddingX;
|
||||
}
|
||||
else // Sometimes distance is not available, so use full cell length for the name
|
||||
{
|
||||
xTopDelim = r.origin.x + w - KPaddingX;
|
||||
}
|
||||
|
||||
_featureName.frame = CGRectMake(r.origin.x, r.origin.y, xTopDelim - r.origin.x, yDelim - r.origin.y);
|
||||
_featureDistance.frame = CGRectMake(xTopDelim, r.origin.y, r.origin.x + w - xTopDelim, yDelim - r.origin.y);
|
||||
|
||||
if ([_featureType.text length])
|
||||
{
|
||||
CGSize const typeTextSize = [_featureType.text sizeWithFont:_featureType.font];
|
||||
if (xBottomDelim + typeTextSize.width < r.origin.x + w)
|
||||
xBottomDelim = r.origin.x + w - typeTextSize.width - KPaddingX;
|
||||
}
|
||||
_featureCountry.frame = CGRectMake(r.origin.x, yDelim, xBottomDelim - r.origin.x, r.origin.y + h - yDelim);
|
||||
_featureType.frame = CGRectMake(xBottomDelim, yDelim, r.origin.x + w - xBottomDelim, r.origin.y + h - yDelim);
|
||||
}
|
||||
|
||||
@end
|
13
iphone/Maps/Classes/SearchUniversalCell.h
Normal file
13
iphone/Maps/Classes/SearchUniversalCell.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "SearchCell.h"
|
||||
|
||||
@interface SearchUniversalCell : SearchCell
|
||||
|
||||
@property (nonatomic, readonly) UILabel * titleLabel;
|
||||
@property (nonatomic, readonly) UILabel * subtitleLabel;
|
||||
@property (nonatomic, readonly) UILabel * distanceLabel;
|
||||
|
||||
+ (CGFloat)cellHeightWithTitle:(NSString *)title subtitle:(NSString *)subtitle viewWidth:(CGFloat)width;
|
||||
|
||||
@end
|
93
iphone/Maps/Classes/SearchUniversalCell.m
Normal file
93
iphone/Maps/Classes/SearchUniversalCell.m
Normal file
|
@ -0,0 +1,93 @@
|
|||
|
||||
#import "SearchUniversalCell.h"
|
||||
#import "UIKitCategories.h"
|
||||
|
||||
@interface SearchUniversalCell ()
|
||||
|
||||
@property (nonatomic) UILabel * titleLabel;
|
||||
@property (nonatomic) UILabel * subtitleLabel;
|
||||
@property (nonatomic) UILabel * distanceLabel;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SearchUniversalCell
|
||||
|
||||
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
|
||||
{
|
||||
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
|
||||
|
||||
[self.contentView addSubview:self.titleLabel];
|
||||
[self.contentView addSubview:self.subtitleLabel];
|
||||
[self.contentView addSubview:self.distanceLabel];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
#define TITLE_FONT [UIFont fontWithName:@"HelveticaNeue-Light" size:15]
|
||||
#define TITLE_WIDTH_REST 150
|
||||
#define TITLE_HEIGHT 60
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
self.distanceLabel.maxX = self.width - 45;
|
||||
self.distanceLabel.midY = self.height / 2 - 0.5;
|
||||
|
||||
self.titleLabel.width = self.width - TITLE_WIDTH_REST;
|
||||
self.titleLabel.minX = 16;
|
||||
[self.titleLabel sizeToFit];
|
||||
if ([self.subtitleLabel.text length])
|
||||
self.titleLabel.minY = 5;
|
||||
else
|
||||
self.titleLabel.midY = self.height / 2 - 1.5;
|
||||
self.subtitleLabel.origin = CGPointMake(self.titleLabel.minX, self.titleLabel.maxY - 1);
|
||||
}
|
||||
|
||||
+ (CGFloat)cellHeightWithTitle:(NSString *)title subtitle:(NSString *)subtitle viewWidth:(CGFloat)width
|
||||
{
|
||||
return MAX(44, [title sizeWithDrawSize:CGSizeMake(width - TITLE_WIDTH_REST, TITLE_HEIGHT) font:TITLE_FONT].height + ([subtitle length] ? 27 : 15));
|
||||
}
|
||||
|
||||
- (UILabel *)distanceLabel
|
||||
{
|
||||
if (!_distanceLabel)
|
||||
{
|
||||
_distanceLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 70, 16)];
|
||||
_distanceLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
|
||||
_distanceLabel.backgroundColor = [UIColor clearColor];
|
||||
_distanceLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:15];
|
||||
_distanceLabel.textColor = [UIColor blackColor];
|
||||
_distanceLabel.textAlignment = NSTextAlignmentRight;
|
||||
_distanceLabel.alpha = 0.5;
|
||||
}
|
||||
return _distanceLabel;
|
||||
}
|
||||
|
||||
- (UILabel *)subtitleLabel
|
||||
{
|
||||
if (!_subtitleLabel)
|
||||
{
|
||||
_subtitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 190, 16)];
|
||||
_subtitleLabel.backgroundColor = [UIColor clearColor];
|
||||
_subtitleLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:10];
|
||||
_subtitleLabel.textColor = [UIColor colorWithColorCode:@"666666"];
|
||||
}
|
||||
return _subtitleLabel;
|
||||
}
|
||||
|
||||
- (UILabel *)titleLabel
|
||||
{
|
||||
if (!_titleLabel)
|
||||
{
|
||||
_titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, TITLE_HEIGHT)];
|
||||
_titleLabel.backgroundColor = [UIColor clearColor];
|
||||
_titleLabel.font = TITLE_FONT;
|
||||
_titleLabel.textColor = [UIColor blackColor];
|
||||
_titleLabel.numberOfLines = 0;
|
||||
_titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
}
|
||||
return _titleLabel;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,24 +0,0 @@
|
|||
#import <UIKit/UIKit.h>
|
||||
#import "LocationManager.h"
|
||||
#import "ScopeView.h"
|
||||
|
||||
class Framework;
|
||||
|
||||
@interface SearchVC : UIViewController
|
||||
<UISearchBarDelegate, UITableViewDelegate, UITableViewDataSource,
|
||||
LocationObserver>
|
||||
{
|
||||
Framework * m_framework;
|
||||
LocationManager * m_locationManager;
|
||||
UITableView * m_table;
|
||||
// Zero when suggestions cells are not visible
|
||||
NSInteger m_suggestionsCount;
|
||||
NSArray * categoriesNames;
|
||||
}
|
||||
|
||||
@property (nonatomic) NSMutableArray * searchResults;
|
||||
|
||||
@property (nonatomic) UISearchBar * searchBar;
|
||||
@property (nonatomic) ScopeView * scopeView;
|
||||
|
||||
@end
|
|
@ -1,681 +0,0 @@
|
|||
#import "SearchVC.h"
|
||||
#import "CompassView.h"
|
||||
#import "LocationManager.h"
|
||||
#import "SearchCell.h"
|
||||
#import "BookmarksVC.h"
|
||||
#import "CustomNavigationView.h"
|
||||
#import "MapsAppDelegate.h"
|
||||
#import "MapViewController.h"
|
||||
#import "Statistics.h"
|
||||
#import "Config.h"
|
||||
#import "UIKitCategories.h"
|
||||
|
||||
#include "Framework.h"
|
||||
|
||||
#include "../../search/result.hpp"
|
||||
#include "../../search/params.hpp"
|
||||
|
||||
#include "../../indexer/mercator.hpp"
|
||||
|
||||
#include "../../platform/platform.hpp"
|
||||
#include "../../platform/preferred_languages.hpp"
|
||||
#include "../../platform/settings.hpp"
|
||||
|
||||
#include "../../geometry/angles.hpp"
|
||||
#include "../../geometry/distance_on_sphere.hpp"
|
||||
|
||||
/// When to display compass instead of country flags
|
||||
#define MIN_COMPASS_DISTANCE 25000.0
|
||||
|
||||
/// To save search scope selection between launches
|
||||
#define SEARCH_MODE_SETTING "SearchMode"
|
||||
|
||||
SearchVC * g_searchVC = nil;
|
||||
|
||||
@interface ResultsWrapper : NSObject
|
||||
{
|
||||
search::Results m_results;
|
||||
}
|
||||
|
||||
// Stores search string which corresponds to these results.
|
||||
@property(nonatomic, retain) NSString * searchString;
|
||||
|
||||
- (id)initWithResults:(search::Results const &)res;
|
||||
|
||||
- (int)getCount;
|
||||
- (search::Result const &)getWithPosition:(NSInteger)pos;
|
||||
|
||||
- (BOOL)isEndMarker;
|
||||
- (BOOL)isEndedNormal;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ResultsWrapper
|
||||
|
||||
@synthesize searchString;
|
||||
|
||||
- (id)initWithResults:(search::Results const &)res
|
||||
{
|
||||
if ((self = [super init]))
|
||||
m_results = res;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (int)getCount
|
||||
{
|
||||
return static_cast<int>(m_results.GetCount());
|
||||
}
|
||||
|
||||
- (search::Result const &)getWithPosition:(NSInteger)pos
|
||||
{
|
||||
return m_results.GetResult(pos);
|
||||
}
|
||||
|
||||
- (BOOL)isEndMarker
|
||||
{
|
||||
return m_results.IsEndMarker();
|
||||
}
|
||||
|
||||
- (BOOL)isEndedNormal
|
||||
{
|
||||
return m_results.IsEndedNormal();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// Last search results are stored between SearchVC sessions
|
||||
// to appear instantly for the user, they also store last search text query.
|
||||
//ResultsWrapper * g_lastSearchResults = nil;
|
||||
|
||||
static NSInteger GetDefaultSearchScope()
|
||||
{
|
||||
NSInteger value;
|
||||
if (Settings::Get(SEARCH_MODE_SETTING, value))
|
||||
return value;
|
||||
return 0; // 0 is default scope ("Near me")
|
||||
}
|
||||
|
||||
NSString * g_lastSearchRequest = nil;
|
||||
NSInteger g_scopeSection = GetDefaultSearchScope();
|
||||
NSInteger g_numberOfRowsInEmptySearch = 0;
|
||||
|
||||
static void OnSearchResultCallback(search::Results const & res)
|
||||
{
|
||||
if (g_searchVC)
|
||||
{
|
||||
ResultsWrapper * w = [[ResultsWrapper alloc] initWithResults:res];
|
||||
[g_searchVC performSelectorOnMainThread:@selector(addResult:)
|
||||
withObject:w waitUntilDone:NO];
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
@interface SearchVC ()
|
||||
|
||||
@property (nonatomic) BOOL searching;
|
||||
@property (nonatomic) UIActivityIndicatorView * activityIndicator;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SearchVC
|
||||
@synthesize searchResults = _searchResults;
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super initWithNibName:nil bundle:nil]))
|
||||
{
|
||||
m_framework = &GetFramework();
|
||||
m_locationManager = [MapsAppDelegate theApp].m_locationManager;
|
||||
|
||||
double lat, lon;
|
||||
bool const hasPt = [m_locationManager getLat:lat Lon:lon];
|
||||
m_framework->PrepareSearch(hasPt, lat, lon);
|
||||
|
||||
//mycode init array of categories
|
||||
categoriesNames = [[NSArray alloc] initWithObjects:
|
||||
@"food",
|
||||
@"shop",
|
||||
@"hotel",
|
||||
@"tourism",
|
||||
@"entertainment",
|
||||
@"atm",
|
||||
@"bank",
|
||||
@"transport",
|
||||
@"fuel",
|
||||
@"parking",
|
||||
@"pharmacy",
|
||||
@"hospital",
|
||||
@"toilet",
|
||||
@"post",
|
||||
@"police",
|
||||
nil];
|
||||
_searchResults = [[NSMutableArray alloc] initWithObjects:[[ResultsWrapper alloc] init], [[ResultsWrapper alloc] init], [[ResultsWrapper alloc] init], nil];
|
||||
if (!g_lastSearchRequest)
|
||||
{
|
||||
g_lastSearchRequest = @"";
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)fillSearchParams:(search::SearchParams &)params withText:(NSString *)queryString
|
||||
{
|
||||
params.m_query = [[queryString precomposedStringWithCompatibilityMapping] UTF8String];
|
||||
params.m_callback = bind(&OnSearchResultCallback, _1);
|
||||
|
||||
// Set current keyboard input mode
|
||||
// Note: input mode was introduced in iOS 4.2 (now we support 4.3+)
|
||||
params.SetInputLanguage([[UITextInputMode currentInputMode].primaryLanguage UTF8String]);
|
||||
|
||||
double lat, lon;
|
||||
if ([m_locationManager getLat:lat Lon:lon])
|
||||
params.SetPosition(lat, lon);
|
||||
}
|
||||
|
||||
- (UISearchBar *)searchBar
|
||||
{
|
||||
if (!_searchBar)
|
||||
{
|
||||
_searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.width - 80, 44)];
|
||||
_searchBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
|
||||
_searchBar.delegate = self;
|
||||
_searchBar.placeholder = NSLocalizedString(@"search_map", @"Search box placeholder text");
|
||||
_searchBar.barStyle = UISearchBarStyleDefault;
|
||||
_searchBar.tintColor = [[UINavigationBar appearance] tintColor];
|
||||
|
||||
if (g_lastSearchRequest)
|
||||
[_searchBar setText:g_lastSearchRequest];
|
||||
}
|
||||
return _searchBar;
|
||||
}
|
||||
|
||||
- (ScopeView *)scopeView
|
||||
{
|
||||
if (!_scopeView)
|
||||
{
|
||||
UISegmentedControl * segmentedControl = [[UISegmentedControl alloc] initWithItems:@[NSLocalizedString(@"search_mode_nearme", nil),
|
||||
NSLocalizedString(@"search_mode_viewport", nil),
|
||||
NSLocalizedString(@"search_mode_all", nil)]];
|
||||
CGFloat width = IPAD ? 400 : 310;
|
||||
segmentedControl.frame = CGRectMake(0, 0, width, 32);
|
||||
if (SYSTEM_VERSION_IS_LESS_THAN(@"7"))
|
||||
segmentedControl.tintColor = [[UINavigationBar appearance] tintColor];
|
||||
else
|
||||
segmentedControl.tintColor = [UIColor whiteColor];
|
||||
|
||||
segmentedControl.selectedSegmentIndex = GetDefaultSearchScope();
|
||||
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
|
||||
[segmentedControl addTarget:self action:@selector(segmentedControlValueChanged:) forControlEvents:UIControlEventValueChanged];
|
||||
_scopeView = [[ScopeView alloc] initWithFrame:CGRectMake(0, 0, self.view.width, 44) segmentedControl:segmentedControl];
|
||||
_scopeView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
|
||||
|
||||
if (SYSTEM_VERSION_IS_LESS_THAN(@"7"))
|
||||
_scopeView.backgroundColor = [[UINavigationBar appearance] tintColor];
|
||||
else
|
||||
_scopeView.backgroundColor = [UIColor colorWithColorCode:@"28384b"];
|
||||
}
|
||||
return _scopeView;
|
||||
}
|
||||
|
||||
- (void)segmentedControlValueChanged:(UISegmentedControl *)segmentedControl
|
||||
{
|
||||
g_scopeSection = segmentedControl.selectedSegmentIndex;
|
||||
// Save selected search mode for future launches
|
||||
Settings::Set(SEARCH_MODE_SETTING, g_scopeSection);
|
||||
[self proceedSearchWithString:self.searchBar.text andForceSearch:YES];
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
g_searchVC = self;
|
||||
|
||||
m_table = [[UITableView alloc] initWithFrame:self.view.bounds];
|
||||
m_table.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
m_table.delegate = self;
|
||||
m_table.dataSource = self;
|
||||
m_table.contentInset = UIEdgeInsetsMake(self.scopeView.height, 0, 0, 0);
|
||||
m_table.scrollIndicatorInsets = m_table.contentInset;
|
||||
|
||||
self.view.backgroundColor = [UIColor whiteColor];
|
||||
[self.view addSubview:m_table];
|
||||
[self.view addSubview:self.scopeView];
|
||||
|
||||
self.navigationItem.titleView = self.searchBar;
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
[super viewWillAppear:animated];
|
||||
|
||||
[m_locationManager start:self];
|
||||
|
||||
[self performAfterDelay:0 block:^{
|
||||
[self resizeNavigationBar];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)resizeNavigationBar
|
||||
{
|
||||
if (SYSTEM_VERSION_IS_LESS_THAN(@"6") || IPAD)
|
||||
return;
|
||||
|
||||
CGFloat landscapeHeight = 32;
|
||||
CGFloat portraitHeight = 44;
|
||||
self.navigationController.navigationBar.height = portraitHeight;
|
||||
if (UIDeviceOrientationIsLandscape(self.interfaceOrientation))
|
||||
m_table.minY = portraitHeight - landscapeHeight;
|
||||
else
|
||||
m_table.minY = 0;
|
||||
self.scopeView.minY = m_table.minY;
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
{
|
||||
// Relaunch search when view has appeared because of search indicator hack
|
||||
// (we replace one control with another, and system calls unsupported method on it)
|
||||
if (GetPlatform().IsPro())
|
||||
[self proceedSearchWithString:g_lastSearchRequest andForceSearch:YES];
|
||||
|
||||
[self.searchBar becomeFirstResponder];
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated
|
||||
{
|
||||
[m_locationManager stop:self];
|
||||
|
||||
// hide keyboard immediately
|
||||
[self.searchBar resignFirstResponder];
|
||||
[super viewWillDisappear:animated];
|
||||
g_numberOfRowsInEmptySearch = 0;
|
||||
}
|
||||
|
||||
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration
|
||||
{
|
||||
[self resizeNavigationBar];
|
||||
}
|
||||
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
|
||||
{
|
||||
return YES; // All orientations are supported.
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
//*********** SearchBar handlers *******************************************
|
||||
- (void)searchBar:(UISearchBar *)sender textDidChange:(NSString *)searchText
|
||||
{
|
||||
self.searching = [searchText length] > 0;
|
||||
g_lastSearchRequest = [[NSString alloc] initWithString:self.searchBar.text];
|
||||
[self clearCacheResults];
|
||||
[self proceedSearchWithString:self.searchBar.text andForceSearch:YES];
|
||||
}
|
||||
|
||||
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
|
||||
{
|
||||
[searchBar resignFirstResponder];
|
||||
}
|
||||
|
||||
- (void)onCloseButton:(id)sender
|
||||
{
|
||||
[self.navigationController popToRootViewControllerAnimated:YES];
|
||||
}
|
||||
//*********** End of SearchBar handlers *************************************
|
||||
//***************************************************************************
|
||||
|
||||
- (void)setSearchBoxText:(NSString *)text
|
||||
{
|
||||
self.searchBar.text = text;
|
||||
// Manually send text change notification if control has no focus,
|
||||
// OR if iOS 6 - it doesn't send textDidChange notification after text property update
|
||||
if (![self.searchBar isFirstResponder]
|
||||
|| [UIDevice currentDevice].systemVersion.floatValue > 5.999)
|
||||
[self searchBar:self.searchBar textDidChange:text];
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
m_suggestionsCount = self.searchBar.text.length ? 0 : 1;
|
||||
//No text in search show categories
|
||||
if (m_suggestionsCount)
|
||||
{
|
||||
return [categoriesNames count];
|
||||
}
|
||||
//If no results we should show 0 strings if search is in progress or 1 string with message thaht there is no results
|
||||
if (![[_searchResults objectAtIndex:g_scopeSection] getCount])
|
||||
{
|
||||
return g_numberOfRowsInEmptySearch;
|
||||
}
|
||||
return [[_searchResults objectAtIndex:g_scopeSection] getCount];
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
NSInteger realRowIndex = indexPath.row;
|
||||
if (m_suggestionsCount)
|
||||
{
|
||||
static NSString *CellIdentifier = @"categoryCell";
|
||||
|
||||
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
|
||||
if (!cell)
|
||||
{
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
|
||||
}
|
||||
|
||||
cell.textLabel.text = NSLocalizedString([categoriesNames objectAtIndex:indexPath.row], nil);
|
||||
cell.imageView.image = [UIImage imageNamed:[categoriesNames objectAtIndex:indexPath.row]];
|
||||
|
||||
return cell;
|
||||
}
|
||||
//No search results
|
||||
if ([self.searchBar.text length] != 0 && ![[_searchResults objectAtIndex:g_scopeSection] getCount] && g_numberOfRowsInEmptySearch)
|
||||
{
|
||||
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"NoResultsCell"];
|
||||
if (!cell)
|
||||
{
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"NoResultsCell"];
|
||||
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
}
|
||||
cell.textLabel.text = NSLocalizedString(@"no_search_results_found", nil);
|
||||
|
||||
// check if we have no position in "near me" screen
|
||||
if (![m_locationManager lastLocationIsValid] && g_scopeSection == 0)
|
||||
cell.detailTextLabel.text = NSLocalizedString(@"unknown_current_position", nil);
|
||||
else
|
||||
cell.detailTextLabel.text = @"";
|
||||
return cell;
|
||||
}
|
||||
|
||||
if ([_searchResults objectAtIndex:g_scopeSection] == nil || realRowIndex >= (NSInteger)[[_searchResults objectAtIndex:g_scopeSection] getCount])
|
||||
{
|
||||
ASSERT(false, ("Invalid m_results with size", [[_searchResults objectAtIndex:g_scopeSection] getCount]));
|
||||
return nil;
|
||||
}
|
||||
|
||||
search::Result const & r = [[_searchResults objectAtIndex:g_scopeSection] getWithPosition:realRowIndex];
|
||||
if (r.GetResultType() != search::Result::RESULT_SUGGESTION)
|
||||
{
|
||||
SearchCell * cell = (SearchCell *)[tableView dequeueReusableCellWithIdentifier:@"FeatureCell"];
|
||||
if (!cell)
|
||||
cell = [[SearchCell alloc] initWithReuseIdentifier:@"FeatureCell"];
|
||||
|
||||
// Init common parameters
|
||||
cell.featureName.text = [NSString stringWithUTF8String:r.GetString()];
|
||||
cell.featureCountry.text = [NSString stringWithUTF8String:r.GetRegionString()];
|
||||
cell.featureType.text = [NSString stringWithUTF8String:r.GetFeatureType()];
|
||||
|
||||
// Get current position and compass "north" direction
|
||||
double azimut = -1.0;
|
||||
double lat, lon;
|
||||
|
||||
if ([m_locationManager getLat:lat Lon:lon])
|
||||
{
|
||||
double north = -1.0;
|
||||
[m_locationManager getNorthRad:north];
|
||||
|
||||
string distance;
|
||||
if (!m_framework->GetDistanceAndAzimut(r.GetFeatureCenter(),
|
||||
lat, lon, north, distance, azimut))
|
||||
{
|
||||
// do not draw arrow for far away features
|
||||
azimut = -1.0;
|
||||
}
|
||||
|
||||
cell.featureDistance.text = [NSString stringWithUTF8String:distance.c_str()];
|
||||
}
|
||||
else
|
||||
cell.featureDistance.text = nil;
|
||||
|
||||
// Show flags only if it has one and no azimut to feature
|
||||
char const * flag = r.GetRegionFlag();
|
||||
if (flag && azimut < 0.0)
|
||||
{
|
||||
UIImage * flagImage = [UIImage imageNamed:[NSString stringWithFormat:@"%s.png", flag]];
|
||||
UIImageView * imgView = [[UIImageView alloc] initWithImage:flagImage];
|
||||
cell.accessoryView = imgView;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try to reuse existing compass view
|
||||
CompassView * compass;
|
||||
if ([cell.accessoryView isKindOfClass:[CompassView class]])
|
||||
compass = (CompassView *)cell.accessoryView;
|
||||
else
|
||||
{
|
||||
// Create compass view
|
||||
float const h = (int)(m_table.rowHeight * 0.6);
|
||||
compass = [[CompassView alloc] initWithFrame:CGRectMake(0, 0, h, h)];
|
||||
cell.accessoryView = compass;
|
||||
}
|
||||
|
||||
// Show arrow for valid azimut and if feature is not a continent (flag is exist)
|
||||
compass.showArrow = (azimut >= 0.0 && flag) ? YES : NO;
|
||||
compass.angle = azimut;
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
else
|
||||
{
|
||||
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"SuggestionCell"];
|
||||
if (!cell)
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"SuggestionCell"];
|
||||
cell.textLabel.text = [NSString stringWithUTF8String:r.GetString()];
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
NSInteger realRowIndex = indexPath.row;
|
||||
// Suggestion cell was clicked
|
||||
if (m_suggestionsCount)
|
||||
{
|
||||
[[Statistics instance] logEvent:@"Category Selection" withParameters:@{@"Category" : [categoriesNames objectAtIndex:realRowIndex]}];
|
||||
[self setSearchBoxText:[NSLocalizedString([categoriesNames objectAtIndex:realRowIndex], Search Suggestion) stringByAppendingString:@" "]];
|
||||
[m_table scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
|
||||
return;
|
||||
}
|
||||
|
||||
if (realRowIndex < (NSInteger)[[_searchResults objectAtIndex:g_scopeSection] getCount])
|
||||
{
|
||||
search::Result const & res = [[_searchResults objectAtIndex:g_scopeSection] getWithPosition:realRowIndex];
|
||||
if (res.GetResultType() != search::Result::RESULT_SUGGESTION)
|
||||
{
|
||||
m_framework->ShowSearchResult(res);
|
||||
|
||||
search::AddressInfo info;
|
||||
info.MakeFrom(res);
|
||||
|
||||
if (g_scopeSection == 0)
|
||||
[[Statistics instance] logEvent:@"Search Filter" withParameters:@{@"Filter Name" : @"Near Me"}];
|
||||
else if (g_scopeSection == 1)
|
||||
[[Statistics instance] logEvent:@"Search Filter" withParameters:@{@"Filter Name" : @"On the Screen"}];
|
||||
else
|
||||
[[Statistics instance] logEvent:@"Search Filter" withParameters:@{@"Filter Name" : @"Everywhere"}];
|
||||
|
||||
[[MapsAppDelegate theApp].m_mapViewController showSearchResultAsBookmarkAtMercatorPoint:res.GetFeatureCenter() withInfo:info];
|
||||
|
||||
[self onCloseButton:nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self setSearchBoxText:[NSString stringWithUTF8String:res.GetSuggestionString()]];
|
||||
// Remove blue selection from the row
|
||||
[tableView deselectRowAtIndexPath: indexPath animated:YES];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setSearching:(BOOL)searching
|
||||
{
|
||||
if (searching)
|
||||
[self.activityIndicator startAnimating];
|
||||
else
|
||||
[self.activityIndicator stopAnimating];
|
||||
|
||||
_searching = searching;
|
||||
}
|
||||
|
||||
- (UIActivityIndicatorView *)activityIndicator
|
||||
{
|
||||
if (!_activityIndicator)
|
||||
{
|
||||
_activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
_activityIndicator.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
|
||||
_activityIndicator.center = CGPointMake(self.searchBar.width - 45, self.searchBar.height / 2);
|
||||
_activityIndicator.backgroundColor = [UIColor whiteColor];
|
||||
[self.searchBar addSubview:_activityIndicator];
|
||||
}
|
||||
return _activityIndicator;
|
||||
}
|
||||
|
||||
// Called on UI thread from search threads
|
||||
- (void)addResult:(id)res
|
||||
{
|
||||
ResultsWrapper * w = (ResultsWrapper *)res;
|
||||
|
||||
if ([w isEndMarker])
|
||||
{
|
||||
if ([w isEndedNormal])
|
||||
{
|
||||
g_numberOfRowsInEmptySearch = 1;
|
||||
self.searching = NO;
|
||||
[m_table reloadData];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_numberOfRowsInEmptySearch = 0;
|
||||
[_searchResults replaceObjectAtIndex:g_scopeSection withObject:w];
|
||||
[m_table reloadData];
|
||||
}
|
||||
}
|
||||
|
||||
void setSearchType(search::SearchParams & params)
|
||||
{
|
||||
switch (g_scopeSection)
|
||||
{
|
||||
case 0:
|
||||
params.SetSearchMode(search::SearchParams::AROUND_POSITION);
|
||||
break;
|
||||
case 1:
|
||||
params.SetSearchMode(search::SearchParams::IN_VIEWPORT);
|
||||
break;
|
||||
case 2:
|
||||
params.SetSearchMode(search::SearchParams::ALL);
|
||||
break;
|
||||
default:
|
||||
params.SetSearchMode(search::SearchParams::ALL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//******************************************************************
|
||||
//*********** Location manager callbacks ***************************
|
||||
- (void)onLocationError:(location::TLocationError)errorCode
|
||||
{
|
||||
// Handle location status changes if necessary
|
||||
}
|
||||
|
||||
- (void)onLocationUpdate:(location::GpsInfo const &)info
|
||||
{
|
||||
// Refresh search results with newer location.
|
||||
if (![self.searchBar.text length])
|
||||
return;
|
||||
search::SearchParams params;
|
||||
setSearchType(params);
|
||||
if (self.searchBar.text)
|
||||
{
|
||||
[self fillSearchParams:params withText:self.searchBar.text];
|
||||
|
||||
// hack, fillSearch Params return invalid position
|
||||
params.SetPosition(info.m_latitude, info.m_longitude);
|
||||
|
||||
g_numberOfRowsInEmptySearch = m_framework->Search(params) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onCompassUpdate:(location::CompassInfo const &)info
|
||||
{
|
||||
double lat, lon;
|
||||
if (![m_locationManager getLat:lat Lon:lon])
|
||||
return;
|
||||
//check if categories are on the screen
|
||||
if (!m_suggestionsCount && [[_searchResults objectAtIndex:g_scopeSection] getCount])
|
||||
{
|
||||
double const northRad = (info.m_trueHeading < 0) ? info.m_magneticHeading : info.m_trueHeading;
|
||||
NSArray * cells = m_table.visibleCells;
|
||||
for (NSUInteger i = 0; i < cells.count; ++i)
|
||||
{
|
||||
UITableViewCell * cell = (UITableViewCell *)[cells objectAtIndex:i];
|
||||
NSInteger realRowIndex = [m_table indexPathForCell:cell].row;
|
||||
search::Result const & res = [[_searchResults objectAtIndex:g_scopeSection] getWithPosition:realRowIndex];
|
||||
if (res.GetResultType() != search::Result::RESULT_SUGGESTION)
|
||||
{
|
||||
// Show compass only for cells without flags
|
||||
if ([cell.accessoryView isKindOfClass:[CompassView class]])
|
||||
{
|
||||
CompassView * compass = (CompassView *)cell.accessoryView;
|
||||
m2::PointD const center = res.GetFeatureCenter();
|
||||
compass.angle = ang::AngleTo(m2::PointD(MercatorBounds::LonToX(lon),
|
||||
MercatorBounds::LatToY(lat)), center) + northRad;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//*********** End of Location manager callbacks ********************
|
||||
//******************************************************************
|
||||
|
||||
// Dismiss virtual keyboard when touching tableview
|
||||
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
|
||||
{
|
||||
[self.searchBar resignFirstResponder];
|
||||
}
|
||||
|
||||
// Dismiss virtual keyboard when "Search" button is pressed
|
||||
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
|
||||
{
|
||||
[self.searchBar resignFirstResponder];
|
||||
}
|
||||
|
||||
// Callback from suggestion cell, called when icon is selected
|
||||
- (void)onSuggestionSelected:(NSString *)suggestion
|
||||
{
|
||||
[self setSearchBoxText:[suggestion stringByAppendingString:@" "]];
|
||||
}
|
||||
|
||||
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
|
||||
{
|
||||
[self onCloseButton:nil];
|
||||
}
|
||||
|
||||
- (void)clearCacheResults
|
||||
{
|
||||
for (int i = 0; i < [_searchResults count]; ++i)
|
||||
{
|
||||
[_searchResults replaceObjectAtIndex:i withObject:[[ResultsWrapper alloc] init]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)proceedSearchWithString:(NSString *)searchText andForceSearch:(BOOL)forceSearch
|
||||
{
|
||||
g_numberOfRowsInEmptySearch = 0;
|
||||
[m_table reloadData];
|
||||
if (![searchText length])
|
||||
return;
|
||||
search::SearchParams params;
|
||||
setSearchType(params);
|
||||
if (forceSearch)
|
||||
{
|
||||
params.SetForceSearch(true);
|
||||
}
|
||||
[self fillSearchParams:params withText:searchText];
|
||||
if (!m_framework->Search(params))
|
||||
{
|
||||
g_numberOfRowsInEmptySearch = 1;
|
||||
[m_table reloadData];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
10
iphone/Maps/Classes/SearchView.h
Normal file
10
iphone/Maps/Classes/SearchView.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "SearchActivityProtocol.h"
|
||||
#import "SearchBar.h"
|
||||
|
||||
@interface SearchView : UIView <SearchActivityProtocol>
|
||||
|
||||
@property (nonatomic) SearchBar * searchBar;
|
||||
|
||||
@end
|
574
iphone/Maps/Classes/SearchView.mm
Normal file
574
iphone/Maps/Classes/SearchView.mm
Normal file
|
@ -0,0 +1,574 @@
|
|||
|
||||
#import "SearchView.h"
|
||||
#import "SegmentedControl.h"
|
||||
#import "SearchUniversalCell.h"
|
||||
#import "UIKitCategories.h"
|
||||
#import "MapsAppDelegate.h"
|
||||
#import "LocationManager.h"
|
||||
#import "Statistics.h"
|
||||
#import "MapViewController.h"
|
||||
#import "LocationManager.h"
|
||||
|
||||
#include "Framework.h"
|
||||
|
||||
#include "../../search/result.hpp"
|
||||
#include "../../search/params.hpp"
|
||||
|
||||
#include "../../indexer/mercator.hpp"
|
||||
|
||||
#include "../../platform/platform.hpp"
|
||||
#include "../../platform/preferred_languages.hpp"
|
||||
#include "../../platform/settings.hpp"
|
||||
|
||||
#include "../../geometry/angles.hpp"
|
||||
#include "../../geometry/distance_on_sphere.hpp"
|
||||
|
||||
|
||||
@interface SearchResultsWrapper : NSObject
|
||||
|
||||
- (id)initWithResults:(search::Results const &)res;
|
||||
|
||||
- (search::Result const &)resultWithPosition:(NSInteger)position;
|
||||
- (NSInteger)count;
|
||||
- (BOOL)isEndMarker;
|
||||
- (BOOL)isEndedNormal;
|
||||
|
||||
@end
|
||||
|
||||
@interface SearchResultsWrapper ()
|
||||
|
||||
@property (nonatomic) search::Results results;
|
||||
@property (nonatomic) NSMutableDictionary * distances;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SearchResultsWrapper
|
||||
|
||||
- (id)initWithResults:(search::Results const &)results
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
self.results = results;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *)distances
|
||||
{
|
||||
if (!_distances)
|
||||
_distances = [[NSMutableDictionary alloc] init];
|
||||
return _distances;
|
||||
}
|
||||
|
||||
- (NSInteger)count
|
||||
{
|
||||
return self.results.GetCount();
|
||||
}
|
||||
|
||||
- (search::Result const &)resultWithPosition:(NSInteger)position
|
||||
{
|
||||
return self.results.GetResult(position);
|
||||
}
|
||||
|
||||
- (BOOL)isEndMarker
|
||||
{
|
||||
return self.results.IsEndMarker();
|
||||
}
|
||||
|
||||
- (BOOL)isEndedNormal
|
||||
{
|
||||
return self.results.IsEndedNormal();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface SearchView () <UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource, SearchBarDelegate, SegmentedControlDelegate, LocationObserver>
|
||||
|
||||
@property (nonatomic) SegmentedControl * segmentedControl;
|
||||
@property (nonatomic) UITableView * tableView;
|
||||
@property (nonatomic) UIView * backgroundView;
|
||||
@property (nonatomic) UIImageView * topBackgroundView;
|
||||
@property (nonatomic) UILabel * emptyResultLabel;
|
||||
|
||||
- (BOOL)isShowingCategories;
|
||||
|
||||
@property (nonatomic) NSMutableArray * searchData;
|
||||
@property (nonatomic) NSArray *categoriesNames;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SearchView
|
||||
@synthesize active = _active;
|
||||
|
||||
__weak SearchView * selfPointer;
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
|
||||
[self addSubview:self.backgroundView];
|
||||
[self addSubview:self.tableView];
|
||||
[self addSubview:self.topBackgroundView];
|
||||
[self addSubview:self.segmentedControl];
|
||||
[self addSubview:self.searchBar];
|
||||
[self addSubview:self.emptyResultLabel];
|
||||
|
||||
self.emptyResultLabel.center = CGPointMake(self.width / 2, 160);
|
||||
self.emptyResultLabel.hidden = YES;
|
||||
|
||||
self.searchBar.midX = self.width / 2;
|
||||
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(barTapped:)];
|
||||
[self.searchBar addGestureRecognizer:tap];
|
||||
|
||||
NSInteger value;
|
||||
self.segmentedControl.selectedSegmentIndex = Settings::Get("SearchMode", value) ? value : 0;
|
||||
self.segmentedControl.midX = self.width / 2;
|
||||
|
||||
[self setActive:NO animated:NO];
|
||||
|
||||
selfPointer = self;
|
||||
|
||||
double latitude;
|
||||
double longitude;
|
||||
LocationManager * locationManager = [MapsAppDelegate theApp].m_locationManager;
|
||||
bool const hasPt = [locationManager getLat:latitude Lon:longitude];
|
||||
GetFramework().PrepareSearch(hasPt, latitude, longitude);
|
||||
|
||||
[locationManager start:self];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)onLocationError:(location::TLocationError)errorCode
|
||||
{
|
||||
NSLog(@"Location error in SearchView");
|
||||
}
|
||||
|
||||
- (void)onLocationUpdate:(location::GpsInfo const &)info
|
||||
{
|
||||
if ([self.searchBar.textField.text length])
|
||||
{
|
||||
search::SearchParams params = [self searchParameters];
|
||||
params.SetPosition(info.m_latitude, info.m_longitude);
|
||||
GetFramework().Search(params);
|
||||
|
||||
[self recalculateDistances];
|
||||
[self.tableView reloadRowsAtIndexPaths:self.tableView.indexPathsForVisibleRows withRowAnimation:UITableViewRowAnimationNone];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)recalculateDistances
|
||||
{
|
||||
LocationManager * locationManager = [MapsAppDelegate theApp].m_locationManager;
|
||||
double north = -1.0;
|
||||
double azimut = -1.0;
|
||||
[locationManager getNorthRad:north];
|
||||
double lat, lon;
|
||||
if ([locationManager getLat:lat Lon:lon])
|
||||
{
|
||||
for (NSInteger segment = 0; segment < [self.segmentedControl segmentsCount]; segment++) {
|
||||
SearchResultsWrapper * wrapper = self.searchData[segment];
|
||||
for (NSInteger position = 0; position < [wrapper count]; position++) {
|
||||
search::Result const & result = [wrapper resultWithPosition:position];
|
||||
string distance;
|
||||
GetFramework().GetDistanceAndAzimut(result.GetFeatureCenter(), lat, lon, north, distance, azimut);
|
||||
wrapper.distances[@(position)] = [NSString stringWithUTF8String:distance.c_str()];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onCompassUpdate:(location::CompassInfo const &)info
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (search::SearchParams)searchParameters
|
||||
{
|
||||
NSInteger scopeIndex = self.segmentedControl.selectedSegmentIndex;
|
||||
search::SearchParams params;
|
||||
if (scopeIndex == 0)
|
||||
params.SetSearchMode(search::SearchParams::AROUND_POSITION);
|
||||
else if (scopeIndex == 1)
|
||||
params.SetSearchMode(search::SearchParams::IN_VIEWPORT);
|
||||
else if (scopeIndex == 2)
|
||||
params.SetSearchMode(search::SearchParams::ALL);
|
||||
|
||||
params.m_query = [[self.searchBar.textField.text precomposedStringWithCompatibilityMapping] UTF8String];
|
||||
params.m_callback = bind(&OnSearchResultCallback, _1);
|
||||
params.SetInputLanguage([[UITextInputMode currentInputMode].primaryLanguage UTF8String]);
|
||||
params.SetForceSearch(true);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
- (void)search
|
||||
{
|
||||
self.emptyResultLabel.hidden = YES;
|
||||
[self.searchBar setSearching:YES];
|
||||
search::SearchParams params = [self searchParameters];
|
||||
double lat, lon;
|
||||
if ([[MapsAppDelegate theApp].m_locationManager getLat:lat Lon:lon])
|
||||
params.SetPosition(lat, lon);
|
||||
GetFramework().Search(params);
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
static void OnSearchResultCallback(search::Results const & results)
|
||||
{
|
||||
SearchResultsWrapper * wrapper = [[SearchResultsWrapper alloc] initWithResults:results];
|
||||
[selfPointer performSelectorOnMainThread:@selector(frameworkDidAddSearchResult:) withObject:wrapper waitUntilDone:NO];
|
||||
}
|
||||
|
||||
- (void)frameworkDidAddSearchResult:(SearchResultsWrapper *)wrapper
|
||||
{
|
||||
if ([wrapper isEndMarker])
|
||||
{
|
||||
if ([wrapper isEndedNormal])
|
||||
{
|
||||
[self.searchBar setSearching:NO];
|
||||
[self recalculateDistances];
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self.emptyResultLabel.hidden = [self isShowingCategories] ? YES : ([wrapper count] > 0);
|
||||
self.searchData[self.segmentedControl.selectedSegmentIndex] = wrapper;
|
||||
[self.tableView reloadData];
|
||||
[self.tableView setContentOffset:CGPointMake(0, -self.tableView.contentInset.top) animated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)searchBarDidPressClearButton:(SearchBar *)searchBar
|
||||
{
|
||||
[self processTextChanging];
|
||||
}
|
||||
|
||||
- (void)searchBarDidPressCancelButton:(id)searchBar
|
||||
{
|
||||
[self setActive:NO animated:YES];
|
||||
}
|
||||
|
||||
- (void)setActive:(BOOL)active animated:(BOOL)animated
|
||||
{
|
||||
[self.searchBar setActive:active animated:animated];
|
||||
[self.segmentedControl setActive:active animated:animated];
|
||||
if (active)
|
||||
{
|
||||
[UIView animateWithDuration:(animated ? 0.4 : 0) delay:0 damping:0.9 initialVelocity:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
||||
self.backgroundView.alpha = 1;
|
||||
self.topBackgroundView.alpha = 1;
|
||||
self.tableView.alpha = 1;
|
||||
self.tableView.minY = 0;
|
||||
} completion:^(BOOL finished){
|
||||
[self.tableView setContentOffset:CGPointMake(0, -self.tableView.contentInset.top) animated:YES];
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
[UIView animateWithDuration:(animated ? 0.4 : 0) delay:0 damping:0.9 initialVelocity:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
||||
self.backgroundView.alpha = 0;
|
||||
self.topBackgroundView.alpha = 0;
|
||||
self.tableView.alpha = 0;
|
||||
self.tableView.minY = self.height;
|
||||
} completion:nil];
|
||||
}
|
||||
[self willChangeValueForKey:@"active"];
|
||||
_active = active;
|
||||
[self didChangeValueForKey:@"active"];
|
||||
}
|
||||
|
||||
- (void)barTapped:(UITapGestureRecognizer *)sender
|
||||
{
|
||||
[self setActive:YES animated:YES];
|
||||
}
|
||||
|
||||
- (void)textFieldTextChanged:(id)sender
|
||||
{
|
||||
[self processTextChanging];
|
||||
}
|
||||
|
||||
- (void)processTextChanging
|
||||
{
|
||||
if ([self isShowingCategories])
|
||||
{
|
||||
self.emptyResultLabel.hidden = YES;
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self search];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)textFieldShouldReturn:(UITextField *)textField
|
||||
{
|
||||
return [textField.text length] > 0;
|
||||
}
|
||||
|
||||
- (void)segmentedControl:(SegmentedControl *)segmentControl didSelectSegment:(NSInteger)segmentIndex
|
||||
{
|
||||
[self search];
|
||||
}
|
||||
|
||||
- (CGFloat)defaultSearchBarMinY
|
||||
{
|
||||
if (SYSTEM_VERSION_IS_LESS_THAN(@"7"))
|
||||
return self.width < self.height ? 10 : 4;
|
||||
else
|
||||
return self.width < self.height ? 30 : 20;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
self.searchBar.minY = [self defaultSearchBarMinY];
|
||||
if (self.width < self.height)
|
||||
{
|
||||
self.segmentedControl.minY = self.searchBar.maxY - 4;
|
||||
self.segmentedControl.height = 40;
|
||||
self.topBackgroundView.height = self.segmentedControl.maxY + 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.segmentedControl.minY = self.searchBar.maxY - 6;
|
||||
self.segmentedControl.height = 27;
|
||||
self.topBackgroundView.height = self.segmentedControl.maxY + 1;
|
||||
}
|
||||
self.tableView.contentInset = UIEdgeInsetsMake(self.topBackgroundView.maxY + 13.5, 0, 14, 0);
|
||||
self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(self.topBackgroundView.maxY, 0, 0, 0);
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
SearchUniversalCell * cell = [tableView dequeueReusableCellWithIdentifier:@"UniversalCell"];
|
||||
if (!cell)
|
||||
cell = [[SearchUniversalCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"UniversalCell"];
|
||||
|
||||
if ([self isShowingCategories])
|
||||
{
|
||||
cell.titleLabel.text = NSLocalizedString(self.categoriesNames[indexPath.row], nil);
|
||||
cell.subtitleLabel.text = nil;
|
||||
cell.distanceLabel.text = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (indexPath.row == 0)
|
||||
{
|
||||
cell.titleLabel.text = @"Показать все";
|
||||
cell.subtitleLabel.text = nil;
|
||||
cell.distanceLabel.text = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchResultsWrapper * wrapper = self.searchData[self.segmentedControl.selectedSegmentIndex];
|
||||
NSInteger position = indexPath.row - 1;
|
||||
search::Result const & result = [wrapper resultWithPosition:position];
|
||||
cell.titleLabel.text = [NSString stringWithUTF8String:result.GetString()];
|
||||
cell.subtitleLabel.text = result.GetRegionString() ? [NSString stringWithUTF8String:result.GetRegionString()] : nil;
|
||||
cell.distanceLabel.text = wrapper.distances[@(position)];
|
||||
}
|
||||
}
|
||||
|
||||
if ([self rowsCount] == 1)
|
||||
cell.position = SearchCellPositionAlone;
|
||||
else if (indexPath.row == 0)
|
||||
cell.position = SearchCellPositionFirst;
|
||||
else if (indexPath.row == [self rowsCount] - 1)
|
||||
cell.position = SearchCellPositionLast;
|
||||
else
|
||||
cell.position = SearchCellPositionMiddle;
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if ([self isShowingCategories])
|
||||
{
|
||||
return [SearchUniversalCell cellHeightWithTitle:self.categoriesNames[indexPath.row] subtitle:nil viewWidth:tableView.width];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (indexPath.row == 0)
|
||||
{
|
||||
return [SearchUniversalCell cellHeightWithTitle:@"Показать все" subtitle:nil viewWidth:tableView.width];
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchResultsWrapper * wrapper = self.searchData[self.segmentedControl.selectedSegmentIndex];
|
||||
NSInteger position = indexPath.row - 1;
|
||||
search::Result const & result = [wrapper resultWithPosition:position];
|
||||
NSString * title = [NSString stringWithUTF8String:result.GetString()];
|
||||
NSString * subtitle = [NSString stringWithUTF8String:result.GetRegionString()];
|
||||
return [SearchUniversalCell cellHeightWithTitle:title subtitle:subtitle viewWidth:tableView.width];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return [self rowsCount];
|
||||
}
|
||||
|
||||
- (NSInteger)rowsCount
|
||||
{
|
||||
SearchResultsWrapper * wrapper = self.searchData[self.segmentedControl.selectedSegmentIndex];
|
||||
NSInteger resultsCount = [wrapper count] ? [wrapper count] + 1 : 0;
|
||||
return [self isShowingCategories] ? [self.categoriesNames count] : resultsCount;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
if ([self isShowingCategories])
|
||||
{
|
||||
[[Statistics instance] logEvent:@"Category Selection" withParameters:@{@"Category" : self.categoriesNames[indexPath.row]}];
|
||||
self.searchBar.textField.text = [NSLocalizedString(self.categoriesNames[indexPath.row], nil) stringByAppendingString:@" "];
|
||||
[self search];
|
||||
return;
|
||||
}
|
||||
|
||||
if (indexPath.row == 0)
|
||||
{
|
||||
GetFramework().ShowAllSearchResults();
|
||||
self.searchBar.isShowingResult = YES;
|
||||
[self setActive:NO animated:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSInteger segmentIndex = self.segmentedControl.selectedSegmentIndex;
|
||||
NSInteger position = indexPath.row - 1;
|
||||
search::Result const & result = [self.searchData[segmentIndex] resultWithPosition:position];
|
||||
if (result.GetResultType() == search::Result::RESULT_SUGGESTION)
|
||||
{
|
||||
self.searchBar.textField.text = [NSString stringWithUTF8String:result.GetSuggestionString()];
|
||||
[self search];
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
GetFramework().ShowSearchResult(result);
|
||||
|
||||
if (segmentIndex == 0)
|
||||
[[Statistics instance] logEvent:@"Search Filter" withParameters:@{@"Filter Name" : @"Near Me"}];
|
||||
else if (segmentIndex == 1)
|
||||
[[Statistics instance] logEvent:@"Search Filter" withParameters:@{@"Filter Name" : @"On the Screen"}];
|
||||
else
|
||||
[[Statistics instance] logEvent:@"Search Filter" withParameters:@{@"Filter Name" : @"Everywhere"}];
|
||||
|
||||
self.searchBar.textField.text = [NSString stringWithUTF8String:result.GetString()];
|
||||
|
||||
self.searchBar.isShowingResult = YES;
|
||||
[self setActive:NO animated:YES];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
|
||||
{
|
||||
if (!scrollView.decelerating && scrollView.dragging)
|
||||
[self.searchBar.textField resignFirstResponder];
|
||||
}
|
||||
|
||||
- (BOOL)isShowingCategories
|
||||
{
|
||||
return ![self.searchBar.textField.text length];
|
||||
}
|
||||
|
||||
- (NSMutableArray *)searchData
|
||||
{
|
||||
if (!_searchData)
|
||||
_searchData = [@[[[SearchResultsWrapper alloc] init], [[SearchResultsWrapper alloc] init], [[SearchResultsWrapper alloc] init]] mutableCopy];
|
||||
return _searchData;
|
||||
}
|
||||
|
||||
- (NSArray *)categoriesNames
|
||||
{
|
||||
if (!_categoriesNames)
|
||||
_categoriesNames = @[@"food", @"shop", @"hotel", @"tourism", @"entertainment", @"atm", @"bank", @"transport", @"fuel", @"parking", @"pharmacy", @"hospital", @"toilet", @"post", @"police",];
|
||||
return _categoriesNames;
|
||||
}
|
||||
|
||||
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
|
||||
{
|
||||
return CGRectContainsPoint(self.searchBar.frame, point) || self.active;
|
||||
}
|
||||
|
||||
- (UITableView *)tableView
|
||||
{
|
||||
if (!_tableView)
|
||||
{
|
||||
_tableView = [[UITableView alloc] initWithFrame:self.bounds];
|
||||
_tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
_tableView.delegate = self;
|
||||
_tableView.dataSource = self;
|
||||
_tableView.backgroundColor = [UIColor clearColor];
|
||||
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
|
||||
}
|
||||
return _tableView;
|
||||
}
|
||||
|
||||
- (UIImageView *)topBackgroundView
|
||||
{
|
||||
if (!_topBackgroundView)
|
||||
{
|
||||
_topBackgroundView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.width, 0)];
|
||||
_topBackgroundView.image = [[UIImage imageNamed:@"SearchViewTopBackground"] resizableImageWithCapInsets:UIEdgeInsetsMake(10, 0, 10, 0)];
|
||||
_topBackgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
|
||||
_topBackgroundView.userInteractionEnabled = YES;
|
||||
}
|
||||
return _topBackgroundView;
|
||||
}
|
||||
|
||||
- (UIView *)backgroundView
|
||||
{
|
||||
if (!_backgroundView)
|
||||
{
|
||||
_backgroundView = [[UIView alloc] initWithFrame:self.bounds];
|
||||
_backgroundView.backgroundColor = [UIColor colorWithColorCode:@"efeff4"];
|
||||
_backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
}
|
||||
return _backgroundView;
|
||||
}
|
||||
|
||||
- (SegmentedControl *)segmentedControl
|
||||
{
|
||||
if (!_segmentedControl)
|
||||
{
|
||||
_segmentedControl = [[SegmentedControl alloc] initWithFrame:CGRectMake(0, 0, 294, 0)];
|
||||
_segmentedControl.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin;
|
||||
_segmentedControl.delegate = self;
|
||||
}
|
||||
return _segmentedControl;
|
||||
}
|
||||
|
||||
- (SearchBar *)searchBar
|
||||
{
|
||||
if (!_searchBar)
|
||||
{
|
||||
_searchBar = [[SearchBar alloc] initWithFrame:CGRectMake(0, 0, self.width, 44)];
|
||||
_searchBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
|
||||
_searchBar.textField.delegate = self;
|
||||
_searchBar.delegate = self;
|
||||
[_searchBar.textField addTarget:self action:@selector(textFieldTextChanged:) forControlEvents:UIControlEventEditingChanged];
|
||||
}
|
||||
return _searchBar;
|
||||
}
|
||||
|
||||
- (UILabel *)emptyResultLabel
|
||||
{
|
||||
if (!_emptyResultLabel)
|
||||
{
|
||||
_emptyResultLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.width, 60)];
|
||||
_emptyResultLabel.backgroundColor = [UIColor clearColor];
|
||||
_emptyResultLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:14];
|
||||
_emptyResultLabel.text = @"Нет результатов";
|
||||
_emptyResultLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin;
|
||||
_emptyResultLabel.textAlignment = NSTextAlignmentCenter;
|
||||
}
|
||||
return _emptyResultLabel;
|
||||
}
|
||||
|
||||
@end
|
21
iphone/Maps/Classes/SegmentedControl.h
Normal file
21
iphone/Maps/Classes/SegmentedControl.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "SearchActivityProtocol.h"
|
||||
|
||||
@class SegmentedControl;
|
||||
@protocol SegmentedControlDelegate <NSObject>
|
||||
|
||||
- (void)segmentedControl:(SegmentedControl *)segmentControl didSelectSegment:(NSInteger)segmentIndex;
|
||||
|
||||
@end
|
||||
|
||||
@interface SegmentedControl : UIView <SearchActivityProtocol>
|
||||
|
||||
- (void)setActive:(BOOL)active animated:(BOOL)animated;
|
||||
@property (nonatomic) NSInteger selectedSegmentIndex;
|
||||
|
||||
@property (nonatomic) id <SegmentedControlDelegate> delegate;
|
||||
|
||||
- (NSInteger)segmentsCount;
|
||||
|
||||
@end
|
144
iphone/Maps/Classes/SegmentedControl.m
Normal file
144
iphone/Maps/Classes/SegmentedControl.m
Normal file
|
@ -0,0 +1,144 @@
|
|||
|
||||
#import "SegmentedControl.h"
|
||||
#import "UIKitCategories.h"
|
||||
|
||||
@interface SegmentedControl ()
|
||||
|
||||
@property (nonatomic, readonly) UIButton * selectedButton;
|
||||
@property (nonatomic) UIImageView * selectionImageView;
|
||||
|
||||
@property (nonatomic) UIButton * leftButton;
|
||||
@property (nonatomic) UIButton * centerButton;
|
||||
@property (nonatomic) UIButton * rightButton;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SegmentedControl
|
||||
@synthesize active = _active;
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
|
||||
[self addSubview:self.selectionImageView];
|
||||
|
||||
self.leftButton = [self buttonWithTitle:NSLocalizedString(@"search_mode_nearme", nil)];
|
||||
self.leftButton.tag = 0;
|
||||
self.centerButton = [self buttonWithTitle:NSLocalizedString(@"search_mode_viewport", nil)];
|
||||
self.centerButton.tag = 1;
|
||||
self.rightButton = [self buttonWithTitle:NSLocalizedString(@"search_mode_all", nil)];
|
||||
self.rightButton.tag = 2;
|
||||
|
||||
[self setSelectedButton:self.leftButton animated:NO];
|
||||
[self setActive:NO animated:NO];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSInteger)segmentsCount
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
- (UIButton *)buttonWithTitle:(NSString *)title
|
||||
{
|
||||
UIButton * button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 90, 44)];
|
||||
[button setTitle:[title lowercaseString] forState:UIControlStateNormal];
|
||||
[button setTitleColor:[UIColor colorWithColorCode:@"333333"] forState:UIControlStateNormal];
|
||||
[button setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
|
||||
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
|
||||
[button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
|
||||
button.midY = self.height / 2;
|
||||
button.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;;
|
||||
button.titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:14];
|
||||
[self addSubview:button];
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
- (UIImageView *)selectionImageView
|
||||
{
|
||||
if (!_selectionImageView)
|
||||
{
|
||||
_selectionImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SegmentSelection"]];
|
||||
_selectionImageView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
|
||||
}
|
||||
return _selectionImageView;
|
||||
}
|
||||
|
||||
- (void)setActive:(BOOL)active animated:(BOOL)animated
|
||||
{
|
||||
if (active)
|
||||
{
|
||||
[UIView animateWithDuration:(animated ? 0.35 : 0) delay:0 damping:0.8 initialVelocity:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
||||
NSInteger count = 3;
|
||||
CGFloat start = (self.width / count) / 2;
|
||||
CGFloat delta = self.width / count;
|
||||
self.leftButton.midX = start;
|
||||
self.centerButton.midX = start + delta;
|
||||
self.rightButton.midX = start + 2 * delta;
|
||||
self.selectionImageView.center = self.selectedButton.center;
|
||||
self.leftButton.alpha = 1;
|
||||
self.centerButton.alpha = 1;
|
||||
self.rightButton.alpha = 1;
|
||||
self.selectionImageView.alpha = 1;
|
||||
} completion:^(BOOL finished){}];
|
||||
}
|
||||
else
|
||||
{
|
||||
[UIView animateWithDuration:(animated ? 0.4 : 0) delay:0 damping:0.8 initialVelocity:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
||||
self.leftButton.maxX = 0;
|
||||
self.rightButton.minX = self.width;
|
||||
self.centerButton.midX = self.width / 2;
|
||||
self.selectionImageView.center = self.selectedButton.center;
|
||||
self.leftButton.alpha = 0;
|
||||
self.centerButton.alpha = 0;
|
||||
self.rightButton.alpha = 0;
|
||||
self.selectionImageView.alpha = 0;
|
||||
} completion:^(BOOL finished){}];
|
||||
}
|
||||
_active = active;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
self.selectionImageView.center = self.selectedButton.center;
|
||||
}
|
||||
|
||||
- (NSInteger)selectedSegmentIndex
|
||||
{
|
||||
return self.selectedButton.tag;
|
||||
}
|
||||
|
||||
- (void)setSelectedSegmentIndex:(NSInteger)selectedSegmentIndex
|
||||
{
|
||||
if (selectedSegmentIndex == 0)
|
||||
[self setSelectedButton:self.leftButton animated:NO];
|
||||
else if (selectedSegmentIndex == 1)
|
||||
[self setSelectedButton:self.centerButton animated:NO];
|
||||
else if (selectedSegmentIndex == 2)
|
||||
[self setSelectedButton:self.rightButton animated:NO];
|
||||
}
|
||||
|
||||
- (void)setSelectedButton:(UIButton *)selectedButton animated:(BOOL)animated
|
||||
{
|
||||
_selectedButton.selected = NO;
|
||||
_selectedButton.titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:14];
|
||||
_selectedButton.userInteractionEnabled = YES;
|
||||
selectedButton.selected = YES;
|
||||
selectedButton.titleLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:14];
|
||||
selectedButton.userInteractionEnabled = NO;
|
||||
[UIView animateWithDuration:(animated ? 0.3 : 0) delay:0 damping:0.8 initialVelocity:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
||||
self.selectionImageView.center = selectedButton.center;
|
||||
} completion:^(BOOL finished){}];
|
||||
|
||||
_selectedButton = selectedButton;
|
||||
}
|
||||
|
||||
- (void)buttonPressed:(UIButton *)sender
|
||||
{
|
||||
[self setSelectedButton:sender animated:YES];
|
||||
[self.delegate segmentedControl:self didSelectSegment:sender.tag];
|
||||
}
|
||||
|
||||
@end
|
|
@ -61,6 +61,18 @@
|
|||
978F9248183B6671000D6C7C /* Main_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 978F9246183B6671000D6C7C /* Main_iPhone.storyboard */; };
|
||||
978F9253183BD530000D6C7C /* NavigationController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 978F9252183BD530000D6C7C /* NavigationController.mm */; };
|
||||
978F9254183BD530000D6C7C /* NavigationController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 978F9252183BD530000D6C7C /* NavigationController.mm */; };
|
||||
97A8000C18B21363000C07A2 /* SearchView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97A8000B18B21363000C07A2 /* SearchView.mm */; };
|
||||
97A8000D18B21363000C07A2 /* SearchView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97A8000B18B21363000C07A2 /* SearchView.mm */; };
|
||||
97A8001018B21395000C07A2 /* SearchBar.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97A8000F18B21395000C07A2 /* SearchBar.mm */; };
|
||||
97A8001118B21395000C07A2 /* SearchBar.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97A8000F18B21395000C07A2 /* SearchBar.mm */; };
|
||||
97A8001418B2140A000C07A2 /* SearchUniversalCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 97A8001318B2140A000C07A2 /* SearchUniversalCell.m */; };
|
||||
97A8001518B2140A000C07A2 /* SearchUniversalCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 97A8001318B2140A000C07A2 /* SearchUniversalCell.m */; };
|
||||
97A8001C18B25497000C07A2 /* SegmentedControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 97A8001B18B25497000C07A2 /* SegmentedControl.m */; };
|
||||
97A8001D18B25497000C07A2 /* SegmentedControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 97A8001B18B25497000C07A2 /* SegmentedControl.m */; };
|
||||
97A8002718B2741C000C07A2 /* SearchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 97A8002618B2741C000C07A2 /* SearchCell.m */; };
|
||||
97A8002818B2741C000C07A2 /* SearchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 97A8002618B2741C000C07A2 /* SearchCell.m */; };
|
||||
97ABBA4518C8DF620079333C /* PlacePageView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97ABBA4418C8DF620079333C /* PlacePageView.mm */; };
|
||||
97ABBA4618C8DF620079333C /* PlacePageView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97ABBA4418C8DF620079333C /* PlacePageView.mm */; };
|
||||
97C9851E186AE3C500AF7E9E /* Reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C9851C186AE3C500AF7E9E /* Reachability.m */; };
|
||||
97C9851F186AE3C500AF7E9E /* Reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C9851C186AE3C500AF7E9E /* Reachability.m */; };
|
||||
97C98522186AE3CF00AF7E9E /* AppInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97C98520186AE3CF00AF7E9E /* AppInfo.mm */; };
|
||||
|
@ -286,7 +298,6 @@
|
|||
FA054612155C465E001F4E37 /* SelectSetVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA054611155C465E001F4E37 /* SelectSetVC.mm */; };
|
||||
FA054613155C465E001F4E37 /* SelectSetVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA054611155C465E001F4E37 /* SelectSetVC.mm */; };
|
||||
FA065FED128614C400FEA989 /* MainWindow-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA065FEC128614C400FEA989 /* MainWindow-iPad.xib */; };
|
||||
FA09E01113F71F6C007E69CA /* SearchVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA09E01013F71F6C007E69CA /* SearchVC.mm */; };
|
||||
FA140651162A6288002BC1ED /* empty@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FA14064D162A6288002BC1ED /* empty@2x.png */; };
|
||||
FA140652162A6288002BC1ED /* empty@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FA14064D162A6288002BC1ED /* empty@2x.png */; };
|
||||
FA140653162A6288002BC1ED /* empty.png in Resources */ = {isa = PBXBuildFile; fileRef = FA14064E162A6288002BC1ED /* empty.png */; };
|
||||
|
@ -312,7 +323,6 @@
|
|||
FA765AB51737BC6D00279CFF /* 64-lite.png in Resources */ = {isa = PBXBuildFile; fileRef = FA765AB11737BC6D00279CFF /* 64-lite.png */; };
|
||||
FA765AB61737BC6D00279CFF /* 320-lite.png in Resources */ = {isa = PBXBuildFile; fileRef = FA765AB21737BC6D00279CFF /* 320-lite.png */; };
|
||||
FA7F4B0017F1FFE800FAB1B5 /* World.mwm in Resources */ = {isa = PBXBuildFile; fileRef = FAFF42291347F101009BBB14 /* World.mwm */; };
|
||||
FA81AE3314D061BF00A0D70D /* SearchCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA81AE3214D061BF00A0D70D /* SearchCell.mm */; };
|
||||
FA85F633145DDDC20090E1A0 /* packed_polygons.bin in Resources */ = {isa = PBXBuildFile; fileRef = FA85F632145DDDC20090E1A0 /* packed_polygons.bin */; };
|
||||
FA87151B12B1518F00592DAF /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA87151A12B1518F00592DAF /* SystemConfiguration.framework */; };
|
||||
FA8F8938132D5DB00048E3FE /* libtomcrypt.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8F8937132D5DB00048E3FE /* libtomcrypt.a */; };
|
||||
|
@ -1378,11 +1388,9 @@
|
|||
FAFB08F0151215EE0041901D /* RenderContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = EE7F297E1219ECA300EB67A9 /* RenderContext.mm */; };
|
||||
FAFB08F1151215EE0041901D /* WebViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = FAFCB63513366E78001A5C59 /* WebViewController.mm */; };
|
||||
FAFB08F2151215EE0041901D /* CustomAlertView.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA34BEC81338D72F00FFB2A7 /* CustomAlertView.mm */; };
|
||||
FAFB08F3151215EE0041901D /* SearchVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA09E01013F71F6C007E69CA /* SearchVC.mm */; };
|
||||
FAFB08F4151215EE0041901D /* CompassView.mm in Sources */ = {isa = PBXBuildFile; fileRef = FABF223D13FAA97A003D4D49 /* CompassView.mm */; };
|
||||
FAFB08F5151215EE0041901D /* Preferences.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA29FDA9141E77F8004ADF66 /* Preferences.mm */; };
|
||||
FAFB08F6151215EE0041901D /* LocationManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = FAA5C2A1144F135F005337F6 /* LocationManager.mm */; };
|
||||
FAFB08F8151215EE0041901D /* SearchCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA81AE3214D061BF00A0D70D /* SearchCell.mm */; };
|
||||
FAFB08FB151215EE0041901D /* libfreetype.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EE12020311CD464100ABDD5D /* libfreetype.a */; };
|
||||
FAFB08FC151215EE0041901D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
|
||||
FAFB08FD151215EE0041901D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
|
||||
|
@ -1467,6 +1475,19 @@
|
|||
978F9246183B6671000D6C7C /* Main_iPhone.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main_iPhone.storyboard; sourceTree = "<group>"; };
|
||||
978F9251183BD530000D6C7C /* NavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavigationController.h; sourceTree = "<group>"; };
|
||||
978F9252183BD530000D6C7C /* NavigationController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NavigationController.mm; sourceTree = "<group>"; };
|
||||
97A8000A18B21363000C07A2 /* SearchView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchView.h; sourceTree = "<group>"; };
|
||||
97A8000B18B21363000C07A2 /* SearchView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SearchView.mm; sourceTree = "<group>"; };
|
||||
97A8000E18B21395000C07A2 /* SearchBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchBar.h; sourceTree = "<group>"; };
|
||||
97A8000F18B21395000C07A2 /* SearchBar.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SearchBar.mm; sourceTree = "<group>"; };
|
||||
97A8001218B2140A000C07A2 /* SearchUniversalCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchUniversalCell.h; sourceTree = "<group>"; };
|
||||
97A8001318B2140A000C07A2 /* SearchUniversalCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SearchUniversalCell.m; sourceTree = "<group>"; };
|
||||
97A8001A18B25497000C07A2 /* SegmentedControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SegmentedControl.h; sourceTree = "<group>"; };
|
||||
97A8001B18B25497000C07A2 /* SegmentedControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SegmentedControl.m; sourceTree = "<group>"; };
|
||||
97A8002518B2741C000C07A2 /* SearchCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchCell.h; sourceTree = "<group>"; };
|
||||
97A8002618B2741C000C07A2 /* SearchCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SearchCell.m; sourceTree = "<group>"; };
|
||||
97A8002918B51238000C07A2 /* SearchActivityProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchActivityProtocol.h; sourceTree = "<group>"; };
|
||||
97ABBA4318C8DF620079333C /* PlacePageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlacePageView.h; sourceTree = "<group>"; };
|
||||
97ABBA4418C8DF620079333C /* PlacePageView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlacePageView.mm; sourceTree = "<group>"; };
|
||||
97C9851C186AE3C500AF7E9E /* Reachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Reachability.m; sourceTree = "<group>"; };
|
||||
97C9851D186AE3C500AF7E9E /* Reachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reachability.h; sourceTree = "<group>"; };
|
||||
97C98520186AE3CF00AF7E9E /* AppInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AppInfo.mm; sourceTree = "<group>"; };
|
||||
|
@ -1779,8 +1800,6 @@
|
|||
FA054610155C465E001F4E37 /* SelectSetVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SelectSetVC.h; path = Bookmarks/SelectSetVC.h; sourceTree = SOURCE_ROOT; };
|
||||
FA054611155C465E001F4E37 /* SelectSetVC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = SelectSetVC.mm; path = Bookmarks/SelectSetVC.mm; sourceTree = SOURCE_ROOT; };
|
||||
FA065FEC128614C400FEA989 /* MainWindow-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "MainWindow-iPad.xib"; path = "Resources-iPad/MainWindow-iPad.xib"; sourceTree = SOURCE_ROOT; };
|
||||
FA09E00F13F71F6C007E69CA /* SearchVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchVC.h; sourceTree = "<group>"; };
|
||||
FA09E01013F71F6C007E69CA /* SearchVC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SearchVC.mm; sourceTree = "<group>"; };
|
||||
FA14064D162A6288002BC1ED /* empty@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "empty@2x.png"; path = "Bookmarks/empty@2x.png"; sourceTree = SOURCE_ROOT; };
|
||||
FA14064E162A6288002BC1ED /* empty.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = empty.png; path = Bookmarks/empty.png; sourceTree = SOURCE_ROOT; };
|
||||
FA14064F162A6288002BC1ED /* eye.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = eye.png; path = Bookmarks/eye.png; sourceTree = SOURCE_ROOT; };
|
||||
|
@ -1809,8 +1828,6 @@
|
|||
FA765AB01737BC6D00279CFF /* 44x58-lite.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "44x58-lite.png"; sourceTree = "<group>"; };
|
||||
FA765AB11737BC6D00279CFF /* 64-lite.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "64-lite.png"; sourceTree = "<group>"; };
|
||||
FA765AB21737BC6D00279CFF /* 320-lite.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "320-lite.png"; sourceTree = "<group>"; };
|
||||
FA81AE3114D061BF00A0D70D /* SearchCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchCell.h; sourceTree = "<group>"; };
|
||||
FA81AE3214D061BF00A0D70D /* SearchCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SearchCell.mm; sourceTree = "<group>"; };
|
||||
FA85F632145DDDC20090E1A0 /* packed_polygons.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = packed_polygons.bin; path = ../../data/packed_polygons.bin; sourceTree = SOURCE_ROOT; };
|
||||
FA87151A12B1518F00592DAF /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
|
||||
FA8F8937132D5DB00048E3FE /* libtomcrypt.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libtomcrypt.a; sourceTree = SOURCE_ROOT; };
|
||||
|
@ -2461,14 +2478,14 @@
|
|||
97B4E9271851DAB300BEC5D7 /* Custom Views */,
|
||||
9789DB53188D5DFF007C6FAE /* In App Messaging */,
|
||||
9770A04618AD19D300126E5C /* More Apps */,
|
||||
FA4135DF120A25B90062D5B4 /* Settings */,
|
||||
97A8000918B210DC000C07A2 /* Search */,
|
||||
978F9251183BD530000D6C7C /* NavigationController.h */,
|
||||
978F9252183BD530000D6C7C /* NavigationController.mm */,
|
||||
97D40C0C184E389000A1D572 /* MailComposeViewController.h */,
|
||||
97D40C0D184E389000A1D572 /* MailComposeViewController.m */,
|
||||
97387544184E475000170BC4 /* MessageComposeViewController.h */,
|
||||
97387545184E475000170BC4 /* MessageComposeViewController.m */,
|
||||
FA09E00F13F71F6C007E69CA /* SearchVC.h */,
|
||||
FA09E01013F71F6C007E69CA /* SearchVC.mm */,
|
||||
EE7F297C1219ECA300EB67A9 /* RenderBuffer.hpp */,
|
||||
EE7F297D1219ECA300EB67A9 /* RenderBuffer.mm */,
|
||||
EE16192B126E374500622BD0 /* RenderContext.hpp */,
|
||||
|
@ -2479,8 +2496,6 @@
|
|||
1D3623250D0F684500981E51 /* MapsAppDelegate.mm */,
|
||||
46F8A2EB10EB63040045521A /* MapViewController.h */,
|
||||
EED10A4411F78D120095FAD4 /* MapViewController.mm */,
|
||||
FA81AE3114D061BF00A0D70D /* SearchCell.h */,
|
||||
FA81AE3214D061BF00A0D70D /* SearchCell.mm */,
|
||||
FAF457E415597BC100DCCC49 /* Framework.h */,
|
||||
FAF457E615597D4600DCCC49 /* Framework.cpp */,
|
||||
EDC5C541175F2CA600420E92 /* ShareActionSheet.h */,
|
||||
|
@ -2509,7 +2524,6 @@
|
|||
FA36B8011540388B004560CC /* Bookmarks */,
|
||||
FA34BEC71338D6DB00FFB2A7 /* Common */,
|
||||
FA6E1F1B124E6B2800F59149 /* Platform */,
|
||||
FA4135DF120A25B90062D5B4 /* Settings */,
|
||||
080E96DDFE201D6D7F000001 /* Classes */,
|
||||
974726401832306C006B7CB7 /* Categories */,
|
||||
29B97315FDCFA39411CA2CEA /* Other Sources */,
|
||||
|
@ -2659,6 +2673,24 @@
|
|||
name = Cells;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97A8000918B210DC000C07A2 /* Search */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
97A8000A18B21363000C07A2 /* SearchView.h */,
|
||||
97A8000B18B21363000C07A2 /* SearchView.mm */,
|
||||
97A8000E18B21395000C07A2 /* SearchBar.h */,
|
||||
97A8000F18B21395000C07A2 /* SearchBar.mm */,
|
||||
97A8001A18B25497000C07A2 /* SegmentedControl.h */,
|
||||
97A8001B18B25497000C07A2 /* SegmentedControl.m */,
|
||||
97A8002518B2741C000C07A2 /* SearchCell.h */,
|
||||
97A8002618B2741C000C07A2 /* SearchCell.m */,
|
||||
97A8001218B2140A000C07A2 /* SearchUniversalCell.h */,
|
||||
97A8001318B2140A000C07A2 /* SearchUniversalCell.m */,
|
||||
97A8002918B51238000C07A2 /* SearchActivityProtocol.h */,
|
||||
);
|
||||
name = Search;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97B4E9271851DAB300BEC5D7 /* Custom Views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -3186,6 +3218,7 @@
|
|||
FA29FDA9141E77F8004ADF66 /* Preferences.mm */,
|
||||
);
|
||||
name = Settings;
|
||||
path = ..;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FA6E1F1B124E6B2800F59149 /* Platform */ = {
|
||||
|
@ -5047,13 +5080,16 @@
|
|||
FAFCB63613366E78001A5C59 /* WebViewController.mm in Sources */,
|
||||
FA34BECA1338D72F00FFB2A7 /* CustomAlertView.mm in Sources */,
|
||||
97F61781183E6172009919E2 /* LocationButton.mm in Sources */,
|
||||
FA09E01113F71F6C007E69CA /* SearchVC.mm in Sources */,
|
||||
9747264318323080006B7CB7 /* UIKitCategories.m in Sources */,
|
||||
97719D421843AF1E00BDD815 /* ScopeView.m in Sources */,
|
||||
97A8001418B2140A000C07A2 /* SearchUniversalCell.m in Sources */,
|
||||
97A8002718B2741C000C07A2 /* SearchCell.m in Sources */,
|
||||
97D807B818A92AAB00D416E0 /* MoreAppsVC.mm in Sources */,
|
||||
FABF223E13FAA97A003D4D49 /* CompassView.mm in Sources */,
|
||||
9789DB5A188D94F9007C6FAE /* InterstitialView.mm in Sources */,
|
||||
FA29FDAA141E77F8004ADF66 /* Preferences.mm in Sources */,
|
||||
97A8001C18B25497000C07A2 /* SegmentedControl.m in Sources */,
|
||||
97A8000C18B21363000C07A2 /* SearchView.mm in Sources */,
|
||||
FAA5C2A2144F135F005337F6 /* LocationManager.mm in Sources */,
|
||||
FA81AE3314D061BF00A0D70D /* SearchCell.mm in Sources */,
|
||||
97DEA09618D75BB000C5F963 /* ContextViews.mm in Sources */,
|
||||
|
@ -5079,6 +5115,7 @@
|
|||
9747277B18328E65006B7CB7 /* SideToolbar.mm in Sources */,
|
||||
97F61794183E7445009919E2 /* LinkCell.m in Sources */,
|
||||
EDCB4E8E175E67120005AA35 /* PlacePreviewViewController.mm in Sources */,
|
||||
97A8001018B21395000C07A2 /* SearchBar.m in Sources */,
|
||||
EDC5C543175F2CA600420E92 /* ShareActionSheet.mm in Sources */,
|
||||
EDFC74D0177AE6C500FAF21F /* PlaceAndCompasView.mm in Sources */,
|
||||
ED48BBB117BE6EA8003E7E92 /* MWMApi.mm in Sources */,
|
||||
|
@ -5101,6 +5138,7 @@
|
|||
97C98643186C487900AF7E9E /* MPInterstitialCustomEvent.m in Sources */,
|
||||
FAFB08EA151215EE0041901D /* MapsAppDelegate.mm in Sources */,
|
||||
FAFB08EB151215EE0041901D /* EAGLView.mm in Sources */,
|
||||
97A8001118B21395000C07A2 /* SearchBar.mm in Sources */,
|
||||
97C98636186C487900AF7E9E /* MPAnalyticsTracker.m in Sources */,
|
||||
FAFB08EC151215EE0041901D /* MapViewController.mm in Sources */,
|
||||
97C98601186C487900AF7E9E /* CJSONSerializedData.m in Sources */,
|
||||
|
@ -5126,12 +5164,12 @@
|
|||
97C9863C186C487900AF7E9E /* MPSessionTracker.m in Sources */,
|
||||
97C98637186C487900AF7E9E /* MPError.m in Sources */,
|
||||
97C9863E186C487900AF7E9E /* MPTimer.m in Sources */,
|
||||
97A8001D18B25497000C07A2 /* SegmentedControl.m in Sources */,
|
||||
97C9860C186C487900AF7E9E /* MPLegacyBannerCustomEventAdapter.m in Sources */,
|
||||
FAFB08F2151215EE0041901D /* CustomAlertView.mm in Sources */,
|
||||
97F61782183E6172009919E2 /* LocationButton.mm in Sources */,
|
||||
97C9860E186C487900AF7E9E /* MPAdAlertManager.m in Sources */,
|
||||
97C985F1186C487900AF7E9E /* MPGoogleAdMobBannerCustomEvent.m in Sources */,
|
||||
FAFB08F3151215EE0041901D /* SearchVC.mm in Sources */,
|
||||
9747264418323080006B7CB7 /* UIKitCategories.m in Sources */,
|
||||
97C9863D186C487900AF7E9E /* MPStoreKitProvider.m in Sources */,
|
||||
97C98600186C487900AF7E9E /* CJSONSerialization.m in Sources */,
|
||||
|
@ -5154,13 +5192,13 @@
|
|||
97C9861F186C487900AF7E9E /* MPInterstitialAdManager.m in Sources */,
|
||||
97C9862B186C487900AF7E9E /* MRCalendarManager.m in Sources */,
|
||||
97C98616186C487900AF7E9E /* MPLastResortDelegate.m in Sources */,
|
||||
FAFB08F8151215EE0041901D /* SearchCell.mm in Sources */,
|
||||
97C98635186C487900AF7E9E /* UIWebView+MPAdditions.m in Sources */,
|
||||
97C985F2186C487900AF7E9E /* MPGoogleAdMobInterstitialCustomEvent.m in Sources */,
|
||||
978F9241183B660F000D6C7C /* SettingsViewController.mm in Sources */,
|
||||
97C98629186C487900AF7E9E /* MRAdViewDisplayController.m in Sources */,
|
||||
97C98617186C487900AF7E9E /* MPProgressOverlayView.m in Sources */,
|
||||
97C98632186C487900AF7E9E /* MRVideoPlayerManager.m in Sources */,
|
||||
97A8001518B2140A000C07A2 /* SearchUniversalCell.m in Sources */,
|
||||
97C985F8186C487900AF7E9E /* MPMillennialInterstitialCustomEvent.m in Sources */,
|
||||
F7B90CD41521E6D200C054EE /* CustomNavigationView.mm in Sources */,
|
||||
97C98605186C487900AF7E9E /* CJSONScanner.m in Sources */,
|
||||
|
@ -5172,6 +5210,7 @@
|
|||
97C9860F186C487900AF7E9E /* MPAdBrowserController.m in Sources */,
|
||||
FA5D4F1A1557F79900E7D8BB /* PlacePageVC.mm in Sources */,
|
||||
FAF457E815597D4600DCCC49 /* Framework.cpp in Sources */,
|
||||
97A8002818B2741C000C07A2 /* SearchCell.m in Sources */,
|
||||
97C9860A186C487900AF7E9E /* MPBannerCustomEventAdapter.m in Sources */,
|
||||
97C98621186C487900AF7E9E /* MPInterstitialViewController.m in Sources */,
|
||||
FA054613155C465E001F4E37 /* SelectSetVC.mm in Sources */,
|
||||
|
@ -5210,6 +5249,7 @@
|
|||
EDFC74D1177AE6C500FAF21F /* PlaceAndCompasView.mm in Sources */,
|
||||
ED48BBB217BE6EA8003E7E92 /* MWMApi.mm in Sources */,
|
||||
97C9862F186C487900AF7E9E /* MRJavaScriptEventEmitter.m in Sources */,
|
||||
97A8000D18B21363000C07A2 /* SearchView.mm in Sources */,
|
||||
97C98628186C487900AF7E9E /* MRAdView.m in Sources */,
|
||||
97C9862A186C487900AF7E9E /* MRBundleManager.m in Sources */,
|
||||
ED48BBBB17C2B1E2003E7E92 /* CircleView.mm in Sources */,
|
||||
|
|
Loading…
Add table
Reference in a new issue