From f55da1620b39ebf23774cfc786decc45c41066a6 Mon Sep 17 00:00:00 2001 From: Ilya Grechuhin Date: Fri, 30 Dec 2016 13:21:00 +0300 Subject: [PATCH] [MAPSME-3388] [ios] Added no results screen to search in downloader. --- iphone/Maps/Bridging-Header.h | 5 ++ iphone/Maps/Common/Common.swift | 3 + iphone/Maps/Maps.xcodeproj/project.pbxproj | 24 ++++++ .../MWMMapDownloaderSearchDataSource.h | 2 + .../MWMMapDownloaderSearchDataSource.mm | 3 + .../MWMMapDownloaderViewController.mm | 82 ++++++++++-------- ...wnloaderNoResultsEmbedViewController.swift | 25 ++++++ .../NoMaps/MWMNoMapsViewController.h | 2 +- iphone/Maps/UI/Mapsme.storyboard | 83 ++++++++++++++++--- .../SearchNoResultsViewController.swift | 33 ++++++++ 10 files changed, 215 insertions(+), 47 deletions(-) create mode 100644 iphone/Maps/Common/Common.swift create mode 100644 iphone/Maps/UI/Downloader/NoMaps/DownloaderNoResultsEmbedViewController.swift create mode 100644 iphone/Maps/UI/Search/SearchNoResultsViewController.swift diff --git a/iphone/Maps/Bridging-Header.h b/iphone/Maps/Bridging-Header.h index 1fb8b2c9f8..0b1139adae 100644 --- a/iphone/Maps/Bridging-Header.h +++ b/iphone/Maps/Bridging-Header.h @@ -4,6 +4,11 @@ #import +#import "MWMKeyboard.h" +#import "MWMNoMapsViewController.h" +#import "MWMSearchNoResults.h" #import "MWMTableViewCell.h" +#import "MWMViewController.h" #import "UIColor+MapsMeColor.h" #import "UIFont+MapsMeFonts.h" +#import "UIViewController+Navigation.h" diff --git a/iphone/Maps/Common/Common.swift b/iphone/Maps/Common/Common.swift new file mode 100644 index 0000000000..98a5f8d8b5 --- /dev/null +++ b/iphone/Maps/Common/Common.swift @@ -0,0 +1,3 @@ +import Foundation + +func L(_ key: String) -> String { return NSLocalizedString(key, comment: "") } diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index 0a1e68d25f..94306eb47d 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -205,6 +205,15 @@ 3476B8E01BFDD33A00874594 /* tts-how-to-set-up-voice-img in Resources */ = {isa = PBXBuildFile; fileRef = 3476B8DF1BFDD33A00874594 /* tts-how-to-set-up-voice-img */; }; 3476B8E11BFDD33A00874594 /* tts-how-to-set-up-voice-img in Resources */ = {isa = PBXBuildFile; fileRef = 3476B8DF1BFDD33A00874594 /* tts-how-to-set-up-voice-img */; }; 347A4C5E1C4E76C9006BA66E /* liboauthcpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 340DC82B1C4E72C700EAA2CC /* liboauthcpp.a */; }; + 34845DAE1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34845DAD1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift */; }; + 34845DAF1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34845DAD1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift */; }; + 34845DB01E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34845DAD1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift */; }; + 34845DB21E165E24003D55B9 /* SearchNoResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34845DB11E165E24003D55B9 /* SearchNoResultsViewController.swift */; }; + 34845DB31E165E24003D55B9 /* SearchNoResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34845DB11E165E24003D55B9 /* SearchNoResultsViewController.swift */; }; + 34845DB41E165E24003D55B9 /* SearchNoResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34845DB11E165E24003D55B9 /* SearchNoResultsViewController.swift */; }; + 34845DB61E166084003D55B9 /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34845DB51E166084003D55B9 /* Common.swift */; }; + 34845DB71E166084003D55B9 /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34845DB51E166084003D55B9 /* Common.swift */; }; + 34845DB81E166084003D55B9 /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34845DB51E166084003D55B9 /* Common.swift */; }; 3490D2DE1CE9DD2500D0B838 /* MWMSideButtons.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3490D2DA1CE9DD2500D0B838 /* MWMSideButtons.mm */; }; 3490D2DF1CE9DD2500D0B838 /* MWMSideButtons.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3490D2DA1CE9DD2500D0B838 /* MWMSideButtons.mm */; }; 3490D2E01CE9DD2500D0B838 /* MWMSideButtonsView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3490D2DC1CE9DD2500D0B838 /* MWMSideButtonsView.mm */; }; @@ -1550,6 +1559,9 @@ 3476B8D51BFDD30B00874594 /* tts-how-to-set-up-voice.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = "tts-how-to-set-up-voice.html"; path = "../../data/tts-how-to-set-up-voice.html"; sourceTree = ""; }; 3476B8DF1BFDD33A00874594 /* tts-how-to-set-up-voice-img */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "tts-how-to-set-up-voice-img"; path = "../../data/tts-how-to-set-up-voice-img"; sourceTree = ""; }; 348320CC1B6A2C52007EC039 /* MWMNavigationViewProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMNavigationViewProtocol.h; sourceTree = ""; }; + 34845DAD1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownloaderNoResultsEmbedViewController.swift; sourceTree = ""; }; + 34845DB11E165E24003D55B9 /* SearchNoResultsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchNoResultsViewController.swift; sourceTree = ""; }; + 34845DB51E166084003D55B9 /* Common.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Common.swift; sourceTree = ""; }; 348E57981B0F49D8000FA02A /* maps.me dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "maps.me dbg.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 3490D2D91CE9DD2500D0B838 /* MWMSideButtons.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSideButtons.h; sourceTree = ""; }; 3490D2DA1CE9DD2500D0B838 /* MWMSideButtons.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSideButtons.mm; sourceTree = ""; }; @@ -2579,6 +2591,7 @@ 3404751E1E081A4600C92850 /* Statistics */, 340475261E081A4600C92850 /* WebViewController.h */, 340475271E081A4600C92850 /* WebViewController.mm */, + 34845DB51E166084003D55B9 /* Common.swift */, ); path = Common; sourceTree = ""; @@ -3381,6 +3394,7 @@ F6E2FC261E097B9F0083EBEC /* MWMNoMapsView.mm */, F6E2FC271E097B9F0083EBEC /* MWMNoMapsViewController.h */, F6E2FC281E097B9F0083EBEC /* MWMNoMapsViewController.mm */, + 34845DAD1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift */, ); path = NoMaps; sourceTree = ""; @@ -3741,6 +3755,7 @@ F6E2FD021E097B9F0083EBEC /* TabbedView */, F6E2FD241E097BA00083EBEC /* TabButtons */, F6E2FD281E097BA00083EBEC /* TableView */, + 34845DB11E165E24003D55B9 /* SearchNoResultsViewController.swift */, ); path = Search; sourceTree = ""; @@ -4722,6 +4737,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 34845DB61E166084003D55B9 /* Common.swift in Sources */, 1D60589B0D05DD56006BFB54 /* main.mm in Sources */, 340837161B72451A00B5C185 /* MWMShareActivityItem.mm in Sources */, F6E2FF0B1E097BA00083EBEC /* MWMSearchHistoryMyPositionCell.mm in Sources */, @@ -4786,6 +4802,7 @@ F64D9C9F1C899C350063FA30 /* MWMEditorViralAlert.mm in Sources */, 34ABA62C1C2D57D500FE1BEC /* MWMInputPasswordValidator.mm in Sources */, F6E2FEF61E097BA00083EBEC /* MWMSearchBookmarksManager.mm in Sources */, + 34845DAE1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift in Sources */, 34ABA6161C2D185C00FE1BEC /* MWMAuthorizationOSMLoginViewController.mm in Sources */, F6E2FEDE1E097BA00083EBEC /* MWMSearchManager+Layout.mm in Sources */, 3454D7D31E07F045004AF2AD /* UIImageView+Coloring.mm in Sources */, @@ -4966,6 +4983,7 @@ 34D15BA81BD8F93C00C8BCBE /* AddSetTableViewCell.mm in Sources */, F6E2FED51E097BA00083EBEC /* MWMSearchChangeModeView.mm in Sources */, F6A218491CA3F26800BE2CC6 /* MWMEditorViralActivityItem.mm in Sources */, + 34845DB21E165E24003D55B9 /* SearchNoResultsViewController.swift in Sources */, 34A759CD1DC795140078C3AE /* MWMWhatsNewEditorController.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -4974,6 +4992,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 34845DB71E166084003D55B9 /* Common.swift in Sources */, 6741A9A31BF340DE002C974C /* main.mm in Sources */, F67E751E1DB76DFC00D6741F /* MWMTaxiCollectionLayout.mm in Sources */, F6E2FF0C1E097BA00083EBEC /* MWMSearchHistoryMyPositionCell.mm in Sources */, @@ -5038,6 +5057,7 @@ 342EE4121C43DAA7009F6A49 /* MWMAuthorizationWebViewLoginViewController.mm in Sources */, 34479C7D1C60C6130065D261 /* MWMFrameworkListener.mm in Sources */, F6E2FEF71E097BA00083EBEC /* MWMSearchBookmarksManager.mm in Sources */, + 34845DAF1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift in Sources */, F6791B141C43DF0B007A8A6E /* MWMStartButton.mm in Sources */, F6E2FEDF1E097BA00083EBEC /* MWMSearchManager+Layout.mm in Sources */, 34A759DF1DC797960078C3AE /* MWMWhatsNewEditorController.mm in Sources */, @@ -5218,6 +5238,7 @@ F6A2184A1CA3F26800BE2CC6 /* MWMEditorViralActivityItem.mm in Sources */, F6E2FED61E097BA00083EBEC /* MWMSearchChangeModeView.mm in Sources */, 6741AA2D1BF340DE002C974C /* AddSetTableViewCell.mm in Sources */, + 34845DB31E165E24003D55B9 /* SearchNoResultsViewController.swift in Sources */, 34A759E31DC797CB0078C3AE /* MWMPageController.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -5226,6 +5247,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 34845DB81E166084003D55B9 /* Common.swift in Sources */, 849CF6821DE842290024A8A5 /* main.mm in Sources */, 3454D7D51E07F045004AF2AD /* UIImageView+Coloring.mm in Sources */, F6E2FF0D1E097BA00083EBEC /* MWMSearchHistoryMyPositionCell.mm in Sources */, @@ -5290,6 +5312,7 @@ 849CF6BF1DE842290024A8A5 /* MWMFrameworkListener.mm in Sources */, 849CF6C31DE842290024A8A5 /* MWMEditorViralAlert.mm in Sources */, F6E2FEF81E097BA00083EBEC /* MWMSearchBookmarksManager.mm in Sources */, + 34845DB01E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift in Sources */, 3454D7E11E07F045004AF2AD /* UITextField+RuntimeAttributes.mm in Sources */, F6E2FEE01E097BA00083EBEC /* MWMSearchManager+Layout.mm in Sources */, 849CF6C61DE842290024A8A5 /* MWMInputPasswordValidator.mm in Sources */, @@ -5470,6 +5493,7 @@ 849CF76D1DE842290024A8A5 /* AddSetTableViewCell.mm in Sources */, F6E2FED71E097BA00083EBEC /* MWMSearchChangeModeView.mm in Sources */, 849CF76E1DE842290024A8A5 /* MWMEditorViralActivityItem.mm in Sources */, + 34845DB41E165E24003D55B9 /* SearchNoResultsViewController.swift in Sources */, 849CF7711DE842290024A8A5 /* MWMWhatsNewEditorController.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/iphone/Maps/UI/Downloader/DataSources/MWMMapDownloaderSearchDataSource.h b/iphone/Maps/UI/Downloader/DataSources/MWMMapDownloaderSearchDataSource.h index a8cebcfa32..5f52bbe37a 100644 --- a/iphone/Maps/UI/Downloader/DataSources/MWMMapDownloaderSearchDataSource.h +++ b/iphone/Maps/UI/Downloader/DataSources/MWMMapDownloaderSearchDataSource.h @@ -4,6 +4,8 @@ @interface MWMMapDownloaderSearchDataSource : MWMMapDownloaderDataSource +@property(nonatomic, readonly) BOOL isEmpty; + - (instancetype)initWithSearchResults:(DownloaderSearchResults const &)results delegate:(id)delegate; @end diff --git a/iphone/Maps/UI/Downloader/DataSources/MWMMapDownloaderSearchDataSource.mm b/iphone/Maps/UI/Downloader/DataSources/MWMMapDownloaderSearchDataSource.mm index 8c851d49f4..3601a79a83 100644 --- a/iphone/Maps/UI/Downloader/DataSources/MWMMapDownloaderSearchDataSource.mm +++ b/iphone/Maps/UI/Downloader/DataSources/MWMMapDownloaderSearchDataSource.mm @@ -91,4 +91,7 @@ extern NSString * const kLargeCountryCellIdentifier; return self.searchMatchedResults[countryId]; } +#pragma mark - Properties + +- (BOOL)isEmpty { return self.searchCountryIds.count == 0; } @end diff --git a/iphone/Maps/UI/Downloader/MWMMapDownloaderViewController.mm b/iphone/Maps/UI/Downloader/MWMMapDownloaderViewController.mm index 03a256710c..eb9a1ddcf4 100644 --- a/iphone/Maps/UI/Downloader/MWMMapDownloaderViewController.mm +++ b/iphone/Maps/UI/Downloader/MWMMapDownloaderViewController.mm @@ -3,6 +3,7 @@ #import "MWMMapDownloaderExtendedDataSourceWithAds.h" #import "MWMMapDownloaderSearchDataSource.h" #import "MWMNoMapsViewController.h" +#import "SwiftBridge.h" #import "UIColor+MapsMeColor.h" #import "UIKitCategories.h" @@ -12,7 +13,8 @@ namespace { -NSString * const kNoMapsSegue = @"MapDownloaderEmbedNoMapsSegue"; +NSString * const kMapDownloaderNoResultsEmbedViewControllerSegue = + @"MapDownloaderNoResultsEmbedViewControllerSegue"; } // namespace using namespace storage; @@ -42,9 +44,11 @@ using namespace storage; @property(weak, nonatomic) IBOutlet UIView * statusBarBackground; @property(weak, nonatomic) IBOutlet UISearchBar * searchBar; @property(weak, nonatomic) IBOutlet UIView * noMapsContainer; -@property(nonatomic) MWMNoMapsViewController * noMapsController; +@property(nonatomic) MWMDownloaderNoResultsEmbedViewController * noResultsEmbedViewController; -@property(nonatomic) MWMMapDownloaderDataSource * searchDataSource; +@property(nonatomic) MWMMapDownloaderSearchDataSource * searchDataSource; + +@property(nonatomic) NSTimeInterval lastSearchTimestamp; @end @@ -57,7 +61,6 @@ using namespace storage; { [super viewDidLoad]; self.searchBar.placeholder = L(@"downloader_search_field_hint"); - [self setupSearchParams]; } - (void)viewWillAppear:(BOOL)animated @@ -81,19 +84,30 @@ using namespace storage; auto const & s = GetFramework().GetStorage(); if (![self.parentCountryId isEqualToString:@(s.GetRootId().c_str())]) return; - if (self.mode == mwm::DownloaderMode::Available || self.dataSource == self.searchDataSource || - s.HaveDownloadedCountries() || s.IsDownloadInProgress()) - { + + auto const showResults = ^{ [self configAllMapsView]; self.tableView.hidden = NO; self.noMapsContainer.hidden = YES; - } - else - { + }; + auto const showNoResults = ^(MWMDownloaderNoResultsScreen screen) { self.showAllMapsButtons = NO; self.tableView.hidden = YES; self.noMapsContainer.hidden = NO; - } + self.noResultsEmbedViewController.screen = screen; + }; + + BOOL const noResults = + self.dataSource == self.searchDataSource && self.searchDataSource.isEmpty; + BOOL const isModeAvailable = self.mode == mwm::DownloaderMode::Available; + BOOL const haveActiveMaps = s.HaveDownloadedCountries() || s.IsDownloadInProgress(); + + if (noResults) + showNoResults(MWMDownloaderNoResultsScreenNoSearchResults); + else if (isModeAvailable || haveActiveMaps) + showResults(); + else + showNoResults(MWMDownloaderNoResultsScreenNoMaps); } #pragma mark - UISearchBarDelegate @@ -124,20 +138,13 @@ using namespace storage; - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { - if (searchText.length == 0) - { - self.dataSource = self.defaultDataSource; - [self reloadTable]; - } - else - { - NSString * primaryLanguage = self.searchBar.textInputMode.primaryLanguage; - if (primaryLanguage) - m_searchParams.m_inputLocale = primaryLanguage.UTF8String; + NSString * primaryLanguage = self.searchBar.textInputMode.primaryLanguage; + if (primaryLanguage) + m_searchParams.m_inputLocale = primaryLanguage.UTF8String; - m_searchParams.m_query = searchText.precomposedStringWithCompatibilityMapping.UTF8String; - GetFramework().SearchInDownloader(m_searchParams); - } + m_searchParams.m_query = searchText.precomposedStringWithCompatibilityMapping.UTF8String; + [self updateSearchCallback]; + GetFramework().SearchInDownloader(m_searchParams); } #pragma mark - UIBarPositioningDelegate @@ -145,19 +152,26 @@ using namespace storage; - (UIBarPosition)positionForBar:(id)bar { return UIBarPositionTopAttached; } #pragma mark - Search -- (void)setupSearchParams +- (void)updateSearchCallback { __weak auto weakSelf = self; - m_searchParams.m_onResults = ^(DownloaderSearchResults const & results) { + NSTimeInterval const timestamp = [NSDate date].timeIntervalSince1970; + self.lastSearchTimestamp = timestamp; + m_searchParams.m_onResults = [weakSelf, timestamp](DownloaderSearchResults const & results) { __strong auto self = weakSelf; - if (!self || results.m_endMarker) + if (!self || timestamp != self.lastSearchTimestamp) return; - self.searchDataSource = - [[MWMMapDownloaderSearchDataSource alloc] initWithSearchResults:results delegate:self]; - dispatch_async(dispatch_get_main_queue(), ^{ + if (results.m_query.empty()) + { + self.dataSource = self.defaultDataSource; + } + else + { + self.searchDataSource = + [[MWMMapDownloaderSearchDataSource alloc] initWithSearchResults:results delegate:self]; self.dataSource = self.searchDataSource; - [self reloadTable]; - }); + } + [self reloadTable]; }; } @@ -176,8 +190,8 @@ using namespace storage; - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { [super prepareForSegue:segue sender:sender]; - if ([segue.identifier isEqualToString:kNoMapsSegue]) - self.noMapsController = segue.destinationViewController; + if ([segue.identifier isEqualToString:kMapDownloaderNoResultsEmbedViewControllerSegue]) + self.noResultsEmbedViewController = segue.destinationViewController; } #pragma mark - Configuration diff --git a/iphone/Maps/UI/Downloader/NoMaps/DownloaderNoResultsEmbedViewController.swift b/iphone/Maps/UI/Downloader/NoMaps/DownloaderNoResultsEmbedViewController.swift new file mode 100644 index 0000000000..6137be47db --- /dev/null +++ b/iphone/Maps/UI/Downloader/NoMaps/DownloaderNoResultsEmbedViewController.swift @@ -0,0 +1,25 @@ +import UIKit + +@objc(MWMDownloaderNoResultsEmbedViewController) +final class DownloaderNoResultsEmbed: UINavigationController { + + @objc(MWMDownloaderNoResultsScreen) + enum Screen: Int { + + case noMaps + case noSearchResults + + } + + var screen = Screen.noMaps { + didSet { + let controller: MWMViewController + switch screen { + case .noMaps: controller = MWMNoMapsViewController.controller() + case .noSearchResults: controller = SearchNoResultsViewController.controller + } + setViewControllers([controller], animated: false) + } + } + +} diff --git a/iphone/Maps/UI/Downloader/NoMaps/MWMNoMapsViewController.h b/iphone/Maps/UI/Downloader/NoMaps/MWMNoMapsViewController.h index cdbd58710d..4c71529247 100644 --- a/iphone/Maps/UI/Downloader/NoMaps/MWMNoMapsViewController.h +++ b/iphone/Maps/UI/Downloader/NoMaps/MWMNoMapsViewController.h @@ -2,6 +2,6 @@ @interface MWMNoMapsViewController : MWMViewController -+ (MWMNoMapsViewController *)controller; ++ (MWMNoMapsViewController *)controller NS_SWIFT_NAME(controller()); @end diff --git a/iphone/Maps/UI/Mapsme.storyboard b/iphone/Maps/UI/Mapsme.storyboard index 8a98bc16b4..c51db9a6cc 100644 --- a/iphone/Maps/UI/Mapsme.storyboard +++ b/iphone/Maps/UI/Mapsme.storyboard @@ -1,11 +1,11 @@ - + - + @@ -771,7 +771,7 @@ @@ -972,7 +972,7 @@ - + @@ -987,16 +987,16 @@ - + - + - + - + @@ -1004,7 +1004,7 @@