forked from organicmaps/organicmaps
[iOS] Ads removal subscription
This commit is contained in:
parent
ead6f849b5
commit
7ba17e82f6
37 changed files with 1474 additions and 60 deletions
iphone/Maps
Bookmarks/Catalog
Bridging-Header.hCategories
Classes
Components/Modal
AlertPresentationAnimator.swiftAlertPresentationController.swiftFadeInAnimatedTransitioning.swiftFadeOutAnimatedTransitioning.swiftFadeTransitioning.swift
MapViewController.hMapViewController.mmMapsAppDelegate.mmRemoveAds
Core/Subscriptions
Images.xcassets
Maps.xcodeproj
UI
Ads
PlacePage/PlacePageLayout/Preview
Search/TableView
|
@ -1,5 +1,5 @@
|
|||
class BookmarksLoadedViewController: UIViewController {
|
||||
private let transitioning = AlertTransitioning()
|
||||
private let transitioning = FadeTransitioning<AlertPresentationController>()
|
||||
@objc var onViewBlock: MWMVoidBlock?
|
||||
@objc var onCancelBlock: MWMVoidBlock?
|
||||
|
||||
|
|
|
@ -77,3 +77,4 @@
|
|||
#import "MWMCatalogCategory.h"
|
||||
#import "MWMCatalogCommon.h"
|
||||
#import "MWMEye.h"
|
||||
#import "MWMPurchaseManager.h"
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
+ (UIColor *)ratingYellow;
|
||||
+ (UIColor *)ratingLightGreen;
|
||||
+ (UIColor *)ratingGreen;
|
||||
+ (UIColor *)border;
|
||||
|
||||
+ (UIColor *)colorWithName:(NSString *)colorName;
|
||||
|
||||
|
|
|
@ -50,7 +50,8 @@ NSDictionary<NSString *, UIColor *> * night = @{
|
|||
@"blackOpaque": [UIColor colorWithWhite:1. alpha:alpha04],
|
||||
@"toastBackground": [UIColor colorWithWhite:0. alpha:alpha87],
|
||||
@"statusBarBackground": [UIColor colorWithWhite:0. alpha:alpha32],
|
||||
@"bannerBackground" : [UIColor colorWithRed:scaled(71) green:scaled(75) blue:scaled(79) alpha:alpha100]
|
||||
@"bannerBackground" : [UIColor colorWithRed:scaled(71) green:scaled(75) blue:scaled(79) alpha:alpha100],
|
||||
@"border" : [UIColor colorWithWhite:1. alpha:alpha04]
|
||||
};
|
||||
|
||||
NSDictionary<NSString *, UIColor *> * day = @{
|
||||
|
@ -97,7 +98,8 @@ NSDictionary<NSString *, UIColor *> * day = @{
|
|||
@"blackOpaque" : [UIColor colorWithWhite:0. alpha:alpha04],
|
||||
@"toastBackground" : [UIColor colorWithWhite:1. alpha:alpha87],
|
||||
@"statusBarBackground" : [UIColor colorWithWhite:1. alpha:alpha36],
|
||||
@"bannerBackground" : [UIColor colorWithRed:scaled(249) green:scaled(251) blue:scaled(231) alpha:alpha100]
|
||||
@"bannerBackground" : [UIColor colorWithRed:scaled(249) green:scaled(251) blue:scaled(231) alpha:alpha100],
|
||||
@"border" : [UIColor colorWithWhite:0. alpha:alpha04]
|
||||
};
|
||||
|
||||
UIColor * color(SEL cmd)
|
||||
|
@ -328,6 +330,11 @@ UIColor * color(SEL cmd)
|
|||
return color(_cmd);
|
||||
}
|
||||
|
||||
+ (UIColor *)border
|
||||
{
|
||||
return color(_cmd);
|
||||
}
|
||||
|
||||
+ (UIColor *)bannerButtonBackground
|
||||
{
|
||||
return [UIColor blackDividers];
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
final class AlertPresentationAnimator: NSObject, UIViewControllerAnimatedTransitioning {
|
||||
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
|
||||
return kDefaultAnimationDuration
|
||||
}
|
||||
|
||||
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
|
||||
guard let toVC = transitionContext.viewController(forKey: .to) else { return }
|
||||
|
||||
let containerView = transitionContext.containerView
|
||||
let finalFrame = transitionContext.finalFrame(for: toVC)
|
||||
containerView.addSubview(toVC.view)
|
||||
|
||||
toVC.view.alpha = 0
|
||||
toVC.view.center = containerView.center
|
||||
toVC.view.frame = finalFrame
|
||||
toVC.view.autoresizingMask = [.flexibleLeftMargin, .flexibleTopMargin, .flexibleRightMargin, .flexibleBottomMargin]
|
||||
UIView.animate(withDuration: transitionDuration(using: transitionContext),
|
||||
animations: {
|
||||
toVC.view.alpha = 1
|
||||
}) { transitionContext.completeTransition($0) }
|
||||
}
|
||||
}
|
|
@ -10,5 +10,18 @@ final class AlertPresentationController: DimmedModalPresentationController {
|
|||
super.presentationTransitionWillBegin()
|
||||
presentedViewController.view.layer.cornerRadius = 12
|
||||
presentedViewController.view.clipsToBounds = true
|
||||
guard let containerView = containerView, let presentedView = presentedView else { return }
|
||||
containerView.addSubview(presentedView)
|
||||
presentedView.center = containerView.center
|
||||
presentedView.frame = frameOfPresentedViewInContainerView
|
||||
presentedView.autoresizingMask = [.flexibleLeftMargin, .flexibleTopMargin, .flexibleRightMargin, .flexibleBottomMargin]
|
||||
}
|
||||
|
||||
override func dismissalTransitionDidEnd(_ completed: Bool) {
|
||||
super.presentationTransitionDidEnd(completed)
|
||||
guard let presentedView = presentedView else { return }
|
||||
if completed {
|
||||
presentedView.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
final class FadeInAnimatedTransitioning: NSObject, UIViewControllerAnimatedTransitioning {
|
||||
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
|
||||
return kDefaultAnimationDuration
|
||||
}
|
||||
|
||||
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
|
||||
guard let presentedView = transitionContext.view(forKey: .to) else { return }
|
||||
|
||||
presentedView.alpha = 0
|
||||
UIView.animate(withDuration: transitionDuration(using: transitionContext),
|
||||
animations: {
|
||||
presentedView.alpha = 1
|
||||
}) { transitionContext.completeTransition($0) }
|
||||
}
|
||||
}
|
|
@ -1,15 +1,14 @@
|
|||
final class AlertDismissalAnimator: NSObject, UIViewControllerAnimatedTransitioning {
|
||||
final class FadeOutAnimatedTransitioning: NSObject, UIViewControllerAnimatedTransitioning {
|
||||
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
|
||||
return kDefaultAnimationDuration
|
||||
}
|
||||
|
||||
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
|
||||
guard let fromVC = transitionContext.viewController(forKey: .from) else { return }
|
||||
guard let presentedView = transitionContext.view(forKey: .from) else { return }
|
||||
UIView.animate(withDuration: transitionDuration(using: transitionContext),
|
||||
animations: {
|
||||
fromVC.view.alpha = 0
|
||||
presentedView.alpha = 0
|
||||
}) { finished in
|
||||
fromVC.view.removeFromSuperview()
|
||||
transitionContext.completeTransition(finished)
|
||||
}
|
||||
}
|
|
@ -1,17 +1,19 @@
|
|||
class AlertTransitioning: NSObject, UIViewControllerTransitioningDelegate {
|
||||
class FadeTransitioning<T: UIPresentationController>: NSObject, UIViewControllerTransitioningDelegate {
|
||||
let presentedTransitioning = FadeInAnimatedTransitioning()
|
||||
let dismissedTransitioning = FadeOutAnimatedTransitioning()
|
||||
func animationController(forPresented presented: UIViewController,
|
||||
presenting: UIViewController,
|
||||
source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
|
||||
return AlertPresentationAnimator()
|
||||
return presentedTransitioning
|
||||
}
|
||||
|
||||
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
|
||||
return AlertDismissalAnimator()
|
||||
return dismissedTransitioning
|
||||
}
|
||||
|
||||
func presentationController(forPresented presented: UIViewController,
|
||||
presenting: UIViewController?,
|
||||
source: UIViewController) -> UIPresentationController? {
|
||||
return AlertPresentationController(presentedViewController: presented, presenting: presenting)
|
||||
return T(presentedViewController: presented, presenting: presenting)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
final class RemoveAdsPresentationController: DimmedModalPresentationController {
|
||||
override func presentationTransitionWillBegin() {
|
||||
super.presentationTransitionWillBegin()
|
||||
guard let containerView = containerView, let presentedView = presentedView else { return }
|
||||
presentedView.frame = containerView.bounds
|
||||
presentedView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||
containerView.addSubview(presentedView)
|
||||
presentedViewController.modalPresentationCapturesStatusBarAppearance = true
|
||||
presentedViewController.setNeedsStatusBarAppearanceUpdate()
|
||||
}
|
||||
|
||||
override func dismissalTransitionDidEnd(_ completed: Bool) {
|
||||
super.presentationTransitionDidEnd(completed)
|
||||
guard let presentedView = presentedView else { return }
|
||||
if completed {
|
||||
presentedView.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,6 +30,7 @@
|
|||
- (void)openCatalogDeeplink:(NSURL * _Nullable)deeplinkUrl animated:(BOOL)animated;
|
||||
- (void)searchText:(NSString *)text;
|
||||
|
||||
- (void)showRemoveAds;
|
||||
- (void)setPlacePageTopBound:(CGFloat)bound;
|
||||
|
||||
- (void)initialize;
|
||||
|
|
|
@ -78,7 +78,8 @@ BOOL gIsFirstMyPositionMode = YES;
|
|||
@end
|
||||
|
||||
@interface MapViewController ()<MWMFrameworkDrapeObserver, MWMFrameworkStorageObserver,
|
||||
MWMWelcomePageControllerProtocol, MWMKeyboardObserver>
|
||||
MWMWelcomePageControllerProtocol, MWMKeyboardObserver,
|
||||
RemoveAdsViewControllerDelegate>
|
||||
|
||||
@property(nonatomic, readwrite) MWMMapViewControlsManager * controlsManager;
|
||||
|
||||
|
@ -492,6 +493,13 @@ BOOL gIsFirstMyPositionMode = YES;
|
|||
[self.controlsManager searchText:text forInputLocale:[[AppInfo sharedInfo] languageId]];
|
||||
}
|
||||
|
||||
- (void)showRemoveAds
|
||||
{
|
||||
auto removeAds = [[RemoveAdsViewController alloc] init];
|
||||
removeAds.delegate = self;
|
||||
[self.navigationController presentViewController:removeAds animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)processMyPositionStateModeEvent:(MWMMyPositionMode)mode
|
||||
{
|
||||
[MWMLocationManager setMyPositionMode:mode];
|
||||
|
@ -531,6 +539,18 @@ BOOL gIsFirstMyPositionMode = YES;
|
|||
gIsFirstMyPositionMode = NO;
|
||||
}
|
||||
|
||||
#pragma mark - MWMRemoveAdsViewControllerDelegate
|
||||
|
||||
- (void)didCompleteSubscribtion:(RemoveAdsViewController *)viewController
|
||||
{
|
||||
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)didCancelSubscribtion:(RemoveAdsViewController *)viewController
|
||||
{
|
||||
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
#pragma mark - MWMFrameworkDrapeObserver
|
||||
|
||||
- (void)processViewportCountryEvent:(TCountryId const &)countryId
|
||||
|
|
|
@ -390,6 +390,7 @@ using namespace osm_auth_ios;
|
|||
if (@available(iOS 10, *))
|
||||
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
|
||||
|
||||
[[SubscriptionManager shared] validate];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
|
22
iphone/Maps/Core/Subscriptions/MWMPurchaseManager.h
Normal file
22
iphone/Maps/Core/Subscriptions/MWMPurchaseManager.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MWMValidationResult)
|
||||
{
|
||||
MWMValidationResultValid,
|
||||
MWMValidationResultNotValid,
|
||||
MWMValidationResultError,
|
||||
};
|
||||
|
||||
typedef void (^ValidateReceiptCallback)(NSString * _Nonnull serverId, MWMValidationResult validationResult);
|
||||
|
||||
@interface MWMPurchaseManager : NSObject
|
||||
|
||||
+ (NSString * _Nonnull)adsRemovalServerId;
|
||||
+ (NSArray<NSString *> * _Nonnull)productIds;
|
||||
+ (MWMPurchaseManager * _Nonnull)sharedManager;
|
||||
|
||||
- (void)validateReceipt:(NSString * _Nonnull)serverId
|
||||
callback:(ValidateReceiptCallback _Nonnull)callback;
|
||||
- (void)setAdsDisabled:(BOOL)disabled;
|
||||
|
||||
@end
|
136
iphone/Maps/Core/Subscriptions/MWMPurchaseManager.mm
Normal file
136
iphone/Maps/Core/Subscriptions/MWMPurchaseManager.mm
Normal file
|
@ -0,0 +1,136 @@
|
|||
#import "MWMPurchaseManager.h"
|
||||
|
||||
#include "Framework.h"
|
||||
#include "Private.h"
|
||||
|
||||
#import <StoreKit/StoreKit.h>
|
||||
|
||||
@interface MWMPurchaseManager() <SKRequestDelegate>
|
||||
|
||||
@property (nonatomic) BOOL didRefreshReceipt;
|
||||
@property (nonatomic, copy) ValidateReceiptCallback callback;
|
||||
@property (nonatomic) SKReceiptRefreshRequest *receiptRequest;
|
||||
@property (nonatomic, copy) NSString * serverId;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MWMPurchaseManager
|
||||
|
||||
+ (NSString *)adsRemovalServerId
|
||||
{
|
||||
return @(ADS_REMOVAL_SERVER_ID);
|
||||
}
|
||||
|
||||
+ (NSArray *)productIds
|
||||
{
|
||||
return @[@(ADS_REMOVAL_WEEKLY_PRODUCT_ID),
|
||||
@(ADS_REMOVAL_MONTHLY_PRODUCT_ID),
|
||||
@(ADS_REMOVAL_YEARLY_PRODUCT_ID)];
|
||||
}
|
||||
|
||||
+ (MWMPurchaseManager *)sharedManager
|
||||
{
|
||||
static MWMPurchaseManager *instance;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
instance = [[MWMPurchaseManager alloc] init];
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
|
||||
- (void)refreshReceipt
|
||||
{
|
||||
self.receiptRequest = [[SKReceiptRefreshRequest alloc] init];
|
||||
self.receiptRequest.delegate = self;
|
||||
[self.receiptRequest start];
|
||||
self.didRefreshReceipt = YES;
|
||||
}
|
||||
|
||||
- (void)validateReceipt:(NSString *)serverId callback:(ValidateReceiptCallback)callback
|
||||
{
|
||||
self.callback = callback;
|
||||
self.serverId = serverId;
|
||||
[self validateReceipt];
|
||||
}
|
||||
|
||||
- (void)validateReceipt
|
||||
{
|
||||
NSURL * receiptUrl = [NSBundle mainBundle].appStoreReceiptURL;
|
||||
NSData * receiptData = [NSData dataWithContentsOfURL:receiptUrl];
|
||||
|
||||
if (!receiptData)
|
||||
{
|
||||
[self noReceipt];
|
||||
return;
|
||||
}
|
||||
|
||||
GetFramework().GetPurchase()->SetValidationCallback([self](auto validationCode, auto const & validationInfo)
|
||||
{
|
||||
switch (validationCode)
|
||||
{
|
||||
case Purchase::ValidationCode::Verified:
|
||||
[self validReceipt];
|
||||
break;
|
||||
case Purchase::ValidationCode::NotVerified:
|
||||
[self invalidReceipt];
|
||||
break;
|
||||
case Purchase::ValidationCode::ServerError:
|
||||
[self serverError];
|
||||
break;
|
||||
}
|
||||
});
|
||||
Purchase::ValidationInfo vi;
|
||||
vi.m_receiptData = [receiptData base64EncodedStringWithOptions:0].UTF8String;
|
||||
vi.m_serverId = self.serverId.UTF8String;
|
||||
vi.m_vendorId = ADS_REMOVAL_VENDOR;
|
||||
GetFramework().GetPurchase()->Validate(vi, {} /* accessToken */);
|
||||
}
|
||||
|
||||
- (void)validReceipt
|
||||
{
|
||||
if (self.callback)
|
||||
self.callback(self.serverId, MWMValidationResultValid);
|
||||
}
|
||||
|
||||
- (void)noReceipt
|
||||
{
|
||||
if (self.callback)
|
||||
self.callback(self.serverId, MWMValidationResultNotValid);
|
||||
}
|
||||
|
||||
- (void)invalidReceipt
|
||||
{
|
||||
if (self.callback)
|
||||
self.callback(self.serverId, MWMValidationResultNotValid);
|
||||
}
|
||||
|
||||
- (void)serverError
|
||||
{
|
||||
if (self.callback)
|
||||
self.callback(self.serverId, MWMValidationResultError);
|
||||
}
|
||||
|
||||
- (void)appstoreError:(NSError *)error
|
||||
{
|
||||
if (self.callback)
|
||||
self.callback(self.serverId, MWMValidationResultError);
|
||||
}
|
||||
|
||||
- (void)setAdsDisabled:(BOOL)disabled
|
||||
{
|
||||
GetFramework().GetPurchase()->SetSubscriptionEnabled(SubscriptionType::RemoveAds, disabled);
|
||||
}
|
||||
|
||||
#pragma mark - SKRequestDelegate
|
||||
|
||||
- (void)requestDidFinish:(SKRequest *)request
|
||||
{
|
||||
[self validateReceipt];
|
||||
}
|
||||
|
||||
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error
|
||||
{
|
||||
[self appstoreError:error];
|
||||
}
|
||||
|
||||
@end
|
31
iphone/Maps/Core/Subscriptions/Subscription.swift
Normal file
31
iphone/Maps/Core/Subscriptions/Subscription.swift
Normal file
|
@ -0,0 +1,31 @@
|
|||
@objc enum SubscriptionPeriod: Int {
|
||||
case week
|
||||
case month
|
||||
case year
|
||||
case unknown
|
||||
}
|
||||
|
||||
@objc protocol ISubscription {
|
||||
var productId: String { get }
|
||||
var price: NSDecimalNumber? { get }
|
||||
var priceLocale: Locale? { get }
|
||||
var period: SubscriptionPeriod { get }
|
||||
}
|
||||
|
||||
class Subscription: ISubscription {
|
||||
public static let productIds = MWMPurchaseManager.productIds()
|
||||
private static let periodMap: [String: SubscriptionPeriod] = [productIds[0]: .week,
|
||||
productIds[1]: .month,
|
||||
productIds[2]: .year]
|
||||
var productId: String
|
||||
var period: SubscriptionPeriod
|
||||
var price: NSDecimalNumber?
|
||||
var priceLocale: Locale?
|
||||
|
||||
init(_ product: SKProduct) {
|
||||
productId = product.productIdentifier
|
||||
period = Subscription.periodMap[productId] ?? .unknown
|
||||
price = product.price
|
||||
priceLocale = product.priceLocale
|
||||
}
|
||||
}
|
142
iphone/Maps/Core/Subscriptions/SubscriptionManager.swift
Normal file
142
iphone/Maps/Core/Subscriptions/SubscriptionManager.swift
Normal file
|
@ -0,0 +1,142 @@
|
|||
@objc protocol SubscriptionManagerListener: AnyObject {
|
||||
func didFailToSubscribe(_ subscription: ISubscription, error: Error?)
|
||||
func didSubsribe(_ subscription: ISubscription)
|
||||
func didFailToValidate(_ subscription: ISubscription, error: Error?)
|
||||
func didDefer(_ subscription: ISubscription)
|
||||
func validationError()
|
||||
}
|
||||
|
||||
class SubscriptionManager: NSObject {
|
||||
typealias SuscriptionsCompletion = ([ISubscription]?, Error?) -> Void
|
||||
|
||||
@objc static var shared: SubscriptionManager = { return SubscriptionManager() }()
|
||||
|
||||
private let paymentQueue = SKPaymentQueue.default()
|
||||
|
||||
private var productsRequest: SKProductsRequest?
|
||||
private var subscriptionsComplection: SuscriptionsCompletion?
|
||||
private var products: [String: SKProduct]?
|
||||
private var pendingSubscription: ISubscription?
|
||||
private var listeners = NSHashTable<SubscriptionManagerListener>.weakObjects()
|
||||
|
||||
override private init() {
|
||||
super.init()
|
||||
paymentQueue.add(self)
|
||||
}
|
||||
|
||||
deinit {
|
||||
paymentQueue.remove(self)
|
||||
}
|
||||
|
||||
@objc static func canMakePayments() -> Bool {
|
||||
return SKPaymentQueue.canMakePayments()
|
||||
}
|
||||
|
||||
@objc func getAvailableSubscriptions(_ completion: @escaping SuscriptionsCompletion){
|
||||
subscriptionsComplection = completion
|
||||
productsRequest = SKProductsRequest(productIdentifiers: Set(Subscription.productIds))
|
||||
productsRequest!.delegate = self
|
||||
productsRequest!.start()
|
||||
}
|
||||
|
||||
@objc func subscribe(to subscription: ISubscription) {
|
||||
pendingSubscription = subscription
|
||||
guard let product = products?[subscription.productId] else { return }
|
||||
paymentQueue.add(SKPayment(product: product))
|
||||
}
|
||||
|
||||
@objc func addListener(_ listener: SubscriptionManagerListener) {
|
||||
listeners.add(listener)
|
||||
}
|
||||
|
||||
@objc func removeListener(_ listener: SubscriptionManagerListener) {
|
||||
listeners.remove(listener)
|
||||
}
|
||||
|
||||
@objc func validate() {
|
||||
MWMPurchaseManager.shared()
|
||||
.validateReceipt(MWMPurchaseManager.adsRemovalServerId()) { (serverId, validationResult) in
|
||||
if validationResult == .error {
|
||||
return
|
||||
} else {
|
||||
MWMPurchaseManager.shared().setAdsDisabled(validationResult == .valid)
|
||||
self.paymentQueue.transactions
|
||||
.filter { $0.transactionState == .purchased || $0.transactionState == .restored }
|
||||
.forEach { self.paymentQueue.finishTransaction($0) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension SubscriptionManager: SKProductsRequestDelegate {
|
||||
func request(_ request: SKRequest, didFailWithError error: Error) {
|
||||
subscriptionsComplection?(nil, error)
|
||||
subscriptionsComplection = nil
|
||||
productsRequest = nil
|
||||
}
|
||||
|
||||
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
|
||||
guard response.products.count == 3 else {
|
||||
subscriptionsComplection?(nil, NSError(domain: "mapsme.subscriptions", code: -1, userInfo: nil))
|
||||
subscriptionsComplection = nil
|
||||
productsRequest = nil
|
||||
return
|
||||
}
|
||||
let subscriptions = response.products.map { Subscription($0) }
|
||||
.sorted { $0.period.rawValue > $1.period.rawValue }
|
||||
products = Dictionary(uniqueKeysWithValues: response.products.map { ($0.productIdentifier, $0) })
|
||||
subscriptionsComplection?(subscriptions, nil)
|
||||
subscriptionsComplection = nil
|
||||
productsRequest = nil
|
||||
}
|
||||
}
|
||||
|
||||
extension SubscriptionManager: SKPaymentTransactionObserver {
|
||||
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
|
||||
transactions
|
||||
.filter { $0.transactionState == .failed }
|
||||
.forEach { processFailed($0, error: $0.error) }
|
||||
|
||||
if transactions.contains(where: {
|
||||
$0.transactionState == .purchased || $0.transactionState == .restored
|
||||
}) {
|
||||
transactions.filter { $0.transactionState == .purchased }
|
||||
.forEach { processPurchased($0) }
|
||||
transactions.filter { $0.transactionState == .restored }
|
||||
.forEach { processRestored($0) }
|
||||
validate()
|
||||
}
|
||||
|
||||
transactions.filter { $0.transactionState == .deferred }
|
||||
.forEach { processDeferred($0) }
|
||||
}
|
||||
|
||||
private func processDeferred(_ transaction: SKPaymentTransaction) {
|
||||
if let ps = pendingSubscription, transaction.payment.productIdentifier == ps.productId {
|
||||
listeners.allObjects.forEach { $0.didDefer(ps) }
|
||||
}
|
||||
}
|
||||
|
||||
private func processPurchased(_ transaction: SKPaymentTransaction) {
|
||||
MWMPurchaseManager.shared().setAdsDisabled(true)
|
||||
paymentQueue.finishTransaction(transaction)
|
||||
if let ps = pendingSubscription, transaction.payment.productIdentifier == ps.productId {
|
||||
listeners.allObjects.forEach { $0.didSubsribe(ps) }
|
||||
}
|
||||
}
|
||||
|
||||
private func processRestored(_ transaction: SKPaymentTransaction) {
|
||||
MWMPurchaseManager.shared().setAdsDisabled(true)
|
||||
paymentQueue.finishTransaction(transaction)
|
||||
if let ps = pendingSubscription, transaction.payment.productIdentifier == ps.productId {
|
||||
listeners.allObjects.forEach { $0.didSubsribe(ps) }
|
||||
}
|
||||
}
|
||||
|
||||
private func processFailed(_ transaction: SKPaymentTransaction, error: Error?) {
|
||||
paymentQueue.finishTransaction(transaction)
|
||||
if let ps = pendingSubscription, transaction.payment.productIdentifier == ps.productId {
|
||||
listeners.allObjects.forEach { $0.didFailToSubscribe(ps, error: error) }
|
||||
}
|
||||
}
|
||||
}
|
6
iphone/Maps/Images.xcassets/AdsRemove/Contents.json
Normal file
6
iphone/Maps/Images.xcassets/AdsRemove/Contents.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
26
iphone/Maps/Images.xcassets/AdsRemove/ic_ads_remove_close.imageset/Contents.json
vendored
Normal file
26
iphone/Maps/Images.xcassets/AdsRemove/ic_ads_remove_close.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "ic16PxClose.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "ic16PxClose@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "ic16PxClose@3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
BIN
iphone/Maps/Images.xcassets/AdsRemove/ic_ads_remove_close.imageset/ic16PxClose.png
vendored
Normal file
BIN
iphone/Maps/Images.xcassets/AdsRemove/ic_ads_remove_close.imageset/ic16PxClose.png
vendored
Normal file
Binary file not shown.
After ![]() (image error) Size: 199 B |
BIN
iphone/Maps/Images.xcassets/AdsRemove/ic_ads_remove_close.imageset/ic16PxClose@2x.png
vendored
Normal file
BIN
iphone/Maps/Images.xcassets/AdsRemove/ic_ads_remove_close.imageset/ic16PxClose@2x.png
vendored
Normal file
Binary file not shown.
After ![]() (image error) Size: 302 B |
BIN
iphone/Maps/Images.xcassets/AdsRemove/ic_ads_remove_close.imageset/ic16PxClose@3x.png
vendored
Normal file
BIN
iphone/Maps/Images.xcassets/AdsRemove/ic_ads_remove_close.imageset/ic16PxClose@3x.png
vendored
Normal file
Binary file not shown.
After ![]() (image error) Size: 404 B |
23
iphone/Maps/Images.xcassets/AdsRemove/mappy_heart.imageset/Contents.json
vendored
Normal file
23
iphone/Maps/Images.xcassets/AdsRemove/mappy_heart.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "mappy-heart.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "mappy-heart@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "mappy-heart@3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
BIN
iphone/Maps/Images.xcassets/AdsRemove/mappy_heart.imageset/mappy-heart.png
vendored
Normal file
BIN
iphone/Maps/Images.xcassets/AdsRemove/mappy_heart.imageset/mappy-heart.png
vendored
Normal file
Binary file not shown.
After ![]() (image error) Size: 14 KiB |
BIN
iphone/Maps/Images.xcassets/AdsRemove/mappy_heart.imageset/mappy-heart@2x.png
vendored
Normal file
BIN
iphone/Maps/Images.xcassets/AdsRemove/mappy_heart.imageset/mappy-heart@2x.png
vendored
Normal file
Binary file not shown.
After ![]() (image error) Size: 32 KiB |
BIN
iphone/Maps/Images.xcassets/AdsRemove/mappy_heart.imageset/mappy-heart@3x.png
vendored
Normal file
BIN
iphone/Maps/Images.xcassets/AdsRemove/mappy_heart.imageset/mappy-heart@3x.png
vendored
Normal file
Binary file not shown.
After ![]() (image error) Size: 54 KiB |
26
iphone/Maps/Images.xcassets/Banner/ic_ad_close.imageset/Contents.json
vendored
Normal file
26
iphone/Maps/Images.xcassets/Banner/ic_ad_close.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "ic_ad_close.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "ic_ad_close@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "ic_ad_close@3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
BIN
iphone/Maps/Images.xcassets/Banner/ic_ad_close.imageset/ic_ad_close.png
vendored
Normal file
BIN
iphone/Maps/Images.xcassets/Banner/ic_ad_close.imageset/ic_ad_close.png
vendored
Normal file
Binary file not shown.
After ![]() (image error) Size: 142 B |
BIN
iphone/Maps/Images.xcassets/Banner/ic_ad_close.imageset/ic_ad_close@2x.png
vendored
Normal file
BIN
iphone/Maps/Images.xcassets/Banner/ic_ad_close.imageset/ic_ad_close@2x.png
vendored
Normal file
Binary file not shown.
After ![]() (image error) Size: 215 B |
BIN
iphone/Maps/Images.xcassets/Banner/ic_ad_close.imageset/ic_ad_close@3x.png
vendored
Normal file
BIN
iphone/Maps/Images.xcassets/Banner/ic_ad_close.imageset/ic_ad_close@3x.png
vendored
Normal file
Binary file not shown.
After ![]() (image error) Size: 289 B |
|
@ -351,6 +351,12 @@
|
|||
470A89FF2134517600D72FBF /* BookmarksTutorialBlur.xib in Resources */ = {isa = PBXBuildFile; fileRef = 470A89FE2134517600D72FBF /* BookmarksTutorialBlur.xib */; };
|
||||
470A8A012136097000D72FBF /* SubwayTutorialBlur.xib in Resources */ = {isa = PBXBuildFile; fileRef = 470A8A002136073000D72FBF /* SubwayTutorialBlur.xib */; };
|
||||
471BBD942130390F00EB17C9 /* TutorialViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 471BBD932130390F00EB17C9 /* TutorialViewController.swift */; };
|
||||
472E3F472146BCD30020E412 /* SubscriptionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472E3F462146BCD30020E412 /* SubscriptionManager.swift */; };
|
||||
472E3F4A2146C4CD0020E412 /* MWMPurchaseManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 472E3F492146C4CD0020E412 /* MWMPurchaseManager.mm */; };
|
||||
472E3F4C2147D5700020E412 /* Subscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472E3F4B2147D5700020E412 /* Subscription.swift */; };
|
||||
474AC76C2139E4F2002F9BF9 /* RemoveAdsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 474AC76A2139E4F2002F9BF9 /* RemoveAdsViewController.swift */; };
|
||||
474AC76D2139E4F2002F9BF9 /* RemoveAdsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 474AC76B2139E4F2002F9BF9 /* RemoveAdsViewController.xib */; };
|
||||
474C9F5A213FF75800369009 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 474C9F59213FF75800369009 /* StoreKit.framework */; };
|
||||
474C9F632141896800369009 /* MWMEye.mm in Sources */ = {isa = PBXBuildFile; fileRef = 474C9F622141896800369009 /* MWMEye.mm */; };
|
||||
4767CD9F20AAD48A00BD8166 /* Checkmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4767CD9E20AAD48A00BD8166 /* Checkmark.swift */; };
|
||||
4767CDA420AAF66B00BD8166 /* NSAttributedString+HTML.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4767CDA320AAF66B00BD8166 /* NSAttributedString+HTML.swift */; };
|
||||
|
@ -368,12 +374,13 @@
|
|||
47E3C72221108E9F008B3B27 /* BookmarksLoadedViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 47E3C72021108E9F008B3B27 /* BookmarksLoadedViewController.xib */; };
|
||||
47E3C7252111E41B008B3B27 /* DimmedModalPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47E3C7242111E41B008B3B27 /* DimmedModalPresentationController.swift */; };
|
||||
47E3C7272111E5A8008B3B27 /* AlertPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47E3C7262111E5A8008B3B27 /* AlertPresentationController.swift */; };
|
||||
47E3C7292111E614008B3B27 /* AlertPresentationAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47E3C7282111E614008B3B27 /* AlertPresentationAnimator.swift */; };
|
||||
47E3C72B2111E62A008B3B27 /* AlertDismissalAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47E3C72A2111E62A008B3B27 /* AlertDismissalAnimator.swift */; };
|
||||
47E3C72D2111E6A2008B3B27 /* AlertTransitioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47E3C72C2111E6A2008B3B27 /* AlertTransitioning.swift */; };
|
||||
47E3C7292111E614008B3B27 /* FadeInAnimatedTransitioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47E3C7282111E614008B3B27 /* FadeInAnimatedTransitioning.swift */; };
|
||||
47E3C72B2111E62A008B3B27 /* FadeOutAnimatedTransitioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47E3C72A2111E62A008B3B27 /* FadeOutAnimatedTransitioning.swift */; };
|
||||
47E3C72D2111E6A2008B3B27 /* FadeTransitioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47E3C72C2111E6A2008B3B27 /* FadeTransitioning.swift */; };
|
||||
47E3C72F2111F472008B3B27 /* CoverVerticalModalTransitioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47E3C72E2111F472008B3B27 /* CoverVerticalModalTransitioning.swift */; };
|
||||
47E3C7312111F4C2008B3B27 /* CoverVerticalPresentationAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47E3C7302111F4C2008B3B27 /* CoverVerticalPresentationAnimator.swift */; };
|
||||
47E3C7332111F4D8008B3B27 /* CoverVerticalDismissalAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47E3C7322111F4D8008B3B27 /* CoverVerticalDismissalAnimator.swift */; };
|
||||
47EF05B321504D8F00EAC269 /* RemoveAdsPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47EF05B221504D8F00EAC269 /* RemoveAdsPresentationController.swift */; };
|
||||
47F86CFF20C936FC00FEE291 /* TabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F86CFE20C936FC00FEE291 /* TabView.swift */; };
|
||||
47F86D0120C93D8D00FEE291 /* TabViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F86D0020C93D8D00FEE291 /* TabViewController.swift */; };
|
||||
4A300ED51C6DCFD400140018 /* countries-strings in Resources */ = {isa = PBXBuildFile; fileRef = 4A300ED31C6DCFD400140018 /* countries-strings */; };
|
||||
|
@ -1328,6 +1335,13 @@
|
|||
470A89FE2134517600D72FBF /* BookmarksTutorialBlur.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = BookmarksTutorialBlur.xib; sourceTree = "<group>"; };
|
||||
470A8A002136073000D72FBF /* SubwayTutorialBlur.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SubwayTutorialBlur.xib; sourceTree = "<group>"; };
|
||||
471BBD932130390F00EB17C9 /* TutorialViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TutorialViewController.swift; sourceTree = "<group>"; };
|
||||
472E3F462146BCD30020E412 /* SubscriptionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionManager.swift; sourceTree = "<group>"; };
|
||||
472E3F482146C4CD0020E412 /* MWMPurchaseManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMPurchaseManager.h; sourceTree = "<group>"; };
|
||||
472E3F492146C4CD0020E412 /* MWMPurchaseManager.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMPurchaseManager.mm; sourceTree = "<group>"; };
|
||||
472E3F4B2147D5700020E412 /* Subscription.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Subscription.swift; sourceTree = "<group>"; };
|
||||
474AC76A2139E4F2002F9BF9 /* RemoveAdsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoveAdsViewController.swift; sourceTree = "<group>"; };
|
||||
474AC76B2139E4F2002F9BF9 /* RemoveAdsViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RemoveAdsViewController.xib; sourceTree = "<group>"; };
|
||||
474C9F59213FF75800369009 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
|
||||
474C9F612141896800369009 /* MWMEye.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMEye.h; sourceTree = "<group>"; };
|
||||
474C9F622141896800369009 /* MWMEye.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMEye.mm; sourceTree = "<group>"; };
|
||||
4767CD9E20AAD48A00BD8166 /* Checkmark.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Checkmark.swift; sourceTree = "<group>"; };
|
||||
|
@ -1347,12 +1361,13 @@
|
|||
47E3C72021108E9F008B3B27 /* BookmarksLoadedViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = BookmarksLoadedViewController.xib; sourceTree = "<group>"; };
|
||||
47E3C7242111E41B008B3B27 /* DimmedModalPresentationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DimmedModalPresentationController.swift; sourceTree = "<group>"; };
|
||||
47E3C7262111E5A8008B3B27 /* AlertPresentationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertPresentationController.swift; sourceTree = "<group>"; };
|
||||
47E3C7282111E614008B3B27 /* AlertPresentationAnimator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertPresentationAnimator.swift; sourceTree = "<group>"; };
|
||||
47E3C72A2111E62A008B3B27 /* AlertDismissalAnimator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertDismissalAnimator.swift; sourceTree = "<group>"; };
|
||||
47E3C72C2111E6A2008B3B27 /* AlertTransitioning.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertTransitioning.swift; sourceTree = "<group>"; };
|
||||
47E3C7282111E614008B3B27 /* FadeInAnimatedTransitioning.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FadeInAnimatedTransitioning.swift; sourceTree = "<group>"; };
|
||||
47E3C72A2111E62A008B3B27 /* FadeOutAnimatedTransitioning.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FadeOutAnimatedTransitioning.swift; sourceTree = "<group>"; };
|
||||
47E3C72C2111E6A2008B3B27 /* FadeTransitioning.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FadeTransitioning.swift; sourceTree = "<group>"; };
|
||||
47E3C72E2111F472008B3B27 /* CoverVerticalModalTransitioning.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoverVerticalModalTransitioning.swift; sourceTree = "<group>"; };
|
||||
47E3C7302111F4C2008B3B27 /* CoverVerticalPresentationAnimator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoverVerticalPresentationAnimator.swift; sourceTree = "<group>"; };
|
||||
47E3C7322111F4D8008B3B27 /* CoverVerticalDismissalAnimator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoverVerticalDismissalAnimator.swift; sourceTree = "<group>"; };
|
||||
47EF05B221504D8F00EAC269 /* RemoveAdsPresentationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoveAdsPresentationController.swift; sourceTree = "<group>"; };
|
||||
47F86CFE20C936FC00FEE291 /* TabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabView.swift; sourceTree = "<group>"; };
|
||||
47F86D0020C93D8D00FEE291 /* TabViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabViewController.swift; sourceTree = "<group>"; };
|
||||
4A00DBDE1AB704C400113624 /* drules_proto_dark.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = drules_proto_dark.bin; path = ../../data/drules_proto_dark.bin; sourceTree = "<group>"; };
|
||||
|
@ -1897,6 +1912,7 @@
|
|||
34D1B6F11E95096B0057E9C7 /* libicu.a in Frameworks */,
|
||||
671E78D31E6A423300B2859B /* librouting_common.a in Frameworks */,
|
||||
34D808861E793F91002F0584 /* Pushwoosh.framework in Frameworks */,
|
||||
474C9F5A213FF75800369009 /* StoreKit.framework in Frameworks */,
|
||||
34D8087B1E793606002F0584 /* Alamofire.framework in Frameworks */,
|
||||
34D8087D1E79360D002F0584 /* AlamofireImage.framework in Frameworks */,
|
||||
67B78B551E42333C0018E590 /* AdSupport.framework in Frameworks */,
|
||||
|
@ -2050,6 +2066,7 @@
|
|||
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
474C9F59213FF75800369009 /* StoreKit.framework */,
|
||||
3D1958EA213804B6009A83EC /* libmetrics.a */,
|
||||
4598438521394CFD00F8CAB2 /* MetalPerformanceShaders.framework */,
|
||||
BB8123CD212C264700ADE512 /* Metal.framework */,
|
||||
|
@ -2212,6 +2229,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
474C9F602141894300369009 /* Metrics */,
|
||||
472E3F4221468AF40020E412 /* Subscriptions */,
|
||||
3472B5E7200F8CEB00DC6CD5 /* UGC */,
|
||||
3472B5DD200F868E00DC6CD5 /* Editor */,
|
||||
3472B5C8200F436700DC6CD5 /* BackgroundFetchScheduler */,
|
||||
|
@ -2384,6 +2402,8 @@
|
|||
children = (
|
||||
3488B0101E9D0AEC0068AFD8 /* AdBanner.swift */,
|
||||
3488B0111E9D0AEC0068AFD8 /* AdBanner.xib */,
|
||||
474AC76A2139E4F2002F9BF9 /* RemoveAdsViewController.swift */,
|
||||
474AC76B2139E4F2002F9BF9 /* RemoveAdsViewController.xib */,
|
||||
);
|
||||
path = Ads;
|
||||
sourceTree = "<group>";
|
||||
|
@ -3188,6 +3208,17 @@
|
|||
path = TipsAndTricks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
472E3F4221468AF40020E412 /* Subscriptions */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
472E3F462146BCD30020E412 /* SubscriptionManager.swift */,
|
||||
472E3F482146C4CD0020E412 /* MWMPurchaseManager.h */,
|
||||
472E3F492146C4CD0020E412 /* MWMPurchaseManager.mm */,
|
||||
472E3F4B2147D5700020E412 /* Subscription.swift */,
|
||||
);
|
||||
path = Subscriptions;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
474A450520EBA03900C10B4E /* Layers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -3209,11 +3240,12 @@
|
|||
47E3C7232111E2F8008B3B27 /* Modal */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
47EF05B12150383A00EAC269 /* RemoveAds */,
|
||||
47E3C7242111E41B008B3B27 /* DimmedModalPresentationController.swift */,
|
||||
47E3C7262111E5A8008B3B27 /* AlertPresentationController.swift */,
|
||||
47E3C7282111E614008B3B27 /* AlertPresentationAnimator.swift */,
|
||||
47E3C72A2111E62A008B3B27 /* AlertDismissalAnimator.swift */,
|
||||
47E3C72C2111E6A2008B3B27 /* AlertTransitioning.swift */,
|
||||
47E3C7282111E614008B3B27 /* FadeInAnimatedTransitioning.swift */,
|
||||
47E3C72A2111E62A008B3B27 /* FadeOutAnimatedTransitioning.swift */,
|
||||
47E3C72C2111E6A2008B3B27 /* FadeTransitioning.swift */,
|
||||
47E3C72E2111F472008B3B27 /* CoverVerticalModalTransitioning.swift */,
|
||||
47E3C7302111F4C2008B3B27 /* CoverVerticalPresentationAnimator.swift */,
|
||||
47E3C7322111F4D8008B3B27 /* CoverVerticalDismissalAnimator.swift */,
|
||||
|
@ -3221,6 +3253,14 @@
|
|||
path = Modal;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
47EF05B12150383A00EAC269 /* RemoveAds */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
47EF05B221504D8F00EAC269 /* RemoveAdsPresentationController.swift */,
|
||||
);
|
||||
path = RemoveAds;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
47F86CFD20C936B300FEE291 /* TabView */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -4244,6 +4284,9 @@
|
|||
LastSwiftMigration = 0900;
|
||||
ProvisioningStyle = Automatic;
|
||||
SystemCapabilities = {
|
||||
com.apple.InAppPurchase = {
|
||||
enabled = 1;
|
||||
};
|
||||
com.apple.Push = {
|
||||
enabled = 1;
|
||||
};
|
||||
|
@ -4410,6 +4453,7 @@
|
|||
34D3B02D1E389D05004100F9 /* MWMEditorAdditionalNameTableViewCell.xib in Resources */,
|
||||
34D3B0331E389D05004100F9 /* MWMEditorCategoryCell.xib in Resources */,
|
||||
F6E2FDCB1E097BA00083EBEC /* MWMEditorNotesFooter.xib in Resources */,
|
||||
474AC76D2139E4F2002F9BF9 /* RemoveAdsViewController.xib in Resources */,
|
||||
34D3B0391E389D05004100F9 /* MWMEditorSelectTableViewCell.xib in Resources */,
|
||||
34AB663B1FC5AA330078E451 /* RouteManagerViewController.xib in Resources */,
|
||||
34D3B03F1E389D05004100F9 /* MWMEditorSwitchTableViewCell.xib in Resources */,
|
||||
|
@ -4601,6 +4645,7 @@
|
|||
344BEAF31F66BDC30045DC45 /* RatingSummaryView.swift in Sources */,
|
||||
6741A9A31BF340DE002C974C /* main.mm in Sources */,
|
||||
34D3B04F1E38A20C004100F9 /* Bundle+Init.swift in Sources */,
|
||||
47EF05B321504D8F00EAC269 /* RemoveAdsPresentationController.swift in Sources */,
|
||||
34AB666E1FC5AA330078E451 /* TransportTransitStepsCollectionView.swift in Sources */,
|
||||
F6E2FF541E097BA00083EBEC /* MWMHelpController.mm in Sources */,
|
||||
349FC5481F680DAE00968C9F /* ExpandableTextView.swift in Sources */,
|
||||
|
@ -4627,6 +4672,7 @@
|
|||
340708781F2B5D6C00029ECC /* DimBackground.swift in Sources */,
|
||||
3490D2DF1CE9DD2500D0B838 /* MWMSideButtons.mm in Sources */,
|
||||
F6E2FDF81E097BA00083EBEC /* MWMOpeningHoursAllDayTableViewCell.mm in Sources */,
|
||||
472E3F4C2147D5700020E412 /* Subscription.swift in Sources */,
|
||||
340B33C61F3AEFDB00A8C1B4 /* MWMRouter+RouteManager.mm in Sources */,
|
||||
F6E2FE191E097BA00083EBEC /* MWMOpeningHoursTimeSpanTableViewCell.mm in Sources */,
|
||||
F6E407D01FC45EF5001F7821 /* MWMDiscoveryController.mm in Sources */,
|
||||
|
@ -4704,10 +4750,10 @@
|
|||
F6E2FEE51E097BA00083EBEC /* MWMSearchNoResults.mm in Sources */,
|
||||
F6E2FF631E097BA00083EBEC /* MWMTTSLanguageViewController.mm in Sources */,
|
||||
342EE4121C43DAA7009F6A49 /* MWMAuthorizationWebViewLoginViewController.mm in Sources */,
|
||||
47E3C7292111E614008B3B27 /* AlertPresentationAnimator.swift in Sources */,
|
||||
47E3C7292111E614008B3B27 /* FadeInAnimatedTransitioning.swift in Sources */,
|
||||
34AB667D1FC5AA330078E451 /* MWMRoutePreview.mm in Sources */,
|
||||
B33D21AC20DA515800BAD749 /* MWMCategoryInfoCell.mm in Sources */,
|
||||
47E3C72D2111E6A2008B3B27 /* AlertTransitioning.swift in Sources */,
|
||||
47E3C72D2111E6A2008B3B27 /* FadeTransitioning.swift in Sources */,
|
||||
34845DAF1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift in Sources */,
|
||||
474C9F632141896800369009 /* MWMEye.mm in Sources */,
|
||||
F6791B141C43DF0B007A8A6E /* MWMStartButton.mm in Sources */,
|
||||
|
@ -4715,6 +4761,7 @@
|
|||
F64D9CA01C899C350063FA30 /* MWMEditorViralAlert.mm in Sources */,
|
||||
34AC8FD11EFC02C000E7F910 /* MWMRoutePoint.mm in Sources */,
|
||||
6741A9CF1BF340DE002C974C /* MWMLocationAlert.mm in Sources */,
|
||||
474AC76C2139E4F2002F9BF9 /* RemoveAdsViewController.swift in Sources */,
|
||||
34ABA62D1C2D57D500FE1BEC /* MWMInputPasswordValidator.mm in Sources */,
|
||||
F6E2FDA11E097BA00083EBEC /* MWMEditorAdditionalNamesTableViewController.mm in Sources */,
|
||||
4767CDA620AB1F6200BD8166 /* LeftAlignedIconButton.swift in Sources */,
|
||||
|
@ -4876,6 +4923,7 @@
|
|||
3404755F1E081A4600C92850 /* MWMLocationPredictor.mm in Sources */,
|
||||
F6E2FE041E097BA00083EBEC /* MWMOpeningHoursDaysSelectorTableViewCell.mm in Sources */,
|
||||
F6E2FE671E097BA00083EBEC /* MWMPlacePageButtonCell.mm in Sources */,
|
||||
472E3F472146BCD30020E412 /* SubscriptionManager.swift in Sources */,
|
||||
F6E2FE131E097BA00083EBEC /* MWMOpeningHoursTimeSelectorTableViewCell.mm in Sources */,
|
||||
344532311F6FE5880059FBCC /* UGCSummaryRatingStarsCell.swift in Sources */,
|
||||
F626D52F1C3E83F800C17D15 /* MWMTableViewCell.mm in Sources */,
|
||||
|
@ -4899,6 +4947,7 @@
|
|||
34F1ADD31F6BC09E001CE79D /* PPPReview.swift in Sources */,
|
||||
F6E2FF4B1E097BA00083EBEC /* SettingsTableViewSwitchCell.swift in Sources */,
|
||||
F6E2FE791E097BA00083EBEC /* MWMOpeningHoursLayoutHelper.mm in Sources */,
|
||||
472E3F4A2146C4CD0020E412 /* MWMPurchaseManager.mm in Sources */,
|
||||
34ABA6211C2D517500FE1BEC /* MWMInputValidator.mm in Sources */,
|
||||
34BBD6601F8270360070CA50 /* AuthorizationiPadPresentationController.swift in Sources */,
|
||||
F6E2FD7D1E097BA00083EBEC /* MWMMapDownloaderExtendedDataSource.mm in Sources */,
|
||||
|
@ -5021,7 +5070,7 @@
|
|||
34845DB31E165E24003D55B9 /* SearchNoResultsViewController.swift in Sources */,
|
||||
34AB660B1FC5AA320078E451 /* MWMNavigationDashboardEntity.mm in Sources */,
|
||||
F5BD29FF26AD58255766C51A /* DiscoverySpinnerCell.swift in Sources */,
|
||||
47E3C72B2111E62A008B3B27 /* AlertDismissalAnimator.swift in Sources */,
|
||||
47E3C72B2111E62A008B3B27 /* FadeOutAnimatedTransitioning.swift in Sources */,
|
||||
F5BD255A0838E70EC012748E /* DiscoverySearchCell.swift in Sources */,
|
||||
F5BD2CA4DBEFACBC48195F39 /* DiscoveryCollectionHolderCell.swift in Sources */,
|
||||
);
|
||||
|
|
|
@ -54,11 +54,26 @@ final class AdBanner: UITableViewCell {
|
|||
@IBOutlet private weak var adCallToActionButtonCompact: UIButton!
|
||||
@IBOutlet private weak var adCallToActionButtonDetailed: UIButton!
|
||||
@IBOutlet private weak var adCallToActionButtonCustom: UIButton!
|
||||
@IBOutlet private weak var nativeAdView: UIView!
|
||||
@IBOutlet private weak var removeAdsSmallButton: UIButton!
|
||||
@IBOutlet private weak var removeAdsLargeButton: UIButton!
|
||||
@IBOutlet private weak var removeAdsImage: UIImageView! {
|
||||
didSet {
|
||||
removeAdsImage.mwm_coloring = .black
|
||||
}
|
||||
}
|
||||
@IBOutlet private weak var fallbackAdView: UIView!
|
||||
@IBOutlet private var nativeAdViewBottom: NSLayoutConstraint!
|
||||
@IBOutlet private var fallbackAdViewBottom: NSLayoutConstraint!
|
||||
@IBOutlet private var fallbackAdViewHeight: NSLayoutConstraint!
|
||||
@IBOutlet private var ctaButtonLeftConstraint: NSLayoutConstraint!
|
||||
@IBOutlet private weak var nativeAdView: UIView! {
|
||||
didSet {
|
||||
nativeAdView.layer.borderColor = UIColor.blackDividers().cgColor
|
||||
}
|
||||
}
|
||||
|
||||
@objc var onRemoveAds: MWMVoidBlock?
|
||||
|
||||
@objc static let detailedBannerExcessHeight: Float = 36
|
||||
|
||||
enum AdType {
|
||||
|
@ -123,6 +138,11 @@ final class AdBanner: UITableViewCell {
|
|||
UIViewController.topViewController().open(url)
|
||||
}
|
||||
|
||||
@IBAction
|
||||
private func removeAction() {
|
||||
onRemoveAds?()
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
switch nativeAd {
|
||||
|
@ -135,7 +155,7 @@ final class AdBanner: UITableViewCell {
|
|||
state = .unset
|
||||
}
|
||||
|
||||
@objc func config(ad: MWMBanner, containerType: AdBannerContainerType) {
|
||||
@objc func config(ad: MWMBanner, containerType: AdBannerContainerType, canRemoveAds: Bool, onRemoveAds: (() -> Void)?) {
|
||||
reset()
|
||||
switch containerType {
|
||||
case .placePage:
|
||||
|
@ -153,6 +173,11 @@ final class AdBanner: UITableViewCell {
|
|||
case let ad as GoogleNativeBanner: configGoogleNativeBanner(ad: ad)
|
||||
default: assert(false)
|
||||
}
|
||||
self.onRemoveAds = onRemoveAds
|
||||
removeAdsSmallButton.isHidden = !canRemoveAds
|
||||
removeAdsLargeButton.isHidden = !canRemoveAds
|
||||
removeAdsImage.isHidden = !canRemoveAds
|
||||
ctaButtonLeftConstraint.priority = canRemoveAds ? .defaultLow : .defaultHigh
|
||||
}
|
||||
|
||||
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
|
@ -19,6 +19,13 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="375" height="109.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ucm-4E-iB7">
|
||||
<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"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" priority="999" constant="109" id="9T6-aq-miV"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="f76-qn-ne4">
|
||||
<rect key="frame" x="4" y="4" width="367" height="101.5"/>
|
||||
<subviews>
|
||||
|
@ -120,8 +127,30 @@
|
|||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="bannerButtonBackground"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="EIT-s3-8BF">
|
||||
<rect key="frame" x="12" y="101" width="165.5" height="36"/>
|
||||
<color key="backgroundColor" red="0.95294117649999999" green="0.92156862750000001" blue="0.85490196080000003" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="36" id="Sec-LO-NfY"/>
|
||||
</constraints>
|
||||
<state key="normal" title="Remove Ads">
|
||||
<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="medium14"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="bannerButtonBackground"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="textColorName" value="blackSecondaryText"/>
|
||||
<userDefinedRuntimeAttribute type="boolean" keyPath="layer.masksToBounds" value="YES"/>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
|
||||
<integer key="value" value="2"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<action selector="removeAction" destination="WK2-gA-ocn" eventType="touchUpInside" id="dCc-Ww-mvy"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NKM-3R-3g1">
|
||||
<rect key="frame" x="12" y="101.5" width="343" height="36"/>
|
||||
<rect key="frame" x="189.5" y="101.5" width="165.5" 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"/>
|
||||
|
@ -150,39 +179,69 @@
|
|||
<action selector="privacyAction" destination="WK2-gA-ocn" eventType="touchUpInside" id="ma2-uV-7hH"/>
|
||||
</connections>
|
||||
</button>
|
||||
<imageView userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_ad_close" translatesAutoresizingMaskIntoConstraints="NO" id="D3u-BA-Ixx">
|
||||
<rect key="frame" x="352" y="2" width="13" height="13"/>
|
||||
<color key="tintColor" white="0.0" alpha="0.54168450338082197" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="13" id="AuT-Sc-FFo"/>
|
||||
<constraint firstAttribute="height" constant="13" id="NRm-LU-MWL"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="blackDividers"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</imageView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="huL-pj-FQy">
|
||||
<rect key="frame" x="335" y="0.0" width="32" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="32" id="Bmc-z7-zKC"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<action selector="removeAction" destination="WK2-gA-ocn" eventType="touchUpInside" id="Jtb-b8-Ihy"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="9qA-JC-fkn" secondAttribute="leading" priority="250" id="5CH-Fo-S70"/>
|
||||
<constraint firstItem="huL-pj-FQy" firstAttribute="top" secondItem="f76-qn-ne4" secondAttribute="top" id="9xd-8o-CPo"/>
|
||||
<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" constant="12" 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 firstItem="D3u-BA-Ixx" firstAttribute="top" secondItem="huL-pj-FQy" secondAttribute="top" constant="2" id="QV1-rU-D4J"/>
|
||||
<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" constant="4" id="ZVP-Gs-m00"/>
|
||||
<constraint firstAttribute="trailing" secondItem="NKM-3R-3g1" secondAttribute="trailing" constant="12" 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 firstItem="NKM-3R-3g1" firstAttribute="leading" secondItem="EIT-s3-8BF" secondAttribute="trailing" priority="500" constant="12" id="b7c-4v-4PG"/>
|
||||
<constraint firstItem="9qA-JC-fkn" firstAttribute="top" secondItem="huL-pj-FQy" secondAttribute="bottom" id="crO-Dv-apD"/>
|
||||
<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="EIT-s3-8BF" firstAttribute="width" secondItem="NKM-3R-3g1" secondAttribute="width" id="gvb-Sb-VpY"/>
|
||||
<constraint firstItem="EIT-s3-8BF" firstAttribute="leading" secondItem="f76-qn-ne4" secondAttribute="leading" constant="12" id="hHP-XI-N3c"/>
|
||||
<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" constant="12" id="hzn-4Y-A0H"/>
|
||||
<constraint firstItem="EIT-s3-8BF" firstAttribute="bottom" secondItem="NKM-3R-3g1" secondAttribute="bottom" id="iB4-7e-JCZ"/>
|
||||
<constraint firstAttribute="trailing" secondItem="huL-pj-FQy" secondAttribute="trailing" id="j1g-TD-yNF"/>
|
||||
<constraint firstItem="D3u-BA-Ixx" firstAttribute="trailing" secondItem="huL-pj-FQy" secondAttribute="trailing" constant="-2" id="lYj-xp-qLn"/>
|
||||
<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="8" 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="EIT-s3-8BF" firstAttribute="top" secondItem="Ev3-yY-ql1" secondAttribute="bottom" constant="8" id="wEs-mb-MUF"/>
|
||||
<constraint firstItem="NKM-3R-3g1" firstAttribute="leading" secondItem="f76-qn-ne4" secondAttribute="leading" priority="250" constant="12" id="ypZ-TK-ao1"/>
|
||||
<constraint firstItem="So8-wM-Cgz" firstAttribute="trailing" secondItem="zWu-Gh-Vf7" secondAttribute="trailing" id="zGz-Sf-G1b"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
|
@ -195,13 +254,6 @@
|
|||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="bannerBackground"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ucm-4E-iB7">
|
||||
<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"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" priority="999" constant="109" id="9T6-aq-miV"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
|
@ -231,11 +283,15 @@
|
|||
<outlet property="adIconImageView" destination="EuF-Rm-DHQ" id="Edf-Ak-VAy"/>
|
||||
<outlet property="adPrivacyImage" destination="042-9V-wU6" id="JLV-4K-UTc"/>
|
||||
<outlet property="adTitleLabel" destination="kIR-cO-v6L" id="OOh-tX-yBM"/>
|
||||
<outlet property="ctaButtonLeftConstraint" destination="ypZ-TK-ao1" id="Qjs-Rw-yKB"/>
|
||||
<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"/>
|
||||
<outlet property="removeAdsImage" destination="D3u-BA-Ixx" id="0qo-wO-cBR"/>
|
||||
<outlet property="removeAdsLargeButton" destination="EIT-s3-8BF" id="Xdb-44-0cc"/>
|
||||
<outlet property="removeAdsSmallButton" destination="huL-pj-FQy" id="dtr-Nq-1O0"/>
|
||||
<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"/>
|
||||
|
@ -247,6 +303,7 @@
|
|||
</tableViewCell>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="ic_ad_close" width="8" height="8"/>
|
||||
<image name="ic_ads_fb" width="20" height="12"/>
|
||||
<image name="img_ad_light" width="20" height="12"/>
|
||||
</resources>
|
||||
|
|
208
iphone/Maps/UI/Ads/RemoveAdsViewController.swift
Normal file
208
iphone/Maps/UI/Ads/RemoveAdsViewController.swift
Normal file
|
@ -0,0 +1,208 @@
|
|||
@objc protocol RemoveAdsViewControllerDelegate: AnyObject {
|
||||
func didCompleteSubscribtion(_ viewController: RemoveAdsViewController)
|
||||
func didCancelSubscribtion(_ viewController: RemoveAdsViewController)
|
||||
}
|
||||
|
||||
@objc class RemoveAdsViewController: MWMViewController {
|
||||
typealias VC = RemoveAdsViewController
|
||||
private let transitioning = FadeTransitioning<RemoveAdsPresentationController>()
|
||||
|
||||
@IBOutlet weak var loadingView: UIView!
|
||||
@IBOutlet weak var loadingIndicator: UIActivityIndicatorView! {
|
||||
didSet {
|
||||
loadingIndicator.color = .blackPrimaryText()
|
||||
}
|
||||
}
|
||||
@IBOutlet weak var payButton: UIButton!
|
||||
@IBOutlet weak var monthButton: UIButton!
|
||||
@IBOutlet weak var weekButton: UIButton!
|
||||
@IBOutlet weak var whySupportButton: UIButton!
|
||||
@IBOutlet weak var saveLabel: UILabel!
|
||||
@IBOutlet weak var productsLoadingIndicator: UIActivityIndicatorView!
|
||||
@IBOutlet weak var whySupportView: UIView!
|
||||
@IBOutlet weak var optionsView: UIView! {
|
||||
didSet {
|
||||
optionsView.layer.borderColor = UIColor.blackDividers().cgColor
|
||||
optionsView.layer.borderWidth = 1
|
||||
}
|
||||
}
|
||||
@IBOutlet weak var optionsHeightConstraint: NSLayoutConstraint!
|
||||
@IBOutlet weak var whySupportConstraint: NSLayoutConstraint!
|
||||
|
||||
@objc weak var delegate: RemoveAdsViewControllerDelegate?
|
||||
var subscriptions: [ISubscription]?
|
||||
|
||||
private static func formatPrice(_ price: NSDecimalNumber?, locale: Locale?) -> String {
|
||||
guard let price = price else { return "" }
|
||||
guard let locale = locale else { return "\(price)" }
|
||||
let formatter = NumberFormatter()
|
||||
formatter.numberStyle = .currency
|
||||
formatter.locale = locale
|
||||
return formatter.string(from: price) ?? ""
|
||||
}
|
||||
|
||||
private static func calculateDiscount(_ price: NSDecimalNumber?,
|
||||
weeklyPrice: NSDecimalNumber?,
|
||||
period: SubscriptionPeriod) -> NSDecimalNumber? {
|
||||
guard let price = price, let weeklyPrice = weeklyPrice else { return nil }
|
||||
|
||||
switch period {
|
||||
case .week:
|
||||
return 0
|
||||
case .month:
|
||||
return weeklyPrice.multiplying(by: 4).subtracting(price)
|
||||
case .year:
|
||||
return weeklyPrice.multiplying(by: 52).subtracting(price)
|
||||
case .unknown:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
SubscriptionManager.shared.addListener(self)
|
||||
SubscriptionManager.shared.getAvailableSubscriptions { (subscriptions, error) in
|
||||
self.subscriptions = subscriptions
|
||||
self.productsLoadingIndicator.stopAnimating()
|
||||
guard let subscriptions = subscriptions else {
|
||||
MWMAlertViewController.activeAlert().presentInfoAlert(L("bookmarks_convert_error_title"), text: L("purchase_error_subtitle"))
|
||||
self.delegate?.didCancelSubscribtion(self)
|
||||
return
|
||||
}
|
||||
self.saveLabel.isHidden = false
|
||||
self.optionsView.isHidden = false
|
||||
self.payButton.isEnabled = true
|
||||
assert(subscriptions.count == 3)
|
||||
let yearlyPrice = subscriptions[0].price
|
||||
let monthlyPrice = subscriptions[1].price
|
||||
let weeklyPrice = subscriptions[2].price
|
||||
let yearlyDiscount = VC.calculateDiscount(yearlyPrice,
|
||||
weeklyPrice: weeklyPrice,
|
||||
period: subscriptions[0].period)
|
||||
let monthlyDiscount = VC.calculateDiscount(monthlyPrice,
|
||||
weeklyPrice: weeklyPrice,
|
||||
period: subscriptions[1].period)
|
||||
let locale = subscriptions[0].priceLocale
|
||||
|
||||
self.payButton.setTitle(String(coreFormat: L("paybtn_title"),
|
||||
arguments: [VC.formatPrice(yearlyPrice, locale: locale)]), for: .normal)
|
||||
self.saveLabel.text = String(coreFormat: L("paybtn_subtitle"),
|
||||
arguments: [VC.formatPrice(yearlyDiscount, locale: locale)])
|
||||
|
||||
self.monthButton.setTitle(String(coreFormat: L("options_dropdown_item1"),
|
||||
arguments: [VC.formatPrice(monthlyPrice ?? 0, locale: locale),
|
||||
VC.formatPrice(monthlyDiscount, locale: locale)]), for: .normal)
|
||||
self.weekButton.setTitle(String(coreFormat: L("options_dropdown_item2"),
|
||||
arguments: [VC.formatPrice(weeklyPrice ?? 0, locale: locale)]), for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
override var prefersStatusBarHidden: Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
deinit {
|
||||
SubscriptionManager.shared.removeListener(self)
|
||||
}
|
||||
|
||||
@IBAction func onClose(_ sender: Any) {
|
||||
delegate?.didCancelSubscribtion(self)
|
||||
}
|
||||
|
||||
@IBAction func onPay(_ sender: UIButton) {
|
||||
subscribe(subscriptions?[0])
|
||||
}
|
||||
|
||||
@IBAction func onMonth(_ sender: UIButton) {
|
||||
subscribe(subscriptions?[1])
|
||||
}
|
||||
|
||||
@IBAction func onWeek(_ sender: UIButton) {
|
||||
subscribe(subscriptions?[2])
|
||||
}
|
||||
|
||||
@IBAction func onMoreOptions(_ sender: UIButton) {
|
||||
view.layoutIfNeeded()
|
||||
UIView.animate(withDuration: kDefaultAnimationDuration) {
|
||||
self.optionsHeightConstraint.constant = 109
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func onWhySupport(_ sender: UIButton) {
|
||||
whySupportView.isHidden = false
|
||||
whySupportView.alpha = 0
|
||||
whySupportConstraint.priority = .defaultHigh
|
||||
UIView.animate(withDuration: kDefaultAnimationDuration) {
|
||||
self.whySupportView.alpha = 1
|
||||
self.whySupportButton.alpha = 0
|
||||
}
|
||||
}
|
||||
|
||||
private func subscribe(_ subscription: ISubscription?) {
|
||||
guard let subscription = subscription else {
|
||||
MWMAlertViewController.activeAlert().presentInfoAlert(L("bookmarks_convert_error_title"),
|
||||
text: L("purchase_error_subtitle"))
|
||||
self.delegate?.didCancelSubscribtion(self)
|
||||
return
|
||||
}
|
||||
showPurchaseProgress()
|
||||
SubscriptionManager.shared.subscribe(to: subscription)
|
||||
}
|
||||
|
||||
private func showPurchaseProgress() {
|
||||
loadingView.isHidden = false
|
||||
loadingView.alpha = 0
|
||||
UIView.animate(withDuration: kDefaultAnimationDuration) {
|
||||
self.loadingView.alpha = 1
|
||||
}
|
||||
}
|
||||
|
||||
private func hidePurchaseProgress() {
|
||||
UIView.animate(withDuration: kDefaultAnimationDuration, animations: {
|
||||
self.loadingView.alpha = 0
|
||||
}) { _ in
|
||||
self.loadingView.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
override var transitioningDelegate: UIViewControllerTransitioningDelegate? {
|
||||
get { return transitioning }
|
||||
set { }
|
||||
}
|
||||
|
||||
override var modalPresentationStyle: UIModalPresentationStyle {
|
||||
get { return .custom }
|
||||
set { }
|
||||
}
|
||||
}
|
||||
|
||||
extension RemoveAdsViewController: SubscriptionManagerListener {
|
||||
func validationError() {
|
||||
hidePurchaseProgress()
|
||||
delegate?.didCompleteSubscribtion(self)
|
||||
}
|
||||
|
||||
func didSubsribe(_ subscription: ISubscription) {
|
||||
hidePurchaseProgress()
|
||||
delegate?.didCompleteSubscribtion(self)
|
||||
}
|
||||
|
||||
func didFailToValidate(_ subscription: ISubscription, error: Error?) {
|
||||
hidePurchaseProgress()
|
||||
MWMAlertViewController.activeAlert().presentInfoAlert(L("bookmarks_convert_error_title"),
|
||||
text: L("purchase_error_subtitle"))
|
||||
}
|
||||
|
||||
func didDefer(_ subscription: ISubscription) {
|
||||
hidePurchaseProgress()
|
||||
delegate?.didCompleteSubscribtion(self)
|
||||
}
|
||||
|
||||
func didFailToSubscribe(_ subscription: ISubscription, error: Error?) {
|
||||
MWMAlertViewController.activeAlert().presentInfoAlert(L("bookmarks_convert_error_title"),
|
||||
text: L("purchase_error_subtitle"))
|
||||
hidePurchaseProgress()
|
||||
}
|
||||
}
|
595
iphone/Maps/UI/Ads/RemoveAdsViewController.xib
Normal file
595
iphone/Maps/UI/Ads/RemoveAdsViewController.xib
Normal file
|
@ -0,0 +1,595 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina4_0" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="RemoveAdsViewController" customModule="maps_me" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="loadingIndicator" destination="LhO-RQ-vOf" id="mz0-la-VFc"/>
|
||||
<outlet property="loadingView" destination="7Al-wo-fvb" id="yEn-uh-D7S"/>
|
||||
<outlet property="monthButton" destination="MPP-Wb-dwQ" id="NcO-qU-wu4"/>
|
||||
<outlet property="optionsHeightConstraint" destination="u0h-Qx-wo9" id="boS-EC-IfC"/>
|
||||
<outlet property="optionsView" destination="moF-VX-t4N" id="YDj-y7-vKN"/>
|
||||
<outlet property="payButton" destination="yaj-2x-NKs" id="hqz-4o-zQJ"/>
|
||||
<outlet property="productsLoadingIndicator" destination="nA0-bV-sRz" id="1tu-UM-7MC"/>
|
||||
<outlet property="saveLabel" destination="2o9-EE-vAM" id="ZfB-p3-baM"/>
|
||||
<outlet property="view" destination="i5T-Pr-FkT" id="sfx-zR-JGt"/>
|
||||
<outlet property="weekButton" destination="XY6-tA-B1U" id="jqz-Re-PDN"/>
|
||||
<outlet property="whySupportButton" destination="3V5-Dx-w2P" id="FLP-sb-E4d"/>
|
||||
<outlet property="whySupportConstraint" destination="gIY-Uk-WiX" id="ghr-ye-kPf"/>
|
||||
<outlet property="whySupportView" destination="pAe-qE-h95" id="9QL-Ib-JS3"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5T-Pr-FkT">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="T82-qa-a8r">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<gestureRecognizers/>
|
||||
<connections>
|
||||
<outletCollection property="gestureRecognizers" destination="cab-7b-e1x" appends="YES" id="8QU-8o-aZD"/>
|
||||
</connections>
|
||||
</view>
|
||||
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="raA-Qo-8vn" userLabel="Container View" customClass="MWMTouchOpaqueView">
|
||||
<rect key="frame" x="0.0" y="20" width="320" height="548"/>
|
||||
<subviews>
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" bounces="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aRL-MT-ZBH">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="548"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="i5M-Pr-FkT">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="548"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="752" verticalCompressionResistancePriority="752" text="Remove all Ads and support MAPS.ME" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vCa-Yl-SkC">
|
||||
<rect key="frame" x="24" y="24" width="272" height="57.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="24"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="remove_ads_title"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular24"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackPrimaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" image="mappy_heart" translatesAutoresizingMaskIntoConstraints="NO" id="AmL-7Q-Kas">
|
||||
<rect key="frame" x="98.5" y="105.5" width="124" height="142"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" id="E4W-ij-UBq"/>
|
||||
</constraints>
|
||||
<variation key="default">
|
||||
<mask key="constraints">
|
||||
<exclude reference="E4W-ij-UBq"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=compact-widthClass=compact">
|
||||
<mask key="constraints">
|
||||
<include reference="E4W-ij-UBq"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=compact-widthClass=regular">
|
||||
<mask key="constraints">
|
||||
<include reference="E4W-ij-UBq"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</imageView>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pAe-qE-h95">
|
||||
<rect key="frame" x="0.0" y="24" width="320" height="165"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="752" verticalCompressionResistancePriority="752" text="Why support MAPS.ME?" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YQ4-oq-7XN">
|
||||
<rect key="frame" x="24" y="0.0" width="272" height="29"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="24"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="why_support"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular24"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackPrimaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Jhy-EZ-HaR">
|
||||
<rect key="frame" x="35" y="45" width="245" height="18"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="•" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SqJ-F7-qg1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="7" height="18"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular15"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="colorName" value="linkBlue"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="We will remove all ads for you" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4wA-Tm-jmm">
|
||||
<rect key="frame" x="15" y="0.0" width="230" height="18"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="why_support_item1"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular15"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackPrimaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="SqJ-F7-qg1" firstAttribute="top" secondItem="Jhy-EZ-HaR" secondAttribute="top" id="82H-S2-p97"/>
|
||||
<constraint firstAttribute="bottom" secondItem="4wA-Tm-jmm" secondAttribute="bottom" id="88j-gG-Ahr"/>
|
||||
<constraint firstAttribute="trailing" secondItem="4wA-Tm-jmm" secondAttribute="trailing" id="ILk-3h-RPH"/>
|
||||
<constraint firstItem="4wA-Tm-jmm" firstAttribute="top" secondItem="Jhy-EZ-HaR" secondAttribute="top" id="Niw-UQ-UzV"/>
|
||||
<constraint firstItem="SqJ-F7-qg1" firstAttribute="leading" secondItem="Jhy-EZ-HaR" secondAttribute="leading" id="aYQ-f5-oiE"/>
|
||||
<constraint firstItem="4wA-Tm-jmm" firstAttribute="leading" secondItem="SqJ-F7-qg1" secondAttribute="trailing" constant="8" id="qWW-ca-iyL"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="N1P-1l-fOT">
|
||||
<rect key="frame" x="35" y="79" width="245" height="18"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="•" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3CU-Qm-qr9">
|
||||
<rect key="frame" x="0.0" y="0.0" width="7" height="18"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular15"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="colorName" value="linkBlue"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="You help us improve MAPS.ME" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WMR-ho-FUS">
|
||||
<rect key="frame" x="15" y="0.0" width="230" height="18"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="why_support_item2"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular15"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackPrimaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="WMR-ho-FUS" firstAttribute="leading" secondItem="3CU-Qm-qr9" secondAttribute="trailing" constant="8" id="GRU-ab-thF"/>
|
||||
<constraint firstItem="3CU-Qm-qr9" firstAttribute="top" secondItem="N1P-1l-fOT" secondAttribute="top" id="K3I-Go-jJe"/>
|
||||
<constraint firstAttribute="trailing" secondItem="WMR-ho-FUS" secondAttribute="trailing" id="Mg8-iu-i0B"/>
|
||||
<constraint firstItem="WMR-ho-FUS" firstAttribute="top" secondItem="N1P-1l-fOT" secondAttribute="top" id="l18-Cp-31b"/>
|
||||
<constraint firstAttribute="bottom" secondItem="WMR-ho-FUS" secondAttribute="bottom" id="tEv-Rh-6ix"/>
|
||||
<constraint firstItem="3CU-Qm-qr9" firstAttribute="leading" secondItem="N1P-1l-fOT" secondAttribute="leading" id="xhb-bc-kaB"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Q0y-IM-H43">
|
||||
<rect key="frame" x="35" y="113" width="245" height="36"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="•" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PXD-OM-5Xd">
|
||||
<rect key="frame" x="0.0" y="0.0" width="7" height="18"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular15"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="colorName" value="linkBlue"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="You help us improve open
maps OpenStreetMap.org" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Yos-eN-bY1">
|
||||
<rect key="frame" x="15" y="0.0" width="230" height="36"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="why_support_item3"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular15"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackPrimaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="Yos-eN-bY1" firstAttribute="top" secondItem="Q0y-IM-H43" secondAttribute="top" id="2Tv-qh-XIE"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Yos-eN-bY1" secondAttribute="trailing" id="3qq-y9-dI8"/>
|
||||
<constraint firstItem="PXD-OM-5Xd" firstAttribute="leading" secondItem="Q0y-IM-H43" secondAttribute="leading" id="UPJ-Dv-6LK"/>
|
||||
<constraint firstItem="Yos-eN-bY1" firstAttribute="leading" secondItem="PXD-OM-5Xd" secondAttribute="trailing" constant="8" id="bJa-tw-GVh"/>
|
||||
<constraint firstItem="PXD-OM-5Xd" firstAttribute="top" secondItem="Q0y-IM-H43" secondAttribute="top" id="bdg-dj-Qdd"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Yos-eN-bY1" secondAttribute="bottom" id="zDD-Sg-9Ug"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="Q0y-IM-H43" firstAttribute="top" secondItem="N1P-1l-fOT" secondAttribute="bottom" constant="16" id="2Lb-kh-iZg"/>
|
||||
<constraint firstItem="Jhy-EZ-HaR" firstAttribute="leading" secondItem="pAe-qE-h95" secondAttribute="leading" constant="35" id="5sS-j1-mUW"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Q0y-IM-H43" secondAttribute="trailing" constant="40" id="AOG-kC-apb"/>
|
||||
<constraint firstItem="N1P-1l-fOT" firstAttribute="top" secondItem="Jhy-EZ-HaR" secondAttribute="bottom" constant="16" id="AbP-zo-gh2"/>
|
||||
<constraint firstItem="YQ4-oq-7XN" firstAttribute="top" secondItem="pAe-qE-h95" secondAttribute="top" id="EkV-BK-L8z"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Q0y-IM-H43" secondAttribute="bottom" priority="500" constant="16" id="G7R-WQ-rqa"/>
|
||||
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="Q0y-IM-H43" secondAttribute="bottom" constant="16" id="HnK-lo-A7U"/>
|
||||
<constraint firstItem="N1P-1l-fOT" firstAttribute="leading" secondItem="pAe-qE-h95" secondAttribute="leading" constant="35" id="a4q-Oc-xpJ"/>
|
||||
<constraint firstItem="Jhy-EZ-HaR" firstAttribute="top" secondItem="YQ4-oq-7XN" secondAttribute="bottom" constant="16" id="dnF-54-ldh"/>
|
||||
<constraint firstAttribute="trailing" secondItem="YQ4-oq-7XN" secondAttribute="trailing" constant="24" id="lC1-ZR-7pr"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Jhy-EZ-HaR" secondAttribute="trailing" constant="40" id="s5X-wf-eO0"/>
|
||||
<constraint firstItem="YQ4-oq-7XN" firstAttribute="leading" secondItem="pAe-qE-h95" secondAttribute="leading" constant="24" id="uwK-dG-yPs"/>
|
||||
<constraint firstAttribute="trailing" secondItem="N1P-1l-fOT" secondAttribute="trailing" constant="40" id="vf7-yc-aSD"/>
|
||||
<constraint firstItem="Q0y-IM-H43" firstAttribute="leading" secondItem="pAe-qE-h95" secondAttribute="leading" constant="35" id="xC8-Qq-IYT"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="white"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
<button opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="yaj-2x-NKs">
|
||||
<rect key="frame" x="32.5" y="259.5" width="256" height="72"/>
|
||||
<color key="backgroundColor" red="0.14000108506944445" green="0.60983615451388884" blue="0.94859483506944442" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="72" id="GcQ-JZ-VF4"/>
|
||||
<constraint firstAttribute="width" constant="256" id="TWS-OZ-AhB"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="20"/>
|
||||
<inset key="contentEdgeInsets" minX="0.0" minY="-18" maxX="0.0" maxY="0.0"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
|
||||
<integer key="value" value="5"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="boolean" keyPath="clipsToBounds" value="YES"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="linkBlue"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundHighlightedColorName" value="linkBlueHighlighted"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<action selector="onPay:" destination="-1" eventType="touchUpInside" id="Q4Z-5u-bTt"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="save $46.49/year" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2o9-EE-vAM">
|
||||
<rect key="frame" x="103.5" y="301.5" width="113" height="17"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<color key="textColor" white="1" alpha="0.79757063356164382" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="nA0-bV-sRz">
|
||||
<rect key="frame" x="141.5" y="277.5" width="37" height="37"/>
|
||||
</activityIndicatorView>
|
||||
<view hidden="YES" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="moF-VX-t4N">
|
||||
<rect key="frame" x="52.5" y="346.5" width="215" height="36"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="1" translatesAutoresizingMaskIntoConstraints="NO" id="zJa-b8-ObU">
|
||||
<rect key="frame" x="0.0" y="0.0" width="215" height="109"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="leading" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7KI-mu-vBe">
|
||||
<rect key="frame" x="0.0" y="0.0" width="215" height="35.5"/>
|
||||
<color key="backgroundColor" white="0.92827492952346802" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="0.0" maxY="0.0"/>
|
||||
<state key="normal" title="MORE OPTIONS">
|
||||
<color key="titleColor" white="0.0" alpha="0.59813784243013701" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</state>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="options_dropdown_title"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular12"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="textColorName" value="blackSecondaryText"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="textColorHighlightedName" value="blackHintText"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="border"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundHighlightedColorName" value="blackDividers"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<action selector="onMoreOptions:" destination="-1" eventType="touchUpInside" id="XWb-f3-MaZ"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="leading" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="MPP-Wb-dwQ">
|
||||
<rect key="frame" x="0.0" y="36.5" width="215" height="36"/>
|
||||
<color key="backgroundColor" white="0.92827492952346802" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="0.0" maxY="0.0"/>
|
||||
<state key="normal" title="$1.99/month (save 18.89/year)">
|
||||
<color key="titleColor" white="0.0" alpha="0.59813784243013701" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</state>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="options_dropdown_title"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular12"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="textColorName" value="blackSecondaryText"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="textColorHighlightedName" value="blackHintText"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="border"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundHighlightedColorName" value="blackDividers"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<action selector="onMonth:" destination="-1" eventType="touchUpInside" id="4ir-Kn-VPR"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="leading" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="XY6-tA-B1U">
|
||||
<rect key="frame" x="0.0" y="73.5" width="215" height="35.5"/>
|
||||
<color key="backgroundColor" white="0.92827492952346802" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="0.0" maxY="0.0"/>
|
||||
<state key="normal" title="$0.99/week (no savings)">
|
||||
<color key="titleColor" white="0.0" alpha="0.59813784243013701" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</state>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="options_dropdown_title"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular12"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="textColorName" value="blackSecondaryText"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="textColorHighlightedName" value="blackHintText"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="border"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundHighlightedColorName" value="blackDividers"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<action selector="onWeek:" destination="-1" eventType="touchUpInside" id="8da-h3-KW6"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="109" id="dSc-YD-4Cn"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="zJa-b8-ObU" firstAttribute="top" secondItem="moF-VX-t4N" secondAttribute="top" id="AES-b6-bzk"/>
|
||||
<constraint firstAttribute="bottom" secondItem="zJa-b8-ObU" secondAttribute="bottom" priority="750" id="AhK-22-qtU"/>
|
||||
<constraint firstItem="zJa-b8-ObU" firstAttribute="leading" secondItem="moF-VX-t4N" secondAttribute="leading" id="NhF-ji-9zZ"/>
|
||||
<constraint firstAttribute="width" constant="215" id="YE2-kk-Dwr"/>
|
||||
<constraint firstAttribute="trailing" secondItem="zJa-b8-ObU" secondAttribute="trailing" id="jZ7-p4-ilg"/>
|
||||
<constraint firstAttribute="height" constant="36" id="u0h-Qx-wo9"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
|
||||
<integer key="value" value="9"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="blackDividers"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3V5-Dx-w2P">
|
||||
<rect key="frame" x="81.5" y="503" width="158" height="29"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<state key="normal" title="Why support MAPS.ME?">
|
||||
<color key="titleColor" white="0.0" alpha="0.53486194349315064" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</state>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="why_support"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular14"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="textColorName" value="blackSecondaryText"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="textColorHighlightedName" value="blackHintText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<action selector="onWhySupport:" destination="-1" eventType="touchUpInside" id="lgd-75-mK8"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="pAe-qE-h95" secondAttribute="trailing" id="1CQ-Ze-Hbl"/>
|
||||
<constraint firstAttribute="bottom" secondItem="3V5-Dx-w2P" secondAttribute="bottom" constant="16" id="2GH-M9-SCD"/>
|
||||
<constraint firstItem="pAe-qE-h95" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" id="2kl-Qa-qav"/>
|
||||
<constraint firstItem="2o9-EE-vAM" firstAttribute="centerX" secondItem="yaj-2x-NKs" secondAttribute="centerX" id="2w3-v0-HNI"/>
|
||||
<constraint firstItem="vCa-Yl-SkC" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" constant="24" id="AWJ-t8-Obh"/>
|
||||
<constraint firstItem="yaj-2x-NKs" firstAttribute="bottom" secondItem="2o9-EE-vAM" secondAttribute="bottom" constant="13" id="Eoo-Qq-0Vz"/>
|
||||
<constraint firstItem="3V5-Dx-w2P" firstAttribute="top" relation="greaterThanOrEqual" secondItem="yaj-2x-NKs" secondAttribute="bottom" constant="141" id="G65-q9-khr"/>
|
||||
<constraint firstItem="moF-VX-t4N" firstAttribute="top" secondItem="yaj-2x-NKs" secondAttribute="bottom" constant="15" id="KU1-p6-eNP"/>
|
||||
<constraint firstItem="pAe-qE-h95" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="24" id="Pyc-Gg-tON"/>
|
||||
<constraint firstItem="moF-VX-t4N" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="TvR-G1-Y0U"/>
|
||||
<constraint firstItem="yaj-2x-NKs" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="WhB-Qb-HvZ"/>
|
||||
<constraint firstItem="yaj-2x-NKs" firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="AmL-7Q-Kas" secondAttribute="bottom" id="a9c-Yc-rJP"/>
|
||||
<constraint firstItem="AmL-7Q-Kas" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="e6f-2Z-brM"/>
|
||||
<constraint firstItem="3V5-Dx-w2P" firstAttribute="top" secondItem="yaj-2x-NKs" secondAttribute="bottom" priority="250" constant="141" id="en1-E7-FAF"/>
|
||||
<constraint firstItem="yaj-2x-NKs" firstAttribute="top" secondItem="pAe-qE-h95" secondAttribute="bottom" priority="250" id="gIY-Uk-WiX"/>
|
||||
<constraint firstItem="yaj-2x-NKs" firstAttribute="top" secondItem="AmL-7Q-Kas" secondAttribute="bottom" priority="750" constant="12" id="hdg-bJ-61l"/>
|
||||
<constraint firstItem="3V5-Dx-w2P" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="idr-4f-Z6r"/>
|
||||
<constraint firstAttribute="trailing" secondItem="vCa-Yl-SkC" secondAttribute="trailing" constant="24" id="lbT-SI-3pb"/>
|
||||
<constraint firstItem="vCa-Yl-SkC" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="24" id="rBS-o0-mCS"/>
|
||||
<constraint firstItem="nA0-bV-sRz" firstAttribute="centerX" secondItem="yaj-2x-NKs" secondAttribute="centerX" id="srt-v2-pus"/>
|
||||
<constraint firstItem="nA0-bV-sRz" firstAttribute="centerY" secondItem="yaj-2x-NKs" secondAttribute="centerY" id="tsA-M8-hFS"/>
|
||||
<constraint firstItem="AmL-7Q-Kas" firstAttribute="top" secondItem="vCa-Yl-SkC" secondAttribute="bottom" constant="24" id="vT7-2H-bmK"/>
|
||||
<constraint firstItem="3V5-Dx-w2P" firstAttribute="top" secondItem="moF-VX-t4N" secondAttribute="bottom" priority="250" constant="16" id="z3U-uz-oiR"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="white"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<variation key="default">
|
||||
<mask key="constraints">
|
||||
<exclude reference="G65-q9-khr"/>
|
||||
<exclude reference="en1-E7-FAF"/>
|
||||
<exclude reference="z3U-uz-oiR"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=compact-widthClass=compact">
|
||||
<mask key="constraints">
|
||||
<include reference="z3U-uz-oiR"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=compact-widthClass=regular">
|
||||
<mask key="constraints">
|
||||
<include reference="z3U-uz-oiR"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular-widthClass=compact">
|
||||
<mask key="constraints">
|
||||
<include reference="G65-q9-khr"/>
|
||||
<include reference="en1-E7-FAF"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular-widthClass=regular">
|
||||
<mask key="constraints">
|
||||
<include reference="G65-q9-khr"/>
|
||||
<include reference="en1-E7-FAF"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</view>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="i5M-Pr-FkT" firstAttribute="top" secondItem="aRL-MT-ZBH" secondAttribute="top" id="4U4-89-oKL"/>
|
||||
<constraint firstItem="i5M-Pr-FkT" firstAttribute="height" relation="greaterThanOrEqual" secondItem="aRL-MT-ZBH" secondAttribute="height" id="90I-og-xrF"/>
|
||||
<constraint firstAttribute="trailing" secondItem="i5M-Pr-FkT" secondAttribute="trailing" id="Ob4-QQ-FMt"/>
|
||||
<constraint firstItem="i5M-Pr-FkT" firstAttribute="leading" secondItem="aRL-MT-ZBH" secondAttribute="leading" id="Tkh-ZG-DyV"/>
|
||||
<constraint firstAttribute="bottom" secondItem="i5M-Pr-FkT" secondAttribute="bottom" id="qPG-U5-are"/>
|
||||
</constraints>
|
||||
</scrollView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="sW4-fw-4Az">
|
||||
<rect key="frame" x="276" y="0.0" width="44" height="44"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="44" id="Jsn-5x-Xxq"/>
|
||||
<constraint firstAttribute="height" constant="44" id="Z3Z-BM-iFO"/>
|
||||
</constraints>
|
||||
<color key="tintColor" white="0.697509765625" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" image="ic_ads_remove_close"/>
|
||||
<connections>
|
||||
<action selector="onClose:" destination="-1" eventType="touchUpInside" id="SD3-LB-6gg"/>
|
||||
</connections>
|
||||
</button>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7Al-wo-fvb">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="548"/>
|
||||
<subviews>
|
||||
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="LhO-RQ-vOf">
|
||||
<rect key="frame" x="141.5" y="255.5" width="37" height="37"/>
|
||||
<color key="color" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</activityIndicatorView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="0.89998929794520544" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="LhO-RQ-vOf" firstAttribute="centerX" secondItem="7Al-wo-fvb" secondAttribute="centerX" id="01M-FO-l2E"/>
|
||||
<constraint firstItem="LhO-RQ-vOf" firstAttribute="centerY" secondItem="7Al-wo-fvb" secondAttribute="centerY" id="AAS-WB-BvS"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="toastBackground"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="sW4-fw-4Az" secondAttribute="trailing" id="Mla-FC-OUr"/>
|
||||
<constraint firstItem="sW4-fw-4Az" firstAttribute="top" secondItem="raA-Qo-8vn" secondAttribute="top" id="ODl-nm-Oxd"/>
|
||||
<constraint firstItem="7Al-wo-fvb" firstAttribute="top" secondItem="raA-Qo-8vn" secondAttribute="top" id="QlH-hB-LQN"/>
|
||||
<constraint firstItem="i5M-Pr-FkT" firstAttribute="height" secondItem="raA-Qo-8vn" secondAttribute="height" id="TDj-Js-St4"/>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="320" id="VdN-qU-lhk"/>
|
||||
<constraint firstAttribute="bottom" secondItem="7Al-wo-fvb" secondAttribute="bottom" id="adv-pq-MZl"/>
|
||||
<constraint firstAttribute="trailing" secondItem="aRL-MT-ZBH" secondAttribute="trailing" id="bB0-8N-f7V"/>
|
||||
<constraint firstItem="aRL-MT-ZBH" firstAttribute="top" secondItem="raA-Qo-8vn" secondAttribute="top" id="ccC-bj-dyo"/>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" priority="999" constant="570" id="eN2-eT-svS"/>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="320" id="gMV-LL-t8v"/>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" priority="999" constant="570" id="iyr-JZ-opr"/>
|
||||
<constraint firstItem="7Al-wo-fvb" firstAttribute="leading" secondItem="raA-Qo-8vn" secondAttribute="leading" id="oIx-qA-TCk"/>
|
||||
<constraint firstAttribute="trailing" secondItem="7Al-wo-fvb" secondAttribute="trailing" id="sOy-jl-HBx"/>
|
||||
<constraint firstItem="i5M-Pr-FkT" firstAttribute="width" secondItem="raA-Qo-8vn" secondAttribute="width" id="wjG-bY-7G0"/>
|
||||
<constraint firstItem="aRL-MT-ZBH" firstAttribute="leading" secondItem="raA-Qo-8vn" secondAttribute="leading" id="y4C-Aq-a7t"/>
|
||||
<constraint firstAttribute="bottom" secondItem="aRL-MT-ZBH" secondAttribute="bottom" id="yQ4-7g-M0F"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
|
||||
<integer key="value" value="9"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<variation key="default">
|
||||
<mask key="constraints">
|
||||
<exclude reference="VdN-qU-lhk"/>
|
||||
<exclude reference="eN2-eT-svS"/>
|
||||
<exclude reference="gMV-LL-t8v"/>
|
||||
<exclude reference="iyr-JZ-opr"/>
|
||||
<exclude reference="TDj-Js-St4"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=compact-widthClass=compact">
|
||||
<mask key="constraints">
|
||||
<exclude reference="VdN-qU-lhk"/>
|
||||
<include reference="gMV-LL-t8v"/>
|
||||
<include reference="iyr-JZ-opr"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=compact-widthClass=regular">
|
||||
<mask key="constraints">
|
||||
<include reference="VdN-qU-lhk"/>
|
||||
<include reference="gMV-LL-t8v"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular-widthClass=compact">
|
||||
<mask key="constraints">
|
||||
<include reference="VdN-qU-lhk"/>
|
||||
<include reference="eN2-eT-svS"/>
|
||||
<include reference="TDj-Js-St4"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular-widthClass=regular">
|
||||
<mask key="constraints">
|
||||
<include reference="VdN-qU-lhk"/>
|
||||
<exclude reference="eN2-eT-svS"/>
|
||||
<exclude reference="TDj-Js-St4"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</view>
|
||||
</subviews>
|
||||
<gestureRecognizers/>
|
||||
<constraints>
|
||||
<constraint firstItem="raA-Qo-8vn" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="b8x-4n-fzO" secondAttribute="leading" id="0rU-jZ-bS6"/>
|
||||
<constraint firstItem="raA-Qo-8vn" firstAttribute="top" secondItem="b8x-4n-fzO" secondAttribute="top" priority="750" constant="56" id="3Ma-5r-TRl"/>
|
||||
<constraint firstItem="b8x-4n-fzO" firstAttribute="trailing" secondItem="raA-Qo-8vn" secondAttribute="trailing" priority="750" constant="56" id="B9y-4c-fIB"/>
|
||||
<constraint firstItem="raA-Qo-8vn" firstAttribute="centerX" secondItem="b8x-4n-fzO" secondAttribute="centerX" id="HG8-Kv-tqa"/>
|
||||
<constraint firstItem="b8x-4n-fzO" firstAttribute="bottom" secondItem="raA-Qo-8vn" secondAttribute="bottom" priority="750" constant="24" id="InF-Ya-BKi"/>
|
||||
<constraint firstItem="raA-Qo-8vn" firstAttribute="top" secondItem="b8x-4n-fzO" secondAttribute="top" priority="750" constant="24" id="TC5-ex-ABv"/>
|
||||
<constraint firstItem="b8x-4n-fzO" firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="raA-Qo-8vn" secondAttribute="trailing" id="VKq-gf-OxM"/>
|
||||
<constraint firstItem="raA-Qo-8vn" firstAttribute="leading" secondItem="b8x-4n-fzO" secondAttribute="leading" priority="750" constant="56" id="WK6-fS-Ffr"/>
|
||||
<constraint firstItem="raA-Qo-8vn" firstAttribute="leading" secondItem="b8x-4n-fzO" secondAttribute="leading" priority="750" constant="24" id="apq-su-Uak"/>
|
||||
<constraint firstItem="b8x-4n-fzO" firstAttribute="bottom" secondItem="raA-Qo-8vn" secondAttribute="bottom" priority="750" constant="56" id="cbM-5A-LWe"/>
|
||||
<constraint firstAttribute="bottom" secondItem="T82-qa-a8r" secondAttribute="bottom" id="fVu-JZ-I8h"/>
|
||||
<constraint firstItem="b8x-4n-fzO" firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="raA-Qo-8vn" secondAttribute="bottom" id="hj9-dv-Y64"/>
|
||||
<constraint firstItem="raA-Qo-8vn" firstAttribute="top" relation="greaterThanOrEqual" secondItem="b8x-4n-fzO" secondAttribute="top" id="iko-gJ-NsP"/>
|
||||
<constraint firstItem="b8x-4n-fzO" firstAttribute="trailing" secondItem="raA-Qo-8vn" secondAttribute="trailing" priority="750" constant="24" id="iwp-8k-tG4"/>
|
||||
<constraint firstAttribute="trailing" secondItem="T82-qa-a8r" secondAttribute="trailing" id="kgC-1q-FUB"/>
|
||||
<constraint firstItem="T82-qa-a8r" firstAttribute="leading" secondItem="i5T-Pr-FkT" secondAttribute="leading" id="maf-fm-wty"/>
|
||||
<constraint firstItem="T82-qa-a8r" firstAttribute="top" secondItem="i5T-Pr-FkT" secondAttribute="top" id="tox-cK-3YS"/>
|
||||
<constraint firstItem="raA-Qo-8vn" firstAttribute="centerY" secondItem="b8x-4n-fzO" secondAttribute="centerY" id="xOQ-NQ-T1d"/>
|
||||
</constraints>
|
||||
<viewLayoutGuide key="safeArea" id="b8x-4n-fzO"/>
|
||||
<variation key="default">
|
||||
<mask key="constraints">
|
||||
<exclude reference="B9y-4c-fIB"/>
|
||||
<exclude reference="InF-Ya-BKi"/>
|
||||
<exclude reference="cbM-5A-LWe"/>
|
||||
<exclude reference="iwp-8k-tG4"/>
|
||||
<exclude reference="3Ma-5r-TRl"/>
|
||||
<exclude reference="TC5-ex-ABv"/>
|
||||
<exclude reference="WK6-fS-Ffr"/>
|
||||
<exclude reference="apq-su-Uak"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=compact-widthClass=compact">
|
||||
<mask key="constraints">
|
||||
<include reference="B9y-4c-fIB"/>
|
||||
<include reference="InF-Ya-BKi"/>
|
||||
<include reference="TC5-ex-ABv"/>
|
||||
<include reference="WK6-fS-Ffr"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=compact-widthClass=regular">
|
||||
<mask key="constraints">
|
||||
<include reference="B9y-4c-fIB"/>
|
||||
<include reference="InF-Ya-BKi"/>
|
||||
<include reference="TC5-ex-ABv"/>
|
||||
<include reference="WK6-fS-Ffr"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular-widthClass=compact">
|
||||
<mask key="constraints">
|
||||
<include reference="cbM-5A-LWe"/>
|
||||
<include reference="iwp-8k-tG4"/>
|
||||
<include reference="3Ma-5r-TRl"/>
|
||||
<include reference="apq-su-Uak"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular-widthClass=regular">
|
||||
<mask key="constraints">
|
||||
<include reference="B9y-4c-fIB"/>
|
||||
<include reference="InF-Ya-BKi"/>
|
||||
<include reference="TC5-ex-ABv"/>
|
||||
<include reference="WK6-fS-Ffr"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<point key="canvasLocation" x="33" y="53"/>
|
||||
</view>
|
||||
<tapGestureRecognizer enabled="NO" id="cab-7b-e1x">
|
||||
<connections>
|
||||
<action selector="onClose:" destination="-1" id="uz7-J3-tJZ"/>
|
||||
</connections>
|
||||
</tapGestureRecognizer>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="ic_ads_remove_close" width="16" height="16"/>
|
||||
<image name="mappy_heart" width="124" height="142"/>
|
||||
</resources>
|
||||
</document>
|
|
@ -279,7 +279,13 @@ std::array<Class, 9> const kPreviewCells = {{[_MWMPPPTitle class],
|
|||
return c;
|
||||
case PreviewRows::Banner:
|
||||
auto bannerCell = static_cast<MWMAdBanner *>(c);
|
||||
[bannerCell configWithAd:data.nativeAd containerType:MWMAdBannerContainerTypePlacePage];
|
||||
[bannerCell configWithAd:data.nativeAd
|
||||
containerType:MWMAdBannerContainerTypePlacePage
|
||||
canRemoveAds:[SubscriptionManager canMakePayments]
|
||||
onRemoveAds: ^{
|
||||
[[MapViewController sharedController] showRemoveAds];
|
||||
}];
|
||||
|
||||
self.cachedBannerCell = bannerCell;
|
||||
return bannerCell;
|
||||
}
|
||||
|
|
|
@ -124,7 +124,12 @@ NSString * GetLocalizedTypeName(search::Result const & result)
|
|||
fallbackAd.cellIndexPath = indexPath;
|
||||
fallbackAd.dynamicSizeDelegate = self;
|
||||
}
|
||||
[cell configWithAd:ad containerType:MWMAdBannerContainerTypeSearch];
|
||||
[cell configWithAd:ad
|
||||
containerType:MWMAdBannerContainerTypeSearch
|
||||
canRemoveAds:[SubscriptionManager canMakePayments]
|
||||
onRemoveAds: ^{
|
||||
[[MapViewController sharedController] showRemoveAds];
|
||||
}];
|
||||
return cell;
|
||||
}
|
||||
case MWMSearchItemTypeSuggestion:
|
||||
|
|
Loading…
Add table
Reference in a new issue