Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Grechuhin <i.grechuhin@gmail.com>2017-09-28 12:23:44 +0300
committerRoman Kuznetsov <r.kuznetsow@gmail.com>2017-09-28 15:31:24 +0300
commit6737cd92217fdd9e02ee0e19eddc45156e7b104a (patch)
tree6bb77bf206eb8daffdf71f2441885e4f92245749
parent1ae5be9bbb65916abebeea638b66bdd22544fa97 (diff)
[google] [ios] Added Google banners to search.
-rw-r--r--iphone/Maps/Categories/UIView+Hierarchy.swift5
-rw-r--r--iphone/Maps/Core/Ads/BannerType.swift24
-rw-r--r--iphone/Maps/Core/Ads/BannersCache.swift64
-rw-r--r--iphone/Maps/Core/Ads/CoreBanner.swift16
-rw-r--r--iphone/Maps/Core/Ads/Facebook/FacebookBanner.swift2
-rw-r--r--iphone/Maps/Core/Ads/Google/GoogleFallbackBanner.swift137
-rw-r--r--iphone/Maps/Core/Ads/Google/GoogleNativeBanner.swift90
-rw-r--r--iphone/Maps/Core/Ads/MWMBanner.h4
-rw-r--r--iphone/Maps/Core/Ads/MWMBannerHelpers.h10
-rw-r--r--iphone/Maps/Core/Search/MWMSearch.mm13
-rw-r--r--iphone/Maps/Core/Search/MWMSearchItemType.h1
-rw-r--r--iphone/Maps/Core/Search/SearchBanners.swift3
-rw-r--r--iphone/Maps/Maps.xcodeproj/project.pbxproj27
-rw-r--r--iphone/Maps/Maps_Prefix.pch1
-rw-r--r--iphone/Maps/UI/Ads/AdBanner.swift66
-rw-r--r--iphone/Maps/UI/Ads/AdBanner.xib276
-rw-r--r--iphone/Maps/UI/Search/TableView/MWMSearchTableViewController.mm23
17 files changed, 587 insertions, 175 deletions
diff --git a/iphone/Maps/Categories/UIView+Hierarchy.swift b/iphone/Maps/Categories/UIView+Hierarchy.swift
index fc2ce2e376..e76f07a676 100644
--- a/iphone/Maps/Categories/UIView+Hierarchy.swift
+++ b/iphone/Maps/Categories/UIView+Hierarchy.swift
@@ -2,4 +2,9 @@ extension UIView {
@objc func hasSubview(viewClass: AnyClass) -> Bool {
return !subviews.filter { type(of: $0) == viewClass }.isEmpty
}
+
+ func clearTreeBackground() {
+ backgroundColor = UIColor.clear
+ subviews.forEach { $0.clearTreeBackground() }
+ }
}
diff --git a/iphone/Maps/Core/Ads/BannerType.swift b/iphone/Maps/Core/Ads/BannerType.swift
index e66850037e..aa1ec5f7db 100644
--- a/iphone/Maps/Core/Ads/BannerType.swift
+++ b/iphone/Maps/Core/Ads/BannerType.swift
@@ -3,15 +3,15 @@ enum BannerType {
case facebook(String)
case rb(String)
case mopub(String)
- case google(String)
+ case google(String, String)
var banner: Banner? {
switch self {
case .none: return nil
- case .facebook(let id): return FacebookBanner(bannerID: id)
- case .rb(let id): return RBBanner(bannerID: id)
- case .mopub(let id): return MopubBanner(bannerID: id)
- case .google: return nil
+ case let .facebook(id): return FacebookBanner(bannerID: id)
+ case let .rb(id): return RBBanner(bannerID: id)
+ case let .mopub(id): return MopubBanner(bannerID: id)
+ case let .google(id, query): return GoogleFallbackBanner(bannerID: id, query: query)
}
}
@@ -25,13 +25,13 @@ enum BannerType {
}
}
- init(type: MWMBannerType, id: String) {
+ init(type: MWMBannerType, id: String, query: String = "") {
switch type {
case .none: self = .none
case .facebook: self = .facebook(id)
case .rb: self = .rb(id)
case .mopub: self = .mopub(id)
- case .google: self = .google(id)
+ case .google: self = .google(id, query)
}
}
}
@@ -43,7 +43,7 @@ extension BannerType: Equatable {
case let (.facebook(l), .facebook(r)): return l == r
case let (.rb(l), .rb(r)): return l == r
case let (.mopub(l), .mopub(r)): return l == r
- case let (.google(l), .google(r)): return l == r
+ case let (.google(l1, l2), .google(r1, r2)): return l1 == r1 && l2 == r2
case (.none, _),
(.facebook, _),
(.rb, _),
@@ -57,10 +57,10 @@ extension BannerType: Hashable {
var hashValue: Int {
switch self {
case .none: return mwmType.hashValue
- case .facebook(let id): return mwmType.hashValue ^ id.hashValue
- case .rb(let id): return mwmType.hashValue ^ id.hashValue
- case .mopub(let id): return mwmType.hashValue ^ id.hashValue
- case .google(let id): return mwmType.hashValue ^ id.hashValue
+ case let .facebook(id): return mwmType.hashValue ^ id.hashValue
+ case let .rb(id): return mwmType.hashValue ^ id.hashValue
+ case let .mopub(id): return mwmType.hashValue ^ id.hashValue
+ case let .google(id, query): return mwmType.hashValue ^ id.hashValue ^ query.hashValue
}
}
}
diff --git a/iphone/Maps/Core/Ads/BannersCache.swift b/iphone/Maps/Core/Ads/BannersCache.swift
index e377c71341..edb4cb045d 100644
--- a/iphone/Maps/Core/Ads/BannersCache.swift
+++ b/iphone/Maps/Core/Ads/BannersCache.swift
@@ -6,10 +6,21 @@ final class BannersCache: NSObject {
@objc static let cache = BannersCache()
private override init() {}
- private enum LoadState {
+ private enum LoadState: Equatable {
case notLoaded(BannerType)
case loaded(BannerType)
- case error
+ case error(BannerType)
+
+ static func ==(lhs: LoadState, rhs: LoadState) -> Bool {
+ switch (lhs, rhs) {
+ case let (.notLoaded(l), .notLoaded(r)): return l == r
+ case let (.loaded(l), .loaded(r)): return l == r
+ case let (.error(l), .error(r)): return l == r
+ case (.notLoaded, _),
+ (.loaded, _),
+ (.error, _): return false
+ }
+ }
}
typealias Completion = (MWMBanner, Bool) -> Void
@@ -40,27 +51,41 @@ final class BannersCache: NSObject {
completion(banner, isAsync)
banner.isBannerOnScreen = true
self.completion = nil
+ loadStates = nil
}
}
@objc func get(coreBanners: [CoreBanner], cacheOnly: Bool, loadNew: Bool = true, completion: @escaping Completion) {
self.completion = completion
self.cacheOnly = cacheOnly
- loadStates = coreBanners.map { coreBanner in
- let bannerType = BannerType(type: coreBanner.mwmType, id: coreBanner.bannerID)
+ loadStates = loadStates ?? []
+ coreBanners.forEach { coreBanner in
+ let bannerType = BannerType(type: coreBanner.mwmType, id: coreBanner.bannerID, query: coreBanner.query)
if let banner = cache[bannerType], (!banner.isPossibleToReload || banner.isNeedToRetain) {
- return .loaded(bannerType)
+ appendLoadState(.loaded(bannerType))
} else {
if loadNew {
get(bannerType: bannerType)
}
- return .notLoaded(bannerType)
+ appendLoadState(.notLoaded(bannerType))
}
}
onCompletion(isAsync: false)
}
+ @objc func refresh(coreBanners: [CoreBanner]) {
+ loadStates = loadStates ?? []
+ coreBanners.forEach { coreBanner in
+ let bannerType = BannerType(type: coreBanner.mwmType, id: coreBanner.bannerID, query: coreBanner.query)
+ let state = LoadState.notLoaded(bannerType)
+ if loadStates.index(of: state) == nil {
+ get(bannerType: bannerType)
+ appendLoadState(state)
+ }
+ }
+ }
+
private func get(bannerType: BannerType) {
guard requests[bannerType] == nil else { return }
@@ -81,6 +106,11 @@ final class BannersCache: NSObject {
})
}
+ private func appendLoadState(_ state: LoadState) {
+ guard loadStates.index(of: state) == nil else { return }
+ loadStates.append(state)
+ }
+
private func notLoadedIndex(bannerType: BannerType) -> Array<LoadState>.Index? {
return loadStates.index(where: {
if case let .notLoaded(type) = $0, type == bannerType {
@@ -92,22 +122,30 @@ final class BannersCache: NSObject {
private func setLoaded(banner: Banner) {
let bannerType = banner.type
- if let notLoadedIndex = notLoadedIndex(bannerType: bannerType) {
- loadStates[notLoadedIndex] = .loaded(bannerType)
- }
cache[bannerType] = banner
requests[bannerType] = nil
+
+ guard loadStates != nil else { return }
+
+ if let notLoadedIndex = loadStates.index(of: .notLoaded(bannerType)) {
+ loadStates[notLoadedIndex] = .loaded(bannerType)
+ }
if !cacheOnly {
onCompletion(isAsync: true)
}
}
private func setError(bannerType: BannerType) {
- if let notLoadedIndex = notLoadedIndex(bannerType: bannerType) {
- loadStates[notLoadedIndex] = .error
- }
requests[bannerType] = nil
- onCompletion(isAsync: true)
+
+ guard loadStates != nil else { return }
+
+ if let notLoadedIndex = loadStates.index(of: .notLoaded(bannerType)) {
+ loadStates[notLoadedIndex] = .error(bannerType)
+ }
+ if !cacheOnly {
+ onCompletion(isAsync: true)
+ }
}
@objc func bannerIsOutOfScreen(coreBanner: MWMBanner) {
diff --git a/iphone/Maps/Core/Ads/CoreBanner.swift b/iphone/Maps/Core/Ads/CoreBanner.swift
index da09c3bcdd..91a5ed2324 100644
--- a/iphone/Maps/Core/Ads/CoreBanner.swift
+++ b/iphone/Maps/Core/Ads/CoreBanner.swift
@@ -2,9 +2,23 @@
final class CoreBanner: NSObject, MWMBanner {
let mwmType: MWMBannerType
let bannerID: String
+ let query: String
- @objc init(mwmType: MWMBannerType, bannerID: String) {
+ @objc init(mwmType: MWMBannerType, bannerID: String, query: String) {
self.mwmType = mwmType
self.bannerID = bannerID
+ self.query = query
+ }
+
+ override var debugDescription: String {
+ let type: String
+ switch mwmType {
+ case .none: type = "none"
+ case .facebook: type = "facebook"
+ case .rb: type = "rb"
+ case .mopub: type = "mopub"
+ case .google: type = "google"
+ }
+ return "Type: <\(type)> | id: <\(bannerID)> | query: <\(query)>"
}
}
diff --git a/iphone/Maps/Core/Ads/Facebook/FacebookBanner.swift b/iphone/Maps/Core/Ads/Facebook/FacebookBanner.swift
index b6b61ddc09..96169335d9 100644
--- a/iphone/Maps/Core/Ads/Facebook/FacebookBanner.swift
+++ b/iphone/Maps/Core/Ads/Facebook/FacebookBanner.swift
@@ -131,7 +131,7 @@ extension FacebookBanner: FBNativeAdDelegate {
guard nativeAd === self.nativeAd else { return }
// https://developers.facebook.com/docs/audience-network/testing
- var params: [String: Any] = [kStatBanner: nativeAd.placementID, kStatProvider: kStatFacebook]
+ var params: [String: Any] = statisticsDescription
let e = error as NSError
let event: String
diff --git a/iphone/Maps/Core/Ads/Google/GoogleFallbackBanner.swift b/iphone/Maps/Core/Ads/Google/GoogleFallbackBanner.swift
new file mode 100644
index 0000000000..05e56e67f2
--- /dev/null
+++ b/iphone/Maps/Core/Ads/Google/GoogleFallbackBanner.swift
@@ -0,0 +1,137 @@
+import GoogleMobileAds
+
+@objc(MWMGoogleFallbackBannerDynamicSizeDelegate)
+protocol GoogleFallbackBannerDynamicSizeDelegate {
+ func dynamicSizeUpdated(banner: GoogleFallbackBanner)
+}
+
+@objc(MWMGoogleFallbackBanner)
+final class GoogleFallbackBanner: GADSearchBannerView, Banner {
+ private enum Limits {
+ static let minTimeSinceLastRequest: TimeInterval = 5
+ }
+
+ fileprivate var success: Banner.Success!
+ fileprivate var failure: Banner.Failure!
+ fileprivate var click: Banner.Click!
+
+ private var requestDate: Date?
+ var isBannerOnScreen: Bool = false
+ var isNeedToRetain: Bool { return true }
+ var isPossibleToReload: Bool {
+ if let date = requestDate {
+ return Date().timeIntervalSince(date) > Limits.minTimeSinceLastRequest
+ }
+ return true
+ }
+ var type: BannerType { return .google(bannerID, query) }
+ var mwmType: MWMBannerType { return type.mwmType }
+ var bannerID: String! { return adUnitID }
+ var statisticsDescription: [String: String] {
+ return [kStatBanner: bannerID, kStatProvider: kStatGoogle]
+ }
+ let query: String
+
+ @objc var dynamicSizeDelegate: GoogleFallbackBannerDynamicSizeDelegate?
+ fileprivate(set) var dynamicSize = CGSize.zero {
+ didSet {
+ dynamicSizeDelegate?.dynamicSizeUpdated(banner: self)
+ }
+ }
+ @objc var cellIndexPath: IndexPath!
+
+ init(bannerID: String, query: String) {
+ self.query = query
+ super.init(adSize: kGADAdSizeFluid)
+ adUnitID = bannerID
+ frame = CGRect.zero
+
+ delegate = self
+ adSizeDelegate = self
+ }
+
+ required init?(coder _: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ func reload(success: @escaping Success, failure: @escaping Failure, click: @escaping Click) {
+ self.success = success
+ self.failure = failure
+ self.click = click
+
+ let searchRequest = GADDynamicHeightSearchRequest()
+ searchRequest.query = query
+ searchRequest.numberOfAds = 1
+ if let loc = MWMLocationManager.lastLocation() {
+ searchRequest.setLocationWithLatitude(CGFloat(loc.coordinate.latitude),
+ longitude: CGFloat(loc.coordinate.longitude),
+ accuracy: CGFloat(loc.horizontalAccuracy))
+ }
+ searchRequest.cssWidth = "100%"
+ let isNightMode = UIColor.isNightMode()
+ searchRequest.adBorderCSSSelections = "bottom"
+ searchRequest.adBorderColor = isNightMode ? "#53575A" : "#E0E0E0"
+ searchRequest.adjustableLineHeight = 18
+ searchRequest.annotationFontSize = 12
+ searchRequest.annotationTextColor = isNightMode ? "#C8C9CA" : "#75726D"
+ searchRequest.attributionBottomSpacing = 4
+ searchRequest.attributionFontSize = 12
+ searchRequest.attributionTextColor = isNightMode ? "#C8C9CA" : "#75726D"
+ searchRequest.backgroundColor = isNightMode ? "#484B50" : "#FFF9EF"
+ searchRequest.boldTitleEnabled = true
+ searchRequest.clickToCallExtensionEnabled = true
+ searchRequest.descriptionFontSize = 12
+ searchRequest.domainLinkColor = isNightMode ? "#51B5E6" : "#1E96F0"
+ searchRequest.domainLinkFontSize = 12
+ searchRequest.locationExtensionEnabled = true
+ searchRequest.locationExtensionFontSize = 12
+ searchRequest.locationExtensionTextColor = isNightMode ? "#C8C9CA" : "#75726D"
+ searchRequest.sellerRatingsExtensionEnabled = false
+ searchRequest.siteLinksExtensionEnabled = false
+ searchRequest.textColor = isNightMode ? "#C8C9CA" : "#75726D"
+ searchRequest.titleFontSize = 12
+ searchRequest.titleLinkColor = isNightMode ? "#FFFFFF" : "#21201E"
+ searchRequest.titleUnderlineHidden = true
+
+ load(searchRequest)
+ requestDate = Date()
+ }
+
+ func unregister() {}
+
+ static func ==(lhs: GoogleFallbackBanner, rhs: GoogleFallbackBanner) -> Bool {
+ return lhs.adUnitID == rhs.adUnitID && lhs.query == rhs.query
+ }
+}
+
+extension GoogleFallbackBanner: GADBannerViewDelegate {
+ func adViewDidReceiveAd(_ bannerView: GADBannerView) {
+ guard let banner = bannerView as? GoogleFallbackBanner, banner == self else { return }
+ success(self)
+ }
+
+ func adView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: GADRequestError) {
+ guard let banner = bannerView as? GoogleFallbackBanner, banner == self else { return }
+ var params: [String: Any] = statisticsDescription
+ params[kStatErrorCode] = error.code
+
+ failure(type, kStatPlacePageBannerError, params, error)
+ }
+
+ func adViewWillPresentScreen(_: GADBannerView) {
+ click(self)
+ }
+
+ func adViewWillLeaveApplication(_: GADBannerView) {
+ click(self)
+ }
+}
+
+extension GoogleFallbackBanner: GADAdSizeDelegate {
+ func adView(_: GADBannerView, willChangeAdSizeTo size: GADAdSize) {
+ var newFrame = frame
+ newFrame.size.height = size.size.height
+ frame = newFrame
+ dynamicSize = size.size
+ }
+}
diff --git a/iphone/Maps/Core/Ads/Google/GoogleNativeBanner.swift b/iphone/Maps/Core/Ads/Google/GoogleNativeBanner.swift
new file mode 100644
index 0000000000..bef821b460
--- /dev/null
+++ b/iphone/Maps/Core/Ads/Google/GoogleNativeBanner.swift
@@ -0,0 +1,90 @@
+import GoogleMobileAds
+
+final class GoogleNativeBanner: NSObject, Banner {
+ private enum Limits {
+ static let minTimeSinceLastRequest: TimeInterval = 5
+ }
+
+ fileprivate var success: Banner.Success!
+ fileprivate var failure: Banner.Failure!
+ fileprivate var click: Banner.Click!
+
+ private var requestDate: Date?
+ var isBannerOnScreen: Bool = false
+ var isNeedToRetain: Bool { return true }
+ var isPossibleToReload: Bool {
+ if let date = requestDate {
+ return Date().timeIntervalSince(date) > Limits.minTimeSinceLastRequest
+ }
+ return true
+ }
+ var type: BannerType { return .google(bannerID, query) }
+ var mwmType: MWMBannerType { return type.mwmType }
+ var bannerID: String! { return adLoader.adUnitID }
+ var statisticsDescription: [String: String] {
+ return [kStatBanner: bannerID, kStatProvider: kStatGoogle]
+ }
+ private let query: String
+ private let adLoader: GADAdLoader
+
+ fileprivate var nativeAd: GADNativeAd!
+
+ init(bannerID _: String, query: String) {
+ self.query = query
+ adLoader = GADAdLoader(adUnitID: "ca-app-pub-6656946757675080/8014770099",
+ rootViewController: UIViewController.topViewController(),
+ adTypes: [GADAdLoaderAdType.nativeAppInstall, GADAdLoaderAdType.nativeContent],
+ options: nil)
+ super.init()
+ adLoader.delegate = self
+ }
+
+ func reload(success: @escaping Success, failure: @escaping Failure, click: @escaping Click) {
+ self.success = success
+ self.failure = failure
+ self.click = click
+
+ let request = GADSearchRequest()
+ request.testDevices = [kGADSimulatorID]
+ request.query = query
+ if let loc = MWMLocationManager.lastLocation() {
+ request.setLocationWithLatitude(CGFloat(loc.coordinate.latitude),
+ longitude: CGFloat(loc.coordinate.longitude),
+ accuracy: CGFloat(loc.horizontalAccuracy))
+ }
+
+ adLoader.load(request)
+ requestDate = Date()
+ }
+
+ func unregister() {
+ switch nativeAd {
+ case let nativeAppInstallAd as GADNativeAppInstallAd: nativeAppInstallAd.unregisterAdView()
+ case let nativeContentAd as GADNativeContentAd: nativeContentAd.unregisterAdView()
+ default: assert(false)
+ }
+ }
+}
+
+extension GoogleNativeBanner: GADAdLoaderDelegate {
+ func adLoader(_: GADAdLoader, didFailToReceiveAdWithError error: GADRequestError) {
+ var params: [String: Any] = statisticsDescription
+ params[kStatErrorCode] = error.code
+
+ failure(type, kStatPlacePageBannerError, params, error)
+ }
+}
+
+extension GoogleNativeBanner: GADNativeAppInstallAdLoaderDelegate {
+ func adLoader(_: GADAdLoader, didReceive nativeAppInstallAd: GADNativeAppInstallAd) {
+ nativeAd = nativeAppInstallAd
+ success(self)
+ }
+}
+
+extension GoogleNativeBanner: GADNativeContentAdLoaderDelegate {
+ func adLoader(_: GADAdLoader, didReceive nativeContentAd: GADNativeContentAd) {
+ nativeAd = nativeContentAd
+ success(self)
+ }
+}
diff --git a/iphone/Maps/Core/Ads/MWMBanner.h b/iphone/Maps/Core/Ads/MWMBanner.h
index 1766a78a48..b16f1912e9 100644
--- a/iphone/Maps/Core/Ads/MWMBanner.h
+++ b/iphone/Maps/Core/Ads/MWMBanner.h
@@ -6,7 +6,7 @@ typedef NS_ENUM(NSInteger, MWMBannerType) {
MWMBannerTypeGoogle
};
-@protocol MWMBanner
+@protocol MWMBanner <NSObject>
@property(nonatomic, readonly) enum MWMBannerType mwmType;
-@property(nonatomic, readonly) NSString * bannerID;
+@property(copy, nonatomic, readonly) NSString * bannerID;
@end
diff --git a/iphone/Maps/Core/Ads/MWMBannerHelpers.h b/iphone/Maps/Core/Ads/MWMBannerHelpers.h
index 4662ee60a9..a4000339bb 100644
--- a/iphone/Maps/Core/Ads/MWMBannerHelpers.h
+++ b/iphone/Maps/Core/Ads/MWMBannerHelpers.h
@@ -19,18 +19,18 @@ static inline MWMBannerType MatchBannerType(ads::Banner::Type coreType)
}
}
-static inline MWMCoreBanner * MatchBanner(ads::Banner const & banner)
+static inline MWMCoreBanner * MatchBanner(ads::Banner const & banner, NSString * query)
{
return [[MWMCoreBanner alloc] initWithMwmType:MatchBannerType(banner.m_type)
- bannerID:@(banner.m_bannerId.c_str())];
+ bannerID:@(banner.m_bannerId.c_str())
+ query:query];
}
-static inline NSArray<MWMCoreBanner *> * MatchPriorityBanners(
- std::vector<ads::Banner> const & banners)
+static inline NSArray<MWMCoreBanner *> * MatchPriorityBanners(std::vector<ads::Banner> const & banners, NSString * query = @"")
{
NSMutableArray<MWMCoreBanner *> * mBanners = [@[] mutableCopy];
for (auto const & banner : banners)
- [mBanners addObject:MatchBanner(banner)];
+ [mBanners addObject:MatchBanner(banner, query)];
return [mBanners copy];
}
}
diff --git a/iphone/Maps/Core/Search/MWMSearch.mm b/iphone/Maps/Core/Search/MWMSearch.mm
index 3ada774ff3..0f6658329a 100644
--- a/iphone/Maps/Core/Search/MWMSearch.mm
+++ b/iphone/Maps/Core/Search/MWMSearch.mm
@@ -44,6 +44,8 @@ using Observers = NSHashTable<Observer>;
@property(nonatomic) NSInteger searchCount;
+@property(copy, nonatomic) NSString * lastQuery;
+
@end
@implementation MWMSearch
@@ -220,10 +222,17 @@ using Observers = NSHashTable<Observer>;
manager->m_everywhereParams.m_inputLocale = locale;
manager->m_viewportParams.m_inputLocale = locale;
}
- string const text = query.precomposedStringWithCompatibilityMapping.UTF8String;
+ manager.lastQuery = query.precomposedStringWithCompatibilityMapping;
+ string const text = manager.lastQuery.UTF8String;
manager->m_everywhereParams.m_query = text;
manager->m_viewportParams.m_query = text;
manager.textChanged = YES;
+ auto const & adsEngine = GetFramework().GetAdsEngine();
+ if (![MWMSettings adForbidden] && adsEngine.HasSearchBanner())
+ {
+ auto coreBanners = banner_helpers::MatchPriorityBanners(adsEngine.GetSearchBanners(), manager.lastQuery);
+ [[MWMBannersCache cache] refreshWithCoreBanners:coreBanners];
+ }
[manager update];
}
@@ -326,7 +335,7 @@ using Observers = NSHashTable<Observer>;
self.banners = [[MWMSearchBanners alloc] initWithSearchIndex:itemsIndex];
__weak auto weakSelf = self;
[[MWMBannersCache cache]
- getWithCoreBanners:banner_helpers::MatchPriorityBanners(adsEngine.GetSearchBanners())
+ getWithCoreBanners:banner_helpers::MatchPriorityBanners(adsEngine.GetSearchBanners(), self.lastQuery)
cacheOnly:YES
loadNew:reloadBanner
completion:^(id<MWMBanner> ad, BOOL isAsync) {
diff --git a/iphone/Maps/Core/Search/MWMSearchItemType.h b/iphone/Maps/Core/Search/MWMSearchItemType.h
index 77bd68e899..f6fa223d39 100644
--- a/iphone/Maps/Core/Search/MWMSearchItemType.h
+++ b/iphone/Maps/Core/Search/MWMSearchItemType.h
@@ -3,5 +3,6 @@ typedef NS_ENUM(NSUInteger, MWMSearchItemType) {
MWMSearchItemTypeRegular,
MWMSearchItemTypeMopub,
MWMSearchItemTypeFacebook,
+ MWMSearchItemTypeGoogle,
MWMSearchItemTypeSuggestion
};
diff --git a/iphone/Maps/Core/Search/SearchBanners.swift b/iphone/Maps/Core/Search/SearchBanners.swift
index a395fd6c53..2f27fe7836 100644
--- a/iphone/Maps/Core/Search/SearchBanners.swift
+++ b/iphone/Maps/Core/Search/SearchBanners.swift
@@ -21,6 +21,9 @@ final class SearchBanners: NSObject {
case .facebook:
type = .facebook
prefferedPosition = 2
+ case .google:
+ type = .google
+ prefferedPosition = 4
default:
assert(false, "Unsupported banner type")
type = .regular
diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj
index fe8225210e..0c6113fb62 100644
--- a/iphone/Maps/Maps.xcodeproj/project.pbxproj
+++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj
@@ -108,6 +108,9 @@
340475801E081B3300C92850 /* iosOGLContextFactory.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3404757C1E081B3300C92850 /* iosOGLContextFactory.mm */; };
340475811E081B3300C92850 /* iosOGLContextFactory.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3404757C1E081B3300C92850 /* iosOGLContextFactory.mm */; };
340475821E081B3300C92850 /* iosOGLContextFactory.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3404757C1E081B3300C92850 /* iosOGLContextFactory.mm */; };
+ 34065A101F45E7F8006684E5 /* GoogleFallbackBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34065A0F1F45E7F8006684E5 /* GoogleFallbackBanner.swift */; };
+ 34065A111F45E7F8006684E5 /* GoogleFallbackBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34065A0F1F45E7F8006684E5 /* GoogleFallbackBanner.swift */; };
+ 34065A121F45E7F8006684E5 /* GoogleFallbackBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34065A0F1F45E7F8006684E5 /* GoogleFallbackBanner.swift */; };
3406FA151C6E0C3300E9FAD2 /* MWMMapDownloadDialog.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3406FA141C6E0C3300E9FAD2 /* MWMMapDownloadDialog.mm */; };
3406FA161C6E0C3300E9FAD2 /* MWMMapDownloadDialog.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3406FA141C6E0C3300E9FAD2 /* MWMMapDownloadDialog.mm */; };
3406FA181C6E0D8F00E9FAD2 /* MWMMapDownloadDialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3406FA171C6E0D8F00E9FAD2 /* MWMMapDownloadDialog.xib */; };
@@ -175,6 +178,9 @@
340E1EFE1E2F614400CE49BF /* Welcome.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 340E1EEA1E2F614400CE49BF /* Welcome.storyboard */; };
340E1EFF1E2F614400CE49BF /* Welcome.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 340E1EEA1E2F614400CE49BF /* Welcome.storyboard */; };
3411387D1C15AE73002E3B3E /* libeditor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3411387C1C15AE73002E3B3E /* libeditor.a */; };
+ 3411E7631F7CE5DD00A49FCD /* GoogleMobileAds.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3411E7621F7CE5DC00A49FCD /* GoogleMobileAds.framework */; };
+ 3411E7641F7CE5DF00A49FCD /* GoogleMobileAds.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3411E7621F7CE5DC00A49FCD /* GoogleMobileAds.framework */; };
+ 3411E7651F7CE5E000A49FCD /* GoogleMobileAds.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3411E7621F7CE5DC00A49FCD /* GoogleMobileAds.framework */; };
341522BF1B666A550077AA8F /* MWMAPIBarView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 341522BE1B666A550077AA8F /* MWMAPIBarView.mm */; };
341B10761E55B15B00071C74 /* MWMMobileInternetAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = 349A13811DEC138C00C7DB60 /* MWMMobileInternetAlert.xib */; };
341C2A571B72092A00AD41A1 /* 02_droidsans-fallback.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9DF04B231B71010E00DACAF1 /* 02_droidsans-fallback.ttf */; };
@@ -529,6 +535,9 @@
34BC72241B0DECAE0012A34B /* MWMMapViewControlsManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34BC72111B0DECAE0012A34B /* MWMMapViewControlsManager.mm */; };
34BF0CC61C31304A00D097EB /* MWMAuthorizationCommon.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34BF0CC51C31304A00D097EB /* MWMAuthorizationCommon.mm */; };
34BF0CC71C31304A00D097EB /* MWMAuthorizationCommon.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34BF0CC51C31304A00D097EB /* MWMAuthorizationCommon.mm */; };
+ 34C0A69C1F4C1B380007CE5B /* GoogleNativeBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C0A69B1F4C1B380007CE5B /* GoogleNativeBanner.swift */; };
+ 34C0A69D1F4C1B380007CE5B /* GoogleNativeBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C0A69B1F4C1B380007CE5B /* GoogleNativeBanner.swift */; };
+ 34C0A69E1F4C1B380007CE5B /* GoogleNativeBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C0A69B1F4C1B380007CE5B /* GoogleNativeBanner.swift */; };
34C5B80F1F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C5B80E1F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift */; };
34C5B8101F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C5B80E1F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift */; };
34C5B8111F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C5B80E1F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift */; };
@@ -1825,6 +1834,7 @@
3404757B1E081B3300C92850 /* iosOGLContextFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iosOGLContextFactory.h; sourceTree = "<group>"; };
3404757C1E081B3300C92850 /* iosOGLContextFactory.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iosOGLContextFactory.mm; sourceTree = "<group>"; };
340537621BBED98600D452C6 /* MWMMapViewControlsCommon.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MWMMapViewControlsCommon.h; path = APIBar/MWMMapViewControlsCommon.h; sourceTree = "<group>"; };
+ 34065A0F1F45E7F8006684E5 /* GoogleFallbackBanner.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GoogleFallbackBanner.swift; sourceTree = "<group>"; };
3406FA131C6E0C3300E9FAD2 /* MWMMapDownloadDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMMapDownloadDialog.h; sourceTree = "<group>"; };
3406FA141C6E0C3300E9FAD2 /* MWMMapDownloadDialog.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMMapDownloadDialog.mm; sourceTree = "<group>"; };
3406FA171C6E0D8F00E9FAD2 /* MWMMapDownloadDialog.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMMapDownloadDialog.xib; sourceTree = "<group>"; };
@@ -2070,6 +2080,7 @@
34BC72111B0DECAE0012A34B /* MWMMapViewControlsManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = MWMMapViewControlsManager.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
34BF0CC51C31304A00D097EB /* MWMAuthorizationCommon.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMAuthorizationCommon.mm; sourceTree = "<group>"; };
34BF0CC81C31306300D097EB /* MWMAuthorizationCommon.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMAuthorizationCommon.h; sourceTree = "<group>"; };
+ 34C0A69B1F4C1B380007CE5B /* GoogleNativeBanner.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GoogleNativeBanner.swift; sourceTree = "<group>"; };
34C5B80E1F335BA8005E50B6 /* RouteManagerViewModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RouteManagerViewModelProtocol.swift; sourceTree = "<group>"; };
34C5B8121F335BCA005E50B6 /* RouteManagerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RouteManagerViewModel.swift; sourceTree = "<group>"; };
34C5B81A1F3367E1005E50B6 /* RouteManagerTransitioningManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RouteManagerTransitioningManager.swift; sourceTree = "<group>"; };
@@ -3152,6 +3163,15 @@
path = Traffic;
sourceTree = "<group>";
};
+ 34065A0E1F45E7E1006684E5 /* Google */ = {
+ isa = PBXGroup;
+ children = (
+ 34065A0F1F45E7F8006684E5 /* GoogleFallbackBanner.swift */,
+ 34C0A69B1F4C1B380007CE5B /* GoogleNativeBanner.swift */,
+ );
+ path = Google;
+ sourceTree = "<group>";
+ };
340837101B7243B500B5C185 /* Share */ = {
isa = PBXGroup;
children = (
@@ -3717,6 +3737,7 @@
34F4071C1E9E1AFF00E57AC0 /* Ads */ = {
isa = PBXGroup;
children = (
+ 34065A0E1F45E7E1006684E5 /* Google */,
34F4071D1E9E1AFF00E57AC0 /* Banner.swift */,
34F4071E1E9E1AFF00E57AC0 /* BannersCache.swift */,
34F4071F1E9E1AFF00E57AC0 /* BannerType.swift */,
@@ -5775,6 +5796,7 @@
340837131B7243CE00B5C185 /* MWMActivityViewController.mm in Sources */,
3486B5181E27AD3B0069C126 /* MWMFrameworkListener.mm in Sources */,
3404756A1E081A4600C92850 /* MWMSearch+CoreSpotlight.mm in Sources */,
+ 34065A101F45E7F8006684E5 /* GoogleFallbackBanner.swift in Sources */,
F653CE111C6DEB5A00A453F1 /* MWMDropDown.mm in Sources */,
3404755B1E081A4600C92850 /* MWMLocationManager.mm in Sources */,
3454D7BB1E07F045004AF2AD /* CLLocation+Mercator.mm in Sources */,
@@ -5859,6 +5881,7 @@
34B924421DC8A29C0008D971 /* MWMMailViewController.mm in Sources */,
34E7760F1F14B165003040B3 /* VisibleArea.swift in Sources */,
F6E2FF171E097BA00083EBEC /* MWMSearchTabbedCollectionViewCell.mm in Sources */,
+ 34C0A69C1F4C1B380007CE5B /* GoogleNativeBanner.swift in Sources */,
F64F199B1AB81A00006EAF7E /* MWMAlert.mm in Sources */,
3488B0191E9D0B230068AFD8 /* UIColor+Modifications.swift in Sources */,
34AC8FD01EFC028600E7F910 /* NavigationAddPointToastView.swift in Sources */,
@@ -6120,6 +6143,7 @@
F626D52F1C3E83F800C17D15 /* MWMTableViewCell.mm in Sources */,
3486B5191E27AD3B0069C126 /* MWMFrameworkListener.mm in Sources */,
3404756B1E081A4600C92850 /* MWMSearch+CoreSpotlight.mm in Sources */,
+ 34065A111F45E7F8006684E5 /* GoogleFallbackBanner.swift in Sources */,
F653CE121C6DEC8E00A453F1 /* MWMDropDown.mm in Sources */,
3404755C1E081A4600C92850 /* MWMLocationManager.mm in Sources */,
3454D7BC1E07F045004AF2AD /* CLLocation+Mercator.mm in Sources */,
@@ -6204,6 +6228,7 @@
F6E2FF181E097BA00083EBEC /* MWMSearchTabbedCollectionViewCell.mm in Sources */,
346DB83D1E5C4F6700E3123E /* GalleryModel.swift in Sources */,
34E776101F14B165003040B3 /* VisibleArea.swift in Sources */,
+ 34C0A69D1F4C1B380007CE5B /* GoogleNativeBanner.swift in Sources */,
3454D7D71E07F045004AF2AD /* UIKitCategories.mm in Sources */,
34AB39C21D2BD8310021857D /* MWMStopButton.mm in Sources */,
3488B01A1E9D0B230068AFD8 /* UIColor+Modifications.swift in Sources */,
@@ -6465,6 +6490,7 @@
849CF7151DE842290024A8A5 /* MWMInputEmailValidator.mm in Sources */,
3486B51A1E27AD3B0069C126 /* MWMFrameworkListener.mm in Sources */,
845E4B1D1DEC83AE00D6BED8 /* MWMMobileInternetAlert.mm in Sources */,
+ 34065A121F45E7F8006684E5 /* GoogleFallbackBanner.swift in Sources */,
849CF7171DE842290024A8A5 /* BookmarksRootVC.mm in Sources */,
849CF7191DE842290024A8A5 /* MWMActivityViewController.mm in Sources */,
849CF71A1DE842290024A8A5 /* MWMDropDown.mm in Sources */,
@@ -6549,6 +6575,7 @@
346DB83E1E5C4F6700E3123E /* GalleryModel.swift in Sources */,
849CF7611DE842290024A8A5 /* MWMMailViewController.mm in Sources */,
34E776111F14B165003040B3 /* VisibleArea.swift in Sources */,
+ 34C0A69E1F4C1B380007CE5B /* GoogleNativeBanner.swift in Sources */,
F6E2FF191E097BA00083EBEC /* MWMSearchTabbedCollectionViewCell.mm in Sources */,
3404754E1E081A4600C92850 /* MWMKeyboard.mm in Sources */,
3488B01B1E9D0B230068AFD8 /* UIColor+Modifications.swift in Sources */,
diff --git a/iphone/Maps/Maps_Prefix.pch b/iphone/Maps/Maps_Prefix.pch
index 19d5cc075e..9935ab9240 100644
--- a/iphone/Maps/Maps_Prefix.pch
+++ b/iphone/Maps/Maps_Prefix.pch
@@ -5,6 +5,7 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
+ #import <GoogleMobileAds/GoogleMobileAds.h>
#import "MWMConsts.h"
#import "MWMMacros.h"
diff --git a/iphone/Maps/UI/Ads/AdBanner.swift b/iphone/Maps/UI/Ads/AdBanner.swift
index f0b615f84d..f1ecc92999 100644
--- a/iphone/Maps/UI/Ads/AdBanner.swift
+++ b/iphone/Maps/UI/Ads/AdBanner.swift
@@ -41,8 +41,30 @@ final class AdBanner: UITableViewCell {
@IBOutlet private weak var adCallToActionButtonDetailed: UIButton!
@IBOutlet private weak var adCallToActionButtonCustom: UIButton!
@IBOutlet private weak var adPrivacyButton: UIButton!
+ @IBOutlet private weak var nativeAdView: UIView!
+ @IBOutlet private weak var fallbackAdView: UIView!
+ @IBOutlet private var nativeAdViewBottom: NSLayoutConstraint!
+ @IBOutlet private var fallbackAdViewBottom: NSLayoutConstraint!
+ @IBOutlet private var fallbackAdViewHeight: NSLayoutConstraint!
@objc static let detailedBannerExcessHeight: Float = 36
+ enum AdType {
+ case native
+ case fallback
+ }
+
+ var adType = AdType.native {
+ didSet {
+ let isNative = adType == .native
+ nativeAdView.isHidden = !isNative
+ fallbackAdView.isHidden = isNative
+
+ nativeAdViewBottom.isActive = isNative
+ fallbackAdViewBottom.isActive = !isNative
+ fallbackAdViewHeight.isActive = !isNative
+ }
+ }
+
@objc var state = AdBannerState.unset {
didSet {
guard state != .unset else {
@@ -82,6 +104,14 @@ final class AdBanner: UITableViewCell {
}
}
+ override func layoutSubviews() {
+ super.layoutSubviews()
+ switch nativeAd {
+ case let ad as GoogleFallbackBanner: updateFallbackBannerLayout(ad: ad)
+ default: break
+ }
+ }
+
func reset() {
state = .unset
}
@@ -96,17 +126,13 @@ final class AdBanner: UITableViewCell {
}
nativeAd = ad as? Banner
- switch ad.mwmType {
- case .none:
- assert(false)
- case .facebook:
- configFBBanner(ad: (ad as! FacebookBanner).nativeAd)
- case .rb:
- configRBBanner(ad: ad as! MTRGNativeAd)
- case .mopub:
- configMopubBanner(ad: ad as! MopubBanner)
- case .google:
- assert(false)
+ switch ad {
+ case let ad as FacebookBanner: configFBBanner(ad: ad.nativeAd)
+ case let ad as RBBanner: configRBBanner(ad: ad)
+ case let ad as MopubBanner: configMopubBanner(ad: ad)
+ case let ad as GoogleFallbackBanner: configGoogleFallbackBanner(ad: ad)
+ case let ad as GoogleNativeBanner: configGoogleNativeBanner(ad: ad)
+ default: assert(false)
}
}
@@ -133,6 +159,7 @@ final class AdBanner: UITableViewCell {
}
private func configFBBanner(ad: FBNativeAd) {
+ adType = .native
let adCallToActionButtons: [UIView]
if state == .search {
adCallToActionButtons = [self, adCallToActionButtonCompact]
@@ -164,6 +191,7 @@ final class AdBanner: UITableViewCell {
private func configRBBanner(ad: MTRGNativeAd) {
guard let banner = ad.banner else { return }
+ adType = .native
MTRGNativeAd.loadImage(banner.icon, to: adIconImageView)
@@ -188,6 +216,7 @@ final class AdBanner: UITableViewCell {
private func configMopubBanner(ad: MopubBanner) {
mpNativeAd = ad.nativeAd
+ adType = .native
let adCallToActionButtons: [UIButton]
if state == .search {
@@ -216,6 +245,21 @@ final class AdBanner: UITableViewCell {
adPrivacyButton.isHidden = ad.privacyInfoURL == nil
}
+ private func configGoogleFallbackBanner(ad: GoogleFallbackBanner) {
+ adType = .fallback
+ fallbackAdView.subviews.forEach { $0.removeFromSuperview() }
+ fallbackAdView.addSubview(ad)
+ updateFallbackBannerLayout(ad: ad)
+ }
+
+ private func updateFallbackBannerLayout(ad: GoogleFallbackBanner) {
+ ad.width = fallbackAdView.width
+ fallbackAdViewHeight.constant = ad.dynamicSize.height
+ }
+
+ private func configGoogleNativeBanner(ad _: GoogleNativeBanner) {
+ }
+
private func refreshBannerIfNeeded() {
if let ad = nativeAd as? MTRGNativeAd {
let clickableView: UIView
diff --git a/iphone/Maps/UI/Ads/AdBanner.xib b/iphone/Maps/UI/Ads/AdBanner.xib
index 481d13b578..e7143623c2 100644
--- a/iphone/Maps/UI/Ads/AdBanner.xib
+++ b/iphone/Maps/UI/Ads/AdBanner.xib
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12118" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12086"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -14,144 +14,167 @@
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="WK2-gA-ocn" customClass="MWMAdBanner">
<rect key="frame" x="0.0" y="0.0" width="375" height="110"/>
<autoresizingMask key="autoresizingMask"/>
- <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="WK2-gA-ocn" id="f76-qn-ne4">
+ <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="WK2-gA-ocn" id="f76-qn-ne5">
<rect key="frame" x="0.0" y="0.0" width="375" height="109.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
- <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="EuF-Rm-DHQ">
- <rect key="frame" x="-40" y="8" width="40" height="40"/>
- <constraints>
- <constraint firstAttribute="width" constant="40" id="dih-tk-IV1"/>
- <constraint firstAttribute="height" constant="40" id="eTa-1E-6Of"/>
- </constraints>
- </imageView>
- <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zWu-Gh-Vf7">
- <rect key="frame" x="16" y="10" width="20" height="12"/>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="f76-qn-ne4">
+ <rect key="frame" x="0.0" y="0.0" width="375" height="109.5"/>
<subviews>
- <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Ads" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iWR-j0-gpt">
- <rect key="frame" x="0.0" y="0.0" width="20" height="12"/>
- <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
- <fontDescription key="fontDescription" type="system" weight="medium" pointSize="8"/>
- <color key="textColor" red="1" green="0.98431372549019602" blue="0.94901960784313721" alpha="1" colorSpace="calibratedRGB"/>
+ <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="EuF-Rm-DHQ">
+ <rect key="frame" x="-40" y="8" width="40" height="40"/>
+ <constraints>
+ <constraint firstAttribute="width" constant="40" id="dih-tk-IV1"/>
+ <constraint firstAttribute="height" constant="40" id="eTa-1E-6Of"/>
+ </constraints>
+ </imageView>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zWu-Gh-Vf7">
+ <rect key="frame" x="16" y="10" width="20" height="12"/>
+ <subviews>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Ads" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iWR-j0-gpt">
+ <rect key="frame" x="0.0" y="0.0" width="20" height="12"/>
+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
+ <fontDescription key="fontDescription" type="system" weight="medium" pointSize="8"/>
+ <color key="textColor" red="1" green="0.98431372549019602" blue="0.94901960784313721" alpha="1" colorSpace="calibratedRGB"/>
+ <nil key="highlightedColor"/>
+ </label>
+ </subviews>
+ <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.23999999999999999" colorSpace="calibratedRGB"/>
+ <constraints>
+ <constraint firstItem="iWR-j0-gpt" firstAttribute="top" secondItem="zWu-Gh-Vf7" secondAttribute="top" id="1Ar-tP-Uoj"/>
+ <constraint firstAttribute="width" constant="20" id="TMB-lh-n1g"/>
+ <constraint firstAttribute="bottom" secondItem="iWR-j0-gpt" secondAttribute="bottom" id="j0v-gq-9l0"/>
+ <constraint firstAttribute="trailing" secondItem="iWR-j0-gpt" secondAttribute="trailing" id="jDy-yc-aSX"/>
+ <constraint firstAttribute="height" constant="12" id="mwW-Ni-one"/>
+ <constraint firstItem="iWR-j0-gpt" firstAttribute="leading" secondItem="zWu-Gh-Vf7" secondAttribute="leading" id="zek-Of-Clw"/>
+ </constraints>
+ </view>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="300" text="Delivery Club" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kIR-cO-v6L">
+ <rect key="frame" x="16" y="8" width="270" height="15"/>
+ <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="12"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.59999999999999998" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="string" keyPath="fontName" value="bold12"/>
+ <userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackSecondaryText"/>
+ </userDefinedRuntimeAttributes>
</label>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="TopLeft" horizontalHuggingPriority="451" verticalHuggingPriority="249" horizontalCompressionResistancePriority="249" text="Как " textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ev3-yY-ql1">
+ <rect key="frame" x="16" y="27" width="270" height="74.5"/>
+ <fontDescription key="fontDescription" type="system" pointSize="12"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.59999999999999998" colorSpace="calibratedRGB"/>
+ <nil key="highlightedColor"/>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular12"/>
+ <userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackSecondaryText"/>
+ </userDefinedRuntimeAttributes>
+ </label>
+ <button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="551" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9qA-JC-fkn">
+ <rect key="frame" x="290" y="18" width="69" height="24"/>
+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="64" id="N7a-ng-e6p"/>
+ <constraint firstAttribute="height" constant="24" id="XME-fd-3O8"/>
+ </constraints>
+ <fontDescription key="fontDescription" type="system" pointSize="12"/>
+ <inset key="contentEdgeInsets" minX="8" minY="0.0" maxX="8" maxY="0.0"/>
+ <state key="normal" title="Заказать">
+ <color key="titleColor" red="0.59999999999999998" green="0.58823529411764708" blue="0.56862745098039214" alpha="0.40000000000000002" colorSpace="calibratedRGB"/>
+ </state>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular12"/>
+ <userDefinedRuntimeAttribute type="string" keyPath="textColorName" value="blackSecondaryText"/>
+ <userDefinedRuntimeAttribute type="color" keyPath="layer.borderUIColor">
+ <color key="value" red="0.0" green="0.0" blue="0.0" alpha="0.59999999999999998" colorSpace="calibratedRGB"/>
+ </userDefinedRuntimeAttribute>
+ <userDefinedRuntimeAttribute type="number" keyPath="layer.borderWidth">
+ <integer key="value" value="1"/>
+ </userDefinedRuntimeAttribute>
+ <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
+ <integer key="value" value="4"/>
+ </userDefinedRuntimeAttribute>
+ </userDefinedRuntimeAttributes>
+ </button>
+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NKM-3R-3g1">
+ <rect key="frame" x="0.0" y="109.5" width="375" height="36"/>
+ <color key="backgroundColor" red="0.95294117647058818" green="0.92156862745098034" blue="0.85490196078431369" alpha="1" colorSpace="calibratedRGB"/>
+ <constraints>
+ <constraint firstAttribute="height" constant="36" id="JMM-je-O9e"/>
+ </constraints>
+ <state key="normal" title="Заказать">
+ <color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="0.40000000000000002" colorSpace="calibratedRGB"/>
+ </state>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular15"/>
+ <userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="bannerButtonBackground"/>
+ <userDefinedRuntimeAttribute type="string" keyPath="textColorName" value="blackSecondaryText"/>
+ </userDefinedRuntimeAttributes>
+ </button>
+ <button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="54O-iN-1Gg">
+ <rect key="frame" x="0.0" y="0.0" width="375" height="109.5"/>
+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
+ </button>
+ <button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="So8-wM-Cgz">
+ <rect key="frame" x="14" y="8" width="24" height="16"/>
+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
+ <connections>
+ <action selector="privacyAction" destination="WK2-gA-ocn" eventType="touchUpInside" id="ma2-uV-7hH"/>
+ </connections>
+ </button>
</subviews>
- <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.23999999999999999" colorSpace="calibratedRGB"/>
+ <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
- <constraint firstItem="iWR-j0-gpt" firstAttribute="top" secondItem="zWu-Gh-Vf7" secondAttribute="top" id="1Ar-tP-Uoj"/>
- <constraint firstAttribute="width" constant="20" id="TMB-lh-n1g"/>
- <constraint firstAttribute="bottom" secondItem="iWR-j0-gpt" secondAttribute="bottom" id="j0v-gq-9l0"/>
- <constraint firstAttribute="trailing" secondItem="iWR-j0-gpt" secondAttribute="trailing" id="jDy-yc-aSX"/>
- <constraint firstAttribute="height" constant="12" id="mwW-Ni-one"/>
- <constraint firstItem="iWR-j0-gpt" firstAttribute="leading" secondItem="zWu-Gh-Vf7" secondAttribute="leading" id="zek-Of-Clw"/>
+ <constraint firstAttribute="trailing" secondItem="9qA-JC-fkn" secondAttribute="leading" priority="250" id="5CH-Fo-S70"/>
+ <constraint firstAttribute="bottom" secondItem="Ev3-yY-ql1" secondAttribute="bottom" priority="500" constant="8" id="FJI-xF-QTM"/>
+ <constraint firstItem="NKM-3R-3g1" firstAttribute="top" relation="greaterThanOrEqual" secondItem="EuF-Rm-DHQ" secondAttribute="bottom" constant="8" id="Fjs-IQ-LQv"/>
+ <constraint firstItem="Ev3-yY-ql1" firstAttribute="top" secondItem="kIR-cO-v6L" secondAttribute="bottom" priority="250" constant="8" id="HHb-Vh-rIl"/>
+ <constraint firstItem="EuF-Rm-DHQ" firstAttribute="trailing" secondItem="f76-qn-ne4" secondAttribute="leading" priority="500" id="HLI-Zw-ETh"/>
+ <constraint firstItem="54O-iN-1Gg" firstAttribute="top" secondItem="f76-qn-ne4" secondAttribute="top" id="JWc-kJ-RaK"/>
+ <constraint firstItem="EuF-Rm-DHQ" firstAttribute="top" secondItem="f76-qn-ne4" secondAttribute="top" constant="8" id="KEp-1t-yK0"/>
+ <constraint firstItem="NKM-3R-3g1" firstAttribute="leading" secondItem="f76-qn-ne4" secondAttribute="leading" id="Ls8-rz-N1Q"/>
+ <constraint firstItem="Ev3-yY-ql1" firstAttribute="top" secondItem="kIR-cO-v6L" secondAttribute="bottom" priority="700" constant="4" id="NmE-r2-ZNA"/>
+ <constraint firstAttribute="trailing" secondItem="kIR-cO-v6L" secondAttribute="trailing" priority="250" constant="16" id="POq-M6-rLU"/>
+ <constraint firstItem="zWu-Gh-Vf7" firstAttribute="top" secondItem="kIR-cO-v6L" secondAttribute="top" constant="2" id="Q0s-7L-aih"/>
+ <constraint firstAttribute="trailing" secondItem="54O-iN-1Gg" secondAttribute="trailing" id="S6I-ea-HJN"/>
+ <constraint firstItem="9qA-JC-fkn" firstAttribute="leading" secondItem="Ev3-yY-ql1" secondAttribute="trailing" priority="500" constant="4" id="YNA-Lu-LXQ"/>
+ <constraint firstItem="kIR-cO-v6L" firstAttribute="leading" secondItem="zWu-Gh-Vf7" secondAttribute="leading" id="ZVP-Gs-m00"/>
+ <constraint firstAttribute="trailing" secondItem="NKM-3R-3g1" secondAttribute="trailing" id="ZiW-Tk-SOB"/>
+ <constraint firstItem="kIR-cO-v6L" firstAttribute="top" secondItem="f76-qn-ne4" secondAttribute="top" constant="8" id="ajZ-XY-N1h"/>
+ <constraint firstItem="So8-wM-Cgz" firstAttribute="bottom" secondItem="zWu-Gh-Vf7" secondAttribute="bottom" constant="2" id="akC-Fs-8Iv"/>
+ <constraint firstAttribute="trailing" secondItem="9qA-JC-fkn" secondAttribute="trailing" priority="500" constant="16" id="dww-N9-1tY"/>
+ <constraint firstItem="Ev3-yY-ql1" firstAttribute="trailing" secondItem="kIR-cO-v6L" secondAttribute="trailing" id="eM3-Nv-zVj"/>
+ <constraint firstItem="So8-wM-Cgz" firstAttribute="top" secondItem="zWu-Gh-Vf7" secondAttribute="top" constant="-2" id="fNs-FC-pga"/>
+ <constraint firstItem="EuF-Rm-DHQ" firstAttribute="leading" secondItem="f76-qn-ne4" secondAttribute="leading" priority="250" constant="16" id="gJI-DA-6rn"/>
+ <constraint firstItem="54O-iN-1Gg" firstAttribute="leading" secondItem="f76-qn-ne4" secondAttribute="leading" id="ge7-AI-110"/>
+ <constraint firstItem="NKM-3R-3g1" firstAttribute="top" secondItem="Ev3-yY-ql1" secondAttribute="bottom" constant="8" id="hn7-T4-7Zo"/>
+ <constraint firstAttribute="bottom" secondItem="NKM-3R-3g1" secondAttribute="bottom" priority="250" id="hzn-4Y-A0H"/>
+ <constraint firstItem="So8-wM-Cgz" firstAttribute="leading" secondItem="zWu-Gh-Vf7" secondAttribute="leading" constant="-2" id="sAg-zL-vMW"/>
+ <constraint firstAttribute="bottom" secondItem="54O-iN-1Gg" secondAttribute="bottom" id="tOj-8H-AsH"/>
+ <constraint firstItem="Ev3-yY-ql1" firstAttribute="leading" secondItem="zWu-Gh-Vf7" secondAttribute="leading" id="tVH-Tk-6D6"/>
+ <constraint firstItem="9qA-JC-fkn" firstAttribute="top" secondItem="f76-qn-ne4" secondAttribute="top" constant="18" id="u8g-fp-l2o"/>
+ <constraint firstItem="zWu-Gh-Vf7" firstAttribute="leading" secondItem="f76-qn-ne4" secondAttribute="leading" priority="600" constant="16" id="vlX-zx-nfP"/>
+ <constraint firstItem="zWu-Gh-Vf7" firstAttribute="leading" secondItem="EuF-Rm-DHQ" secondAttribute="trailing" priority="250" constant="8" id="w5K-BT-1ED"/>
+ <constraint firstItem="So8-wM-Cgz" firstAttribute="trailing" secondItem="zWu-Gh-Vf7" secondAttribute="trailing" constant="2" id="zGz-Sf-G1b"/>
</constraints>
</view>
- <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="300" text="Delivery Club" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kIR-cO-v6L">
- <rect key="frame" x="16" y="8" width="270" height="15"/>
- <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="12"/>
- <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.59999999999999998" colorSpace="calibratedRGB"/>
- <nil key="highlightedColor"/>
- <userDefinedRuntimeAttributes>
- <userDefinedRuntimeAttribute type="string" keyPath="fontName" value="bold12"/>
- <userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackSecondaryText"/>
- </userDefinedRuntimeAttributes>
- </label>
- <label opaque="NO" userInteractionEnabled="NO" contentMode="TopLeft" horizontalHuggingPriority="451" verticalHuggingPriority="249" horizontalCompressionResistancePriority="249" text="Как " textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ev3-yY-ql1">
- <rect key="frame" x="16" y="27" width="270" height="74.5"/>
- <fontDescription key="fontDescription" type="system" pointSize="12"/>
- <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.59999999999999998" colorSpace="calibratedRGB"/>
- <nil key="highlightedColor"/>
- <userDefinedRuntimeAttributes>
- <userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular12"/>
- <userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackSecondaryText"/>
- </userDefinedRuntimeAttributes>
- </label>
- <button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="551" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9qA-JC-fkn">
- <rect key="frame" x="290" y="18" width="69" height="24"/>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ucm-4E-iB7">
+ <rect key="frame" x="12" y="0.0" width="351" height="109.5"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
- <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="64" id="N7a-ng-e6p"/>
- <constraint firstAttribute="height" constant="24" id="XME-fd-3O8"/>
- </constraints>
- <fontDescription key="fontDescription" type="system" pointSize="12"/>
- <inset key="contentEdgeInsets" minX="8" minY="0.0" maxX="8" maxY="0.0"/>
- <state key="normal" title="Заказать">
- <color key="titleColor" red="0.59999999999999998" green="0.58823529411764708" blue="0.56862745098039214" alpha="0.40000000000000002" colorSpace="calibratedRGB"/>
- </state>
- <userDefinedRuntimeAttributes>
- <userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular12"/>
- <userDefinedRuntimeAttribute type="string" keyPath="textColorName" value="blackSecondaryText"/>
- <userDefinedRuntimeAttribute type="color" keyPath="layer.borderUIColor">
- <color key="value" red="0.0" green="0.0" blue="0.0" alpha="0.59999999999999998" colorSpace="calibratedRGB"/>
- </userDefinedRuntimeAttribute>
- <userDefinedRuntimeAttribute type="number" keyPath="layer.borderWidth">
- <integer key="value" value="1"/>
- </userDefinedRuntimeAttribute>
- <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
- <integer key="value" value="4"/>
- </userDefinedRuntimeAttribute>
- </userDefinedRuntimeAttributes>
- </button>
- <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NKM-3R-3g1">
- <rect key="frame" x="0.0" y="109.5" width="375" height="36"/>
- <color key="backgroundColor" red="0.95294117647058818" green="0.92156862745098034" blue="0.85490196078431369" alpha="1" colorSpace="calibratedRGB"/>
- <constraints>
- <constraint firstAttribute="height" constant="36" id="JMM-je-O9e"/>
+ <constraint firstAttribute="height" constant="109.5" id="9T6-aq-miV"/>
</constraints>
- <state key="normal" title="Заказать">
- <color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="0.40000000000000002" colorSpace="calibratedRGB"/>
- </state>
- <userDefinedRuntimeAttributes>
- <userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular15"/>
- <userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="bannerButtonBackground"/>
- <userDefinedRuntimeAttribute type="string" keyPath="textColorName" value="blackSecondaryText"/>
- </userDefinedRuntimeAttributes>
- </button>
- <button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="54O-iN-1Gg">
- <rect key="frame" x="0.0" y="0.0" width="375" height="109.5"/>
- <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
- </button>
- <button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="So8-wM-Cgz">
- <rect key="frame" x="14" y="8" width="24" height="16"/>
- <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
- <connections>
- <action selector="privacyAction" destination="WK2-gA-ocn" eventType="touchUpInside" id="ma2-uV-7hH"/>
- </connections>
- </button>
+ </view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
- <constraint firstAttribute="trailing" secondItem="9qA-JC-fkn" secondAttribute="leading" priority="250" id="5CH-Fo-S70"/>
- <constraint firstAttribute="bottom" secondItem="Ev3-yY-ql1" secondAttribute="bottom" priority="500" constant="8" id="FJI-xF-QTM"/>
- <constraint firstItem="NKM-3R-3g1" firstAttribute="top" relation="greaterThanOrEqual" secondItem="EuF-Rm-DHQ" secondAttribute="bottom" constant="8" id="Fjs-IQ-LQv"/>
- <constraint firstItem="Ev3-yY-ql1" firstAttribute="top" secondItem="kIR-cO-v6L" secondAttribute="bottom" priority="250" constant="8" id="HHb-Vh-rIl"/>
- <constraint firstItem="EuF-Rm-DHQ" firstAttribute="trailing" secondItem="f76-qn-ne4" secondAttribute="leading" priority="500" id="HLI-Zw-ETh"/>
- <constraint firstItem="54O-iN-1Gg" firstAttribute="top" secondItem="f76-qn-ne4" secondAttribute="top" id="JWc-kJ-RaK"/>
- <constraint firstItem="EuF-Rm-DHQ" firstAttribute="top" secondItem="f76-qn-ne4" secondAttribute="top" constant="8" id="KEp-1t-yK0"/>
- <constraint firstItem="NKM-3R-3g1" firstAttribute="leading" secondItem="f76-qn-ne4" secondAttribute="leading" id="Ls8-rz-N1Q"/>
- <constraint firstItem="Ev3-yY-ql1" firstAttribute="top" secondItem="kIR-cO-v6L" secondAttribute="bottom" priority="700" constant="4" id="NmE-r2-ZNA"/>
- <constraint firstAttribute="trailing" secondItem="kIR-cO-v6L" secondAttribute="trailing" priority="250" constant="16" id="POq-M6-rLU"/>
- <constraint firstItem="zWu-Gh-Vf7" firstAttribute="top" secondItem="kIR-cO-v6L" secondAttribute="top" constant="2" id="Q0s-7L-aih"/>
- <constraint firstAttribute="trailing" secondItem="54O-iN-1Gg" secondAttribute="trailing" id="S6I-ea-HJN"/>
- <constraint firstItem="9qA-JC-fkn" firstAttribute="leading" secondItem="Ev3-yY-ql1" secondAttribute="trailing" priority="500" constant="4" id="YNA-Lu-LXQ"/>
- <constraint firstItem="kIR-cO-v6L" firstAttribute="leading" secondItem="zWu-Gh-Vf7" secondAttribute="leading" id="ZVP-Gs-m00"/>
- <constraint firstAttribute="trailing" secondItem="NKM-3R-3g1" secondAttribute="trailing" id="ZiW-Tk-SOB"/>
- <constraint firstItem="kIR-cO-v6L" firstAttribute="top" secondItem="f76-qn-ne4" secondAttribute="top" constant="8" id="ajZ-XY-N1h"/>
- <constraint firstItem="So8-wM-Cgz" firstAttribute="bottom" secondItem="zWu-Gh-Vf7" secondAttribute="bottom" constant="2" id="akC-Fs-8Iv"/>
- <constraint firstAttribute="trailing" secondItem="9qA-JC-fkn" secondAttribute="trailing" priority="500" constant="16" id="dww-N9-1tY"/>
- <constraint firstItem="Ev3-yY-ql1" firstAttribute="trailing" secondItem="kIR-cO-v6L" secondAttribute="trailing" id="eM3-Nv-zVj"/>
- <constraint firstItem="So8-wM-Cgz" firstAttribute="top" secondItem="zWu-Gh-Vf7" secondAttribute="top" constant="-2" id="fNs-FC-pga"/>
- <constraint firstItem="EuF-Rm-DHQ" firstAttribute="leading" secondItem="f76-qn-ne4" secondAttribute="leading" priority="250" constant="16" id="gJI-DA-6rn"/>
- <constraint firstItem="54O-iN-1Gg" firstAttribute="leading" secondItem="f76-qn-ne4" secondAttribute="leading" id="ge7-AI-110"/>
- <constraint firstItem="NKM-3R-3g1" firstAttribute="top" secondItem="Ev3-yY-ql1" secondAttribute="bottom" constant="8" id="hn7-T4-7Zo"/>
- <constraint firstAttribute="bottom" secondItem="NKM-3R-3g1" secondAttribute="bottom" priority="250" id="hzn-4Y-A0H"/>
- <constraint firstItem="So8-wM-Cgz" firstAttribute="leading" secondItem="zWu-Gh-Vf7" secondAttribute="leading" constant="-2" id="sAg-zL-vMW"/>
- <constraint firstAttribute="bottom" secondItem="54O-iN-1Gg" secondAttribute="bottom" id="tOj-8H-AsH"/>
- <constraint firstItem="Ev3-yY-ql1" firstAttribute="leading" secondItem="zWu-Gh-Vf7" secondAttribute="leading" id="tVH-Tk-6D6"/>
- <constraint firstItem="9qA-JC-fkn" firstAttribute="top" secondItem="f76-qn-ne4" secondAttribute="top" constant="18" id="u8g-fp-l2o"/>
- <constraint firstItem="zWu-Gh-Vf7" firstAttribute="leading" secondItem="f76-qn-ne4" secondAttribute="leading" priority="600" constant="16" id="vlX-zx-nfP"/>
- <constraint firstItem="zWu-Gh-Vf7" firstAttribute="leading" secondItem="EuF-Rm-DHQ" secondAttribute="trailing" priority="250" constant="8" id="w5K-BT-1ED"/>
- <constraint firstItem="So8-wM-Cgz" firstAttribute="trailing" secondItem="zWu-Gh-Vf7" secondAttribute="trailing" constant="2" id="zGz-Sf-G1b"/>
+ <constraint firstItem="f76-qn-ne4" firstAttribute="top" secondItem="f76-qn-ne5" secondAttribute="top" id="5de-Xp-prZ"/>
+ <constraint firstAttribute="bottom" secondItem="f76-qn-ne4" secondAttribute="bottom" id="7c6-rR-ue5"/>
+ <constraint firstAttribute="trailing" secondItem="f76-qn-ne4" secondAttribute="trailing" id="9IQ-Gl-EXk"/>
+ <constraint firstItem="f76-qn-ne4" firstAttribute="leading" secondItem="f76-qn-ne5" secondAttribute="leading" id="Bht-aF-E0n"/>
+ <constraint firstAttribute="bottom" secondItem="ucm-4E-iB7" secondAttribute="bottom" id="DdI-tM-5Yy"/>
+ <constraint firstAttribute="trailing" secondItem="ucm-4E-iB7" secondAttribute="trailing" constant="12" id="XfZ-ns-v6e"/>
+ <constraint firstItem="ucm-4E-iB7" firstAttribute="top" secondItem="f76-qn-ne5" secondAttribute="top" id="cA5-OB-yRM"/>
+ <constraint firstItem="ucm-4E-iB7" firstAttribute="leading" secondItem="f76-qn-ne5" secondAttribute="leading" constant="12" id="w4s-WH-a6c"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="bannerBackground"/>
@@ -167,6 +190,11 @@
<outlet property="adIconImageView" destination="EuF-Rm-DHQ" id="Edf-Ak-VAy"/>
<outlet property="adPrivacyButton" destination="So8-wM-Cgz" id="tY6-tl-gGx"/>
<outlet property="adTitleLabel" destination="kIR-cO-v6L" id="OOh-tX-yBM"/>
+ <outlet property="fallbackAdView" destination="ucm-4E-iB7" id="dOb-SQ-pex"/>
+ <outlet property="fallbackAdViewBottom" destination="DdI-tM-5Yy" id="Tyv-gy-gf7"/>
+ <outlet property="fallbackAdViewHeight" destination="9T6-aq-miV" id="gze-UL-E6b"/>
+ <outlet property="nativeAdView" destination="f76-qn-ne4" id="9hb-za-zgw"/>
+ <outlet property="nativeAdViewBottom" destination="7c6-rR-ue5" id="8x7-ar-cxz"/>
<outletCollection property="detailedModeConstraints" destination="w5K-BT-1ED" collectionClass="NSMutableArray" id="Lv4-E4-dYV"/>
<outletCollection property="detailedModeConstraints" destination="POq-M6-rLU" collectionClass="NSMutableArray" id="rqF-JD-SZe"/>
<outletCollection property="detailedModeConstraints" destination="gJI-DA-6rn" collectionClass="NSMutableArray" id="Bf5-KV-Yq1"/>
diff --git a/iphone/Maps/UI/Search/TableView/MWMSearchTableViewController.mm b/iphone/Maps/UI/Search/TableView/MWMSearchTableViewController.mm
index 165b97c084..4fe7fee391 100644
--- a/iphone/Maps/UI/Search/TableView/MWMSearchTableViewController.mm
+++ b/iphone/Maps/UI/Search/TableView/MWMSearchTableViewController.mm
@@ -5,7 +5,7 @@
#import "Statistics.h"
#import "SwiftBridge.h"
-@interface MWMSearchTableViewController ()<UITableViewDataSource, UITableViewDelegate>
+@interface MWMSearchTableViewController ()<UITableViewDataSource, UITableViewDelegate, MWMGoogleFallbackBannerDynamicSizeDelegate>
@property(weak, nonatomic) IBOutlet UITableView * tableView;
@@ -100,10 +100,17 @@
}
case MWMSearchItemTypeMopub:
case MWMSearchItemTypeFacebook:
+ case MWMSearchItemTypeGoogle:
{
- auto cell = static_cast<MWMAdBanner *>(
- [tableView dequeueReusableCellWithCellClass:[MWMAdBanner class] indexPath:indexPath]);
+ auto cell = static_cast<MWMAdBanner *>([tableView dequeueReusableCellWithCellClass:[MWMAdBanner class] indexPath:indexPath]);
auto ad = [MWMSearch adWithContainerIndex:containerIndex];
+ if ([ad isKindOfClass:[MWMGoogleFallbackBanner class]])
+ {
+ auto fallbackAd = static_cast<MWMGoogleFallbackBanner *>(ad);
+ fallbackAd.cellIndexPath = indexPath;
+ fallbackAd.dynamicSizeDelegate = self;
+ [cell configWithAd:fallbackAd containerType:MWMAdBannerContainerTypeSearch];
+ }
[cell configWithAd:ad containerType:MWMAdBannerContainerTypeSearch];
return cell;
}
@@ -120,6 +127,13 @@
}
}
+#pragma mark - MWMGoogleFallbackBannerDynamicSizeDelegate
+
+- (void)dynamicSizeUpdatedWithBanner:(MWMGoogleFallbackBanner * _Nonnull)banner
+{
+ [self.tableView reloadRowsAtIndexPaths:@[banner.cellIndexPath] withRowAnimation:UITableViewRowAnimationFade];
+}
+
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
@@ -138,7 +152,8 @@
break;
}
case MWMSearchItemTypeMopub:
- case MWMSearchItemTypeFacebook: break;
+ case MWMSearchItemTypeFacebook:
+ case MWMSearchItemTypeGoogle: break;
case MWMSearchItemTypeSuggestion:
{
auto const & suggestion = [MWMSearch resultWithContainerIndex:containerIndex];