Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
|
|
@ -0,0 +1,62 @@
|
|||
typedef NS_ENUM(NSInteger, MWMActionBarButtonType) {
|
||||
MWMActionBarButtonTypeBooking,
|
||||
MWMActionBarButtonTypeBookingSearch,
|
||||
MWMActionBarButtonTypeBookmark,
|
||||
MWMActionBarButtonTypeTrack,
|
||||
MWMActionBarButtonTypeSaveTrackRecording,
|
||||
MWMActionBarButtonTypeNotSaveTrackRecording,
|
||||
MWMActionBarButtonTypeCall,
|
||||
MWMActionBarButtonTypeDownload,
|
||||
MWMActionBarButtonTypeMore,
|
||||
MWMActionBarButtonTypeOpentable,
|
||||
MWMActionBarButtonTypeRouteAddStop,
|
||||
MWMActionBarButtonTypeRouteFrom,
|
||||
MWMActionBarButtonTypeRouteRemoveStop,
|
||||
MWMActionBarButtonTypeRouteTo,
|
||||
MWMActionBarButtonTypeAvoidToll,
|
||||
MWMActionBarButtonTypeAvoidDirty,
|
||||
MWMActionBarButtonTypeAvoidFerry
|
||||
} NS_SWIFT_NAME(ActionBarButtonType);
|
||||
|
||||
typedef NS_ENUM(NSInteger, MWMBookmarksButtonState) {
|
||||
MWMBookmarksButtonStateSave,
|
||||
MWMBookmarksButtonStateDelete,
|
||||
MWMBookmarksButtonStateRecover,
|
||||
};
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
NSString * titleForButton(MWMActionBarButtonType type, BOOL isSelected);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@class MWMActionBarButton;
|
||||
@class MWMCircularProgress;
|
||||
|
||||
NS_SWIFT_NAME(ActionBarButtonDelegate)
|
||||
@protocol MWMActionBarButtonDelegate <NSObject>
|
||||
|
||||
- (void)tapOnButtonWithType:(MWMActionBarButtonType)type;
|
||||
|
||||
@end
|
||||
|
||||
NS_SWIFT_NAME(ActionBarButton)
|
||||
@interface MWMActionBarButton : UIView
|
||||
|
||||
@property(nonatomic, readonly) MWMActionBarButtonType type;
|
||||
@property(nonatomic, readonly, nullable) MWMCircularProgress *mapDownloadProgress;
|
||||
|
||||
+ (MWMActionBarButton *)buttonWithDelegate:(id<MWMActionBarButtonDelegate>)delegate
|
||||
buttonType:(MWMActionBarButtonType)type
|
||||
isSelected:(BOOL)isSelected
|
||||
isEnabled:(BOOL)isEnabled;
|
||||
|
||||
- (void)setBookmarkButtonState:(MWMBookmarksButtonState)state;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
#import "MWMActionBarButton.h"
|
||||
#import "MWMButton.h"
|
||||
#import "MWMCircularProgress.h"
|
||||
#import "SwiftBridge.h"
|
||||
|
||||
static NSString * const kUDDidHighlightRouteToButton = @"kUDDidHighlightPoint2PointButton";
|
||||
|
||||
NSString *titleForButton(MWMActionBarButtonType type, BOOL isSelected) {
|
||||
switch (type) {
|
||||
case MWMActionBarButtonTypeDownload:
|
||||
return L(@"download");
|
||||
case MWMActionBarButtonTypeBooking:
|
||||
case MWMActionBarButtonTypeOpentable:
|
||||
return L(@"book_button");
|
||||
case MWMActionBarButtonTypeBookingSearch:
|
||||
return L(@"booking_search");
|
||||
case MWMActionBarButtonTypeCall:
|
||||
return L(@"placepage_call_button");
|
||||
case MWMActionBarButtonTypeBookmark:
|
||||
case MWMActionBarButtonTypeTrack:
|
||||
return L(isSelected ? @"delete" : @"save");
|
||||
case MWMActionBarButtonTypeSaveTrackRecording:
|
||||
return L(@"save");
|
||||
case MWMActionBarButtonTypeNotSaveTrackRecording:
|
||||
return L(@"delete");
|
||||
case MWMActionBarButtonTypeRouteFrom:
|
||||
return L(@"p2p_from_here");
|
||||
case MWMActionBarButtonTypeRouteTo:
|
||||
return L(@"p2p_to_here");
|
||||
case MWMActionBarButtonTypeMore:
|
||||
return L(@"placepage_more_button");
|
||||
case MWMActionBarButtonTypeRouteAddStop:
|
||||
return L(@"placepage_add_stop");
|
||||
case MWMActionBarButtonTypeRouteRemoveStop:
|
||||
return L(@"placepage_remove_stop");
|
||||
case MWMActionBarButtonTypeAvoidToll:
|
||||
return L(@"avoid_tolls");
|
||||
case MWMActionBarButtonTypeAvoidDirty:
|
||||
return L(@"avoid_unpaved");
|
||||
case MWMActionBarButtonTypeAvoidFerry:
|
||||
return L(@"avoid_ferry");
|
||||
}
|
||||
}
|
||||
|
||||
@interface MWMActionBarButton () <MWMCircularProgressProtocol>
|
||||
|
||||
@property(nonatomic) MWMActionBarButtonType type;
|
||||
@property(nonatomic) MWMCircularProgress *mapDownloadProgress;
|
||||
@property(weak, nonatomic) IBOutlet MWMButton *button;
|
||||
@property(weak, nonatomic) IBOutlet UILabel *label;
|
||||
@property(weak, nonatomic) IBOutlet UIView *extraBackground;
|
||||
@property(weak, nonatomic) id<MWMActionBarButtonDelegate> delegate;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MWMActionBarButton
|
||||
|
||||
- (void)configButton:(BOOL)isSelected enabled:(BOOL)isEnabled {
|
||||
self.label.text = titleForButton(self.type, isSelected);
|
||||
self.extraBackground.hidden = YES;
|
||||
self.button.coloring = MWMButtonColoringBlack;
|
||||
[self.button.imageView setContentMode:UIViewContentModeScaleAspectFit];
|
||||
|
||||
switch (self.type) {
|
||||
case MWMActionBarButtonTypeDownload: {
|
||||
if (self.mapDownloadProgress)
|
||||
return;
|
||||
|
||||
self.mapDownloadProgress = [MWMCircularProgress downloaderProgressForParentView:self.button];
|
||||
self.mapDownloadProgress.delegate = self;
|
||||
|
||||
MWMCircularProgressStateVec affectedStates =
|
||||
@[@(MWMCircularProgressStateNormal), @(MWMCircularProgressStateSelected)];
|
||||
|
||||
[self.mapDownloadProgress setImageName:@"ic_download" forStates:affectedStates];
|
||||
[self.mapDownloadProgress setColoring:MWMButtonColoringBlue forStates:affectedStates];
|
||||
break;
|
||||
}
|
||||
case MWMActionBarButtonTypeBooking:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_booking_logo"] forState:UIControlStateNormal];
|
||||
self.label.styleName = @"PPActionBarTitlePartner";
|
||||
self.backgroundColor = [UIColor bookingBackground];
|
||||
if (!IPAD) {
|
||||
self.extraBackground.backgroundColor = [UIColor bookingBackground];
|
||||
self.extraBackground.hidden = NO;
|
||||
}
|
||||
break;
|
||||
case MWMActionBarButtonTypeBookingSearch:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_booking_search"] forState:UIControlStateNormal];
|
||||
self.label.styleName = @"PPActionBarTitlePartner";
|
||||
self.backgroundColor = [UIColor bookingBackground];
|
||||
if (!IPAD) {
|
||||
self.extraBackground.backgroundColor = [UIColor bookingBackground];
|
||||
self.extraBackground.hidden = NO;
|
||||
}
|
||||
break;
|
||||
case MWMActionBarButtonTypeOpentable:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_opentable"] forState:UIControlStateNormal];
|
||||
self.label.styleName = @"PPActionBarTitlePartner";
|
||||
self.backgroundColor = [UIColor opentableBackground];
|
||||
if (!IPAD) {
|
||||
self.extraBackground.backgroundColor = [UIColor opentableBackground];
|
||||
self.extraBackground.hidden = NO;
|
||||
}
|
||||
break;
|
||||
case MWMActionBarButtonTypeCall:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_placepage_phone_number"] forState:UIControlStateNormal];
|
||||
break;
|
||||
case MWMActionBarButtonTypeBookmark:
|
||||
[self setupBookmarkButton:isSelected];
|
||||
break;
|
||||
case MWMActionBarButtonTypeTrack:
|
||||
[self.button setImage:[[UIImage imageNamed:@"ic_route_manager_trash"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
|
||||
self.button.coloring = MWMButtonColoringRed;
|
||||
break;
|
||||
case MWMActionBarButtonTypeSaveTrackRecording:
|
||||
[self.button setImage:[UIImage systemImageNamed:@"square.and.arrow.down" withConfiguration:[UIImageSymbolConfiguration configurationWithPointSize:22 weight:UIImageSymbolWeightSemibold]] forState:UIControlStateNormal];
|
||||
break;
|
||||
case MWMActionBarButtonTypeNotSaveTrackRecording:
|
||||
[self.button setImage:[UIImage systemImageNamed:@"trash.fill" withConfiguration:[UIImageSymbolConfiguration configurationWithPointSize:22 weight:UIImageSymbolWeightSemibold]] forState:UIControlStateNormal];
|
||||
self.button.coloring = MWMButtonColoringRed;
|
||||
break;
|
||||
case MWMActionBarButtonTypeRouteFrom:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_route_from"] forState:UIControlStateNormal];
|
||||
break;
|
||||
case MWMActionBarButtonTypeRouteTo:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_route_to"] forState:UIControlStateNormal];
|
||||
if ([self needsToHighlightRouteToButton])
|
||||
self.button.coloring = MWMButtonColoringBlue;
|
||||
break;
|
||||
case MWMActionBarButtonTypeMore:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_placepage_more"] forState:UIControlStateNormal];
|
||||
break;
|
||||
case MWMActionBarButtonTypeRouteAddStop:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_add_route_point"] forState:UIControlStateNormal];
|
||||
break;
|
||||
case MWMActionBarButtonTypeRouteRemoveStop:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_remove_route_point"] forState:UIControlStateNormal];
|
||||
break;
|
||||
case MWMActionBarButtonTypeAvoidToll:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_avoid_tolls"] forState:UIControlStateNormal];
|
||||
break;
|
||||
case MWMActionBarButtonTypeAvoidDirty:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_avoid_dirty"] forState:UIControlStateNormal];
|
||||
break;
|
||||
case MWMActionBarButtonTypeAvoidFerry:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_avoid_ferry"] forState:UIControlStateNormal];
|
||||
break;
|
||||
}
|
||||
|
||||
self.button.enabled = isEnabled;
|
||||
}
|
||||
|
||||
+ (MWMActionBarButton *)buttonWithDelegate:(id<MWMActionBarButtonDelegate>)delegate
|
||||
buttonType:(MWMActionBarButtonType)type
|
||||
isSelected:(BOOL)isSelected
|
||||
isEnabled:(BOOL)isEnabled {
|
||||
MWMActionBarButton *button = [NSBundle.mainBundle loadNibNamed:[self className] owner:nil options:nil].firstObject;
|
||||
button.delegate = delegate;
|
||||
button.type = type;
|
||||
[button configButton:isSelected enabled:isEnabled];
|
||||
return button;
|
||||
}
|
||||
|
||||
- (void)progressButtonPressed:(MWMCircularProgress *)progress {
|
||||
[self.delegate tapOnButtonWithType:self.type];
|
||||
}
|
||||
|
||||
- (IBAction)tap {
|
||||
if (self.type == MWMActionBarButtonTypeRouteTo)
|
||||
[self disableRouteToButtonHighlight];
|
||||
|
||||
[self.delegate tapOnButtonWithType:self.type];
|
||||
}
|
||||
|
||||
- (void)setBookmarkButtonState:(MWMBookmarksButtonState)state {
|
||||
switch (state) {
|
||||
case MWMBookmarksButtonStateSave:
|
||||
self.label.text = L(@"save");
|
||||
self.button.selected = false;
|
||||
break;
|
||||
case MWMBookmarksButtonStateDelete:
|
||||
self.label.text = L(@"delete");
|
||||
if (!self.button.selected)
|
||||
[self.button.imageView startAnimating];
|
||||
self.button.selected = true;
|
||||
break;
|
||||
case MWMBookmarksButtonStateRecover:
|
||||
self.label.text = L(@"restore");
|
||||
self.button.selected = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setupBookmarkButton:(BOOL)isSelected {
|
||||
MWMButton *btn = self.button;
|
||||
[btn setImage:[UIImage imageNamed:@"ic_bookmarks_off"] forState:UIControlStateNormal];
|
||||
[btn setImage:[UIImage imageNamed:@"ic_bookmarks_on"] forState:UIControlStateSelected];
|
||||
[btn setImage:[UIImage imageNamed:@"ic_bookmarks_on"] forState:UIControlStateHighlighted];
|
||||
[btn setImage:[UIImage imageNamed:@"ic_bookmarks_on"] forState:UIControlStateDisabled];
|
||||
|
||||
[btn setSelected:isSelected];
|
||||
|
||||
NSUInteger const animationImagesCount = 11;
|
||||
NSMutableArray *animationImages = [NSMutableArray arrayWithCapacity:animationImagesCount];
|
||||
for (NSUInteger i = 0; i < animationImagesCount; ++i) {
|
||||
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"ic_bookmarks_%@", @(i + 1)]];
|
||||
animationImages[i] = image;
|
||||
}
|
||||
UIImageView *animationIV = btn.imageView;
|
||||
animationIV.animationImages = animationImages;
|
||||
animationIV.animationRepeatCount = 1;
|
||||
}
|
||||
|
||||
- (BOOL)needsToHighlightRouteToButton {
|
||||
return ![NSUserDefaults.standardUserDefaults boolForKey:kUDDidHighlightRouteToButton];
|
||||
}
|
||||
|
||||
- (void)disableRouteToButtonHighlight {
|
||||
[NSUserDefaults.standardUserDefaults setBool:true forKey:kUDDidHighlightRouteToButton];
|
||||
}
|
||||
|
||||
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
|
||||
[super traitCollectionDidChange:previousTraitCollection];
|
||||
if (@available(iOS 13.0, *)) {
|
||||
if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection])
|
||||
// Update button for the current selection state.
|
||||
[self.button setSelected:self.button.isSelected];
|
||||
}
|
||||
}
|
||||
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
|
||||
return [self pointInside:point withEvent:event] ? self.button : nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21679"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="MWMActionBarButton"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="MWMActionBarButton" propertyAccessControl="none">
|
||||
<rect key="frame" x="0.0" y="0.0" width="80" height="48"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="R50-Tj-X0W">
|
||||
<rect key="frame" x="0.0" y="0.0" width="80" height="48"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</view>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="W07-Hz-J60" customClass="MWMButton">
|
||||
<rect key="frame" x="0.0" y="2" width="80" height="33"/>
|
||||
<connections>
|
||||
<action selector="tap" destination="iN0-l3-epB" eventType="touchUpInside" id="yKY-7K-Wyl"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="80" translatesAutoresizingMaskIntoConstraints="NO" id="rrI-0A-w3s">
|
||||
<rect key="frame" x="0.0" y="32" width="80" height="14"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="14" id="BBl-pC-RJq"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="PPActionBarTitle"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="R50-Tj-X0W" secondAttribute="trailing" id="2jF-U9-Gei"/>
|
||||
<constraint firstAttribute="trailing" secondItem="rrI-0A-w3s" secondAttribute="trailing" id="LPs-Yx-xz6"/>
|
||||
<constraint firstItem="rrI-0A-w3s" firstAttribute="top" secondItem="W07-Hz-J60" secondAttribute="bottom" constant="-3" id="SMD-s3-Tz5"/>
|
||||
<constraint firstItem="W07-Hz-J60" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="2" id="UJy-Ef-B7E"/>
|
||||
<constraint firstItem="rrI-0A-w3s" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="X6f-tU-o9a"/>
|
||||
<constraint firstItem="R50-Tj-X0W" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="ZHQ-XD-E90"/>
|
||||
<constraint firstAttribute="bottom" secondItem="rrI-0A-w3s" secondAttribute="bottom" constant="2" id="Zsi-G2-yc8"/>
|
||||
<constraint firstAttribute="bottom" secondItem="R50-Tj-X0W" secondAttribute="bottom" id="adE-76-Hab"/>
|
||||
<constraint firstItem="R50-Tj-X0W" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="qid-13-F5b"/>
|
||||
<constraint firstItem="W07-Hz-J60" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="rBR-of-5Ha"/>
|
||||
<constraint firstAttribute="trailing" secondItem="W07-Hz-J60" secondAttribute="trailing" id="teM-gm-CX7"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outlet property="button" destination="W07-Hz-J60" id="dAN-CS-btL"/>
|
||||
<outlet property="extraBackground" destination="R50-Tj-X0W" id="c90-1d-BSU"/>
|
||||
<outlet property="label" destination="rrI-0A-w3s" id="LMD-pz-agZ"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="139" y="154"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="MWMOpeningHoursCell" id="Ive-iN-SIs" customClass="MWMOpeningHoursCell" propertyAccessControl="all">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Ive-iN-SIs" id="ab9-am-bMR">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" scrollEnabled="NO" style="plain" separatorStyle="none" allowsSelection="NO" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="JR5-1q-ZuW">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" priority="750" constant="43" id="JLa-25-thU"/>
|
||||
</constraints>
|
||||
<color key="separatorColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<inset key="separatorInset" minX="60" minY="0.0" maxX="0.0" maxY="0.0"/>
|
||||
</tableView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="JR5-1q-ZuW" secondAttribute="trailing" id="59Z-Q5-25r"/>
|
||||
<constraint firstAttribute="bottom" secondItem="JR5-1q-ZuW" secondAttribute="bottom" id="P8D-kD-kMF"/>
|
||||
<constraint firstItem="JR5-1q-ZuW" firstAttribute="leading" secondItem="ab9-am-bMR" secondAttribute="leading" id="Xox-6I-JsG"/>
|
||||
<constraint firstItem="JR5-1q-ZuW" firstAttribute="top" secondItem="ab9-am-bMR" secondAttribute="top" id="hgZ-Jr-yDd"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<outlet property="tableView" destination="JR5-1q-ZuW" id="Qyu-x3-lTv"/>
|
||||
<outlet property="tableViewHeight" destination="JLa-25-thU" id="dtQ-TV-gso"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="-872.5" y="-141"/>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#import "MWMTableViewCell.h"
|
||||
|
||||
@protocol MWMPlacePageOpeningHoursCellProtocol <NSObject>
|
||||
|
||||
- (BOOL)forcedButton;
|
||||
- (BOOL)isPlaceholder;
|
||||
- (BOOL)isEditor;
|
||||
- (BOOL)openingHoursCellExpanded;
|
||||
- (void)setOpeningHoursCellExpanded:(BOOL)openingHoursCellExpanded;
|
||||
|
||||
@end
|
||||
|
||||
@interface MWMPlacePageOpeningHoursCell : MWMTableViewCell
|
||||
|
||||
@property (nonatomic, readonly) BOOL isClosed;
|
||||
|
||||
- (void)configWithDelegate:(id<MWMPlacePageOpeningHoursCellProtocol>)delegate
|
||||
info:(NSString *)info;
|
||||
|
||||
- (CGFloat)cellHeight;
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,272 @@
|
|||
#import "MWMPlacePageOpeningHoursCell.h"
|
||||
#import <CoreApi/MWMCommon.h>
|
||||
#import <CoreApi/MWMOpeningHoursCommon.h>
|
||||
#import "MWMPlacePageOpeningHoursDayView.h"
|
||||
#import "SwiftBridge.h"
|
||||
|
||||
#include "editor/ui2oh.hpp"
|
||||
|
||||
using namespace editor;
|
||||
using namespace osmoh;
|
||||
|
||||
using WeekDayView = MWMPlacePageOpeningHoursDayView *;
|
||||
|
||||
@interface MWMPlacePageOpeningHoursCell ()
|
||||
|
||||
@property(weak, nonatomic) IBOutlet WeekDayView currentDay;
|
||||
@property(weak, nonatomic) IBOutlet UIView * middleSeparator;
|
||||
@property(weak, nonatomic) IBOutlet UIView * weekDaysView;
|
||||
@property(weak, nonatomic) IBOutlet UIImageView * expandImage;
|
||||
@property(weak, nonatomic) IBOutlet UIButton * toggleButton;
|
||||
|
||||
@property(weak, nonatomic) IBOutlet UILabel * openTime;
|
||||
@property(weak, nonatomic) IBOutlet NSLayoutConstraint * openTimeLeadingOffset;
|
||||
@property(weak, nonatomic) IBOutlet NSLayoutConstraint * openTimeTrailingOffset;
|
||||
|
||||
@property(weak, nonatomic) IBOutlet NSLayoutConstraint * weekDaysViewHeight;
|
||||
@property(nonatomic) CGFloat weekDaysViewEstimatedHeight;
|
||||
|
||||
@property(weak, nonatomic) id<MWMPlacePageOpeningHoursCellProtocol> delegate;
|
||||
|
||||
@property(nonatomic, readwrite) BOOL isClosed;
|
||||
@property(nonatomic) BOOL haveExpandSchedule;
|
||||
|
||||
@end
|
||||
|
||||
NSString * stringFromTimeSpan(Timespan const & timeSpan)
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@ - %@", stringFromTime(timeSpan.GetStart()),
|
||||
stringFromTime(timeSpan.GetEnd())];
|
||||
}
|
||||
|
||||
NSArray<NSString *> * arrayFromClosedTimes(TTimespans const & closedTimes)
|
||||
{
|
||||
NSMutableArray<NSString *> * breaks = [NSMutableArray arrayWithCapacity:closedTimes.size()];
|
||||
for (auto & ct : closedTimes)
|
||||
{
|
||||
[breaks addObject:stringFromTimeSpan(ct)];
|
||||
}
|
||||
return [breaks copy];
|
||||
}
|
||||
|
||||
WeekDayView getWeekDayView()
|
||||
{
|
||||
return [NSBundle.mainBundle loadNibNamed:@"MWMPlacePageOpeningHoursWeekDayView"
|
||||
owner:nil
|
||||
options:nil]
|
||||
.firstObject;
|
||||
}
|
||||
|
||||
@implementation MWMPlacePageOpeningHoursCell
|
||||
{
|
||||
ui::TimeTableSet timeTableSet;
|
||||
}
|
||||
|
||||
- (void)configWithDelegate:(id<MWMPlacePageOpeningHoursCellProtocol>)delegate info:(NSString *)info
|
||||
{
|
||||
self.delegate = delegate;
|
||||
WeekDayView cd = self.currentDay;
|
||||
cd.currentDay = YES;
|
||||
|
||||
self.toggleButton.hidden = !delegate.forcedButton;
|
||||
self.expandImage.hidden = !delegate.forcedButton;
|
||||
self.expandImage.image = [UIImage imageNamed:@"ic_arrow_gray_right"];
|
||||
self.expandImage.styleName = @"MWMGray";
|
||||
if (isInterfaceRightToLeft())
|
||||
self.expandImage.transform = CGAffineTransformMakeScale(-1, 1);
|
||||
NSAssert(info, @"Schedule can not be empty");
|
||||
osmoh::OpeningHours oh(info.UTF8String);
|
||||
if (MakeTimeTableSet(oh, timeTableSet))
|
||||
{
|
||||
cd.isCompatibility = NO;
|
||||
if (delegate.isEditor)
|
||||
self.isClosed = NO;
|
||||
else
|
||||
self.isClosed = oh.IsClosed(time(nullptr));
|
||||
[self processSchedule];
|
||||
}
|
||||
else
|
||||
{
|
||||
cd.isCompatibility = YES;
|
||||
[cd setCompatibilityText:info isPlaceholder:delegate.isPlaceholder];
|
||||
}
|
||||
BOOL const isHidden = !self.isExpanded;
|
||||
self.middleSeparator.hidden = isHidden;
|
||||
self.weekDaysView.hidden = isHidden;
|
||||
[cd invalidate];
|
||||
}
|
||||
|
||||
- (void)processSchedule
|
||||
{
|
||||
NSCalendar * cal = NSCalendar.currentCalendar;
|
||||
cal.locale = NSLocale.currentLocale;
|
||||
Weekday currentDay =
|
||||
static_cast<Weekday>([cal components:NSCalendarUnitWeekday fromDate:[NSDate date]].weekday);
|
||||
BOOL haveCurrentDay = NO;
|
||||
size_t timeTablesCount = timeTableSet.Size();
|
||||
self.haveExpandSchedule = (timeTablesCount > 1 || !timeTableSet.GetUnhandledDays().empty());
|
||||
self.weekDaysViewEstimatedHeight = 0.0;
|
||||
[self.weekDaysView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
for (size_t idx = 0; idx < timeTablesCount; ++idx)
|
||||
{
|
||||
auto tt = timeTableSet.Get(idx);
|
||||
ui::OpeningDays const & workingDays = tt.GetOpeningDays();
|
||||
if (workingDays.find(currentDay) != workingDays.end())
|
||||
{
|
||||
haveCurrentDay = YES;
|
||||
[self addCurrentDay:tt];
|
||||
}
|
||||
if (self.isExpanded)
|
||||
[self addWeekDays:tt];
|
||||
}
|
||||
if (!haveCurrentDay)
|
||||
[self addEmptyCurrentDay];
|
||||
id<MWMPlacePageOpeningHoursCellProtocol> delegate = self.delegate;
|
||||
if (self.haveExpandSchedule)
|
||||
{
|
||||
self.toggleButton.hidden = NO;
|
||||
self.expandImage.hidden = NO;
|
||||
if (delegate.forcedButton)
|
||||
self.expandImage.image = [UIImage imageNamed:@"ic_arrow_gray_right"];
|
||||
else if (self.isExpanded)
|
||||
self.expandImage.image = [UIImage imageNamed:@"ic_arrow_gray_up"];
|
||||
else
|
||||
self.expandImage.image = [UIImage imageNamed:@"ic_arrow_gray_down"];
|
||||
|
||||
self.expandImage.styleName = @"MWMGray";
|
||||
if (isInterfaceRightToLeft())
|
||||
self.expandImage.transform = CGAffineTransformMakeScale(-1, 1);
|
||||
|
||||
if (self.isExpanded)
|
||||
[self addClosedDays];
|
||||
}
|
||||
self.openTimeTrailingOffset.priority =
|
||||
delegate.forcedButton ? UILayoutPriorityDefaultHigh : UILayoutPriorityDefaultLow;
|
||||
self.weekDaysViewHeight.constant = ceil(self.weekDaysViewEstimatedHeight);
|
||||
[self alignTimeOffsets];
|
||||
}
|
||||
|
||||
- (void)addCurrentDay:(ui::TimeTableSet::Proxy)timeTable
|
||||
{
|
||||
WeekDayView cd = self.currentDay;
|
||||
NSString * label;
|
||||
NSString * openTime;
|
||||
NSArray<NSString *> * breaks;
|
||||
|
||||
BOOL const everyDay = isEveryDay(timeTable);
|
||||
if (timeTable.IsTwentyFourHours())
|
||||
{
|
||||
label = everyDay ? L(@"twentyfour_seven") : L(@"editor_time_allday");
|
||||
openTime = @"";
|
||||
breaks = @[];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.haveExpandSchedule |= !everyDay;
|
||||
label = everyDay ? L(@"daily") : L(@"today");
|
||||
openTime = stringFromTimeSpan(timeTable.GetOpeningTime());
|
||||
breaks = arrayFromClosedTimes(timeTable.GetExcludeTime());
|
||||
}
|
||||
|
||||
[cd setLabelText:label isRed:NO];
|
||||
[cd setOpenTimeText:openTime];
|
||||
[cd setBreaks:breaks];
|
||||
[cd setClosed:self.isClosed];
|
||||
}
|
||||
|
||||
- (void)addEmptyCurrentDay
|
||||
{
|
||||
WeekDayView cd = self.currentDay;
|
||||
[cd setLabelText:L(@"day_off_today") isRed:YES];
|
||||
[cd setOpenTimeText:@""];
|
||||
[cd setBreaks:@[]];
|
||||
[cd setClosed:NO];
|
||||
}
|
||||
|
||||
- (void)addWeekDays:(ui::TimeTableSet::Proxy)timeTable
|
||||
{
|
||||
WeekDayView wd = getWeekDayView();
|
||||
wd.currentDay = NO;
|
||||
wd.frame = {{0, self.weekDaysViewEstimatedHeight}, {self.weekDaysView.width, 0}};
|
||||
[wd setLabelText:stringFromOpeningDays(timeTable.GetOpeningDays()) isRed:NO];
|
||||
if (timeTable.IsTwentyFourHours())
|
||||
{
|
||||
BOOL const everyDay = isEveryDay(timeTable);
|
||||
[wd setOpenTimeText:everyDay ? L(@"twentyfour_seven") : L(@"editor_time_allday")];
|
||||
[wd setBreaks:@[]];
|
||||
}
|
||||
else
|
||||
{
|
||||
[wd setOpenTimeText:stringFromTimeSpan(timeTable.GetOpeningTime())];
|
||||
[wd setBreaks:arrayFromClosedTimes(timeTable.GetExcludeTime())];
|
||||
}
|
||||
[wd invalidate];
|
||||
[self.weekDaysView addSubview:wd];
|
||||
self.weekDaysViewEstimatedHeight += wd.viewHeight;
|
||||
}
|
||||
|
||||
- (void)addClosedDays
|
||||
{
|
||||
editor::ui::OpeningDays closedDays = timeTableSet.GetUnhandledDays();
|
||||
if (closedDays.empty())
|
||||
return;
|
||||
WeekDayView wd = getWeekDayView();
|
||||
wd.currentDay = NO;
|
||||
wd.frame = {{0, self.weekDaysViewEstimatedHeight}, {self.weekDaysView.width, 0}};
|
||||
[wd setLabelText:stringFromOpeningDays(closedDays) isRed:NO];
|
||||
[wd setOpenTimeText:L(@"day_off")];
|
||||
[wd setBreaks:@[]];
|
||||
[wd invalidate];
|
||||
[self.weekDaysView addSubview:wd];
|
||||
self.weekDaysViewEstimatedHeight += wd.viewHeight;
|
||||
}
|
||||
|
||||
- (void)alignTimeOffsets
|
||||
{
|
||||
CGFloat offset = self.openTime.minX;
|
||||
for (WeekDayView wd in self.weekDaysView.subviews)
|
||||
offset = MAX(offset, wd.openTimeLeadingOffset);
|
||||
|
||||
for (WeekDayView wd in self.weekDaysView.subviews)
|
||||
wd.openTimeLeadingOffset = offset;
|
||||
}
|
||||
|
||||
- (CGFloat)cellHeight
|
||||
{
|
||||
CGFloat height = self.currentDay.viewHeight;
|
||||
if (self.isExpanded)
|
||||
{
|
||||
CGFloat const bottomOffset = 4.0;
|
||||
height += bottomOffset;
|
||||
if (!self.currentDay.isCompatibility)
|
||||
height += self.weekDaysViewHeight.constant;
|
||||
}
|
||||
return ceil(height);
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (IBAction)toggleButtonTap
|
||||
{
|
||||
id<MWMPlacePageOpeningHoursCellProtocol> delegate = self.delegate;
|
||||
[delegate setOpeningHoursCellExpanded:!delegate.openingHoursCellExpanded];
|
||||
|
||||
// Workaround for slow devices.
|
||||
// Major QA can tap multiple times before first segue call is performed.
|
||||
// This leads to multiple identical controllers to be pushed.
|
||||
self.toggleButton.enabled = NO;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self.toggleButton.enabled = YES;
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (BOOL)isExpanded
|
||||
{
|
||||
if (self.currentDay.isCompatibility || !self.haveExpandSchedule)
|
||||
return NO;
|
||||
return self.delegate.openingHoursCellExpanded;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,215 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="KGk-i7-Jjw" customClass="MWMPlacePageOpeningHoursCell" propertyAccessControl="none">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="249"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="249"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="swk-um-XzG" customClass="MWMPlacePageOpeningHoursDayView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="126"/>
|
||||
<subviews>
|
||||
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Mo-Su 11:00-24:00" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="228" translatesAutoresizingMaskIntoConstraints="NO" id="ZdV-4y-cz4">
|
||||
<rect key="frame" x="60" y="53.5" width="228" height="19"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular16:blackPrimaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="300" text="Сегодня" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="14" preferredMaxLayoutWidth="68" translatesAutoresizingMaskIntoConstraints="NO" id="Ot5-QJ-jhp">
|
||||
<rect key="frame" x="60" y="12" width="68" height="20"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" priority="750" constant="68" id="5G1-mL-J4T"/>
|
||||
<constraint firstAttribute="height" constant="20" id="Uo2-AE-U2v"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular16:blackPrimaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="10:00—20:00" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="140" translatesAutoresizingMaskIntoConstraints="NO" id="oTF-IZ-Un1">
|
||||
<rect key="frame" x="140" y="12" width="140" height="19"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" priority="300" constant="140" id="up3-Kv-Z1P"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular16:blackPrimaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Перерыв" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="94" translatesAutoresizingMaskIntoConstraints="NO" id="hpw-oR-ZSb">
|
||||
<rect key="frame" x="60" y="36" width="68" height="16"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" priority="750" constant="68" id="Aji-QM-nRY"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular14:blackSecondaryText"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="editor_hours_closed"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7Oa-hg-icC">
|
||||
<rect key="frame" x="140" y="36" width="140" height="58"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="58" id="RWf-JS-tim"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Сейчас закрыто" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="107" translatesAutoresizingMaskIntoConstraints="NO" id="EcD-Q8-7zu">
|
||||
<rect key="frame" x="60" y="98" width="106" height="16"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="16" id="LKy-Dc-veQ"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<color key="textColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="redText"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="closed_now"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<imageView userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_arrow_gray_down" translatesAutoresizingMaskIntoConstraints="NO" id="mGc-k4-uvQ">
|
||||
<rect key="frame" x="288" y="51" width="24" height="24"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="24" id="514-4Z-QO3"/>
|
||||
<constraint firstAttribute="height" constant="24" id="OJ4-4J-1uv"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="MWMGray"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</imageView>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_placepage_open_hours" translatesAutoresizingMaskIntoConstraints="NO" id="pa0-fe-w8W">
|
||||
<rect key="frame" x="16" y="49" width="28" height="28"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="28" id="2AI-Zc-VlL"/>
|
||||
<constraint firstAttribute="height" constant="28" id="gd5-OU-PDF"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="MWMBlack"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</imageView>
|
||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3Fa-V6-tC5" userLabel="Toggle Button">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="248"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<state key="normal">
|
||||
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="titleShadowColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="toggleButtonTap" destination="KGk-i7-Jjw" eventType="touchUpInside" id="XDD-YV-Lea"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="ZdV-4y-cz4" firstAttribute="centerY" secondItem="swk-um-XzG" secondAttribute="centerY" id="6hD-qt-buS"/>
|
||||
<constraint firstItem="oTF-IZ-Un1" firstAttribute="top" secondItem="swk-um-XzG" secondAttribute="top" constant="12" id="93j-yG-wF2"/>
|
||||
<constraint firstItem="hpw-oR-ZSb" firstAttribute="top" secondItem="Ot5-QJ-jhp" secondAttribute="bottom" constant="4" id="9GL-pC-tse"/>
|
||||
<constraint firstItem="oTF-IZ-Un1" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Ot5-QJ-jhp" secondAttribute="trailing" priority="310" constant="4" id="9QL-6i-a0L"/>
|
||||
<constraint firstItem="EcD-Q8-7zu" firstAttribute="leading" secondItem="swk-um-XzG" secondAttribute="leading" constant="60" id="Bhv-rl-AUe"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="oTF-IZ-Un1" secondAttribute="trailing" constant="16" id="C9i-5K-AVk"/>
|
||||
<constraint firstAttribute="trailing" secondItem="mGc-k4-uvQ" secondAttribute="trailing" constant="8" id="CS2-Y7-odx"/>
|
||||
<constraint firstItem="pa0-fe-w8W" firstAttribute="centerY" secondItem="swk-um-XzG" secondAttribute="centerY" id="CXB-0i-wxj"/>
|
||||
<constraint firstItem="mGc-k4-uvQ" firstAttribute="centerY" secondItem="swk-um-XzG" secondAttribute="centerY" id="DQP-gP-Lv1"/>
|
||||
<constraint firstItem="pa0-fe-w8W" firstAttribute="leading" secondItem="swk-um-XzG" secondAttribute="leading" constant="16" id="Dgv-BZ-60x"/>
|
||||
<constraint firstItem="7Oa-hg-icC" firstAttribute="top" secondItem="hpw-oR-ZSb" secondAttribute="top" id="J7A-De-gPK"/>
|
||||
<constraint firstItem="oTF-IZ-Un1" firstAttribute="leading" secondItem="swk-um-XzG" secondAttribute="leading" priority="250" id="KGY-T0-s0P"/>
|
||||
<constraint firstItem="7Oa-hg-icC" firstAttribute="leading" secondItem="oTF-IZ-Un1" secondAttribute="leading" priority="300" id="RBf-8S-CYY"/>
|
||||
<constraint firstItem="7Oa-hg-icC" firstAttribute="trailing" secondItem="oTF-IZ-Un1" secondAttribute="trailing" priority="300" id="XqV-8v-RkG"/>
|
||||
<constraint firstItem="ZdV-4y-cz4" firstAttribute="leading" secondItem="swk-um-XzG" secondAttribute="leading" constant="60" id="YId-0j-rvE"/>
|
||||
<constraint firstItem="Ot5-QJ-jhp" firstAttribute="leading" secondItem="swk-um-XzG" secondAttribute="leading" constant="60" id="ZcQ-Ll-hiP"/>
|
||||
<constraint firstItem="hpw-oR-ZSb" firstAttribute="leading" secondItem="Ot5-QJ-jhp" secondAttribute="leading" id="dpq-9g-Kme"/>
|
||||
<constraint firstItem="7Oa-hg-icC" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="hpw-oR-ZSb" secondAttribute="trailing" priority="310" constant="12" id="efF-u9-Cqb"/>
|
||||
<constraint firstAttribute="trailing" secondItem="ZdV-4y-cz4" secondAttribute="trailing" constant="32" id="hnz-zM-TYH"/>
|
||||
<constraint firstAttribute="height" constant="126" id="hsa-4B-Df0"/>
|
||||
<constraint firstItem="mGc-k4-uvQ" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="oTF-IZ-Un1" secondAttribute="trailing" priority="750" id="iiH-Tm-ybN"/>
|
||||
<constraint firstItem="Ot5-QJ-jhp" firstAttribute="top" secondItem="swk-um-XzG" secondAttribute="top" constant="12" id="n1a-Y2-Nfo"/>
|
||||
<constraint firstAttribute="bottom" secondItem="EcD-Q8-7zu" secondAttribute="bottom" constant="12" id="qwA-KB-e9x"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="breakLabel" destination="hpw-oR-ZSb" id="3Rc-7X-y7r"/>
|
||||
<outlet property="breakLabelWidth" destination="Aji-QM-nRY" id="uKp-5M-qg3"/>
|
||||
<outlet property="breaksHolder" destination="7Oa-hg-icC" id="ttI-ww-abo"/>
|
||||
<outlet property="breaksHolderHeight" destination="RWf-JS-tim" id="Pgt-3Q-cEG"/>
|
||||
<outlet property="closedLabel" destination="EcD-Q8-7zu" id="hhh-Q4-9vo"/>
|
||||
<outlet property="compatibilityLabel" destination="ZdV-4y-cz4" id="Jwu-Ux-lqO"/>
|
||||
<outlet property="height" destination="hsa-4B-Df0" id="he7-ZL-kOE"/>
|
||||
<outlet property="label" destination="Ot5-QJ-jhp" id="zOc-Fe-grg"/>
|
||||
<outlet property="labelOpenTimeLabelSpacing" destination="9QL-6i-a0L" id="ShG-5V-lOy"/>
|
||||
<outlet property="labelTopSpacing" destination="n1a-Y2-Nfo" id="upg-Ua-PDE"/>
|
||||
<outlet property="labelWidth" destination="5G1-mL-J4T" id="esU-tO-DPm"/>
|
||||
<outlet property="openTime" destination="oTF-IZ-Un1" id="oSf-bK-Va1"/>
|
||||
</connections>
|
||||
</view>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="separator_image" translatesAutoresizingMaskIntoConstraints="NO" id="0kQ-hh-2Cy">
|
||||
<rect key="frame" x="60" y="126" width="228" height="1"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="1" id="5lV-kq-jGM"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="MWMSeparator"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</imageView>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fNU-1q-AiR">
|
||||
<rect key="frame" x="0.0" y="127" width="320" height="122"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="122" id="Ifb-EB-LIb"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="fNU-1q-AiR" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="08I-np-9jr"/>
|
||||
<constraint firstAttribute="trailing" secondItem="fNU-1q-AiR" secondAttribute="trailing" id="2Hz-cA-KuN"/>
|
||||
<constraint firstItem="0kQ-hh-2Cy" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="60" id="KwF-TF-PmH"/>
|
||||
<constraint firstAttribute="trailing" secondItem="0kQ-hh-2Cy" secondAttribute="trailing" constant="32" id="RqH-0b-AyG"/>
|
||||
<constraint firstItem="swk-um-XzG" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="VsQ-qI-dIi"/>
|
||||
<constraint firstItem="0kQ-hh-2Cy" firstAttribute="top" secondItem="swk-um-XzG" secondAttribute="bottom" id="Xrh-Vg-VYg"/>
|
||||
<constraint firstItem="swk-um-XzG" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="p14-Mi-kcR"/>
|
||||
<constraint firstItem="fNU-1q-AiR" firstAttribute="top" secondItem="0kQ-hh-2Cy" secondAttribute="bottom" id="uKD-bb-yHT"/>
|
||||
<constraint firstAttribute="trailing" secondItem="swk-um-XzG" secondAttribute="trailing" id="zir-No-59Q"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="Background"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</tableViewCellContentView>
|
||||
<inset key="separatorInset" minX="60" minY="0.0" maxX="0.0" maxY="0.0"/>
|
||||
<connections>
|
||||
<outlet property="currentDay" destination="swk-um-XzG" id="CJG-LQ-Pu8"/>
|
||||
<outlet property="expandImage" destination="mGc-k4-uvQ" id="ohq-Yq-hLX"/>
|
||||
<outlet property="middleSeparator" destination="0kQ-hh-2Cy" id="TJM-Ch-7E0"/>
|
||||
<outlet property="openTime" destination="oTF-IZ-Un1" id="hsY-uV-wWE"/>
|
||||
<outlet property="openTimeLeadingOffset" destination="KGY-T0-s0P" id="rHG-56-gHg"/>
|
||||
<outlet property="openTimeTrailingOffset" destination="iiH-Tm-ybN" id="Abp-Yd-ZCk"/>
|
||||
<outlet property="toggleButton" destination="3Fa-V6-tC5" id="8FI-Je-uFy"/>
|
||||
<outlet property="weekDaysView" destination="fNU-1q-AiR" id="zM3-OD-vBA"/>
|
||||
<outlet property="weekDaysViewHeight" destination="Ifb-EB-LIb" id="sEe-Y1-ubY"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="139" y="155"/>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="ic_arrow_gray_down" width="28" height="28"/>
|
||||
<image name="ic_placepage_open_hours" width="28" height="28"/>
|
||||
<image name="separator_image" width="1" height="1"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
@interface MWMPlacePageOpeningHoursDayView : UIView
|
||||
|
||||
@property (nonatomic) BOOL currentDay;
|
||||
@property (nonatomic) CGFloat viewHeight;
|
||||
@property (nonatomic) BOOL isCompatibility;
|
||||
|
||||
@property (nonatomic) CGFloat openTimeLeadingOffset;
|
||||
|
||||
- (void)setLabelText:(NSString *)text isRed:(BOOL)isRed;
|
||||
- (void)setOpenTimeText:(NSString *)text;
|
||||
- (void)setBreaks:(NSArray<NSString *> *)breaks;
|
||||
- (void)setClosed:(BOOL)closed;
|
||||
- (void)setCompatibilityText:(NSString *)text isPlaceholder:(BOOL)isPlaceholder;
|
||||
|
||||
- (void)invalidate;
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
#import "MWMPlacePageOpeningHoursDayView.h"
|
||||
#import "SwiftBridge.h"
|
||||
|
||||
@interface MWMPlacePageOpeningHoursDayView ()
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UILabel * label;
|
||||
@property (weak, nonatomic) IBOutlet UILabel * openTime;
|
||||
@property (weak, nonatomic) IBOutlet UILabel * compatibilityLabel;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UILabel * breakLabel;
|
||||
@property (weak, nonatomic) IBOutlet UIView * breaksHolder;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UILabel * closedLabel;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * height;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * labelTopSpacing;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * labelWidth;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * breakLabelWidth;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * breaksHolderHeight;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * openTimeLabelLeadingOffset;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * labelOpenTimeLabelSpacing;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MWMPlacePageOpeningHoursDayView
|
||||
|
||||
- (void)setLabelText:(NSString *)text isRed:(BOOL)isRed
|
||||
{
|
||||
UILabel * label = self.label;
|
||||
label.text = text;
|
||||
if (isRed)
|
||||
[label setStyleNameAndApply:@"redText"];
|
||||
else if (self.currentDay)
|
||||
[label setStyleNameAndApply:@"blackPrimaryText"];
|
||||
else
|
||||
[label setStyleNameAndApply:@"blackSecondaryText"];
|
||||
}
|
||||
|
||||
- (void)setOpenTimeText:(NSString *)text
|
||||
{
|
||||
self.openTime.hidden = (text.length == 0);
|
||||
self.openTime.text = text;
|
||||
}
|
||||
|
||||
- (void)setBreaks:(NSArray<NSString *> *)breaks
|
||||
{
|
||||
NSUInteger breaksCount = breaks.count;
|
||||
BOOL haveBreaks = breaksCount != 0;
|
||||
[self.breaksHolder.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
if (haveBreaks)
|
||||
{
|
||||
CGFloat breakSpacerHeight = 4.0;
|
||||
self.breakLabel.hidden = NO;
|
||||
self.breaksHolder.hidden = NO;
|
||||
CGFloat labelY = 0.0;
|
||||
for (NSString * br in breaks)
|
||||
{
|
||||
UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(0, labelY, 0, 0)];
|
||||
label.text = br;
|
||||
label.font = self.currentDay ? [UIFont regular14] : [UIFont light12];
|
||||
label.textColor = [UIColor blackSecondaryText];
|
||||
[label sizeToIntegralFit];
|
||||
[self.breaksHolder addSubview:label];
|
||||
labelY += label.height + breakSpacerHeight;
|
||||
}
|
||||
self.breaksHolderHeight.constant = ceil(labelY - breakSpacerHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
self.breakLabel.hidden = YES;
|
||||
self.breaksHolder.hidden = YES;
|
||||
self.breaksHolderHeight.constant = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setClosed:(BOOL)closed
|
||||
{
|
||||
self.closedLabel.hidden = !closed;
|
||||
}
|
||||
|
||||
- (void)setCompatibilityText:(NSString *)text isPlaceholder:(BOOL)isPlaceholder
|
||||
{
|
||||
self.compatibilityLabel.text = text;
|
||||
self.compatibilityLabel.textColor = isPlaceholder ? [UIColor blackHintText] : [UIColor blackPrimaryText];
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
CGFloat viewHeight;
|
||||
if (self.isCompatibility)
|
||||
{
|
||||
[self.compatibilityLabel sizeToIntegralFit];
|
||||
CGFloat compatibilityLabelVerticalOffsets = 24.0;
|
||||
viewHeight = self.compatibilityLabel.height + compatibilityLabelVerticalOffsets;
|
||||
}
|
||||
else
|
||||
{
|
||||
UILabel * label = self.label;
|
||||
UILabel * openTime = self.openTime;
|
||||
CGFloat labelOpenTimeLabelSpacing = self.labelOpenTimeLabelSpacing.constant;
|
||||
[label sizeToIntegralFit];
|
||||
self.labelWidth.constant = MIN(label.width, openTime.minX - label.minX - labelOpenTimeLabelSpacing);
|
||||
|
||||
[self.breakLabel sizeToIntegralFit];
|
||||
self.breakLabelWidth.constant = self.breakLabel.width;
|
||||
|
||||
CGFloat verticalSuperviewSpacing = self.labelTopSpacing.constant;
|
||||
CGFloat minHeight = label.height + 2 * verticalSuperviewSpacing;
|
||||
CGFloat breaksHolderHeight = self.breaksHolderHeight.constant;
|
||||
CGFloat additionalHeight = (breaksHolderHeight > 0 ? 4.0 : 0.0);
|
||||
viewHeight = minHeight + breaksHolderHeight + additionalHeight;
|
||||
|
||||
if (self.closedLabel && !self.closedLabel.hidden)
|
||||
{
|
||||
CGFloat heightForClosedLabel = 20.0;
|
||||
viewHeight += heightForClosedLabel;
|
||||
}
|
||||
}
|
||||
|
||||
self.viewHeight = ceil(viewHeight);
|
||||
|
||||
[self setNeedsLayout];
|
||||
[self layoutIfNeeded];
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (void)setViewHeight:(CGFloat)viewHeight
|
||||
{
|
||||
_viewHeight = viewHeight;
|
||||
if (self.currentDay)
|
||||
{
|
||||
self.height.constant = viewHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
CGRect frame = self.frame;
|
||||
frame.size.height = viewHeight;
|
||||
self.frame = frame;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setIsCompatibility:(BOOL)isCompatibility
|
||||
{
|
||||
_isCompatibility = isCompatibility;
|
||||
self.compatibilityLabel.hidden = !isCompatibility;
|
||||
self.label.hidden = isCompatibility;
|
||||
self.openTime.hidden = isCompatibility;
|
||||
self.breakLabel.hidden = isCompatibility;
|
||||
self.breaksHolder.hidden = isCompatibility;
|
||||
self.closedLabel.hidden = isCompatibility;
|
||||
}
|
||||
|
||||
- (CGFloat)openTimeLeadingOffset
|
||||
{
|
||||
return self.openTime.minX;
|
||||
}
|
||||
|
||||
- (void)setOpenTimeLeadingOffset:(CGFloat)openTimeLeadingOffset
|
||||
{
|
||||
self.openTimeLabelLeadingOffset.constant = openTimeLeadingOffset;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="SUx-BN-Qk1" customClass="MWMPlacePageOpeningHoursDayView" propertyAccessControl="none">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Пн-Пт" textAlignment="natural" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="68" translatesAutoresizingMaskIntoConstraints="NO" id="DqS-ds-oj4">
|
||||
<rect key="frame" x="60" y="4" width="68" height="16.5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" priority="750" constant="68" id="TSk-hp-vXl"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular14:blackSecondaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="10:00—20:00" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="180" translatesAutoresizingMaskIntoConstraints="NO" id="Pzb-84-nVN">
|
||||
<rect key="frame" x="136" y="4.5" width="100" height="16"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="HSs-ZO-QYt"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular14:blackSecondaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Перерыв" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="68" translatesAutoresizingMaskIntoConstraints="NO" id="LY3-Eu-ESE">
|
||||
<rect key="frame" x="60" y="24.5" width="68" height="14"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" priority="750" constant="68" id="zcl-0l-OMI"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular12:blackSecondaryText"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="editor_hours_closed"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="skl-yW-xDB">
|
||||
<rect key="frame" x="136" y="24.5" width="100" height="58"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="58" id="JQd-xS-lP1"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="skl-yW-xDB" firstAttribute="trailing" secondItem="Pzb-84-nVN" secondAttribute="trailing" id="2Qa-dX-CKF"/>
|
||||
<constraint firstItem="skl-yW-xDB" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="LY3-Eu-ESE" secondAttribute="trailing" priority="310" constant="8" id="4HL-o3-GlG"/>
|
||||
<constraint firstItem="Pzb-84-nVN" firstAttribute="centerY" secondItem="DqS-ds-oj4" secondAttribute="centerY" id="D6k-RM-Cx8"/>
|
||||
<constraint firstItem="skl-yW-xDB" firstAttribute="leading" secondItem="Pzb-84-nVN" secondAttribute="leading" id="H3w-tN-bFd"/>
|
||||
<constraint firstItem="LY3-Eu-ESE" firstAttribute="top" secondItem="DqS-ds-oj4" secondAttribute="bottom" constant="4" id="MKr-pT-3ET"/>
|
||||
<constraint firstItem="LY3-Eu-ESE" firstAttribute="leading" secondItem="DqS-ds-oj4" secondAttribute="leading" id="OFa-uz-HMs"/>
|
||||
<constraint firstItem="DqS-ds-oj4" firstAttribute="top" secondItem="SUx-BN-Qk1" secondAttribute="top" constant="4" id="gGO-xk-DeA"/>
|
||||
<constraint firstItem="skl-yW-xDB" firstAttribute="top" secondItem="LY3-Eu-ESE" secondAttribute="top" id="iut-jl-BrW"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="Pzb-84-nVN" secondAttribute="trailing" priority="750" constant="32" id="rPc-Jd-cW6"/>
|
||||
<constraint firstItem="DqS-ds-oj4" firstAttribute="leading" secondItem="SUx-BN-Qk1" secondAttribute="leading" constant="60" id="sqM-DI-KUl"/>
|
||||
<constraint firstItem="Pzb-84-nVN" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="DqS-ds-oj4" secondAttribute="trailing" priority="310" constant="8" id="vtQ-YR-qDv"/>
|
||||
<constraint firstItem="Pzb-84-nVN" firstAttribute="leading" secondItem="SUx-BN-Qk1" secondAttribute="leading" priority="300" id="xiL-Qi-HQc"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outlet property="breakLabel" destination="LY3-Eu-ESE" id="n3q-d9-OCx"/>
|
||||
<outlet property="breakLabelWidth" destination="zcl-0l-OMI" id="OQq-QW-fVw"/>
|
||||
<outlet property="breaksHolder" destination="skl-yW-xDB" id="O5A-vk-D8U"/>
|
||||
<outlet property="breaksHolderHeight" destination="JQd-xS-lP1" id="yD5-Y7-gDM"/>
|
||||
<outlet property="label" destination="DqS-ds-oj4" id="6RA-e6-H3w"/>
|
||||
<outlet property="labelOpenTimeLabelSpacing" destination="vtQ-YR-qDv" id="Ya6-Gr-qHm"/>
|
||||
<outlet property="labelTopSpacing" destination="gGO-xk-DeA" id="8qk-bN-ayf"/>
|
||||
<outlet property="labelWidth" destination="TSk-hp-vXl" id="r1R-Cy-QXI"/>
|
||||
<outlet property="openTime" destination="Pzb-84-nVN" id="3YU-3c-hyz"/>
|
||||
<outlet property="openTimeLabelLeadingOffset" destination="xiL-Qi-HQc" id="vIE-5M-9Q0"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="332" y="512"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="_MWMOHHeaderCell" id="LXG-cP-akO" customClass="_MWMOHHeaderCell" propertyAccessControl="none">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="48"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="LXG-cP-akO" id="WuT-dc-opP">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="48"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_placepage_open_hours" translatesAutoresizingMaskIntoConstraints="NO" id="nwH-Nj-buF">
|
||||
<rect key="frame" x="16" y="12" width="24" height="24"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="24" id="AU3-h8-Jf3"/>
|
||||
<constraint firstAttribute="width" constant="24" id="RuT-UD-d6E"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="MWMBlack"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Сегодня 8:00 – 18:00" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qDh-SU-MHG" userLabel="Text">
|
||||
<rect key="frame" x="60" y="14" width="271" height="20"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_arrow_gray_down" translatesAutoresizingMaskIntoConstraints="NO" id="VHY-FB-giE">
|
||||
<rect key="frame" x="339" y="10" width="28" height="28"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="28" id="GMF-Az-vGZ"/>
|
||||
<constraint firstAttribute="width" constant="28" id="qap-Cz-ia0"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="MWMBlack"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</imageView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Mvv-gY-euE">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="48"/>
|
||||
<connections>
|
||||
<action selector="extendTap" destination="LXG-cP-akO" eventType="touchUpInside" id="yMy-04-GCs"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="qDh-SU-MHG" secondAttribute="bottom" constant="14" id="0DZ-az-Lhs"/>
|
||||
<constraint firstItem="nwH-Nj-buF" firstAttribute="leading" secondItem="WuT-dc-opP" secondAttribute="leading" constant="16" id="6Pu-RX-aEk"/>
|
||||
<constraint firstItem="Mvv-gY-euE" firstAttribute="leading" secondItem="WuT-dc-opP" secondAttribute="leading" id="8P4-c4-MZD"/>
|
||||
<constraint firstItem="VHY-FB-giE" firstAttribute="leading" secondItem="qDh-SU-MHG" secondAttribute="trailing" constant="8" id="9t0-oW-VAo"/>
|
||||
<constraint firstItem="qDh-SU-MHG" firstAttribute="top" secondItem="WuT-dc-opP" secondAttribute="top" constant="14" id="EEt-O9-WgL"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Mvv-gY-euE" secondAttribute="bottom" id="Gbe-0R-FgZ"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Mvv-gY-euE" secondAttribute="trailing" id="fbo-mH-Bi6"/>
|
||||
<constraint firstAttribute="trailing" secondItem="VHY-FB-giE" secondAttribute="trailing" constant="8" id="jQX-bd-gBc"/>
|
||||
<constraint firstItem="qDh-SU-MHG" firstAttribute="leading" secondItem="nwH-Nj-buF" secondAttribute="trailing" constant="20" id="rcw-Eo-aHO"/>
|
||||
<constraint firstItem="Mvv-gY-euE" firstAttribute="top" secondItem="WuT-dc-opP" secondAttribute="top" id="zyW-ZM-u0d"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<constraints>
|
||||
<constraint firstItem="nwH-Nj-buF" firstAttribute="centerY" secondItem="LXG-cP-akO" secondAttribute="centerY" id="Fk1-cA-KAh"/>
|
||||
<constraint firstItem="VHY-FB-giE" firstAttribute="centerY" secondItem="LXG-cP-akO" secondAttribute="centerY" id="x8c-sP-BJ3"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="arrowIcon" destination="VHY-FB-giE" id="j5m-f3-Wv6"/>
|
||||
<outlet property="text" destination="qDh-SU-MHG" id="OTq-0N-S6b"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="65.94202898550725" y="28.794642857142854"/>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="ic_arrow_gray_down" width="28" height="28"/>
|
||||
<image name="ic_placepage_open_hours" width="28" height="28"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="_MWMOHSubCell" id="QJs-zE-xfN" customClass="_MWMOHSubCell" propertyAccessControl="none">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="75"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="QJs-zE-xfN" id="n1O-q5-zmj">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="75"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="248" verticalHuggingPriority="251" text="Sun-Wed, Fri-Sat" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YIs-LL-j77" userLabel="Days">
|
||||
<rect key="frame" x="60" y="14" width="132.5" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular15:blackPrimaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="All Day (24 hours)" textAlignment="right" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vjg-UU-FVu" userLabel="Schedule">
|
||||
<rect key="frame" x="221.5" y="14" width="137.5" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular15:blackPrimaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Перерыв 12:00 – 13:00" textAlignment="right" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iYw-fc-mKi">
|
||||
<rect key="frame" x="60" y="38.5" width="299" height="21.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular13:blackSecondaryText"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="iYw-fc-mKi" firstAttribute="top" secondItem="vjg-UU-FVu" secondAttribute="bottom" constant="4" id="LaC-Fj-SGw"/>
|
||||
<constraint firstItem="YIs-LL-j77" firstAttribute="leading" secondItem="n1O-q5-zmj" secondAttribute="leading" constant="60" id="Pqu-1L-AJT"/>
|
||||
<constraint firstItem="vjg-UU-FVu" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="YIs-LL-j77" secondAttribute="trailing" constant="10" id="S0j-ZD-Yzm"/>
|
||||
<constraint firstAttribute="trailing" secondItem="vjg-UU-FVu" secondAttribute="trailing" constant="16" id="Y3R-u7-9vy"/>
|
||||
<constraint firstItem="iYw-fc-mKi" firstAttribute="top" secondItem="YIs-LL-j77" secondAttribute="bottom" constant="4" id="c2Y-bD-pvv"/>
|
||||
<constraint firstAttribute="trailing" secondItem="iYw-fc-mKi" secondAttribute="trailing" constant="16" id="fDs-dk-Fok"/>
|
||||
<constraint firstItem="YIs-LL-j77" firstAttribute="top" secondItem="n1O-q5-zmj" secondAttribute="top" constant="14" id="hto-60-gvp"/>
|
||||
<constraint firstAttribute="bottom" secondItem="iYw-fc-mKi" secondAttribute="bottom" constant="15" id="j14-1H-U4E"/>
|
||||
<constraint firstItem="iYw-fc-mKi" firstAttribute="leading" secondItem="n1O-q5-zmj" secondAttribute="leading" constant="60" id="qgW-Wu-maW"/>
|
||||
<constraint firstItem="vjg-UU-FVu" firstAttribute="top" secondItem="n1O-q5-zmj" secondAttribute="top" constant="14" id="qzM-8s-sDR"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<outlet property="breaks" destination="iYw-fc-mKi" id="2ez-hw-xaw"/>
|
||||
<outlet property="days" destination="YIs-LL-j77" id="dqM-WD-2NN"/>
|
||||
<outlet property="schedule" destination="vjg-UU-FVu" id="Xdv-dH-NPZ"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="-96.376811594202906" y="16.40625"/>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
@objc(MWMUGCSelectImpressionCell)
|
||||
final class UGCSelectImpressionCell: MWMTableViewCell {
|
||||
@IBOutlet private var buttons: [UIButton]!
|
||||
private weak var delegate: MWMPlacePageButtonsProtocol?
|
||||
|
||||
@objc func configWith(delegate: MWMPlacePageButtonsProtocol?) {
|
||||
self.delegate = delegate
|
||||
}
|
||||
|
||||
@IBAction private func tap(on: UIButton) {
|
||||
buttons.forEach { $0.isSelected = false }
|
||||
on.isSelected = true
|
||||
delegate?.review(on: on.tag)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
@objc(MWMUGCSpecificReviewDelegate)
|
||||
protocol UGCSpecificReviewDelegate: NSObjectProtocol {
|
||||
func changeReviewRate(_ rate: Int, atIndexPath: NSIndexPath)
|
||||
}
|
||||
|
||||
@objc(MWMUGCSpecificReviewCell)
|
||||
final class UGCSpecificReviewCell: MWMTableViewCell {
|
||||
@IBOutlet private weak var specification: UILabel!
|
||||
@IBOutlet private var stars: [UIButton]!
|
||||
private var indexPath: NSIndexPath = NSIndexPath()
|
||||
private var delegate: UGCSpecificReviewDelegate?
|
||||
|
||||
@objc func configWith(specification: String, rate: Int, atIndexPath: NSIndexPath, delegate: UGCSpecificReviewDelegate?) {
|
||||
self.specification.text = specification
|
||||
self.delegate = delegate
|
||||
indexPath = atIndexPath
|
||||
stars.forEach { $0.isSelected = $0.tag <= rate }
|
||||
}
|
||||
|
||||
@IBAction private func tap(on: UIButton) {
|
||||
stars.forEach { $0.isSelected = $0.tag <= on.tag }
|
||||
delegate?.changeReviewRate(on.tag, atIndexPath: indexPath)
|
||||
}
|
||||
|
||||
// TODO: Make highlighting and dragging.
|
||||
|
||||
@IBAction private func highlight(on _: UIButton) {}
|
||||
|
||||
@IBAction private func touchingCanceled(on _: UIButton) {}
|
||||
|
||||
@IBAction private func drag(inside _: UIButton) {}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
@objc(MWMUGCTextReviewDelegate)
|
||||
protocol UGCTextReviewDelegate: NSObjectProtocol {
|
||||
func changeReviewText(_ text: String)
|
||||
}
|
||||
|
||||
@objc(MWMUGCTextReviewCell)
|
||||
final class UGCTextReviewCell: MWMTableViewCell, UITextViewDelegate {
|
||||
private enum Consts {
|
||||
static let kMaxNumberOfSymbols = 400
|
||||
}
|
||||
|
||||
@IBOutlet private weak var textView: MWMTextView!
|
||||
@IBOutlet private weak var countLabel: UILabel!
|
||||
private weak var delegate: UGCTextReviewDelegate?
|
||||
private var indexPath: NSIndexPath = NSIndexPath()
|
||||
|
||||
@objc func configWith(delegate: UGCTextReviewDelegate?) {
|
||||
self.delegate = delegate
|
||||
setCount(textView.text.characters.count)
|
||||
}
|
||||
|
||||
private func setCount(_ count: Int) {
|
||||
countLabel.text = "\(count)/\(Consts.kMaxNumberOfSymbols)"
|
||||
}
|
||||
|
||||
// MARK: UITextViewDelegate
|
||||
func textView(_ textView: UITextView, shouldChangeTextIn _: NSRange, replacementText _: String) -> Bool {
|
||||
return textView.text.characters.count <= Consts.kMaxNumberOfSymbols
|
||||
}
|
||||
|
||||
func textViewDidChange(_ textView: UITextView) {
|
||||
setCount(textView.text.characters.count)
|
||||
}
|
||||
|
||||
func textViewDidEndEditing(_ textView: UITextView) {
|
||||
delegate?.changeReviewText(textView.text)
|
||||
}
|
||||
}
|
||||
13
iphone/Maps/UI/PlacePage/PlacePageLayout/CopyLabel.swift
Normal file
13
iphone/Maps/UI/PlacePage/PlacePageLayout/CopyLabel.swift
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
final class CopyLabel: UILabel {
|
||||
override var canBecomeFirstResponder: Bool {
|
||||
true
|
||||
}
|
||||
|
||||
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
|
||||
action == #selector(copy(_:))
|
||||
}
|
||||
|
||||
override func copy(_ sender: Any?) {
|
||||
UIPasteboard.general.string = text
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
enum PlacePageState {
|
||||
case closed(CGFloat)
|
||||
case preview(CGFloat)
|
||||
case previewPlus(CGFloat)
|
||||
case expanded(CGFloat)
|
||||
case full(CGFloat)
|
||||
|
||||
var offset: CGFloat {
|
||||
switch self {
|
||||
case .closed(let value):
|
||||
return value
|
||||
case .preview(let value):
|
||||
return value
|
||||
case .previewPlus(let value):
|
||||
return value
|
||||
case .expanded(let value):
|
||||
return value
|
||||
case .full(let value):
|
||||
return value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protocol IPlacePageLayout: AnyObject {
|
||||
var presenter: PlacePagePresenterProtocol? { get set }
|
||||
var headerViewControllers: [UIViewController] { get }
|
||||
var headerViewController: PlacePageHeaderViewController { get }
|
||||
var bodyViewControllers: [UIViewController] { get }
|
||||
var actionBar: ActionBarViewController? { get }
|
||||
var navigationBar: UIViewController? { get }
|
||||
var sectionSpacing: CGFloat { get }
|
||||
|
||||
func calculateSteps(inScrollView scrollView: UIScrollView, compact: Bool) -> [PlacePageState]
|
||||
}
|
||||
|
||||
extension IPlacePageLayout {
|
||||
var sectionSpacing: CGFloat { return 24.0 }
|
||||
}
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
class PlacePageCommonLayout: NSObject, IPlacePageLayout {
|
||||
|
||||
private let distanceFormatter = DistanceFormatter.self
|
||||
private let altitudeFormatter = AltitudeFormatter.self
|
||||
|
||||
private var placePageData: PlacePageData
|
||||
private var interactor: PlacePageInteractor
|
||||
private let storyboard: UIStoryboard
|
||||
private var lastLocation: CLLocation?
|
||||
|
||||
weak var presenter: PlacePagePresenterProtocol?
|
||||
|
||||
var headerViewControllers: [UIViewController] {
|
||||
[headerViewController, previewViewController]
|
||||
}
|
||||
|
||||
lazy var bodyViewControllers: [UIViewController] = {
|
||||
configureViewControllers()
|
||||
}()
|
||||
|
||||
var actionBar: ActionBarViewController? {
|
||||
actionBarViewController
|
||||
}
|
||||
|
||||
var navigationBar: UIViewController? {
|
||||
placePageNavigationViewController
|
||||
}
|
||||
|
||||
lazy var headerViewController: PlacePageHeaderViewController = {
|
||||
PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .flexible)
|
||||
}()
|
||||
|
||||
private lazy var previewViewController: PlacePagePreviewViewController = {
|
||||
let vc = storyboard.instantiateViewController(ofType: PlacePagePreviewViewController.self)
|
||||
vc.placePagePreviewData = placePageData.previewData
|
||||
return vc
|
||||
}()
|
||||
|
||||
private lazy var wikiDescriptionViewController: WikiDescriptionViewController = {
|
||||
let vc = storyboard.instantiateViewController(ofType: WikiDescriptionViewController.self)
|
||||
vc.view.isHidden = true
|
||||
vc.delegate = interactor
|
||||
return vc
|
||||
}()
|
||||
|
||||
private lazy var editBookmarkViewController: PlacePageEditBookmarkOrTrackViewController = {
|
||||
let vc = storyboard.instantiateViewController(ofType: PlacePageEditBookmarkOrTrackViewController.self)
|
||||
vc.view.isHidden = true
|
||||
vc.delegate = interactor
|
||||
return vc
|
||||
}()
|
||||
|
||||
private lazy var infoViewController: PlacePageInfoViewController = {
|
||||
let vc = storyboard.instantiateViewController(ofType: PlacePageInfoViewController.self)
|
||||
vc.placePageInfoData = placePageData.infoData
|
||||
vc.delegate = interactor
|
||||
return vc
|
||||
}()
|
||||
|
||||
private lazy var buttonsViewController: PlacePageButtonsViewController = {
|
||||
let vc = storyboard.instantiateViewController(ofType: PlacePageButtonsViewController.self)
|
||||
vc.buttonsData = placePageData.buttonsData!
|
||||
vc.delegate = interactor
|
||||
return vc
|
||||
}()
|
||||
|
||||
private lazy var actionBarViewController: ActionBarViewController = {
|
||||
let vc = storyboard.instantiateViewController(ofType: ActionBarViewController.self)
|
||||
vc.placePageData = placePageData
|
||||
vc.canAddStop = MWMRouter.canAddIntermediatePoint()
|
||||
vc.isRoutePlanning = MWMNavigationDashboardManager.shared().state != .hidden
|
||||
vc.delegate = interactor
|
||||
return vc
|
||||
}()
|
||||
|
||||
private lazy var placePageNavigationViewController: PlacePageHeaderViewController = {
|
||||
return PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .fixed)
|
||||
}()
|
||||
|
||||
init(interactor: PlacePageInteractor, storyboard: UIStoryboard, data: PlacePageData) {
|
||||
self.interactor = interactor
|
||||
self.storyboard = storyboard
|
||||
self.placePageData = data
|
||||
}
|
||||
|
||||
private func configureViewControllers() -> [UIViewController] {
|
||||
var viewControllers = [UIViewController]()
|
||||
|
||||
viewControllers.append(editBookmarkViewController)
|
||||
if let bookmarkData = placePageData.bookmarkData {
|
||||
editBookmarkViewController.data = .bookmark(bookmarkData)
|
||||
editBookmarkViewController.view.isHidden = false
|
||||
}
|
||||
|
||||
viewControllers.append(wikiDescriptionViewController)
|
||||
if let wikiDescriptionHtml = placePageData.wikiDescriptionHtml {
|
||||
wikiDescriptionViewController.descriptionHtml = wikiDescriptionHtml
|
||||
wikiDescriptionViewController.view.isHidden = false
|
||||
}
|
||||
|
||||
if placePageData.infoData != nil {
|
||||
viewControllers.append(infoViewController)
|
||||
}
|
||||
|
||||
if placePageData.buttonsData != nil {
|
||||
viewControllers.append(buttonsViewController)
|
||||
}
|
||||
|
||||
placePageData.onBookmarkStatusUpdate = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.actionBarViewController.updateBookmarkButtonState(isSelected: self.placePageData.bookmarkData != nil)
|
||||
self.previewViewController.placePagePreviewData = self.placePageData.previewData
|
||||
self.updateBookmarkRelatedSections()
|
||||
}
|
||||
|
||||
LocationManager.add(observer: self)
|
||||
if let lastLocation = LocationManager.lastLocation() {
|
||||
onLocationUpdate(lastLocation)
|
||||
self.lastLocation = lastLocation
|
||||
}
|
||||
if let lastHeading = LocationManager.lastHeading() {
|
||||
onHeadingUpdate(lastHeading)
|
||||
}
|
||||
|
||||
placePageData.onMapNodeStatusUpdate = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.actionBarViewController.updateDownloadButtonState(self.placePageData.mapNodeAttributes!.nodeStatus)
|
||||
switch self.placePageData.mapNodeAttributes!.nodeStatus {
|
||||
case .onDisk, .onDiskOutOfDate, .undefined:
|
||||
self.actionBarViewController.resetButtons()
|
||||
if self.placePageData.buttonsData != nil {
|
||||
self.buttonsViewController.buttonsEnabled = true
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
placePageData.onMapNodeProgressUpdate = { [weak self] (downloadedBytes, totalBytes) in
|
||||
guard let self = self, let downloadButton = self.actionBarViewController.downloadButton else { return }
|
||||
downloadButton.mapDownloadProgress?.progress = CGFloat(downloadedBytes) / CGFloat(totalBytes)
|
||||
}
|
||||
|
||||
return viewControllers
|
||||
}
|
||||
|
||||
func calculateSteps(inScrollView scrollView: UIScrollView, compact: Bool) -> [PlacePageState] {
|
||||
var steps: [PlacePageState] = []
|
||||
let scrollHeight = scrollView.height
|
||||
steps.append(.closed(-scrollHeight))
|
||||
guard let preview = previewViewController.view else {
|
||||
return steps
|
||||
}
|
||||
let previewFrame = scrollView.convert(preview.bounds, from: preview)
|
||||
steps.append(.preview(previewFrame.maxY - scrollHeight))
|
||||
if !compact {
|
||||
if placePageData.isPreviewPlus {
|
||||
steps.append(.previewPlus(-scrollHeight * 0.55))
|
||||
}
|
||||
steps.append(.expanded(-scrollHeight * 0.3))
|
||||
}
|
||||
steps.append(.full(0))
|
||||
return steps
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - PlacePageData async callbacks for loaders
|
||||
|
||||
extension PlacePageCommonLayout {
|
||||
func updateBookmarkRelatedSections() {
|
||||
var isBookmark = false
|
||||
if let bookmarkData = placePageData.bookmarkData {
|
||||
editBookmarkViewController.data = .bookmark(bookmarkData)
|
||||
isBookmark = true
|
||||
}
|
||||
if let title = placePageData.previewData.title, let headerViewController = headerViewControllers.compactMap({ $0 as? PlacePageHeaderViewController }).first {
|
||||
let secondaryTitle = placePageData.previewData.secondaryTitle
|
||||
headerViewController.setTitle(title, secondaryTitle: secondaryTitle)
|
||||
placePageNavigationViewController.setTitle(title, secondaryTitle: secondaryTitle)
|
||||
}
|
||||
presenter?.layoutIfNeeded()
|
||||
UIView.animate(withDuration: kDefaultAnimationDuration) { [unowned self] in
|
||||
self.editBookmarkViewController.view.isHidden = !isBookmark
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - MWMLocationObserver
|
||||
|
||||
extension PlacePageCommonLayout: MWMLocationObserver {
|
||||
func onHeadingUpdate(_ heading: CLHeading) {
|
||||
if !placePageData.isMyPosition {
|
||||
updateHeading(heading.trueHeading)
|
||||
}
|
||||
}
|
||||
|
||||
func onLocationUpdate(_ location: CLLocation) {
|
||||
if placePageData.isMyPosition {
|
||||
let altString = "▲ \(altitudeFormatter.altitudeString(fromMeters: location.altitude))"
|
||||
if location.speed > 0 && location.timestamp.timeIntervalSinceNow >= -2 {
|
||||
let speedMeasure = Measure.init(asSpeed: location.speed)
|
||||
let speedString = "\(LocationManager.speedSymbolFor(location.speed))\(speedMeasure.valueAsString) \(speedMeasure.unit)"
|
||||
previewViewController.updateSpeedAndAltitude("\(altString) \(speedString)")
|
||||
} else {
|
||||
previewViewController.updateSpeedAndAltitude(altString)
|
||||
}
|
||||
} else {
|
||||
let ppLocation = CLLocation(latitude: placePageData.locationCoordinate.latitude,
|
||||
longitude: placePageData.locationCoordinate.longitude)
|
||||
let distance = location.distance(from: ppLocation)
|
||||
let formattedDistance = distanceFormatter.distanceString(fromMeters: distance)
|
||||
previewViewController.updateDistance(formattedDistance)
|
||||
|
||||
lastLocation = location
|
||||
}
|
||||
}
|
||||
|
||||
func onLocationError(_ locationError: MWMLocationStatus) {
|
||||
|
||||
}
|
||||
|
||||
private func updateHeading(_ heading: CLLocationDirection) {
|
||||
guard let location = lastLocation, heading > 0 else {
|
||||
return
|
||||
}
|
||||
|
||||
let rad = heading * Double.pi / 180
|
||||
let angle = GeoUtil.angle(atPoint: location.coordinate, toPoint: placePageData.locationCoordinate)
|
||||
previewViewController.updateHeading(CGFloat(angle) + CGFloat(rad))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
class PlacePageTrackLayout: IPlacePageLayout {
|
||||
private var placePageData: PlacePageData
|
||||
private var trackData: PlacePageTrackData
|
||||
private var interactor: PlacePageInteractor
|
||||
private let storyboard: UIStoryboard
|
||||
weak var presenter: PlacePagePresenterProtocol?
|
||||
|
||||
lazy var bodyViewControllers: [UIViewController] = {
|
||||
return configureViewControllers()
|
||||
}()
|
||||
|
||||
var actionBar: ActionBarViewController? {
|
||||
actionBarViewController
|
||||
}
|
||||
|
||||
var navigationBar: UIViewController? {
|
||||
placePageNavigationViewController
|
||||
}
|
||||
|
||||
var headerViewControllers: [UIViewController] {
|
||||
[headerViewController, previewViewController]
|
||||
}
|
||||
|
||||
lazy var headerViewController: PlacePageHeaderViewController = {
|
||||
PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .flexible)
|
||||
}()
|
||||
|
||||
private lazy var previewViewController: PlacePagePreviewViewController = {
|
||||
let vc = storyboard.instantiateViewController(ofType: PlacePagePreviewViewController.self)
|
||||
vc.placePagePreviewData = placePageData.previewData
|
||||
return vc
|
||||
}()
|
||||
|
||||
private lazy var placePageNavigationViewController: PlacePageHeaderViewController = {
|
||||
return PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .fixed)
|
||||
}()
|
||||
|
||||
private lazy var editTrackViewController: PlacePageEditBookmarkOrTrackViewController = {
|
||||
let vc = storyboard.instantiateViewController(ofType: PlacePageEditBookmarkOrTrackViewController.self)
|
||||
vc.view.isHidden = true
|
||||
vc.delegate = interactor
|
||||
return vc
|
||||
}()
|
||||
|
||||
lazy var elevationMapViewController: ElevationProfileViewController? = {
|
||||
guard trackData.trackInfo.hasElevationInfo, trackData.elevationProfileData != nil else {
|
||||
return nil
|
||||
}
|
||||
return ElevationProfileBuilder.build(trackData: trackData, delegate: interactor)
|
||||
}()
|
||||
|
||||
private lazy var actionBarViewController: ActionBarViewController = {
|
||||
let vc = storyboard.instantiateViewController(ofType: ActionBarViewController.self)
|
||||
vc.placePageData = placePageData
|
||||
vc.canAddStop = MWMRouter.canAddIntermediatePoint()
|
||||
vc.isRoutePlanning = MWMNavigationDashboardManager.shared().state != .hidden
|
||||
vc.delegate = interactor
|
||||
return vc
|
||||
}()
|
||||
|
||||
init(interactor: PlacePageInteractor, storyboard: UIStoryboard, data: PlacePageData) {
|
||||
self.interactor = interactor
|
||||
self.storyboard = storyboard
|
||||
self.placePageData = data
|
||||
guard let trackData = data.trackData else {
|
||||
fatalError("PlacePageData must contain trackData for the PlacePageTrackLayout")
|
||||
}
|
||||
self.trackData = trackData
|
||||
}
|
||||
|
||||
private func configureViewControllers() -> [UIViewController] {
|
||||
var viewControllers = [UIViewController]()
|
||||
|
||||
viewControllers.append(editTrackViewController)
|
||||
if let trackData = placePageData.trackData {
|
||||
editTrackViewController.view.isHidden = false
|
||||
editTrackViewController.data = .track(trackData)
|
||||
}
|
||||
|
||||
placePageData.onBookmarkStatusUpdate = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.previewViewController.placePagePreviewData = self.placePageData.previewData
|
||||
self.updateTrackRelatedSections()
|
||||
}
|
||||
|
||||
if let elevationMapViewController {
|
||||
viewControllers.append(elevationMapViewController)
|
||||
}
|
||||
|
||||
return viewControllers
|
||||
}
|
||||
|
||||
func calculateSteps(inScrollView scrollView: UIScrollView, compact: Bool) -> [PlacePageState] {
|
||||
var steps: [PlacePageState] = []
|
||||
let scrollHeight = scrollView.height
|
||||
steps.append(.closed(-scrollHeight))
|
||||
steps.append(.full(0))
|
||||
return steps
|
||||
}
|
||||
}
|
||||
|
||||
private extension PlacePageTrackLayout {
|
||||
func updateTrackRelatedSections() {
|
||||
guard let trackData = placePageData.trackData else {
|
||||
presenter?.closeAnimated()
|
||||
return
|
||||
}
|
||||
editTrackViewController.data = .track(trackData)
|
||||
let previewData = placePageData.previewData
|
||||
if let headerViewController = headerViewControllers.compactMap({ $0 as? PlacePageHeaderViewController }).first {
|
||||
headerViewController.setTitle(previewData.title, secondaryTitle: previewData.secondaryTitle)
|
||||
placePageNavigationViewController.setTitle(previewData.title, secondaryTitle: previewData.secondaryTitle)
|
||||
}
|
||||
if let previewViewController = headerViewControllers.compactMap({ $0 as? PlacePagePreviewViewController }).first {
|
||||
previewViewController.placePagePreviewData = previewData
|
||||
previewViewController.updateViews()
|
||||
}
|
||||
presenter?.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
final class PlacePageTrackRecordingLayout: IPlacePageLayout {
|
||||
private var placePageData: PlacePageData
|
||||
private var interactor: PlacePageInteractor
|
||||
private let storyboard: UIStoryboard
|
||||
weak var presenter: PlacePagePresenterProtocol?
|
||||
|
||||
lazy var bodyViewControllers: [UIViewController] = {
|
||||
configureViewControllers()
|
||||
}()
|
||||
|
||||
var actionBar: ActionBarViewController? {
|
||||
actionBarViewController
|
||||
}
|
||||
|
||||
var navigationBar: UIViewController? {
|
||||
placePageNavigationViewController
|
||||
}
|
||||
|
||||
var headerViewControllers: [UIViewController] {
|
||||
[headerViewController]
|
||||
}
|
||||
|
||||
lazy var headerViewController: PlacePageHeaderViewController = {
|
||||
PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .flexible)
|
||||
}()
|
||||
|
||||
private lazy var placePageNavigationViewController: PlacePageHeaderViewController = {
|
||||
PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .fixed)
|
||||
}()
|
||||
|
||||
private lazy var elevationProfileViewController: ElevationProfileViewController? = {
|
||||
guard let trackData = placePageData.trackData else {
|
||||
return nil
|
||||
}
|
||||
return ElevationProfileBuilder.build(trackData: trackData,
|
||||
delegate: interactor)
|
||||
}()
|
||||
|
||||
private lazy var actionBarViewController: ActionBarViewController = {
|
||||
let vc = storyboard.instantiateViewController(ofType: ActionBarViewController.self)
|
||||
vc.placePageData = placePageData
|
||||
vc.canAddStop = MWMRouter.canAddIntermediatePoint()
|
||||
vc.isRoutePlanning = MWMNavigationDashboardManager.shared().state != .hidden
|
||||
vc.delegate = interactor
|
||||
return vc
|
||||
}()
|
||||
|
||||
var sectionSpacing: CGFloat { 0.0 }
|
||||
|
||||
init(interactor: PlacePageInteractor, storyboard: UIStoryboard, data: PlacePageData) {
|
||||
self.interactor = interactor
|
||||
self.storyboard = storyboard
|
||||
self.placePageData = data
|
||||
}
|
||||
|
||||
private func configureViewControllers() -> [UIViewController] {
|
||||
var viewControllers = [UIViewController]()
|
||||
|
||||
if let elevationProfileViewController {
|
||||
viewControllers.append(elevationProfileViewController)
|
||||
}
|
||||
|
||||
placePageData.onTrackRecordingProgressUpdate = { [weak self] in
|
||||
self?.updateTrackRecordingRelatedSections()
|
||||
}
|
||||
|
||||
return viewControllers
|
||||
}
|
||||
|
||||
func calculateSteps(inScrollView scrollView: UIScrollView, compact: Bool) -> [PlacePageState] {
|
||||
var steps: [PlacePageState] = []
|
||||
let scrollHeight = scrollView.height
|
||||
steps.append(.closed(-scrollHeight))
|
||||
steps.append(.full(0))
|
||||
return steps
|
||||
}
|
||||
}
|
||||
|
||||
private extension PlacePageTrackRecordingLayout {
|
||||
func updateTrackRecordingRelatedSections() {
|
||||
guard let elevationProfileViewController, let trackData = placePageData.trackData else { return }
|
||||
headerViewController.setTitle(placePageData.previewData.title, secondaryTitle: nil)
|
||||
elevationProfileViewController.presenter?.update(with: trackData)
|
||||
presenter?.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue