forked from organicmaps/organicmaps
[ios] New way of banners showing.
This commit is contained in:
parent
9ab22f3d3c
commit
25867c3dff
9 changed files with 168 additions and 83 deletions
|
@ -152,7 +152,7 @@ static NSString * const kStatOther = @"Other";
|
|||
static NSString * const kStatOut = @"Out";
|
||||
static NSString * const kStatPedestrian = @"Pedestrian";
|
||||
static NSString * const kStatPlacePage = @"Place page";
|
||||
static NSString * const kStatPlacePageBannerClick = @"Placepage_Banner_click";
|
||||
static NSString * const kStatPlacePageBannerError = @"Placepage_Banner_error";
|
||||
static NSString * const kStatPlacePageBannerShow = @"Placepage_Banner_show";
|
||||
static NSString * const kPlacePageHotelBook = @"Placepage_Hotel_book";
|
||||
static NSString * const kPlacePageHotelDetails = @"Placepage_Hotel_details";
|
||||
|
|
|
@ -19,70 +19,37 @@ enum FBAdsBannerState: Int {
|
|||
@objc(MWMFBAdsBanner)
|
||||
final class FBAdsBanner: UITableViewCell {
|
||||
@IBOutlet private var detailedModeConstraints: [NSLayoutConstraint]!
|
||||
@IBOutlet fileprivate weak var adIconImageView: UIImageView!
|
||||
@IBOutlet fileprivate weak var adTitleLabel: UILabel!
|
||||
@IBOutlet fileprivate weak var adBodyLabel: UILabel!
|
||||
@IBOutlet fileprivate var adCallToActionButtonCompact: UIButton!
|
||||
@IBOutlet fileprivate var adCallToActionButtonDetailed: UIButton!
|
||||
@IBOutlet private weak var adIconImageView: UIImageView!
|
||||
@IBOutlet private weak var adTitleLabel: UILabel!
|
||||
@IBOutlet private weak var adBodyLabel: UILabel!
|
||||
@IBOutlet private var adCallToActionButtonCompact: UIButton!
|
||||
@IBOutlet private var adCallToActionButtonDetailed: UIButton!
|
||||
static let detailedBannerExcessHeight: Float = 36
|
||||
|
||||
var state = FBAdsBannerState.compact {
|
||||
var state = alternative(iPhone: FBAdsBannerState.compact, iPad: FBAdsBannerState.detailed) {
|
||||
didSet {
|
||||
let config = state.config()
|
||||
layoutIfNeeded()
|
||||
adBodyLabel.numberOfLines = config.numberOfLines
|
||||
detailedModeConstraints.forEach { $0.priority = config.priority }
|
||||
setNeedsLayout()
|
||||
UIView.animate(withDuration: kDefaultAnimationDuration) { self.layoutIfNeeded() }
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate var nativeAd: FBNativeAd?
|
||||
private var nativeAd: FBNativeAd?
|
||||
|
||||
func config(placementID: String) {
|
||||
style()
|
||||
contentView.alpha = 0
|
||||
state = .compact
|
||||
let nativeAd = FBNativeAd(placementID: placementID)
|
||||
nativeAd.delegate = self
|
||||
nativeAd.mediaCachePolicy = .all
|
||||
nativeAd.load()
|
||||
}
|
||||
|
||||
private func style() {
|
||||
adTitleLabel.font = UIFont.bold12()
|
||||
adBodyLabel.font = UIFont.regular12()
|
||||
adCallToActionButtonCompact.titleLabel?.font = UIFont.regular12()
|
||||
adCallToActionButtonDetailed.titleLabel?.font = UIFont.regular15()
|
||||
|
||||
backgroundColor = UIColor.bannerBackground()
|
||||
let color = UIColor.blackSecondaryText()!
|
||||
adTitleLabel.textColor = color
|
||||
adBodyLabel.textColor = color
|
||||
adCallToActionButtonCompact.setTitleColor(color, for: .normal)
|
||||
adCallToActionButtonDetailed.setTitleColor(color, for: .normal)
|
||||
adCallToActionButtonDetailed.backgroundColor = UIColor.bannerButtonBackground()
|
||||
|
||||
let layer = adCallToActionButtonCompact.layer
|
||||
layer.borderColor = color.cgColor
|
||||
layer.borderWidth = 1
|
||||
layer.cornerRadius = 4
|
||||
}
|
||||
}
|
||||
|
||||
extension FBAdsBanner: FBNativeAdDelegate {
|
||||
func nativeAdDidLoad(_ nativeAd: FBNativeAd) {
|
||||
if let sNativeAd = self.nativeAd {
|
||||
sNativeAd.unregisterView()
|
||||
}
|
||||
self.nativeAd = nativeAd
|
||||
func config(ad: FBNativeAd) {
|
||||
nativeAd = ad
|
||||
ad.unregisterView()
|
||||
let adCallToActionButtons = [adCallToActionButtonCompact!, adCallToActionButtonDetailed!]
|
||||
nativeAd.registerView(forInteraction: self, with: nil, withClickableViews: adCallToActionButtons)
|
||||
ad.registerView(forInteraction: self, with: nil, withClickableViews: adCallToActionButtons)
|
||||
|
||||
nativeAd.icon?.loadAsync { [weak self] image in
|
||||
ad.icon?.loadAsync { [weak self] image in
|
||||
self?.adIconImageView.image = image
|
||||
}
|
||||
adTitleLabel.text = nativeAd.title
|
||||
adBodyLabel.text = nativeAd.body
|
||||
adCallToActionButtons.forEach { $0.setTitle(nativeAd.callToAction, for: .normal) }
|
||||
UIView.animate(withDuration: kDefaultAnimationDuration) { self.contentView.alpha = 1 }
|
||||
|
||||
adTitleLabel.text = ad.title
|
||||
adBodyLabel.text = ad.body
|
||||
adCallToActionButtons.forEach { $0.setTitle(ad.callToAction, for: .normal) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,12 +51,20 @@
|
|||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="12"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.59999999999999998" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="bold12"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackSecondaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="TopLeft" horizontalHuggingPriority="551" verticalHuggingPriority="249" horizontalCompressionResistancePriority="249" text="Как превратить обычный день в праздник? Просто сделай заказ через Delivery Club!" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ev3-yY-ql1">
|
||||
<rect key="frame" x="16" y="27" width="258.5" height="74.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.59999999999999998" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular12"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackSecondaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="551" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9qA-JC-fkn">
|
||||
<rect key="frame" x="290" y="18" width="69" height="24"/>
|
||||
|
@ -70,6 +78,19 @@
|
|||
<state key="normal" title="Заказать">
|
||||
<color key="titleColor" red="0.59999999999999998" green="0.58823529411764708" blue="0.56862745098039214" alpha="0.40000000000000002" colorSpace="calibratedRGB"/>
|
||||
</state>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular12"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="textColorName" value="blackSecondaryText"/>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="layer.borderUIColor">
|
||||
<color key="value" red="0.0" green="0.0" blue="0.0" alpha="0.59999999999999998" colorSpace="calibratedRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="layer.borderWidth">
|
||||
<integer key="value" value="1"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
|
||||
<integer key="value" value="4"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NKM-3R-3g1">
|
||||
<rect key="frame" x="0.0" y="109.5" width="375" height="36"/>
|
||||
|
@ -80,6 +101,11 @@
|
|||
<state key="normal" title="Заказать">
|
||||
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="0.40000000000000002" colorSpace="calibratedRGB"/>
|
||||
</state>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular15"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="bannerButtonBackground"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="textColorName" value="blackSecondaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
|
@ -107,6 +133,9 @@
|
|||
<constraint firstItem="zWu-Gh-Vf7" firstAttribute="leading" secondItem="f76-qn-ne4" secondAttribute="leading" priority="600" constant="16" id="vlX-zx-nfP"/>
|
||||
<constraint firstItem="zWu-Gh-Vf7" firstAttribute="leading" secondItem="EuF-Rm-DHQ" secondAttribute="trailing" priority="250" constant="8" id="w5K-BT-1ED"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="bannerBackground"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</tableViewCellContentView>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<connections>
|
||||
|
|
|
@ -88,17 +88,20 @@ enum class OpeningHours
|
|||
Unknown
|
||||
};
|
||||
|
||||
using NewSectionsReady = void(^)(NSRange const & range);
|
||||
using NewSectionsAreReady = void (^)(NSRange const & range);
|
||||
using BannerIsReady = void (^)();
|
||||
|
||||
} // namespace place_page
|
||||
|
||||
|
||||
@class MWMGalleryItemModel;
|
||||
@class FBNativeAd;
|
||||
|
||||
/// ViewModel for place page.
|
||||
@interface MWMPlacePageData : NSObject
|
||||
|
||||
@property (copy, nonatomic) place_page::NewSectionsReady sectionsReadyCallback;
|
||||
@property(copy, nonatomic) place_page::NewSectionsAreReady sectionsAreReadyCallback;
|
||||
@property(copy, nonatomic) place_page::BannerIsReady bannerIsReadyCallback;
|
||||
|
||||
// ready callback will be called from main queue.
|
||||
- (instancetype)initWithPlacePageInfo:(place_page::Info const &)info;
|
||||
|
@ -131,7 +134,7 @@ using NewSectionsReady = void(^)(NSRange const & range);
|
|||
- (NSArray<MWMGalleryItemModel *> *)photos;
|
||||
|
||||
// Banner
|
||||
- (banners::Banner)banner;
|
||||
- (FBNativeAd *)nativeAd;
|
||||
|
||||
// API
|
||||
- (NSString *)apiURL;
|
||||
|
|
|
@ -2,8 +2,11 @@
|
|||
#import "AppInfo.h"
|
||||
#import "MWMNetworkPolicy.h"
|
||||
#import "MWMSettings.h"
|
||||
#import "Statistics.h"
|
||||
#import "SwiftBridge.h"
|
||||
|
||||
#import <FBAudienceNetwork/FBAudienceNetwork.h>
|
||||
|
||||
#include "Framework.h"
|
||||
|
||||
#include "indexer/banners.hpp"
|
||||
|
@ -20,9 +23,10 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS";
|
|||
|
||||
using namespace place_page;
|
||||
|
||||
@interface MWMPlacePageData()
|
||||
@interface MWMPlacePageData ()<FBNativeAdDelegate>
|
||||
|
||||
@property(copy, nonatomic) NSString * cachedMinPrice;
|
||||
@property(nonatomic) FBNativeAd * nativeAd;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -97,7 +101,13 @@ using namespace place_page;
|
|||
NSAssert(!m_previewRows.empty(), @"Preview row's can't be empty!");
|
||||
m_previewRows.push_back(PreviewRows::Space);
|
||||
if (network_policy::CanUseNetwork() && ![MWMSettings adForbidden] && m_info.HasBanner())
|
||||
m_previewRows.push_back(PreviewRows::Banner);
|
||||
{
|
||||
self.nativeAd =
|
||||
[[FBNativeAd alloc] initWithPlacementID:@(m_info.GetBanner().m_bannerId.c_str())];
|
||||
self.nativeAd.delegate = self;
|
||||
self.nativeAd.mediaCachePolicy = FBNativeAdsCachePolicyAll;
|
||||
[self.nativeAd loadAd];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)fillMetaInfoSection
|
||||
|
@ -237,8 +247,8 @@ using namespace place_page;
|
|||
reviewsRows.emplace_back(HotelReviewsRow::ShowMore);
|
||||
length++;
|
||||
}
|
||||
|
||||
self.sectionsReadyCallback({position, length});
|
||||
|
||||
self.sectionsAreReadyCallback({position, length});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -407,10 +417,6 @@ using namespace place_page;
|
|||
return res;
|
||||
}
|
||||
|
||||
#pragma mark - Banner
|
||||
|
||||
- (banners::Banner)banner { return m_info.GetBanner(); }
|
||||
|
||||
#pragma mark - Bookmark
|
||||
|
||||
- (NSString *)externalTitle
|
||||
|
@ -510,4 +516,34 @@ using namespace place_page;
|
|||
return [result componentsJoinedByString:@", "];
|
||||
}
|
||||
|
||||
#pragma mark - FBNativeAdDelegate
|
||||
|
||||
- (void)nativeAdDidLoad:(FBNativeAd *)nativeAd
|
||||
{
|
||||
if (![nativeAd isEqual:self.nativeAd])
|
||||
return;
|
||||
|
||||
[Statistics logEvent:kStatPlacePageBannerShow
|
||||
withParameters:@{
|
||||
kStatTags : self.statisticsTags,
|
||||
kStatBanner : @(m_info.GetBanner().m_bannerId.c_str()),
|
||||
kStatProvider : kStatFacebook
|
||||
}];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self->m_previewRows.push_back(PreviewRows::Banner);
|
||||
self.bannerIsReadyCallback();
|
||||
});
|
||||
}
|
||||
|
||||
- (void)nativeAd:(FBNativeAd *)nativeAd didFailWithError:(NSError *)error
|
||||
{
|
||||
[Statistics logEvent:kStatPlacePageBannerError
|
||||
withParameters:@{
|
||||
kStatTags : self.statisticsTags,
|
||||
kStatBanner : @(m_info.GetBanner().m_bannerId.c_str()),
|
||||
kStatProvider : kStatFacebook
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -118,12 +118,14 @@ map<MetainfoRows, Class> const kMetaInfoCells = {
|
|||
{
|
||||
self.isPlacePageButtonsEnabled = YES;
|
||||
self.data = data;
|
||||
data.sectionsReadyCallback = ^(NSRange const & range)
|
||||
{
|
||||
data.sectionsAreReadyCallback = ^(NSRange const & range) {
|
||||
[self.placePageView.tableView insertSections:[NSIndexSet indexSetWithIndexesInRange:range]
|
||||
withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
};
|
||||
|
||||
|
||||
data.bannerIsReadyCallback = ^{
|
||||
[self.previewLayoutHelper insertRowAtTheEnd];
|
||||
};
|
||||
self.bookmarkCell = nil;
|
||||
|
||||
[self.actionBar configureWithData:static_cast<id<MWMActionBarSharedData>>(data)];
|
||||
|
|
|
@ -23,7 +23,8 @@ CGFloat const kLuftDraggingOffset = 30;
|
|||
CGFloat const kMinOffset = 1;
|
||||
} // namespace
|
||||
|
||||
@interface MWMiPhonePlacePageLayoutImpl () <UIScrollViewDelegate, UITableViewDelegate>
|
||||
@interface MWMiPhonePlacePageLayoutImpl ()<UIScrollViewDelegate, UITableViewDelegate,
|
||||
MWMPPPreviewLayoutHelperDelegate>
|
||||
|
||||
@property(nonatomic) MWMPPScrollView * scrollView;
|
||||
@property(nonatomic) ScrollDirection direction;
|
||||
|
@ -118,6 +119,29 @@ CGFloat const kMinOffset = 1;
|
|||
self.scrollView.contentSize = {size.width, size.height + self.placePageView.height};
|
||||
}
|
||||
|
||||
- (void)setPreviewLayoutHelper:(MWMPPPreviewLayoutHelper *)previewLayoutHelper
|
||||
{
|
||||
previewLayoutHelper.delegate = self;
|
||||
_previewLayoutHelper = previewLayoutHelper;
|
||||
}
|
||||
|
||||
#pragma mark - MWMPPPreviewLayoutHelperDelegate
|
||||
|
||||
- (void)heightWasChanged
|
||||
{
|
||||
auto scrollView = self.scrollView;
|
||||
scrollView.scrollEnabled = NO;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
auto actionBar = self.actionBar;
|
||||
actionBar.maxY = actionBar.superview.height;
|
||||
self.expandedContentOffset =
|
||||
self.previewLayoutHelper.height + actionBar.height - self.placePageView.top.height;
|
||||
if (self.state == State::Bottom)
|
||||
[scrollView setContentOffset:{ 0, self.expandedContentOffset } animated:YES];
|
||||
scrollView.scrollEnabled = YES;
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - UIScrollViewDelegate
|
||||
|
||||
- (BOOL)isPortrait
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
@class MWMPlacePageData;
|
||||
|
||||
@protocol MWMPPPreviewLayoutHelperDelegate<NSObject>
|
||||
|
||||
- (void)heightWasChanged;
|
||||
|
||||
@end
|
||||
|
||||
@interface MWMPPPreviewLayoutHelper : NSObject
|
||||
|
||||
- (instancetype)initWithTableView:(UITableView *)tableView;
|
||||
- (void)configWithData:(MWMPlacePageData *)data;
|
||||
- (void)setDelegate:(id<MWMPPPreviewLayoutHelperDelegate>)delegate;
|
||||
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
withData:(MWMPlacePageData *)data;
|
||||
- (void)rotateDirectionArrowToAngle:(CGFloat)angle;
|
||||
- (void)setDistanceToObject:(NSString *)distance;
|
||||
- (void)insertRowAtTheEnd;
|
||||
- (CGFloat)height;
|
||||
|
||||
- (void)layoutInOpenState:(BOOL)isOpen;
|
||||
|
|
|
@ -134,6 +134,9 @@ array<Class, 8> const kPreviewCells = {{[_MWMPPPTitle class], [_MWMPPPExternalTi
|
|||
@property(weak, nonatomic) NSLayoutConstraint * distanceCellTrailing;
|
||||
@property(weak, nonatomic) UIView * distanceView;
|
||||
|
||||
@property(weak, nonatomic) MWMPlacePageData * data;
|
||||
@property(weak, nonatomic) id<MWMPPPreviewLayoutHelperDelegate> delegate;
|
||||
|
||||
@property(nonatomic) CGFloat leading;
|
||||
@property(nonatomic) MWMDirectionView * directionView;
|
||||
@property(copy, nonatomic) NSString * distance;
|
||||
|
@ -168,9 +171,10 @@ array<Class, 8> const kPreviewCells = {{[_MWMPPPTitle class], [_MWMPPPExternalTi
|
|||
|
||||
- (void)configWithData:(MWMPlacePageData *)data
|
||||
{
|
||||
self.data = data;
|
||||
auto const & previewRows = data.previewRows;
|
||||
using place_page::PreviewRows;
|
||||
self.lastCellIsBanner = previewRows.back() == PreviewRows::Banner;
|
||||
self.lastCellIsBanner = NO;
|
||||
self.lastCellIndexPath = [NSIndexPath indexPathForRow:previewRows.size() - 1 inSection:0];
|
||||
auto it = find(previewRows.begin(), previewRows.end(), PreviewRows::Space);
|
||||
if (it != previewRows.end())
|
||||
|
@ -230,21 +234,8 @@ array<Class, 8> const kPreviewCells = {{[_MWMPPPTitle class], [_MWMPPPExternalTi
|
|||
case PreviewRows::Space:
|
||||
return c;
|
||||
case PreviewRows::Banner:
|
||||
auto banner = [data banner];
|
||||
NSString * bannerId = @(banner.m_bannerId.c_str());
|
||||
[Statistics logEvent:kStatPlacePageBannerShow
|
||||
withParameters:@{
|
||||
kStatTags : data.statisticsTags,
|
||||
kStatBanner : bannerId,
|
||||
kStatState : IPAD ? @1 : @0
|
||||
}];
|
||||
auto bannerCell = static_cast<MWMFBAdsBanner *>(c);
|
||||
using namespace banners;
|
||||
switch (banner.m_type)
|
||||
{
|
||||
case Banner::Type::None: NSAssert(false, @"Invalid banner type"); break;
|
||||
case Banner::Type::Facebook: [bannerCell configWithPlacementID:bannerId]; break;
|
||||
}
|
||||
[bannerCell configWithAd:data.nativeAd];
|
||||
self.cachedBannerCell = bannerCell;
|
||||
return bannerCell;
|
||||
}
|
||||
|
@ -302,14 +293,39 @@ array<Class, 8> const kPreviewCells = {{[_MWMPPPTitle class], [_MWMPPPExternalTi
|
|||
self.directionView.distanceLabel.text = distance;
|
||||
}
|
||||
|
||||
- (void)insertRowAtTheEnd
|
||||
{
|
||||
auto const & previewRows = self.data.previewRows;
|
||||
auto const size = previewRows.size();
|
||||
self.lastCellIsBanner = previewRows.back() == place_page::PreviewRows::Banner;
|
||||
self.lastCellIndexPath =
|
||||
[NSIndexPath indexPathForRow:size - 1
|
||||
inSection:static_cast<NSUInteger>(place_page::Sections::Preview)];
|
||||
[self.tableView insertRowsAtIndexPaths:@[ self.lastCellIndexPath ]
|
||||
withRowAnimation:UITableViewRowAnimationLeft];
|
||||
[self.delegate heightWasChanged];
|
||||
}
|
||||
|
||||
- (CGFloat)height
|
||||
{
|
||||
auto const rect = [self.tableView rectForRowAtIndexPath:self.lastCellIndexPath];
|
||||
return rect.origin.y + rect.size.height + (self.lastCellIsBanner ? 4 : 0);
|
||||
auto const height = rect.origin.y + rect.size.height;
|
||||
if (!self.lastCellIndexPath)
|
||||
return height;
|
||||
|
||||
auto constexpr gapBannerHeight = 4.0;
|
||||
CGFloat const excessHeight = self.cachedBannerCell.state == MWMFBAdsBannerStateDetailed
|
||||
? [MWMFBAdsBanner detailedBannerExcessHeight]
|
||||
: 0;
|
||||
|
||||
return height + gapBannerHeight - excessHeight;
|
||||
}
|
||||
|
||||
- (void)layoutInOpenState:(BOOL)isOpen
|
||||
{
|
||||
if (IPAD)
|
||||
return;
|
||||
|
||||
[self.tableView update:^{
|
||||
self.cachedBannerCell.state = isOpen ? MWMFBAdsBannerStateDetailed : MWMFBAdsBannerStateCompact;
|
||||
}];
|
||||
|
|
Loading…
Add table
Reference in a new issue