[ios] Refactored editor.

This commit is contained in:
VladiMihaylenko 2016-04-14 12:20:20 +03:00
parent ad4d681fa5
commit a85016b807
3 changed files with 88 additions and 77 deletions

View file

@ -39,19 +39,7 @@ vector<MWMPlacePageCellType> const kSectionCategoryCellTypes{MWMPlacePageCellTyp
vector<MWMPlacePageCellType> const kSectionNameCellTypes{MWMPlacePageCellTypeName};
vector<MWMPlacePageCellType> const kSectionAddressCellTypes{
{MWMPlacePageCellTypeStreet, MWMPlacePageCellTypeBuilding}};
vector<MWMPlacePageCellType> const kSectionDetailsCellTypes{
{MWMPlacePageCellTypeOpenHours, MWMPlacePageCellTypePhoneNumber, MWMPlacePageCellTypeWebsite,
MWMPlacePageCellTypeEmail, MWMPlacePageCellTypeCuisine, MWMPlacePageCellTypeWiFi}};
using CellTypesSectionMap = pair<vector<MWMPlacePageCellType>, MWMEditorSection>;
vector<CellTypesSectionMap> const kCellTypesSectionMap{
{kSectionCategoryCellTypes, MWMEditorSectionCategory},
{kSectionNameCellTypes, MWMEditorSectionName},
{kSectionAddressCellTypes, MWMEditorSectionAddress},
{kSectionDetailsCellTypes, MWMEditorSectionDetails}};
MWMPlacePageCellTypeStreet, MWMPlacePageCellTypeBuilding};
MWMPlacePageCellTypeValueMap const kCellType2ReuseIdentifier{
{MWMPlacePageCellTypeCategory, "MWMEditorCategoryCell"},
@ -72,6 +60,57 @@ NSString * reuseIdentifier(MWMPlacePageCellType cellType)
ASSERT(haveCell, ());
return haveCell ? @(it->second.c_str()) : @"";
}
vector<MWMPlacePageCellType> cellsForProperties(vector<osm::Props> const & props)
{
using namespace osm;
vector<MWMPlacePageCellType> res;
for (auto const p : props)
{
switch (p)
{
case Props::OpeningHours:
res.push_back(MWMPlacePageCellTypeOpenHours);
break;
case Props::Phone:
res.push_back(MWMPlacePageCellTypePhoneNumber);
break;
case Props::Website:
res.push_back(MWMPlacePageCellTypeWebsite);
break;
case Props::Email:
res.push_back(MWMPlacePageCellTypeEmail);
break;
case Props::Cuisine:
res.push_back(MWMPlacePageCellTypeCuisine);
break;
case Props::Internet:
res.push_back(MWMPlacePageCellTypeWiFi);
break;
case Props::Wikipedia:
case Props::Fax:
case Props::Stars:
case Props::Operator:
case Props::Elevation:
case Props::Flats:
case Props::BuildingLevels:
break;
}
}
return res;
}
void registerCellsForTableView(vector<MWMPlacePageCellType> const & cells, UITableView * tv)
{
for (auto const c : cells)
{
NSString * identifier = reuseIdentifier(c);
if (UINib * nib = [UINib nibWithNibName:identifier bundle:nil])
[tv registerNib:nib forCellReuseIdentifier:identifier];
else
ASSERT(false, ("Incorrect cell"));
}
}
} // namespace
@interface MWMEditorViewController() <UITableViewDelegate, UITableViewDataSource,
@ -205,81 +244,56 @@ NSString * reuseIdentifier(MWMPlacePageCellType cellType)
return cell;
}
// TODO(Vlad): This code can be much better.
- (bool)hasField:(feature::Metadata::EType)field
{
auto const & editable = m_mapObject.GetEditableFields();
return editable.end() != find(editable.begin(), editable.end(), field);
}
// TODO(Vlad): This code can be much better.
- (bool)isEditable:(MWMPlacePageCellType)cellType
{
switch (cellType)
{
case MWMPlacePageCellTypePostcode: return [self hasField:feature::Metadata::FMD_POSTCODE];
case MWMPlacePageCellTypePhoneNumber: return [self hasField:feature::Metadata::FMD_PHONE_NUMBER];
case MWMPlacePageCellTypeWebsite: return [self hasField:feature::Metadata::FMD_WEBSITE];
// TODO(Vlad): We should not have URL field in the UI. Website should always be used instead.
case MWMPlacePageCellTypeURL: return [self hasField:feature::Metadata::FMD_URL];
case MWMPlacePageCellTypeEmail: return [self hasField:feature::Metadata::FMD_EMAIL];
case MWMPlacePageCellTypeOpenHours: return [self hasField:feature::Metadata::FMD_OPEN_HOURS];
case MWMPlacePageCellTypeWiFi: return [self hasField:feature::Metadata::FMD_INTERNET];
case MWMPlacePageCellTypeCuisine: return [self hasField:feature::Metadata::FMD_CUISINE];
// TODO(Vlad): return true when we allow coordinates editing.
case MWMPlacePageCellTypeCoordinate: return false;
case MWMPlacePageCellTypeName: return m_mapObject.IsNameEditable();
case MWMPlacePageCellTypeStreet: return m_mapObject.IsAddressEditable();
case MWMPlacePageCellTypeBuilding: return m_mapObject.IsAddressEditable();
case MWMPlacePageCellTypeCategory: return self.isCreating;
default: NSAssert(false, @"Invalid cell type %@", @(cellType)); return false;
}
}
- (void)configTable
{
self.offscreenCells = [NSMutableDictionary dictionary];
self.invalidCells = [NSMutableArray array];
m_sections.clear();
m_cells.clear();
for (auto const & cellsSection : kCellTypesSectionMap)
{
for (auto cellType : cellsSection.first)
{
if (![self isEditable:cellType])
continue;
m_sections.emplace_back(cellsSection.second);
m_cells[cellsSection.second].emplace_back(cellType);
NSString * identifier = reuseIdentifier(cellType);
if (UINib * nib = [UINib nibWithNibName:identifier bundle:nil])
[self.tableView registerNib:nib forCellReuseIdentifier:identifier];
else
NSAssert(false, @"Incorrect cell");
if (self.isCreating)
{
m_sections.push_back(MWMEditorSectionCategory);
m_cells[MWMEditorSectionCategory] = kSectionCategoryCellTypes;
registerCellsForTableView(kSectionCategoryCellTypes, self.tableView);
}
if (m_mapObject.IsNameEditable())
{
m_sections.push_back(MWMEditorSectionName);
m_cells[MWMEditorSectionName] = kSectionNameCellTypes;
registerCellsForTableView(kSectionNameCellTypes, self.tableView);
}
if (m_mapObject.IsAddressEditable())
{
m_sections.push_back(MWMEditorSectionAddress);
m_cells[MWMEditorSectionAddress] = kSectionAddressCellTypes;
registerCellsForTableView(kSectionAddressCellTypes, self.tableView);
}
if (!m_mapObject.GetEditableProperties().empty())
{
auto const cells = cellsForProperties(m_mapObject.GetEditableProperties());
if (!cells.empty())
{
m_sections.push_back(MWMEditorSectionDetails);
m_cells[MWMEditorSectionDetails] = cells;
registerCellsForTableView(cells, self.tableView);
}
}
sort(m_sections.begin(), m_sections.end());
m_sections.erase(unique(m_sections.begin(), m_sections.end()), m_sections.end());
}
- (MWMPlacePageCellType)cellTypeForIndexPath:(NSIndexPath *)indexPath
{
MWMEditorSection const section = m_sections[indexPath.section];
MWMPlacePageCellType const cellType = m_cells[section][indexPath.row];
return cellType;
return m_cells[m_sections[indexPath.section]][indexPath.row];
}
- (NSString *)cellIdentifierForIndexPath:(NSIndexPath *)indexPath
{
MWMPlacePageCellType const cellType = [self cellTypeForIndexPath:indexPath];
return reuseIdentifier(cellType);
return reuseIdentifier([self cellTypeForIndexPath:indexPath]);
}
#pragma mark - Fill cells with data
- (void)fillCell:(UITableViewCell * _Nonnull)cell atIndexPath:(NSIndexPath * _Nonnull)indexPath
{
MWMPlacePageCellType const cellType = [self cellTypeForIndexPath:indexPath];
switch (cellType)
switch ([self cellTypeForIndexPath:indexPath])
{
case MWMPlacePageCellTypeCategory:
{
@ -385,7 +399,9 @@ NSString * reuseIdentifier(MWMPlacePageCellType cellType)
- (UITableViewCell * _Nonnull)tableView:(UITableView * _Nonnull)tableView cellForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
{
NSString * reuseIdentifier = [self cellIdentifierForIndexPath:indexPath];
return [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
[self fillCell:cell atIndexPath:indexPath];
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView * _Nonnull)tableView
@ -395,8 +411,7 @@ NSString * reuseIdentifier(MWMPlacePageCellType cellType)
- (NSInteger)tableView:(UITableView * _Nonnull)tableView numberOfRowsInSection:(NSInteger)section
{
MWMEditorSection const sec = m_sections[section];
return m_cells[sec].size();
return m_cells[m_sections[section]].size();
}
#pragma mark - UITableViewDelegate
@ -404,6 +419,7 @@ NSString * reuseIdentifier(MWMPlacePageCellType cellType)
- (CGFloat)tableView:(UITableView * _Nonnull)tableView heightForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
{
NSString * reuseIdentifier = [self cellIdentifierForIndexPath:indexPath];
UITableViewCell * cell = [self offscreenCellForIdentifier:reuseIdentifier];
// TODO(Vlad, IGrechuhin): It's bad idea to fill cells here.
// heightForRowAtIndexPath is called way too often for the table.
@ -428,11 +444,6 @@ NSString * reuseIdentifier(MWMPlacePageCellType cellType)
}
}
- (void)tableView:(UITableView * _Nonnull)tableView willDisplayCell:(UITableViewCell * _Nonnull)cell forRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
{
[self fillCell:cell atIndexPath:indexPath];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
switch (m_sections[section])

View file

@ -105,7 +105,7 @@ namespace
return c.m_name == category;
});
NSAssert(it != all.end(), @"Incorrect category!");
self.selectedIndexPath = [NSIndexPath indexPathForRow:(it - all.begin())
self.selectedIndexPath = [NSIndexPath indexPathForRow:(distance(all.begin(), it))
inSection:m_categories.m_lastUsed.empty() ? 0 : 1];
}

View file

@ -59,7 +59,7 @@ namespace
}
else
{
self.selectedStreet = it - m_streets.begin();
self.selectedStreet = distance(m_streets.begin(), it);
}
}
else