[ios] Added opening time editor controller.

This commit is contained in:
Илья Гречухин 2015-12-12 22:25:31 +03:00 committed by Sergey Yershov
parent cd38dda713
commit 9292537cc6
28 changed files with 1476 additions and 0 deletions

View file

@ -0,0 +1,5 @@
#import "MWMOpeningHoursTableViewCell.h"
@interface MWMOpeningHoursAddClosedTableViewCell : MWMOpeningHoursTableViewCell
@end

View file

@ -0,0 +1,30 @@
#import "MWMOpeningHoursAddClosedTableViewCell.h"
@interface MWMOpeningHoursAddClosedTableViewCell ()
@property (weak, nonatomic) IBOutlet UIButton * addClosedButton;
@end
@implementation MWMOpeningHoursAddClosedTableViewCell
+ (CGFloat)heightForWidth:(CGFloat)width
{
return 44.0;
}
- (void)refresh
{
[super refresh];
self.addClosedButton.enabled = self.section.canAddClosedTime;
}
#pragma mark - Actions
- (IBAction)addClosedTap
{
if (self.isVisible)
[self.section addClosedTime];
}
@end

View file

@ -0,0 +1,9 @@
#import "MWMOpeningHoursModel.h"
@interface MWMOpeningHoursAddScheduleTableViewCell : UITableViewCell
+ (CGFloat)height;
@property (weak, nonatomic) MWMOpeningHoursModel * model;
@end

View file

@ -0,0 +1,34 @@
#import "MWMOpeningHoursAddScheduleTableViewCell.h"
#import "MWMOpeningHoursEditorViewController.h"
@interface MWMOpeningHoursAddScheduleTableViewCell ()
@property (weak, nonatomic) IBOutlet UIButton * addScheduleButton;
@end
@implementation MWMOpeningHoursAddScheduleTableViewCell
+ (CGFloat)height
{
return 84.0;
}
#pragma mark - Actions
- (IBAction)addScheduleTap
{
[self.model addSchedule];
}
#pragma mark - Properties
- (void)setModel:(MWMOpeningHoursModel *)model
{
_model = model;
NSString * unhandledDays = [model.unhandledDays componentsJoinedByString:@", "];
NSString * title = [NSString stringWithFormat:@"%@ %@", L(@"add_schedule_for"), unhandledDays];
[self.addScheduleButton setTitle:title forState:UIControlStateNormal];
}
@end

View file

@ -0,0 +1,5 @@
#import "MWMOpeningHoursTableViewCell.h"
@interface MWMOpeningHoursAllDayTableViewCell : MWMOpeningHoursTableViewCell
@end

View file

@ -0,0 +1,29 @@
#import "MWMOpeningHoursAllDayTableViewCell.h"
@interface MWMOpeningHoursAllDayTableViewCell ()
@property (weak, nonatomic) IBOutlet UISwitch * switcher;
@end
@implementation MWMOpeningHoursAllDayTableViewCell
+ (CGFloat)heightForWidth:(CGFloat)width
{
return 44.0;
}
- (void)refresh
{
[super refresh];
self.switcher.on = self.section.allDay;
}
#pragma mark - Actions
- (IBAction)onSwitch
{
self.section.allDay = self.switcher.on;
}
@end

View file

@ -0,0 +1,5 @@
#import "MWMOpeningHoursTableViewCell.h"
@interface MWMOpeningHoursClosedSpanTableViewCell : MWMOpeningHoursTableViewCell
@end

View file

@ -0,0 +1,119 @@
#import "MWMOpeningHoursClosedSpanTableViewCell.h"
#import "UIFont+MapsMeFonts.h"
#import "UIColor+MapsMeColor.h"
static NSString * const kLabelText = L(@"hours_closed");
CGFloat labelWidth()
{
UILabel * label = [[UILabel alloc] initWithFrame:CGRectZero];
label.font = [UIFont regular17];
label.text = kLabelText;
[label sizeToFit];
return label.width;
}
static CGFloat const kLabelWidth = labelWidth();
BOOL isCompactForCellWidth(CGFloat width)
{
CGFloat const widthOfAllElementsWithoutLabel = 234.0;
CGFloat const maxLabelWidthForCompactCell = width - widthOfAllElementsWithoutLabel;
return kLabelWidth < maxLabelWidthForCompactCell;
}
@interface MWMOpeningHoursClosedSpanTableViewCell ()
@property (weak, nonatomic) IBOutlet UILabel * hoursClosedLabel;
@property (weak, nonatomic) IBOutlet UILabel * timeSpanLabel;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * timeSpanHorizontalAlignment;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * timeSpanVerticalAlignment;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * hoursClosedTrailing;
@property (nonatomic) BOOL isCompact;
@end
@implementation MWMOpeningHoursClosedSpanTableViewCell
+ (CGFloat)heightForWidth:(CGFloat)width
{
return isCompactForCellWidth(width) ? 44.0 : 64.0;
}
- (void)awakeFromNib
{
[super awakeFromNib];
self.hoursClosedLabel.text = kLabelText;
self.isCompact = YES;
}
- (void)layoutSubviews
{
if (self.isCompact != isCompactForCellWidth(self.width))
{
self.isCompact = !self.isCompact;
if (self.isCompact)
{
self.hoursClosedLabel.font = [UIFont regular17];
self.timeSpanLabel.textAlignment = NSTextAlignmentRight;
self.timeSpanHorizontalAlignment.priority = UILayoutPriorityDefaultLow;
self.timeSpanVerticalAlignment.priority = UILayoutPriorityDefaultLow;
self.hoursClosedTrailing.priority = UILayoutPriorityDefaultLow;
}
else
{
self.hoursClosedLabel.font = [UIFont regular14];
self.timeSpanLabel.textAlignment = NSTextAlignmentLeft;
self.timeSpanHorizontalAlignment.priority = UILayoutPriorityDefaultHigh;
self.timeSpanVerticalAlignment.priority = UILayoutPriorityDefaultHigh;
self.hoursClosedTrailing.priority = UILayoutPriorityDefaultHigh;
}
}
[super layoutSubviews];
}
- (void)refresh
{
[super refresh];
NSLocale * locale = [NSLocale currentLocale];
NSCalendar * calendar = [NSCalendar currentCalendar];
calendar.locale = locale;
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.locale = locale;
dateFormatter.timeStyle = NSDateFormatterShortStyle;
dateFormatter.dateStyle = NSDateFormatterNoStyle;
MWMOpeningHoursSection * section = self.section;
NSUInteger const row = self.row;
NSDate * openDate = [calendar dateFromComponents:[section timeForRow:row isStart:YES]];
NSDate * closeDate = [calendar dateFromComponents:[section timeForRow:row isStart:NO]];
NSString * openString = [dateFormatter stringFromDate:openDate];
NSString * closeString = [dateFormatter stringFromDate:closeDate];
self.timeSpanLabel.text = [NSString stringWithFormat:@"%@-%@", openString, closeString];
self.timeSpanLabel.textColor =
[self.section isRowSelected:row] ? [UIColor linkBlue] : [UIColor blackSecondaryText];
}
#pragma mark - Actions
- (IBAction)cancelTap
{
[self.section removeClosedTime:self.row];
}
- (IBAction)expandTap
{
if (!self.isVisible)
return;
NSUInteger const row = self.row;
self.section.selectedRow = [self.section isRowSelected:row] ? nil : @(row);
[self.section refresh:NO];
}
@end

View file

@ -0,0 +1,5 @@
#import "MWMOpeningHoursTableViewCell.h"
@interface MWMOpeningHoursDaysSelectorTableViewCell : MWMOpeningHoursTableViewCell
@end

View file

@ -0,0 +1,97 @@
#import "MWMOpeningHoursDaysSelectorTableViewCell.h"
#import "UIColor+MapsMeColor.h"
#include "3party/opening_hours/opening_hours.hpp"
@interface MWMOpeningHoursDaysSelectorTableViewCell ()
@property (nonatomic) IBOutletCollection(UIButton) NSArray * buttons;
@property (nonatomic) IBOutletCollection(UILabel) NSArray * labels;
@property (nonatomic) IBOutletCollection(UIImageView) NSArray * images;
@property (nonatomic) NSUInteger firstWeekday;
@end
using namespace osmoh;
@implementation MWMOpeningHoursDaysSelectorTableViewCell
+ (CGFloat)heightForWidth:(CGFloat)width
{
return 76.0;
}
- (void)awakeFromNib
{
[super awakeFromNib];
NSCalendar * cal = [NSCalendar currentCalendar];
cal.locale = [NSLocale currentLocale];
self.firstWeekday = [cal firstWeekday];
NSArray<NSString *> * weekdaySymbols = cal.shortStandaloneWeekdaySymbols;
for (UILabel * label in self.labels)
{
label.text = weekdaySymbols[[self tag2SymbolIndex:label.tag]];
}
}
- (NSUInteger)tag2SymbolIndex:(NSUInteger)tag
{
NSUInteger idx = tag + self.firstWeekday - 1;
NSUInteger const weekDaysCount = 7;
if (idx >= weekDaysCount)
idx -= weekDaysCount;
return idx;
}
- (Weekday)tag2Weekday:(NSUInteger)tag
{
return static_cast<Weekday>([self tag2SymbolIndex:tag] + 1);
}
- (void)makeDay:(NSUInteger)tag selected:(BOOL)selected refresh:(BOOL)refresh
{
if (refresh)
{
Weekday const wd = [self tag2Weekday:tag];
if (selected)
[self.section addSelectedDay:wd];
else
[self.section removeSelectedDay:wd];
}
for (UIButton * btn in self.buttons)
{
if (btn.tag == tag)
btn.selected = selected;
}
for (UILabel * label in self.labels)
{
if (label.tag == tag)
label.textColor = (selected ? [UIColor blackPrimaryText] : [UIColor blackHintText]);
}
for (UIImageView * image in self.images)
{
if (image.tag == tag)
image.highlighted = selected;
}
}
- (void)refresh
{
[super refresh];
for (UILabel * label in self.labels)
{
NSUInteger const tag = label.tag;
BOOL const selected = [self.section containsSelectedDay:[self tag2Weekday:tag]];
[self makeDay:tag selected:selected refresh:NO];
}
}
#pragma mark - Actions
- (IBAction)selectDay:(UIButton *)sender
{
[self makeDay:sender.tag selected:!sender.isSelected refresh:YES];
}
@end

View file

@ -0,0 +1,5 @@
#import "MWMOpeningHoursTableViewCell.h"
@interface MWMOpeningHoursDeleteScheduleTableViewCell : MWMOpeningHoursTableViewCell
@end

View file

@ -0,0 +1,15 @@
#import "MWMOpeningHoursDeleteScheduleTableViewCell.h"
@implementation MWMOpeningHoursDeleteScheduleTableViewCell
+ (CGFloat)heightForWidth:(CGFloat)width
{
return 44.0;
}
- (IBAction)deleteScheduleTap
{
[self.section deleteSchedule];
}
@end

View file

@ -0,0 +1,5 @@
#import "MWMOpeningHoursTableViewCell.h"
@interface MWMOpeningHoursSpacerTableViewCell : MWMOpeningHoursTableViewCell
@end

View file

@ -0,0 +1,10 @@
#import "MWMOpeningHoursSpacerTableViewCell.h"
@implementation MWMOpeningHoursSpacerTableViewCell
+ (CGFloat)heightForWidth:(CGFloat)width
{
return 40.0;
}
@end

View file

@ -0,0 +1,16 @@
#import "MWMOpeningHoursSection.h"
@interface MWMOpeningHoursTableViewCell : UITableViewCell
+ (CGFloat)heightForWidth:(CGFloat)width;
@property (nonatomic, readonly) NSUInteger row;
@property (weak, nonatomic) MWMOpeningHoursSection * section;
@property (nonatomic) NSIndexPath * indexPathAtInit;
@property (nonatomic, readonly) BOOL isVisible;
- (void)hide;
- (void)refresh;
@end

View file

@ -0,0 +1,51 @@
#import "MWMOpeningHoursTableViewCell.h"
@implementation MWMOpeningHoursTableViewCell
+ (CGFloat)heightForWidth:(CGFloat)width
{
return 0.0;
}
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
}
- (void)hide
{
self.alpha = 0.0;
}
- (void)refresh
{
self.alpha = 1.0;
}
#pragma mark - Properties
- (void)setSection:(MWMOpeningHoursSection *)section
{
_section = section;
[self refresh];
}
- (NSUInteger)row
{
UITableView * tableView = self.section.delegate.tableView;
NSIndexPath * indexPath = [tableView indexPathForCell:self];
if (!indexPath)
indexPath = self.indexPathAtInit;
return indexPath.row;
}
- (BOOL)isVisible
{
UITableView * tableView = self.section.delegate.tableView;
return [tableView indexPathForCell:self] != nil;
}
@end

View file

@ -0,0 +1,5 @@
#import "MWMOpeningHoursTableViewCell.h"
@interface MWMOpeningHoursTimeSelectorTableViewCell : MWMOpeningHoursTableViewCell
@end

View file

@ -0,0 +1,59 @@
#import "MWMOpeningHoursTimeSelectorTableViewCell.h"
@interface MWMOpeningHoursTimeSelectorTableViewCell ()
@property (weak, nonatomic) IBOutlet UIDatePicker * openTimePicker;
@property (weak, nonatomic) IBOutlet UIDatePicker * closeTimePicker;
@property (nonatomic) NSCalendar * calendar;
@end
@implementation MWMOpeningHoursTimeSelectorTableViewCell
+ (CGFloat)heightForWidth:(CGFloat)width
{
return 180.0;
}
- (void)awakeFromNib
{
[super awakeFromNib];
self.calendar = [NSCalendar currentCalendar];
self.calendar.locale = [NSLocale currentLocale];
}
- (void)refresh
{
[super refresh];
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.locale = [NSLocale currentLocale];
dateFormatter.timeStyle = NSDateFormatterShortStyle;
dateFormatter.dateStyle = NSDateFormatterNoStyle;
MWMOpeningHoursSection * section = self.section;
NSUInteger const row = section.selectedRow.unsignedIntegerValue;
NSDate * openDate = [self.calendar dateFromComponents:[section timeForRow:row isStart:YES]];
NSDate * closeDate = [self.calendar dateFromComponents:[section timeForRow:row isStart:NO]];
[self.openTimePicker setDate:openDate animated:NO];
[self.closeTimePicker setDate:closeDate animated:NO];
}
#pragma mark - Actions
- (IBAction)openValueChanged
{
NSDate * date = self.openTimePicker.date;
NSCalendarUnit const components = NSCalendarUnitHour | NSCalendarUnitMinute;
self.section.cachedStartTime = [self.calendar components:components fromDate:date];
}
- (IBAction)closeValueChanged
{
NSDate * date = self.closeTimePicker.date;
NSCalendarUnit const components = NSCalendarUnitHour | NSCalendarUnitMinute;
self.section.cachedEndTime = [self.calendar components:components fromDate:date];
}
@end

View file

@ -0,0 +1,5 @@
#import "MWMOpeningHoursTableViewCell.h"
@interface MWMOpeningHoursTimeSpanTableViewCell : MWMOpeningHoursTableViewCell
@end

View file

@ -0,0 +1,56 @@
#import "MWMOpeningHoursTimeSpanTableViewCell.h"
#import "UIColor+MapsMeColor.h"
@interface MWMOpeningHoursTimeSpanTableViewCell ()
@property (weak, nonatomic) IBOutlet UILabel * openTimeLabel;
@property (weak, nonatomic) IBOutlet UILabel * closeTimeLabel;
@end
@implementation MWMOpeningHoursTimeSpanTableViewCell
+ (CGFloat)heightForWidth:(CGFloat)width
{
return 64.0;
}
- (void)refresh
{
[super refresh];
NSLocale * locale = [NSLocale currentLocale];
NSCalendar * calendar = [NSCalendar currentCalendar];
calendar.locale = locale;
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.locale = locale;
dateFormatter.timeStyle = NSDateFormatterShortStyle;
dateFormatter.dateStyle = NSDateFormatterNoStyle;
MWMOpeningHoursSection * section = self.section;
NSUInteger const row = self.row;
NSDate * openDate = [calendar dateFromComponents:[section timeForRow:row isStart:YES]];
NSDate * closeDate = [calendar dateFromComponents:[section timeForRow:row isStart:NO]];
self.openTimeLabel.text = [dateFormatter stringFromDate:openDate];
self.closeTimeLabel.text = [dateFormatter stringFromDate:closeDate];
UIColor * clr = [self.section isRowSelected:row] ? [UIColor linkBlue] : [UIColor blackSecondaryText];
self.openTimeLabel.textColor = clr;
self.closeTimeLabel.textColor = clr;
}
#pragma mark - Actions
- (IBAction)expandTap
{
if (self.isVisible)
{
MWMOpeningHoursSection * section = self.section;
NSUInteger const row = self.row;
section.selectedRow = [self.section isRowSelected:row] ? nil : @(row);
[self.section refresh:NO];
}
}
@end

View file

@ -0,0 +1,13 @@
typedef NS_ENUM (NSUInteger, MWMOpeningHoursEditorCells)
{
MWMOpeningHoursEditorDaysSelectorCell,
MWMOpeningHoursEditorAllDayCell,
MWMOpeningHoursEditorTimeSpanCell,
MWMOpeningHoursEditorTimeSelectorCell,
MWMOpeningHoursEditorClosedSpanCell,
MWMOpeningHoursEditorAddClosedCell,
MWMOpeningHoursEditorDeleteScheduleCell,
MWMOpeningHoursEditorSpacerCell,
MWMOpeningHoursEditorAddScheduleCell
};

View file

@ -0,0 +1,7 @@
#import "ViewController.h"
@interface MWMOpeningHoursEditorViewController : ViewController
@property (copy, nonatomic) NSString * openingHours;
@end

View file

@ -0,0 +1,140 @@
#import "MWMOpeningHoursAddScheduleTableViewCell.h"
#import "MWMOpeningHoursEditorViewController.h"
#import "MWMOpeningHoursModel.h"
#import "MWMOpeningHoursSection.h"
extern NSDictionary * const kMWMOpeningHoursEditorTableCells = @{
@(MWMOpeningHoursEditorDaysSelectorCell) : @"MWMOpeningHoursDaysSelectorTableViewCell",
@(MWMOpeningHoursEditorAllDayCell) : @"MWMOpeningHoursAllDayTableViewCell",
@(MWMOpeningHoursEditorTimeSpanCell) : @"MWMOpeningHoursTimeSpanTableViewCell",
@(MWMOpeningHoursEditorTimeSelectorCell) : @"MWMOpeningHoursTimeSelectorTableViewCell",
@(MWMOpeningHoursEditorClosedSpanCell) : @"MWMOpeningHoursClosedSpanTableViewCell",
@(MWMOpeningHoursEditorAddClosedCell) : @"MWMOpeningHoursAddClosedTableViewCell",
@(MWMOpeningHoursEditorDeleteScheduleCell) : @"MWMOpeningHoursDeleteScheduleTableViewCell",
@(MWMOpeningHoursEditorSpacerCell) : @"MWMOpeningHoursSpacerTableViewCell",
@(MWMOpeningHoursEditorAddScheduleCell) : @"MWMOpeningHoursAddScheduleTableViewCell",
};
@interface MWMOpeningHoursEditorViewController ()<UITableViewDelegate, UITableViewDataSource,
MWMOpeningHoursModelProtocol>
@property (weak, nonatomic, readwrite) IBOutlet UITableView * tableView;
@property (nonatomic) MWMOpeningHoursModel * model;
@end
@implementation MWMOpeningHoursEditorViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self configNavBar];
[self configTable];
[self configData];
}
#pragma mark - Configuration
- (void)configNavBar
{
self.title = L(@"opening_hours");
self.navigationItem.rightBarButtonItem =
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:@selector(onDone)];
}
- (void)configTable
{
[kMWMOpeningHoursEditorTableCells
enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, NSString * identifier,
BOOL * _Nonnull stop)
{
[self.tableView registerNib:[UINib nibWithNibName:identifier bundle:nil]
forCellReuseIdentifier:identifier];
}];
}
- (void)configData
{
self.model = [[MWMOpeningHoursModel alloc] initWithDelegate:self];
}
#pragma mark - Actions
- (void)onDone
{
}
#pragma mark - Table
- (MWMOpeningHoursEditorCells)cellKeyForIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section < self.model.count)
return [self.model cellKeyForIndexPath:indexPath];
else
return MWMOpeningHoursEditorAddScheduleCell;
}
- (NSString *)cellIdentifierForIndexPath:(NSIndexPath *)indexPath
{
NSString * identifier = kMWMOpeningHoursEditorTableCells[@([self cellKeyForIndexPath:indexPath])];
NSAssert(identifier, @"Identifier can not be nil");
return identifier;
}
- (CGFloat)heightForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
{
CGFloat const width = self.view.width;
if (indexPath.section < self.model.count)
return [self.model heightForIndexPath:indexPath withWidth:width];
else
return [MWMOpeningHoursAddScheduleTableViewCell height];
}
#pragma mark - Fill cells with data
- (void)fillCell:(MWMOpeningHoursTableViewCell * _Nonnull)cell atIndexPath:(NSIndexPath * _Nonnull)indexPath
{
if (indexPath.section < self.model.count)
[self.model fillCell:cell atIndexPath:indexPath];
else if ([cell isKindOfClass:[MWMOpeningHoursAddScheduleTableViewCell class]])
((MWMOpeningHoursAddScheduleTableViewCell *)cell).model = self.model;
}
#pragma mark - UITableViewDataSource
- (UITableViewCell * _Nonnull)tableView:(UITableView * _Nonnull)tableView cellForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
{
return [tableView dequeueReusableCellWithIdentifier:[self cellIdentifierForIndexPath:indexPath]];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView * _Nonnull)tableView
{
return self.model.count + (self.model.canAddSection ? 1 : 0);
}
- (NSInteger)tableView:(UITableView * _Nonnull)tableView numberOfRowsInSection:(NSInteger)section
{
return (section < self.model.count ? [self.model numberOfRowsInSection:section] : 1);
}
#pragma mark - UITableViewDelegate
- (CGFloat)tableView:(UITableView * _Nonnull)tableView heightForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
{
return [self heightForRowAtIndexPath:indexPath];
}
- (CGFloat)tableView:(UITableView * _Nonnull)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
{
return [self heightForRowAtIndexPath:indexPath];
}
- (void)tableView:(UITableView * _Nonnull)tableView willDisplayCell:(MWMOpeningHoursTableViewCell * _Nonnull)cell forRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
{
[self fillCell:cell atIndexPath:indexPath];
}
@end

View file

@ -0,0 +1,27 @@
#import "MWMOpeningHoursEditorCells.h"
#import "MWMOpeningHoursTableViewCell.h"
@protocol MWMOpeningHoursModelProtocol <NSObject>
@property (weak, nonatomic, readonly) UITableView * tableView;
@end
@interface MWMOpeningHoursModel : NSObject
@property (nonatomic, readonly) NSUInteger count;
@property (nonatomic, readonly) BOOL canAddSection;
@property (nonnull, nonatomic, readonly) NSArray<NSString *> * unhandledDays;
- (instancetype _Nullable)initWithDelegate:(id<MWMOpeningHoursModelProtocol> _Nonnull)delegate;
- (void)addSchedule;
- (void)deleteSchedule:(NSUInteger)index;
- (MWMOpeningHoursEditorCells)cellKeyForIndexPath:(NSIndexPath * _Nonnull)indexPath;
- (CGFloat)heightForIndexPath:(NSIndexPath * _Nonnull)indexPath withWidth:(CGFloat)width;
- (void)fillCell:(MWMOpeningHoursTableViewCell * _Nonnull)cell atIndexPath:(NSIndexPath * _Nonnull)indexPath;
- (NSUInteger)numberOfRowsInSection:(NSUInteger)section;
@end

View file

@ -0,0 +1,164 @@
#import "MWMOpeningHoursModel.h"
#import "MWMOpeningHoursSection.h"
#include "editor/opening_hours_ui.hpp"
extern UITableViewRowAnimation const kMWMOpeningHoursEditorRowAnimation = UITableViewRowAnimationFade;
@interface MWMOpeningHoursModel () <MWMOpeningHoursSectionProtocol>
@property (weak, nonatomic, readwrite) UITableView * tableView;
@property (nonatomic) NSMutableArray<MWMOpeningHoursSection *> * sections;
@end
using namespace editor::ui;
using namespace osmoh;
@implementation MWMOpeningHoursModel
{
TimeTableSet timeTableSet;
}
- (instancetype _Nullable)initWithDelegate:(id<MWMOpeningHoursModelProtocol> _Nonnull)delegate
{
self = [super init];
if (self)
{
_tableView = delegate.tableView;
_sections = [NSMutableArray arrayWithCapacity:timeTableSet.Size()];
while (self.sections.count < timeTableSet.Size())
[self addSection];
}
return self;
}
- (void)addSection
{
[self.sections addObject:[[MWMOpeningHoursSection alloc] initWithDelegate:self]];
[self refreshSectionsIndexes];
NSIndexSet * set = [[NSIndexSet alloc] initWithIndex:self.count - 1];
[self.tableView reloadSections:set withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
}
- (void)refreshSectionsIndexes
{
[self.sections enumerateObjectsUsingBlock:^(MWMOpeningHoursSection * _Nonnull section,
NSUInteger idx, BOOL * _Nonnull stop)
{
[section refreshIndex:idx];
}];
}
- (void)addSchedule
{
NSAssert(self.canAddSection, @"Can not add schedule");
timeTableSet.Append(timeTableSet.GetComplementTimeTable());
[self addSection];
NSAssert(timeTableSet.Size() == self.sections.count, @"Inconsistent state");
[self.sections[self.sections.count - 1] scrollIntoView];
}
- (void)deleteSchedule:(NSUInteger)index
{
NSAssert(index < self.count, @"Invalid section index");
BOOL const needRealDelete = self.canAddSection;
timeTableSet.Remove(index);
[self.sections removeObjectAtIndex:index];
[self refreshSectionsIndexes];
if (needRealDelete)
{
NSIndexSet * set = [[NSIndexSet alloc] initWithIndex:index];
[self.tableView deleteSections:set withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
}
else
{
NSIndexSet * set = [[NSIndexSet alloc] initWithIndexesInRange:{index, self.count - index + 1}];
[self.tableView reloadSections:set withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
}
}
- (void)updateActiveSection:(NSUInteger)index
{
for (MWMOpeningHoursSection * section in self.sections)
{
if (section.index != index)
section.selectedRow = nil;
}
}
- (TTimeTableProxy)getTimeTableProxy:(NSUInteger)index
{
NSAssert(index < self.count, @"Invalid section index");
return timeTableSet.Get(index);
}
- (MWMOpeningHoursEditorCells)cellKeyForIndexPath:(NSIndexPath * _Nonnull)indexPath
{
NSUInteger const section = indexPath.section;
NSAssert(section < self.count, @"Invalid section index");
return [self.sections[section] cellKeyForRow:indexPath.row];
}
- (CGFloat)heightForIndexPath:(NSIndexPath * _Nonnull)indexPath withWidth:(CGFloat)width
{
NSUInteger const section = indexPath.section;
NSAssert(section < self.count, @"Invalid section index");
return [self.sections[section] heightForRow:indexPath.row withWidth:width];
}
- (void)fillCell:(MWMOpeningHoursTableViewCell * _Nonnull)cell atIndexPath:(NSIndexPath * _Nonnull)indexPath
{
NSUInteger const section = indexPath.section;
NSAssert(section < self.count, @"Invalid section index");
cell.indexPathAtInit = indexPath;
cell.section = self.sections[section];
}
- (NSUInteger)numberOfRowsInSection:(NSUInteger)section
{
NSAssert(section < self.count, @"Invalid section index");
return self.sections[section].numberOfRows;
}
#pragma mark - Properties
- (NSUInteger)count
{
NSAssert(timeTableSet.Size() == self.sections.count, @"Inconsistent state");
return self.sections.count;
}
- (BOOL)canAddSection
{
return !timeTableSet.GetUnhandledDays().empty();
}
- (NSArray<NSString *> *)unhandledDays
{
auto const unhandledDays = timeTableSet.GetUnhandledDays();
NSCalendar * cal = [NSCalendar currentCalendar];
cal.locale = [NSLocale currentLocale];
NSUInteger const firstWeekday = [cal firstWeekday] - 1;
Weekday (^day2Weekday)(NSUInteger) = ^Weekday(NSUInteger day)
{
NSUInteger idx = day + 1;
if (idx > static_cast<NSUInteger>(Weekday::Saturday))
idx -= static_cast<NSUInteger>(Weekday::Saturday);
return static_cast<Weekday>(idx);
};
NSArray<NSString *> * weekdaySymbols = cal.shortStandaloneWeekdaySymbols;
NSMutableArray<NSString *> * dayNames = [NSMutableArray arrayWithCapacity:unhandledDays.size()];
NSUInteger const weekDaysCount = 7;
for (NSUInteger i = 0, day = firstWeekday; i < weekDaysCount; ++i, ++day)
{
Weekday const wd = day2Weekday(day);
if (unhandledDays.find(wd) != unhandledDays.end())
[dayNames addObject:weekdaySymbols[static_cast<NSInteger>(wd) - 1]];
}
return dayNames;
}
@end

View file

@ -0,0 +1,58 @@
#import "MWMOpeningHoursEditorCells.h"
#include "editor/opening_hours_ui.hpp"
@class MWMOpeningHoursTableViewCell;
@protocol MWMOpeningHoursSectionProtocol <NSObject>
@property (weak, nonatomic, readonly) UITableView * tableView;
- (void)updateActiveSection:(NSUInteger)index;
- (editor::ui::TTimeTableProxy)getTimeTableProxy:(NSUInteger)index;
- (void)deleteSchedule:(NSUInteger)index;
@end
@interface MWMOpeningHoursSection : NSObject
@property (nonatomic) BOOL allDay;
@property (nonatomic, readonly) NSUInteger index;
@property (nullable, nonatomic) NSNumber * selectedRow;
@property (nonatomic, readonly) NSUInteger numberOfRows;
@property (nullable, nonatomic) NSDateComponents * cachedStartTime;
@property (nullable, nonatomic) NSDateComponents * cachedEndTime;
@property (nonatomic, readonly) BOOL canAddClosedTime;
@property (weak, nonatomic, readonly) id<MWMOpeningHoursSectionProtocol> delegate;
- (instancetype _Nullable)initWithDelegate:(id<MWMOpeningHoursSectionProtocol> _Nonnull)delegate;
- (void)refreshIndex:(NSUInteger)index;
- (MWMOpeningHoursEditorCells)cellKeyForRow:(NSUInteger)row;
- (CGFloat)heightForRow:(NSUInteger)row withWidth:(CGFloat)width;
- (NSDateComponents * _Nonnull)timeForRow:(NSUInteger)row isStart:(BOOL)isStart;
- (void)addSelectedDay:(osmoh::Weekday)day;
- (void)removeSelectedDay:(osmoh::Weekday)day;
- (BOOL)containsSelectedDay:(osmoh::Weekday)day;
- (void)addClosedTime;
- (void)removeClosedTime:(NSUInteger)row;
- (void)deleteSchedule;
- (void)refresh:(BOOL)force;
- (void)scrollIntoView;
- (BOOL)isRowSelected:(NSUInteger)row;
@end

View file

@ -0,0 +1,488 @@
#import "MWMOpeningHoursSection.h"
#import "MWMOpeningHoursTableViewCell.h"
#include "3party/opening_hours/opening_hours.hpp"
#include "editor/opening_hours_ui.hpp"
extern NSDictionary * const kMWMOpeningHoursEditorTableCells;
extern UITableViewRowAnimation const kMWMOpeningHoursEditorRowAnimation;
@interface MWMOpeningHoursSection ()
@property (nonatomic, readonly) NSUInteger excludeTimeCount;
@property (nonatomic) BOOL skipStoreCachedData;
@end
using namespace editor::ui;
using namespace osmoh;
@implementation MWMOpeningHoursSection
- (instancetype _Nullable)initWithDelegate:(id<MWMOpeningHoursSectionProtocol> _Nonnull)delegate
{
self = [super init];
if (self)
{
_delegate = delegate;
_selectedRow = nil;
}
return self;
}
- (void)refreshIndex:(NSUInteger)index
{
_index = index;
}
#pragma mark - Rows
- (NSUInteger)firstRowForKey:(MWMOpeningHoursEditorCells)key
{
NSUInteger const numberOfRows = self.numberOfRows;
for (NSUInteger row = 0; row != numberOfRows; ++row)
{
if ([self cellKeyForRow:row] == key)
return row;
}
return numberOfRows;
}
- (MWMOpeningHoursEditorCells)cellKeyForRow:(NSUInteger)row
{
if (row == 0)
return MWMOpeningHoursEditorDaysSelectorCell;
if (row == 1)
return MWMOpeningHoursEditorAllDayCell;
NSUInteger const numberOfRows = self.numberOfRows;
BOOL const firstSection = (self.index == 0);
if (row == numberOfRows - 1)
return MWMOpeningHoursEditorSpacerCell;
else if (firstSection && row == numberOfRows - 2)
return MWMOpeningHoursEditorAddClosedCell;
else if (!firstSection && row == numberOfRows - 2)
return MWMOpeningHoursEditorDeleteScheduleCell;
else if (!firstSection && row == numberOfRows - 3)
return MWMOpeningHoursEditorAddClosedCell;
else if (row == 2)
return MWMOpeningHoursEditorTimeSpanCell;
if ([self.selectedRow isEqualToNumber:@(row - 1)])
return MWMOpeningHoursEditorTimeSelectorCell;
return MWMOpeningHoursEditorClosedSpanCell;
}
- (NSUInteger)numberOfRowsForAllDay:(BOOL)allDay
{
NSUInteger rowsCount = 3; // MWMOpeningHoursDaysSelectorTableViewCell, MWMOpeningHoursAllDayTableViewCell, MWMOpeningHoursSpacerTableViewCell
if (!allDay)
{
rowsCount += 2; // MWMOpeningHoursTimeSpanTableViewCell, MWMOpeningHoursAddClosedTableViewCell
rowsCount += [self closedTimesCount]; // MWMOpeningHoursClosedSpanTableViewCell
if (self.selectedRow)
rowsCount++; // MWMOpeningHoursTimeSelectorTableViewCell
}
if (self.index != 0)
rowsCount++; // MWMOpeningHoursDeleteScheduleTableViewCell
return rowsCount;
}
- (CGFloat)heightForRow:(NSUInteger)row withWidth:(CGFloat)width
{
NSString * className = kMWMOpeningHoursEditorTableCells[@([self cellKeyForRow:row])];
NSAssert(className, @"Invalid class name");
return [NSClassFromString(className) heightForWidth:width];
}
- (void)fillCell:(MWMOpeningHoursTableViewCell * _Nonnull)cell
{
cell.section = self;
}
#pragma mark - Row time
- (NSDateComponents * _Nonnull)timeForRow:(NSUInteger)row isStart:(BOOL)isStart
{
NSDateComponents * cachedTime = isStart ? self.cachedStartTime : self.cachedEndTime;
if (cachedTime && [self isRowSelected:row])
return cachedTime;
BOOL const isClosed = [self cellKeyForRow:row] != MWMOpeningHoursEditorTimeSpanCell;
TTimeTableProxy tt = [self getTimeTableProxy];
NSUInteger const index = isClosed ? [self closedTimeIndex:row] : 0;
Timespan span = isClosed ? tt.GetExcludeTime()[index] : tt.GetOpeningTime();
Time const & t = isStart ? span.GetStart() : span.GetEnd();
NSDateComponents * time = [[NSDateComponents alloc] init];
time.hour = t.GetHoursCount();
time.minute = t.GetMinutesCount();
return time;
}
- (void)setTime:(NSDateComponents *)time isStart:(BOOL)isStart isClosed:(BOOL)isClosed
{
if (!time)
return;
HourMinutes hm;
hm.SetHours(HourMinutes::THours(time.hour));
hm.SetMinutes(HourMinutes::TMinutes(time.minute));
TTimeTableProxy tt = [self getTimeTableProxy];
NSUInteger const row = self.selectedRow.unsignedIntegerValue;
NSUInteger const index = isClosed ? [self closedTimeIndex:row] : 0;
Timespan span = isClosed ? tt.GetExcludeTime()[index] : tt.GetOpeningTime();
if (isStart)
span.SetStart(hm);
else
span.SetEnd(hm);
NSUInteger const closedTimesCountBeforeUpdate = [self closedTimesCount];
if (isClosed)
tt.ReplaceExcludeTime(span, index);
else
tt.SetOpeningTime(span);
tt.Commit();
[self refresh:closedTimesCountBeforeUpdate != [self closedTimesCount]];
}
#pragma mark - Closed Time
- (NSUInteger)closedTimesCount
{
return [self getTimeTableProxy].GetExcludeTime().size();
}
- (NSUInteger)closedTimeIndex:(NSUInteger)row
{
NSUInteger indexShift = [self firstRowForKey:MWMOpeningHoursEditorTimeSpanCell] + 1;
if (self.selectedRow && self.selectedRow.unsignedIntegerValue + 1 < row)
indexShift++;
NSAssert(row >= indexShift, @"Invalid row index");
NSAssert(row - indexShift < [self closedTimesCount], @"Invalid row index");
return row - indexShift;
}
- (void)addClosedTime
{
self.selectedRow = nil;
NSUInteger const row = [self firstRowForKey:MWMOpeningHoursEditorAddClosedCell];
TTimeTableProxy timeTable = [self getTimeTableProxy];
NSUInteger const closedTimesCountBeforeUpdate = [self closedTimesCount];
Timespan timeSpan = timeTable.GetPredefinedExcludeTime();
timeTable.AddExcludeTime(timeSpan);
timeTable.Commit();
NSUInteger const closedTimesCountAfterUpdate = [self closedTimesCount];
if (closedTimesCountAfterUpdate < closedTimesCountBeforeUpdate)
{
[self refresh:YES];
return;
}
if (closedTimesCountAfterUpdate > closedTimesCountBeforeUpdate)
{
UITableView * tableView = self.delegate.tableView;
[tableView beginUpdates];
[self insertRow:row];
self.selectedRow = @(row);
[tableView endUpdates];
}
[self refresh:NO];
}
- (void)removeClosedTime:(NSUInteger)row
{
NSUInteger const closedTimesCountBeforeUpdate = [self closedTimesCount];
self.skipStoreCachedData = [self isRowSelected:row];
self.selectedRow = nil;
if (closedTimesCountBeforeUpdate == [self closedTimesCount])
{
UITableView * tableView = self.delegate.tableView;
[tableView beginUpdates];
TTimeTableProxy timeTable = [self getTimeTableProxy];
timeTable.RemoveExcludeTime([self closedTimeIndex:row]);
timeTable.Commit();
[self deleteRow:row];
[tableView endUpdates];
}
[self refresh:NO];
}
#pragma mark - Selected days
- (void)addSelectedDay:(Weekday)day
{
TTimeTableProxy timeTable = [self getTimeTableProxy];
TOpeningDays openingDays(timeTable.GetWorkingDays());
openingDays.insert(day);
timeTable.SetWorkingDays(openingDays);
timeTable.Commit();
[self refresh:YES];
}
- (void)removeSelectedDay:(Weekday)day
{
TTimeTableProxy timeTable = [self getTimeTableProxy];
TOpeningDays openingDays(timeTable.GetWorkingDays());
openingDays.erase(day);
timeTable.SetWorkingDays(openingDays);
timeTable.Commit();
[self refresh:YES];
}
- (BOOL)containsSelectedDay:(Weekday)day
{
TTimeTableProxy timeTable = [self getTimeTableProxy];
TOpeningDays const & openingDays = timeTable.GetWorkingDays();
return openingDays.find(day) != openingDays.end();
}
#pragma mark - Table
- (void)refresh:(BOOL)force
{
if (force)
{
[self.delegate.tableView reloadData];
return;
}
for (MWMOpeningHoursTableViewCell * cell in self.delegate.tableView.visibleCells)
{
[cell refresh];
}
}
- (void)refreshForNewRowCount:(NSUInteger)newRowCount oldRowCount:(NSUInteger)oldRowCount
{
NSAssert(newRowCount != oldRowCount, @"Invalid rows change");
UITableView * tableView = self.delegate.tableView;
[tableView beginUpdates];
BOOL const addRows = newRowCount > oldRowCount;
NSUInteger const minRows = MIN(newRowCount, oldRowCount);
NSUInteger const maxRows = MAX(newRowCount, oldRowCount);
NSMutableArray<NSIndexPath *> * indexes = [NSMutableArray arrayWithCapacity:maxRows - minRows];
for (NSUInteger row = minRows; row < maxRows; ++row)
[indexes addObject:[NSIndexPath indexPathForRow:row inSection:self.index]];
NSUInteger const reloadRow = [self firstRowForKey:MWMOpeningHoursEditorAllDayCell] + 1;
NSIndexPath * reloadPath = [NSIndexPath indexPathForRow:reloadRow inSection:self.index];
MWMOpeningHoursTableViewCell * reloadCell = [tableView cellForRowAtIndexPath:reloadPath];
[reloadCell hide];
[tableView reloadRowsAtIndexPaths:@[ reloadPath ]
withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
if (addRows)
[tableView insertRowsAtIndexPaths:indexes withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
else
[tableView deleteRowsAtIndexPaths:indexes withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
[tableView endUpdates];
[self refresh:NO];
}
- (void)insertRow:(NSUInteger)row
{
NSIndexPath * path = [NSIndexPath indexPathForRow:row inSection:self.index];
UITableView * tableView = self.delegate.tableView;
[tableView insertRowsAtIndexPaths:@[ path ] withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
}
- (void)deleteRow:(NSUInteger)row
{
NSIndexPath * path = [NSIndexPath indexPathForRow:row inSection:self.index];
UITableView * tableView = self.delegate.tableView;
[tableView deleteRowsAtIndexPaths:@[ path ] withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
}
#pragma mark - Model
- (TTimeTableProxy)getTimeTableProxy
{
return [self.delegate getTimeTableProxy:self.index];
}
- (void)deleteSchedule
{
[self.delegate deleteSchedule:self.index];
}
#pragma mark - Selected row
- (void)setSelectedRow:(NSNumber *)selectedRow
{
if ((!_selectedRow && !selectedRow) || _selectedRow.unsignedIntegerValue == selectedRow.unsignedIntegerValue)
return;
NSUInteger const closedTimesCountBeforeUpdate = [self closedTimesCount];
[self storeCachedData];
if (closedTimesCountBeforeUpdate != [self closedTimesCount])
{
_selectedRow = nil;
[self refresh:YES];
return;
}
NSNumber * oldSelectedRow = _selectedRow;
NSUInteger const newInd = selectedRow.unsignedIntegerValue;
NSUInteger const oldInd = oldSelectedRow.unsignedIntegerValue;
UITableView * tableView = self.delegate.tableView;
[tableView beginUpdates];
if (!oldSelectedRow)
{
_selectedRow = selectedRow;
[self insertRow:newInd + 1];
[self.delegate updateActiveSection:self.index];
}
else if (selectedRow)
{
if (newInd < oldInd)
{
_selectedRow = selectedRow;
[self insertRow:newInd + 1];
}
else
{
_selectedRow = @(newInd - 1);
[self insertRow:newInd];
}
[self deleteRow:oldInd + 1];
}
else
{
_selectedRow = selectedRow;
[self deleteRow:oldInd + 1];
}
[tableView endUpdates];
[self scrollToSelection];
}
- (BOOL)isRowSelected:(NSUInteger)row
{
return self.selectedRow && self.selectedRow.unsignedIntegerValue == row;
}
- (void)storeCachedData
{
if (!self.selectedRow)
return;
if (!self.skipStoreCachedData)
{
switch ([self cellKeyForRow:self.selectedRow.unsignedIntegerValue])
{
case MWMOpeningHoursEditorTimeSpanCell:
[self setTime:self.cachedStartTime isStart:YES isClosed:NO];
[self setTime:self.cachedEndTime isStart:NO isClosed:NO];
break;
case MWMOpeningHoursEditorClosedSpanCell:
[self setTime:self.cachedStartTime isStart:YES isClosed:YES];
[self setTime:self.cachedEndTime isStart:NO isClosed:YES];
break;
default:
NSAssert(false, @"Invalid case");
break;
}
}
self.cachedStartTime = nil;
self.cachedEndTime = nil;
self.skipStoreCachedData = NO;
}
#pragma mark - Scrolling
- (void)scrollIntoView
{
dispatch_async(dispatch_get_main_queue(), ^
{
UITableView * tableView = self.delegate.tableView;
NSUInteger const lastRow = self.numberOfRows - 1;
NSIndexPath * path = [NSIndexPath indexPathForRow:lastRow inSection:self.index];
[tableView scrollToRowAtIndexPath:path
atScrollPosition:UITableViewScrollPositionNone
animated:YES];
});
}
- (void)scrollToSelection
{
dispatch_async(dispatch_get_main_queue(), ^
{
if (!self.selectedRow)
return;
UITableView * tableView = self.delegate.tableView;
NSUInteger const timeSelectorRow = self.selectedRow.unsignedIntegerValue + 1;
NSIndexPath * path = [NSIndexPath indexPathForRow:timeSelectorRow inSection:self.index];
[tableView scrollToRowAtIndexPath:path
atScrollPosition:UITableViewScrollPositionNone
animated:YES];
});
}
#pragma mark - Properties
- (BOOL)allDay
{
return [self getTimeTableProxy].IsTwentyFourHours();
}
- (void)setAllDay:(BOOL)allDay
{
BOOL const currentAllDay = self.allDay;
if (currentAllDay == allDay)
return;
self.selectedRow = nil;
NSUInteger const deleteScheduleCellShift = self.index != 0 ? 1 : 0;
NSUInteger const oldRowCount = [self numberOfRowsForAllDay:currentAllDay] - deleteScheduleCellShift;
NSUInteger const newRowCount = [self numberOfRowsForAllDay:allDay] - deleteScheduleCellShift;
TTimeTableProxy timeTable = [self getTimeTableProxy];
timeTable.SetTwentyFourHours(allDay);
timeTable.Commit();
[self refreshForNewRowCount:newRowCount oldRowCount:oldRowCount];
[self scrollIntoView];
}
- (NSUInteger)numberOfRows
{
return [self numberOfRowsForAllDay:self.allDay];
}
- (void)setCachedStartTime:(NSDateComponents *)cachedStartTime
{
_cachedStartTime = cachedStartTime;
if (cachedStartTime)
[self refresh:NO];
}
- (void)setCachedEndTime:(NSDateComponents *)cachedEndTime
{
_cachedEndTime = cachedEndTime;
if (cachedEndTime)
[self refresh:NO];
}
- (BOOL)canAddClosedTime
{
return [self getTimeTableProxy].CanAddExcludeTime();
}
@end

View file

@ -7,7 +7,9 @@
#import "MWMAlertViewController.h"
#import "MWMAPIBar.h"
#import "MWMMapViewControlsManager.h"
#import "MWMOpeningHoursEditorViewController.h"
#import "MWMPageController.h"
#import "MWMPlacePageEntity.h"
#import "MWMTextToSpeech.h"
#import "RouteState.h"
#import "Statistics.h"
@ -788,6 +790,18 @@ typedef NS_ENUM(NSUInteger, UserTouchesAction)
[[MapsAppDelegate theApp] enableStandby];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"Map2PlacePageEditor"])
{
MWMPlacePageEntity * entity = sender;
NSUInteger const timeIndex = [entity.metadataTypes indexOfObject:@(MWMPlacePageMetadataTypeOpenHours)];
BOOL const haveTime = (timeIndex != NSNotFound);
MWMOpeningHoursEditorViewController * dvc = segue.destinationViewController;
dvc.openingHours = haveTime ? entity.metadataValues[timeIndex] : @"";
}
}
#pragma mark - Properties
- (void)setAppWallAd:(MTRGNativeAppwallAd *)appWallAd