[ios] Speed cam settings redisign.

This commit is contained in:
VladiMihaylenko 2018-12-13 18:53:28 +03:00 committed by Aleksey Belousov
parent 7f0249ae1f
commit 47e79f54f8
7 changed files with 359 additions and 426 deletions

View file

@ -583,7 +583,6 @@
F642D1231F0F9D1D005E3C25 /* ugc_types.csv in Resources */ = {isa = PBXBuildFile; fileRef = F642D1221F0F9D1D005E3C25 /* ugc_types.csv */; };
F64D9CA01C899C350063FA30 /* MWMEditorViralAlert.mm in Sources */ = {isa = PBXBuildFile; fileRef = F64D9C9E1C899C350063FA30 /* MWMEditorViralAlert.mm */; };
F64D9CA31C899C760063FA30 /* MWMEditorViralAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = F64D9CA11C899C760063FA30 /* MWMEditorViralAlert.xib */; };
F64EC41B219EFDC20059DC7C /* MWMSpeedCamSettingsController.mm in Sources */ = {isa = PBXBuildFile; fileRef = F64EC41A219EFDC20059DC7C /* MWMSpeedCamSettingsController.mm */; };
F653CE0E1C6DEB2E00A453F1 /* MWMDropDown.xib in Resources */ = {isa = PBXBuildFile; fileRef = F652B2E91C6DE8E500D20C8C /* MWMDropDown.xib */; };
F653CE121C6DEC8E00A453F1 /* MWMDropDown.mm in Sources */ = {isa = PBXBuildFile; fileRef = F653CE101C6DEB5A00A453F1 /* MWMDropDown.mm */; };
F653CE191C71F62700A453F1 /* MWMAddPlaceNavigationBar.mm in Sources */ = {isa = PBXBuildFile; fileRef = F653CE151C71F60200A453F1 /* MWMAddPlaceNavigationBar.mm */; };
@ -1624,8 +1623,6 @@
F64D9C9D1C899C350063FA30 /* MWMEditorViralAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMEditorViralAlert.h; sourceTree = "<group>"; };
F64D9C9E1C899C350063FA30 /* MWMEditorViralAlert.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = MWMEditorViralAlert.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
F64D9CA11C899C760063FA30 /* MWMEditorViralAlert.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMEditorViralAlert.xib; sourceTree = "<group>"; };
F64EC419219EFDC20059DC7C /* MWMSpeedCamSettingsController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMSpeedCamSettingsController.h; sourceTree = "<group>"; };
F64EC41A219EFDC20059DC7C /* MWMSpeedCamSettingsController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSpeedCamSettingsController.mm; sourceTree = "<group>"; };
F64F19811AB81A00006EAF7E /* MWMAlertViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMAlertViewController.h; sourceTree = "<group>"; };
F64F19821AB81A00006EAF7E /* MWMAlertViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMAlertViewController.mm; sourceTree = "<group>"; };
F64F19831AB81A00006EAF7E /* MWMAlertViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMAlertViewController.xib; sourceTree = "<group>"; };
@ -4330,8 +4327,6 @@
F6E2FD491E097BA00083EBEC /* MWMTTSLanguageViewController.mm */,
F6E2FD4A1E097BA00083EBEC /* MWMTTSSettingsViewController.h */,
F6E2FD4B1E097BA00083EBEC /* MWMTTSSettingsViewController.mm */,
F64EC419219EFDC20059DC7C /* MWMSpeedCamSettingsController.h */,
F64EC41A219EFDC20059DC7C /* MWMSpeedCamSettingsController.mm */,
F6E2FD4C1E097BA00083EBEC /* MWMUnitsController.h */,
F6E2FD4D1E097BA00083EBEC /* MWMUnitsController.mm */,
);
@ -5191,7 +5186,6 @@
33F8BA4A2199AA1300ECA8EE /* MWMTagGroup+Convenience.mm in Sources */,
3488B0131E9D0AEC0068AFD8 /* AdBanner.swift in Sources */,
3404755F1E081A4600C92850 /* MWMLocationPredictor.mm in Sources */,
F64EC41B219EFDC20059DC7C /* MWMSpeedCamSettingsController.mm in Sources */,
F6E2FE041E097BA00083EBEC /* MWMOpeningHoursDaysSelectorTableViewCell.mm in Sources */,
F6E2FE671E097BA00083EBEC /* MWMPlacePageButtonCell.mm in Sources */,
472E3F472146BCD30020E412 /* SubscriptionManager.swift in Sources */,

View file

@ -41,7 +41,6 @@ extern NSString * const kAlohalyticsTapEventKey;
@property(weak, nonatomic) IBOutlet SettingsTableViewSwitchCell * perspectiveViewCell;
@property(weak, nonatomic) IBOutlet SettingsTableViewSwitchCell * autoZoomCell;
@property(weak, nonatomic) IBOutlet SettingsTableViewLinkCell * voiceInstructionsCell;
@property(weak, nonatomic) IBOutlet SettingsTableViewLinkCell * speedCamsCell;
@property(weak, nonatomic) IBOutlet SettingsTableViewLinkCell * helpCell;
@property(weak, nonatomic) IBOutlet SettingsTableViewLinkCell * aboutCell;
@ -186,43 +185,8 @@ extern NSString * const kAlohalyticsTapEventKey;
title:L(@"pref_map_auto_zoom")
isOn:GetFramework().LoadAutoZoom()];
NSString * voiceInstructions = nil;
if ([MWMTextToSpeech isTTSEnabled])
{
NSString * savedLanguage = [MWMTextToSpeech savedLanguage];
if (savedLanguage.length != 0)
{
string const savedLanguageTwine = locale_translator::bcp47ToTwineLanguage(savedLanguage);
voiceInstructions = @(tts::translatedTwine(savedLanguageTwine).c_str());
}
}
else
{
voiceInstructions = L(@"duration_disabled");
}
[self.voiceInstructionsCell configWithTitle:L(@"pref_tts_language_title") info:voiceInstructions];
using namespace routing;
NSString * info = nil;
switch (f.GetRoutingManager().GetSpeedCamManager().GetMode())
{
case SpeedCameraManagerMode::Auto:
info = L(@"speedcam_option_auto");
break;
case SpeedCameraManagerMode::Always:
info = L(@"speedcam_option_always");
break;
case SpeedCameraManagerMode::Never:
info = L(@"speedcam_option_never");
break;
case SpeedCameraManagerMode::MaxValue:
CHECK(false, ("Unexpected mode SpeedCameraManagerMode::MaxValue."));
break;
}
CHECK(info, ("Speed camera warning mode can't be empty"));
[self.speedCamsCell configWithTitle:L(@"speedcams_alert_title") info:info];
NSString * ttsEnabledString = [MWMTextToSpeech isTTSEnabled] ? L(@"on") : L(@"off");
[self.voiceInstructionsCell configWithTitle:L(@"pref_tts_enable_title") info:ttsEnabledString];
}
- (void)configInfoSection
@ -367,11 +331,6 @@ extern NSString * const kAlohalyticsTapEventKey;
withParameters:@{kStatAction : kStatChangeLanguage}];
[self performSegueWithIdentifier:@"SettingsToTTSSegue" sender:nil];
}
else if (cell == self.speedCamsCell)
{
// TODO: Log some event here
[self performSegueWithIdentifier:@"SettingsToSpeedCamsSegue" sender:nil];
}
else if (cell == self.helpCell)
{
[Statistics logEvent:kStatSettingsOpenSection withParameters:@{kStatName : kStatHelp}];

View file

@ -1,9 +0,0 @@
#import "MWMTableViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface MWMSpeedCamSettingsController : MWMTableViewController
@end
NS_ASSUME_NONNULL_END

View file

@ -1,93 +0,0 @@
#import "MWMSpeedCamSettingsController.h"
#import "Statistics.h"
#import "SwiftBridge.h"
#include "Framework.h"
#include "routing/speed_camera_manager.hpp"
#include "map/routing_manager.hpp"
#include "base/assert.hpp"
@interface MWMSpeedCamSettingsController ()
@property(weak, nonatomic) IBOutlet SettingsTableViewSelectableCell * autoCell;
@property(weak, nonatomic) IBOutlet SettingsTableViewSelectableCell * alwaysCell;
@property(weak, nonatomic) IBOutlet SettingsTableViewSelectableCell * neverCell;
@property(weak, nonatomic) SettingsTableViewSelectableCell * selectedCell;
@end
using namespace routing;
@implementation MWMSpeedCamSettingsController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = L(@"speedcams_alert_title");
switch (GetFramework().GetRoutingManager().GetSpeedCamManager().GetMode())
{
case SpeedCameraManagerMode::Auto:
_selectedCell = self.autoCell;
break;
case SpeedCameraManagerMode::Always:
_selectedCell = self.alwaysCell;
break;
case SpeedCameraManagerMode::Never:
_selectedCell = self.neverCell;
break;
case SpeedCameraManagerMode::MaxValue:
CHECK(false, ("Invalid SpeedCameraManagerMode."));
break;
}
auto selectedCell = self.selectedCell;
CHECK(selectedCell, ());
selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
- (void)setSelectedCell:(SettingsTableViewSelectableCell *)selectedCell
{
if (self.selectedCell == selectedCell)
return;
_selectedCell.accessoryType = UITableViewCellAccessoryNone;
auto & scm = GetFramework().GetRoutingManager().GetSpeedCamManager();
auto mode = SpeedCameraManagerMode::MaxValue;
if (selectedCell == self.autoCell)
mode = SpeedCameraManagerMode::Auto;
else if (selectedCell == self.alwaysCell)
mode = SpeedCameraManagerMode::Always;
else
mode = SpeedCameraManagerMode::Never;
CHECK_NOT_EQUAL(mode, SpeedCameraManagerMode::MaxValue, ());
scm.SetMode(mode);
[Statistics logEvent:kStatSettingsSpeedCameras
withParameters:@{kStatValue : @(DebugPrint(mode).c_str())}];
selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
_selectedCell = selectedCell;
}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.selectedCell = [tableView cellForRowAtIndexPath:indexPath];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
#pragma mark - UITableViewDataSource
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
switch (section)
{
case 0: return L(@"speedcams_notice_message");
default: return nil;
}
}
@end

View file

@ -1,10 +1,13 @@
#import "MWMTableViewController.h"
#include "std/string.hpp"
#include "std/utility.hpp"
#include <string>
#include <vector>
#include <utility>
@interface MWMTTSSettingsViewController : MWMTableViewController
- (void)setAdditionalTTSLanguage:(pair<string, string> const &)l;
- (void)setAdditionalTTSLanguage:(std::pair<std::string, std::string> const &)l;
- (std::vector<std::pair<std::string, std::string>> const &)languages;
@end

View file

@ -5,16 +5,238 @@
#import "SwiftBridge.h"
#import "WebViewController.h"
#include "Framework.h"
#include "LocaleTranslator.h"
static NSString * kSelectTTSLanguageSegueName = @"TTSLanguage";
#include "routing/speed_camera_manager.hpp"
#include "map/routing_manager.hpp"
#include "base/assert.hpp"
#include "base/stl_helpers.hpp"
#include <algorithm>
#include <memory>
#include <type_traits>
#include <unordered_map>
using namespace locale_translator;
using namespace routing;
using namespace std;
@interface MWMTTSSettingsViewController ()
namespace
{
std::pair<std::string, std::string> _additionalTTSLanguage;
std::vector<std::pair<std::string, std::string>> _languages;
NSString * kSelectTTSLanguageSegueName = @"TTSLanguage";
enum class Section
{
VoiceInstructions,
Language,
SpeedCameras,
FAQ,
Count
};
using SectionType = underlying_type_t<Section>;
struct BaseCellStategy
{
virtual UITableViewCell * BuildCell(UITableView * tableView, NSIndexPath * indexPath,
MWMTTSSettingsViewController * controller) = 0;
virtual void SelectCell(UITableView * /* tableView */, NSIndexPath * /* indexPath */,
MWMTTSSettingsViewController * /* controller */) {};
virtual NSString * TitleForFooter() const { return nil; }
virtual NSString * TitleForHeader() const { return nil; }
virtual size_t NumberOfRows(MWMTTSSettingsViewController * /* controller */) const { return 1; }
};
struct VoiceInstructionCellStrategy : BaseCellStategy
{
UITableViewCell * BuildCell(UITableView * tableView, NSIndexPath * indexPath,
MWMTTSSettingsViewController * controller) override
{
Class cls = [SettingsTableViewSwitchCell class];
auto cell = static_cast<SettingsTableViewSwitchCell *>(
[tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath]);
[cell configWithDelegate:static_cast<id<SettingsTableViewSwitchCellDelegate>>(controller)
title:L(@"pref_tts_enable_title")
isOn:[MWMTextToSpeech isTTSEnabled]];
return cell;
}
};
struct LanguageCellStrategy : BaseCellStategy
{
UITableViewCell * BuildCell(UITableView * tableView, NSIndexPath * indexPath,
MWMTTSSettingsViewController * controller) override
{
NSInteger const row = indexPath.row;
if (row == controller.languages.size())
{
Class cls = [SettingsTableViewLinkCell class];
auto cell = static_cast<SettingsTableViewLinkCell *>(
[tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath]);
[cell configWithTitle:L(@"pref_tts_other_section_title") info:nil];
return cell;
}
Class cls = [SettingsTableViewSelectableCell class];
auto cell = static_cast<SettingsTableViewSelectableCell *>(
[tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath]);
pair<string, string> const p = controller.languages[row];
[cell configWithTitle:@(p.second.c_str())];
BOOL const isSelected = [@(p.first.c_str()) isEqualToString:[MWMTextToSpeech savedLanguage]];
if (isSelected)
{
m_selectedCell = cell;
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
size_t NumberOfRows(MWMTTSSettingsViewController * controller) const override
{
return controller.languages.size() + 1; // Number of languages + "Other" cell
}
NSString * TitleForHeader() const override { return L(@"pref_tts_language_title"); }
void SelectCell(UITableView * tableView, NSIndexPath * indexPath,
MWMTTSSettingsViewController * controller) override
{
NSInteger const row = indexPath.row;
if (row == controller.languages.size())
{
[Statistics logEvent:kStatEventName(kStatTTSSettings, kStatChangeLanguage)
withParameters:@{kStatValue: kStatOther}];
[controller performSegueWithIdentifier:kSelectTTSLanguageSegueName sender:nil];
return;
}
auto cell = [tableView cellForRowAtIndexPath:indexPath];
if (m_selectedCell == cell)
return;
m_selectedCell.accessoryType = UITableViewCellAccessoryNone;
[[MWMTextToSpeech tts] setNotificationsLocale:@(controller.languages[row].first.c_str())];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
m_selectedCell = cell;
}
SettingsTableViewSelectableCell * m_selectedCell = nil;
};
struct CamerasCellStrategy : BaseCellStategy
{
UITableViewCell * BuildCell(UITableView * tableView, NSIndexPath * indexPath,
MWMTTSSettingsViewController * controller) override
{
auto const mode = GetFramework().GetRoutingManager().GetSpeedCamManager().GetMode();
Class cls = [SettingsTableViewSelectableCell class];
auto cell = static_cast<SettingsTableViewSelectableCell *>(
[tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath]);
NSString * title = nil;
switch (static_cast<SpeedCameraManagerMode>(indexPath.row))
{
case SpeedCameraManagerMode::Auto: title = L(@"speedcam_option_auto"); break;
case SpeedCameraManagerMode::Always: title = L(@"speedcam_option_always"); break;
case SpeedCameraManagerMode::Never: title = L(@"speedcam_option_never"); break;
case SpeedCameraManagerMode::MaxValue: CHECK(false, ()); return nil;
}
CHECK(title, ());
[cell configWithTitle:title];
bool const isSelectedCell = base::Key(mode) == indexPath.row;
if (isSelectedCell)
{
m_selectedCell = cell;
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
size_t NumberOfRows(MWMTTSSettingsViewController * /* controller */) const override
{
return base::Key(SpeedCameraManagerMode::MaxValue);
}
NSString * TitleForHeader() const override { return L(@"speedcams_alert_title"); }
NSString * TitleForFooter() const override { return L(@"speedcams_notice_message"); }
void SelectCell(UITableView * tableView, NSIndexPath * indexPath,
MWMTTSSettingsViewController * /* controller */) override
{
auto cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell == m_selectedCell)
return;
m_selectedCell.accessoryType = UITableViewCellAccessoryNone;
auto & scm = GetFramework().GetRoutingManager().GetSpeedCamManager();
auto const mode = static_cast<SpeedCameraManagerMode>(indexPath.row);
CHECK_NOT_EQUAL(mode, SpeedCameraManagerMode::MaxValue, ());
scm.SetMode(mode);
[Statistics logEvent:kStatSettingsSpeedCameras
withParameters:@{
kStatValue: @(DebugPrint(mode).c_str())
}];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
m_selectedCell = cell;
}
SettingsTableViewSelectableCell * m_selectedCell = nil;
};
struct FAQCellStrategy : BaseCellStategy
{
UITableViewCell * BuildCell(UITableView * tableView, NSIndexPath * indexPath,
MWMTTSSettingsViewController * /* controller */) override
{
Class cls = [SettingsTableViewLinkCell class];
auto cell = static_cast<SettingsTableViewLinkCell *>(
[tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath]);
[cell configWithTitle:L(@"pref_tts_how_to_set_up_voice") info:nil];
return cell;
}
void SelectCell(UITableView * /* tableView */, NSIndexPath * /* indexPath */,
MWMTTSSettingsViewController * controller) override
{
[Statistics logEvent:kStatEventName(kStatTTSSettings, kStatHelp)];
NSString * path = [NSBundle.mainBundle pathForResource:@"tts-how-to-set-up-voice"
ofType:@"html"];
NSString * html = [[NSString alloc] initWithContentsOfFile:path
encoding:NSUTF8StringEncoding
error:nil];
NSURL * baseURL = [NSURL fileURLWithPath:path];
WebViewController * vc =
[[WebViewController alloc] initWithHtml:html
baseUrl:baseURL
title:L(@"pref_tts_how_to_set_up_voice")];
[controller.navigationController pushViewController:vc animated:YES];
};
};
} // namespace
@interface MWMTTSSettingsViewController ()<SettingsTableViewSwitchCellDelegate>
{
pair<string, string> m_additionalTTSLanguage;
vector<pair<string, string>> m_languages;
unordered_map<SectionType, unique_ptr<BaseCellStategy>> m_strategies;
}
@property(nonatomic) BOOL isLocaleLanguageAbsent;
@ -23,18 +245,33 @@ using namespace locale_translator;
@implementation MWMTTSSettingsViewController
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
using base::Key;
m_strategies.emplace(Key(Section::VoiceInstructions), make_unique<VoiceInstructionCellStrategy>());
m_strategies.emplace(Key(Section::Language), make_unique<LanguageCellStrategy>());
m_strategies.emplace(Key(Section::SpeedCameras), make_unique<CamerasCellStrategy>());
m_strategies.emplace(Key(Section::FAQ), make_unique<FAQCellStrategy>());
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = L(@"pref_tts_language_title");
self.title = L(@"pref_tts_enable_title");
self.tableView.separatorColor = [UIColor blackDividers];
MWMTextToSpeech * tts = [MWMTextToSpeech tts];
_languages.reserve(3);
m_languages.reserve(3);
auto const & v = tts.availableLanguages;
NSAssert(!v.empty(), @"Vector can't be empty!");
pair<string, string> const standart = v.front();
_languages.push_back(standart);
m_languages.push_back(standart);
using namespace tts;
NSString * currentBcp47 = [AVSpeechSynthesisVoice currentLanguageCode];
@ -45,7 +282,7 @@ using namespace locale_translator;
string const translated = translatedTwine(currentTwineStr);
pair<string, string> const cur{currentBcp47Str, translated};
if (translated.empty() || find(v.begin(), v.end(), cur) != v.end())
_languages.push_back(cur);
m_languages.push_back(cur);
else
self.isLocaleLanguageAbsent = YES;
}
@ -56,29 +293,29 @@ using namespace locale_translator;
string const savedLanguage = nsSavedLanguage.UTF8String;
if (savedLanguage != currentBcp47Str && savedLanguage != standart.first &&
!savedLanguage.empty())
_languages.emplace_back(
m_languages.emplace_back(
make_pair(savedLanguage, translatedTwine(bcp47ToTwineLanguage(nsSavedLanguage))));
}
}
- (IBAction)unwind:(id)sender
{
size_t const size = _languages.size();
if (find(_languages.begin(), _languages.end(), _additionalTTSLanguage) != _languages.end())
size_t const size = m_languages.size();
if (find(m_languages.begin(), m_languages.end(), m_additionalTTSLanguage) != m_languages.end())
{
[self.tableView reloadData];
return;
}
switch (size)
{
case 1: _languages.push_back(_additionalTTSLanguage); break;
case 1: m_languages.push_back(m_additionalTTSLanguage); break;
case 2:
if (self.isLocaleLanguageAbsent)
_languages[size - 1] = _additionalTTSLanguage;
m_languages[size - 1] = m_additionalTTSLanguage;
else
_languages.push_back(_additionalTTSLanguage);
m_languages.push_back(m_additionalTTSLanguage);
break;
case 3: _languages[size - 1] = _additionalTTSLanguage; break;
case 3: m_languages[size - 1] = m_additionalTTSLanguage; break;
default: NSAssert(false, @"Incorrect language's count"); break;
}
[self.tableView reloadData];
@ -87,119 +324,80 @@ using namespace locale_translator;
- (void)setAdditionalTTSLanguage:(pair<string, string> const &)l
{
[[MWMTextToSpeech tts] setNotificationsLocale:@(l.first.c_str())];
_additionalTTSLanguage = l;
m_additionalTTSLanguage = l;
}
- (vector<pair<string, string>> const &)languages
{
return m_languages;
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 2; }
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
auto const & strategy = m_strategies[static_cast<SectionType>(section)];
CHECK(strategy, ());
return strategy->TitleForHeader();
}
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
auto const & strategy = m_strategies[static_cast<SectionType>(section)];
CHECK(strategy, ());
return strategy->TitleForFooter();
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [MWMTextToSpeech isTTSEnabled] ? base::Key(Section::Count) : 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 0)
return _languages.size() + 2;
else
return 1;
auto const & strategy = m_strategies[static_cast<SectionType>(section)];
CHECK(strategy, ());
return strategy->NumberOfRows(self);
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
{
if (indexPath.row == 0)
{
Class cls = [SettingsTableViewSelectableCell class];
auto cell = static_cast<SettingsTableViewSelectableCell *>(
[tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath]);
[cell configWithTitle:L(@"duration_disabled")];
cell.accessoryType = [MWMTextToSpeech isTTSEnabled] ? UITableViewCellAccessoryNone
: UITableViewCellAccessoryCheckmark;
return cell;
}
else
{
NSInteger const row = indexPath.row - 1;
if (row == _languages.size())
{
Class cls = [SettingsTableViewLinkCell class];
auto cell = static_cast<SettingsTableViewLinkCell *>(
[tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath]);
[cell configWithTitle:L(@"pref_tts_other_section_title") info:nil];
return cell;
}
else
{
Class cls = [SettingsTableViewSelectableCell class];
auto cell = static_cast<SettingsTableViewSelectableCell *>(
[tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath]);
pair<string, string> const p = _languages[row];
[cell configWithTitle:@(p.second.c_str())];
BOOL const isSelected =
[@(p.first.c_str()) isEqualToString:[MWMTextToSpeech savedLanguage]];
cell.accessoryType = [MWMTextToSpeech isTTSEnabled] && isSelected
? UITableViewCellAccessoryCheckmark
: UITableViewCellAccessoryNone;
return cell;
}
}
}
else
{
Class cls = [SettingsTableViewLinkCell class];
auto cell = static_cast<SettingsTableViewLinkCell *>(
[tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath]);
[cell configWithTitle:L(@"pref_tts_how_to_set_up_voice") info:nil];
return cell;
}
auto const & strategy = m_strategies[static_cast<SectionType>(indexPath.section)];
CHECK(strategy, ());
return strategy->BuildCell(tableView, indexPath, self);
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (indexPath.section == 0)
auto const & strategy = m_strategies[static_cast<SectionType>(indexPath.section)];
CHECK(strategy, ());
return strategy->SelectCell(tableView, indexPath, self);
}
#pragma mark - SettingsTableViewSwitchCellDelegate
- (void)switchCell:(SettingsTableViewSwitchCell *)cell didChangeValue:(BOOL)value
{
[MWMTextToSpeech setTTSEnabled:value];
auto indexSet = [NSIndexSet
indexSetWithIndexesInRange:{base::Key(Section::Language), base::Key(Section::Count) - 1}];
auto const animation = UITableViewRowAnimationFade;
NSString * statValue = nil;
if (value)
{
if (indexPath.row == 0)
{
[Statistics logEvent:kStatEventName(kStatSettings, kStatTTS)
withParameters:@{kStatValue : kStatOff}];
[MWMTextToSpeech setTTSEnabled:NO];
[tableView reloadSections:[NSIndexSet indexSetWithIndex:0]
withRowAnimation:UITableViewRowAnimationFade];
}
else
{
[Statistics logEvent:kStatEventName(kStatSettings, kStatTTS)
withParameters:@{kStatValue : kStatOn}];
[MWMTextToSpeech setTTSEnabled:YES];
NSInteger const row = indexPath.row - 1;
if (row == _languages.size())
{
[Statistics logEvent:kStatEventName(kStatTTSSettings, kStatChangeLanguage)
withParameters:@{kStatValue : kStatOther}];
[self performSegueWithIdentifier:kSelectTTSLanguageSegueName sender:nil];
}
else
{
[[MWMTextToSpeech tts] setNotificationsLocale:@(_languages[row].first.c_str())];
[tableView reloadSections:[NSIndexSet indexSetWithIndex:0]
withRowAnimation:UITableViewRowAnimationFade];
}
}
[self.tableView insertSections:indexSet withRowAnimation:animation];
statValue = kStatOn;
}
else if (indexPath.section == 1)
else
{
[Statistics logEvent:kStatEventName(kStatTTSSettings, kStatHelp)];
NSString * path =
[NSBundle.mainBundle pathForResource:@"tts-how-to-set-up-voice" ofType:@"html"];
NSString * html =
[[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NSURL * baseURL = [NSURL fileURLWithPath:path];
WebViewController * vc =
[[WebViewController alloc] initWithHtml:html
baseUrl:baseURL
title:L(@"pref_tts_how_to_set_up_voice")];
[self.navigationController pushViewController:vc animated:YES];
[self.tableView deleteSections:indexSet withRowAnimation:animation];
statValue = kStatOff;
}
[Statistics logEvent:kStatEventName(kStatSettings, kStatTTS)
withParameters:@{kStatValue: statValue}];
}
@end

View file

@ -514,7 +514,7 @@
<rect key="frame" x="0.0" y="790.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Wqu-gu-kFj" id="aVC-Mw-Q04">
<rect key="frame" x="0.0" y="0.0" width="349" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Управление подписками" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="k6E-9d-5e0">
@ -553,7 +553,7 @@
<rect key="frame" x="0.0" y="882.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="QNt-XC-xma" id="fBV-aJ-Mo8">
<rect key="frame" x="0.0" y="0.0" width="349" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Ночной режим" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="q7P-cj-3tZ">
@ -656,7 +656,7 @@
<rect key="frame" x="0.0" y="1014.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="nED-2n-gN6" id="2oQ-0g-poj">
<rect key="frame" x="0.0" y="0.0" width="349" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Голосовые инструкции" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2v2-mU-aWi">
@ -687,47 +687,12 @@
<outlet property="title" destination="2v2-mU-aWi" id="Zp1-zJ-xDM"/>
</connections>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="SettingsTableViewLinkCell" id="fdb-8T-bRe" customClass="SettingsTableViewLinkCell" customModule="maps_me" customModuleProvider="target">
<rect key="frame" x="0.0" y="1058.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="fdb-8T-bRe" id="DcP-q9-DzN">
<rect key="frame" x="0.0" y="0.0" width="349" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Уведомления о камерах" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lHi-hM-vYP">
<rect key="frame" x="16" y="12" width="293" height="19.5"/>
<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"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="300" verticalHuggingPriority="251" horizontalCompressionResistancePriority="700" text="Auto" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JKY-pj-4MS">
<rect key="frame" x="313" y="12" width="36" height="19.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.54000000000000004" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="JKY-pj-4MS" secondAttribute="bottom" constant="12" id="OOS-6m-gcp"/>
<constraint firstItem="JKY-pj-4MS" firstAttribute="leading" secondItem="lHi-hM-vYP" secondAttribute="trailing" constant="4" id="cNP-7O-301"/>
<constraint firstItem="lHi-hM-vYP" firstAttribute="top" secondItem="DcP-q9-DzN" secondAttribute="top" constant="12" id="fFg-Y3-IiS"/>
<constraint firstItem="JKY-pj-4MS" firstAttribute="top" secondItem="DcP-q9-DzN" secondAttribute="top" constant="12" id="fJY-QH-IlH"/>
<constraint firstItem="lHi-hM-vYP" firstAttribute="leading" secondItem="DcP-q9-DzN" secondAttribute="leading" constant="16" id="oEc-OC-Y8i"/>
<constraint firstAttribute="trailing" secondItem="JKY-pj-4MS" secondAttribute="trailing" id="rXI-tZ-Tnn"/>
<constraint firstAttribute="bottom" secondItem="lHi-hM-vYP" secondAttribute="bottom" constant="12" id="v9a-AJ-AqZ"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="info" destination="JKY-pj-4MS" id="DJi-Ix-5s1"/>
<outlet property="title" destination="lHi-hM-vYP" id="zNY-0l-Wze"/>
</connections>
</tableViewCell>
</cells>
</tableViewSection>
<tableViewSection headerTitle="ИНФОРМАЦИЯ" id="i4H-WV-BaS">
<cells>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="SettingsTableViewLinkCell" id="JTZ-K9-RVv" customClass="SettingsTableViewLinkCell" customModule="maps_me" customModuleProvider="target">
<rect key="frame" x="0.0" y="1150.5" width="375" height="44"/>
<rect key="frame" x="0.0" y="1106.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="JTZ-K9-RVv" id="mHA-wn-hse">
<rect key="frame" x="0.0" y="0.0" width="349" height="43.5"/>
@ -762,7 +727,7 @@
</connections>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="SettingsTableViewLinkCell" id="Kv3-pO-jV5" customClass="SettingsTableViewLinkCell" customModule="maps_me" customModuleProvider="target">
<rect key="frame" x="0.0" y="1194.5" width="375" height="44"/>
<rect key="frame" x="0.0" y="1150.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Kv3-pO-jV5" id="8mJ-wm-9uJ">
<rect key="frame" x="0.0" y="0.0" width="349" height="43.5"/>
@ -828,7 +793,6 @@
<outlet property="recentTrackCell" destination="VyW-Wh-2QX" id="zXx-a3-FBg"/>
<outlet property="restoreSubscriptionCell" destination="2pB-bw-TE4" id="wqz-cu-DZJ"/>
<outlet property="showOffersCell" destination="F1Y-qu-HAo" id="poJ-lN-MJ2"/>
<outlet property="speedCamsCell" destination="fdb-8T-bRe" id="Dgv-Nw-0id"/>
<outlet property="statisticsCell" destination="NOt-bc-7ls" id="OeS-uK-O2Q"/>
<outlet property="transliterationCell" destination="f8Z-Jk-JIR" id="4X8-tt-Wf3"/>
<outlet property="unitsCell" destination="Igk-BI-aHN" id="wc7-AI-ZlZ"/>
@ -842,7 +806,6 @@
<segue destination="WyW-ez-gUy" kind="custom" identifier="SettingsToAbout" customClass="MWMSegue" id="GJ9-7y-RKR"/>
<segue destination="f2i-mO-skH" kind="custom" identifier="SettingsToHelp" customClass="MWMSegue" id="PSn-ic-YWl"/>
<segue destination="4XX-qH-r6x" kind="custom" identifier="SettingsToMobileInternetSegue" customClass="MWMSegue" id="wBF-fV-zWQ"/>
<segue destination="F6A-V3-8ci" kind="custom" identifier="SettingsToSpeedCamsSegue" customClass="MWMSegue" id="SHg-u0-eVg"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="I90-hv-hTP" userLabel="First Responder" sceneMemberID="firstResponder"/>
@ -1189,9 +1152,47 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.96078431372549022" green="0.96078431372549022" blue="0.96078431372549022" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<prototypes>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="checkmark" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="SettingsTableViewSelectableCell" id="79I-kz-hl4" customClass="SettingsTableViewSelectableCell" customModule="maps_me" customModuleProvider="target">
<tableViewCell contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="SettingsTableViewSwitchCell" id="hb3-Fe-677" customClass="SettingsTableViewSwitchCell" customModule="maps_me" customModuleProvider="target">
<rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="hb3-Fe-677" id="gQB-q8-5c8">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Voice instructions" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="13" translatesAutoresizingMaskIntoConstraints="NO" id="1JE-c4-BGG">
<rect key="frame" x="16" y="14" width="278" height="15.5"/>
<inset key="insetFor6xAndEarlier" minX="0.0" minY="0.0" maxX="-25" maxY="0.0"/>
<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="colorName" value="blackPrimaryText"/>
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular17"/>
</userDefinedRuntimeAttributes>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Y9L-MA-GCQ">
<rect key="frame" x="302" y="6.5" width="51" height="31"/>
<inset key="insetFor6xAndEarlier" minX="3" minY="-2" maxX="-3" maxY="2"/>
<color key="onTintColor" red="0.1176470588" green="0.58823529409999997" blue="0.94117647059999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</switch>
</subviews>
<constraints>
<constraint firstItem="1JE-c4-BGG" firstAttribute="top" secondItem="gQB-q8-5c8" secondAttribute="topMargin" constant="3" id="6vy-AD-AcL"/>
<constraint firstItem="Y9L-MA-GCQ" firstAttribute="centerY" secondItem="gQB-q8-5c8" secondAttribute="centerY" id="7PA-sU-7vo"/>
<constraint firstItem="1JE-c4-BGG" firstAttribute="leading" secondItem="gQB-q8-5c8" secondAttribute="leading" constant="16" id="LJM-Xe-kOa"/>
<constraint firstAttribute="bottomMargin" secondItem="1JE-c4-BGG" secondAttribute="bottom" constant="3.5" id="c1W-JK-rTN"/>
<constraint firstItem="Y9L-MA-GCQ" firstAttribute="leading" secondItem="1JE-c4-BGG" secondAttribute="trailing" constant="8" id="f6r-ld-z4j"/>
<constraint firstAttribute="trailingMargin" secondItem="Y9L-MA-GCQ" secondAttribute="trailing" constant="8" id="yoV-EP-lGK"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="switchButton" destination="Y9L-MA-GCQ" id="KcX-qB-RNs"/>
<outlet property="title" destination="1JE-c4-BGG" id="umA-FF-qdh"/>
</connections>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="checkmark" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="SettingsTableViewSelectableCell" id="79I-kz-hl4" customClass="SettingsTableViewSelectableCell" customModule="maps_me" customModuleProvider="target">
<rect key="frame" x="0.0" y="99.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="79I-kz-hl4" id="gBB-ji-big">
<rect key="frame" x="0.0" y="0.0" width="335" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
@ -1219,7 +1220,7 @@
</connections>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="SettingsTableViewLinkCell" id="lO6-zb-qb8" customClass="SettingsTableViewLinkCell" customModule="maps_me" customModuleProvider="target">
<rect key="frame" x="0.0" y="99.5" width="375" height="44"/>
<rect key="frame" x="0.0" y="143.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="lO6-zb-qb8" id="35k-Nb-XSD">
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
@ -1986,125 +1987,5 @@
</objects>
<point key="canvasLocation" x="1881" y="1088"/>
</scene>
<!--Speed Cam Settings Controller-->
<scene sceneID="hSN-pU-5dA">
<objects>
<tableViewController id="F6A-V3-8ci" customClass="MWMSpeedCamSettingsController" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="iui-Gy-S8j">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.96078431369999995" green="0.96078431369999995" blue="0.96078431369999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<sections>
<tableViewSection footerTitle="Auto - Warn about speedcams if there is a risk of exceeding the speed limit" id="vIv-h0-cIZ">
<cells>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="SettingsTableViewSelectableCell" id="XIR-dX-Iyu" customClass="SettingsTableViewSelectableCell" customModule="maps_me" customModuleProvider="target">
<rect key="frame" x="0.0" y="35" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="XIR-dX-Iyu" id="nXx-Kg-JON">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Auto" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4iL-lH-XUN">
<rect key="frame" x="16" y="14" width="333" height="15.5"/>
<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="colorName" value="blackPrimaryText"/>
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular17"/>
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="speedcam_option_auto"/>
</userDefinedRuntimeAttributes>
</label>
</subviews>
<constraints>
<constraint firstItem="4iL-lH-XUN" firstAttribute="top" secondItem="nXx-Kg-JON" secondAttribute="topMargin" constant="3" id="14d-qO-oHm"/>
<constraint firstAttribute="trailingMargin" secondItem="4iL-lH-XUN" secondAttribute="trailing" constant="10" id="S7V-fK-F1F"/>
<constraint firstItem="4iL-lH-XUN" firstAttribute="leading" secondItem="nXx-Kg-JON" secondAttribute="leading" constant="16" id="Z0I-mc-URe"/>
<constraint firstAttribute="bottomMargin" secondItem="4iL-lH-XUN" secondAttribute="bottom" constant="3.5" id="fCh-hI-EmM"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="title" destination="4iL-lH-XUN" id="l0r-4R-6HT"/>
</connections>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="SettingsTableViewSelectableCell" id="qIy-EY-QEG" customClass="SettingsTableViewSelectableCell" customModule="maps_me" customModuleProvider="target">
<rect key="frame" x="0.0" y="79" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="qIy-EY-QEG" id="YZV-lF-1i4">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Always" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iw2-aS-cMw">
<rect key="frame" x="16" y="14" width="333" height="15.5"/>
<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="colorName" value="blackPrimaryText"/>
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular17"/>
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="speedcam_option_always"/>
</userDefinedRuntimeAttributes>
</label>
</subviews>
<constraints>
<constraint firstItem="iw2-aS-cMw" firstAttribute="leading" secondItem="YZV-lF-1i4" secondAttribute="leading" constant="16" id="Qh3-v5-fYO"/>
<constraint firstAttribute="bottomMargin" secondItem="iw2-aS-cMw" secondAttribute="bottom" constant="3.5" id="cH6-Kl-X4V"/>
<constraint firstAttribute="trailingMargin" secondItem="iw2-aS-cMw" secondAttribute="trailing" constant="10" id="njS-Ct-ykT"/>
<constraint firstItem="iw2-aS-cMw" firstAttribute="top" secondItem="YZV-lF-1i4" secondAttribute="topMargin" constant="3" id="oce-nG-rCW"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="title" destination="iw2-aS-cMw" id="UYR-c9-sPR"/>
</connections>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="SettingsTableViewSelectableCell" id="XHh-tD-Eh0" customClass="SettingsTableViewSelectableCell" customModule="maps_me" customModuleProvider="target">
<rect key="frame" x="0.0" y="123" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="XHh-tD-Eh0" id="G3j-Pp-PQk">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Never" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="LO3-1M-pCn">
<rect key="frame" x="16" y="14" width="333" height="15.5"/>
<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="colorName" value="blackPrimaryText"/>
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular17"/>
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="speedcam_option_never"/>
</userDefinedRuntimeAttributes>
</label>
</subviews>
<constraints>
<constraint firstItem="LO3-1M-pCn" firstAttribute="leading" secondItem="G3j-Pp-PQk" secondAttribute="leading" constant="16" id="EzB-XS-qEP"/>
<constraint firstAttribute="trailingMargin" secondItem="LO3-1M-pCn" secondAttribute="trailing" constant="10" id="HLd-V5-qWq"/>
<constraint firstAttribute="bottomMargin" secondItem="LO3-1M-pCn" secondAttribute="bottom" constant="3.5" id="dLJ-3d-uzU"/>
<constraint firstItem="LO3-1M-pCn" firstAttribute="top" secondItem="G3j-Pp-PQk" secondAttribute="topMargin" constant="3" id="uvQ-3h-w7R"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="title" destination="LO3-1M-pCn" id="3iW-iw-XYz"/>
</connections>
</tableViewCell>
</cells>
</tableViewSection>
</sections>
<connections>
<outlet property="dataSource" destination="F6A-V3-8ci" id="DXN-r9-0dB"/>
<outlet property="delegate" destination="F6A-V3-8ci" id="e16-Nq-Mgl"/>
</connections>
</tableView>
<navigationItem key="navigationItem" id="hcW-SE-QaP"/>
<connections>
<outlet property="alwaysCell" destination="qIy-EY-QEG" id="t5g-gh-Dx7"/>
<outlet property="autoCell" destination="XIR-dX-Iyu" id="Xt3-nm-5Na"/>
<outlet property="neverCell" destination="XHh-tD-Eh0" id="SRL-Mk-hWQ"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Iiz-Be-fgS" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1881" y="397"/>
</scene>
</scenes>
</document>