From ba6781239321ec0925eb9158a74cbd9cc76f99b0 Mon Sep 17 00:00:00 2001 From: Aleksey Belouosv Date: Tue, 19 Feb 2019 14:50:08 +0300 Subject: [PATCH] [iOS] limit maximum number of tags --- .../Sharing/BookmarksSharingFlow.storyboard | 9 ++--- .../Tags/SharingTagsViewController.swift | 39 +++++++++++++++++-- .../Sharing/Tags/TagCollectionViewCell.swift | 19 ++++++--- .../Tags/TagsCollectionViewLayout.swift | 8 ++-- .../Sharing/Tags/TagsDataSource.swift | 13 +++++-- .../Maps/Core/Bookmarks/MWMBookmarksManager.h | 5 ++- .../Core/Bookmarks/MWMBookmarksManager.mm | 5 +-- 7 files changed, 74 insertions(+), 24 deletions(-) diff --git a/iphone/Maps/Bookmarks/Categories/Sharing/BookmarksSharingFlow.storyboard b/iphone/Maps/Bookmarks/Categories/Sharing/BookmarksSharingFlow.storyboard index ebb773c34b..961afd748e 100644 --- a/iphone/Maps/Bookmarks/Categories/Sharing/BookmarksSharingFlow.storyboard +++ b/iphone/Maps/Bookmarks/Categories/Sharing/BookmarksSharingFlow.storyboard @@ -378,7 +378,6 @@ - @@ -501,7 +500,7 @@ - + - - + @@ -555,6 +553,7 @@ + diff --git a/iphone/Maps/Bookmarks/Categories/Sharing/Tags/SharingTagsViewController.swift b/iphone/Maps/Bookmarks/Categories/Sharing/Tags/SharingTagsViewController.swift index e54fd7d72c..749f53d910 100644 --- a/iphone/Maps/Bookmarks/Categories/Sharing/Tags/SharingTagsViewController.swift +++ b/iphone/Maps/Bookmarks/Categories/Sharing/Tags/SharingTagsViewController.swift @@ -4,11 +4,15 @@ protocol SharingTagsViewControllerDelegate: AnyObject { } final class SharingTagsViewController: MWMViewController { - @IBOutlet private weak var loadingTagsView: UIView! @IBOutlet private weak var progressView: UIView! @IBOutlet private weak var collectionView: UICollectionView! @IBOutlet private weak var doneButton: UIBarButtonItem! + @IBOutlet private weak var descriptionLabel: UILabel! { + didSet { + descriptionLabel.text = "" + } + } private lazy var progress: MWMCircularProgress = { return MWMCircularProgress(parentView: progressView) @@ -16,6 +20,7 @@ final class SharingTagsViewController: MWMViewController { let dataSource = TagsDataSource() weak var delegate: SharingTagsViewControllerDelegate? + var isSelectionAvailable = true let kTagCellIdentifier = "TagCellIdentifier" let kTagHeaderIdentifier = "TagHeaderIdentifier" @@ -24,7 +29,9 @@ final class SharingTagsViewController: MWMViewController { super.viewDidLoad() title = L("ugc_route_tags_screen_label") - + descriptionLabel.text = String(coreFormat: L("ugc_route_tags_desc"), + arguments:[dataSource.maxNumberOfTagsToSelect]) + doneButton.isEnabled = false navigationItem.rightBarButtonItem = doneButton navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, @@ -46,6 +53,8 @@ final class SharingTagsViewController: MWMViewController { self.loadingTagsView.isHidden = true if success { + self.descriptionLabel.text = String(coreFormat: L("ugc_route_tags_desc"), + arguments:[self.dataSource.maxNumberOfTagsToSelect]) self.collectionView.reloadData() } else { MWMAlertViewController.activeAlert().presentTagsLoadingErrorAlert(okBlock: { [weak self] in @@ -84,7 +93,8 @@ final class SharingTagsViewController: MWMViewController { func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: kTagCellIdentifier,for: indexPath) as! TagCollectionViewCell - cell.update(with: dataSource.tag(in: indexPath.section, at: indexPath.item)) + cell.update(with: dataSource.tag(in: indexPath.section, at: indexPath.item), + enabled: cell.isSelected || isSelectionAvailable) //we need to do this because of bug - ios 12 doesnt apply layout to cells until scrolling if #available(iOS 12.0, *) { @@ -107,6 +117,11 @@ final class SharingTagsViewController: MWMViewController { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { doneButton.isEnabled = true + + if collectionView.indexPathsForSelectedItems?.count == dataSource.maxNumberOfTagsToSelect { + isSelectionAvailable = false + reloadUnselectedCells() + } } func collectionView(_ collectionView: UICollectionView, @@ -116,5 +131,23 @@ final class SharingTagsViewController: MWMViewController { } else { doneButton.isEnabled = false } + + isSelectionAvailable = true + reloadUnselectedCells() + } + + func reloadUnselectedCells() { + if let selectedItemsIndexes = collectionView.indexPathsForSelectedItems { + let visibleItemsIndexes = collectionView.indexPathsForVisibleItems + let notSelectedItemsIndexes = visibleItemsIndexes.filter { !selectedItemsIndexes.contains($0) } + UIView.performWithoutAnimation { + collectionView.reloadItems(at: notSelectedItemsIndexes) + } + } + } + + func collectionView(_ collectionView: UICollectionView, + shouldSelectItemAt indexPath: IndexPath) -> Bool { + return isSelectionAvailable } } diff --git a/iphone/Maps/Bookmarks/Categories/Sharing/Tags/TagCollectionViewCell.swift b/iphone/Maps/Bookmarks/Categories/Sharing/Tags/TagCollectionViewCell.swift index c41751168a..7b9d216073 100644 --- a/iphone/Maps/Bookmarks/Categories/Sharing/Tags/TagCollectionViewCell.swift +++ b/iphone/Maps/Bookmarks/Categories/Sharing/Tags/TagCollectionViewCell.swift @@ -10,16 +10,25 @@ final class TagCollectionViewCell: UICollectionViewCell { } } - override var isSelected: Bool{ + override var isSelected: Bool { didSet { - containerView.backgroundColor = isSelected ? color : .white() - title.textColor = isSelected ? .whitePrimaryText() : color + updateSelectedState() } } - func update(with tag: MWMTag) { + func update(with tag: MWMTag, enabled: Bool) { title.text = tag.name - color = tag.color + if enabled { + color = tag.color + updateSelectedState() + } else { + color = .blackDividers() + } + } + + func updateSelectedState() { + containerView.backgroundColor = isSelected ? color : .white() + title.textColor = isSelected ? .whitePrimaryText() : color } override func prepareForReuse() { diff --git a/iphone/Maps/Bookmarks/Categories/Sharing/Tags/TagsCollectionViewLayout.swift b/iphone/Maps/Bookmarks/Categories/Sharing/Tags/TagsCollectionViewLayout.swift index 0f59328106..b545dbede3 100644 --- a/iphone/Maps/Bookmarks/Categories/Sharing/Tags/TagsCollectionViewLayout.swift +++ b/iphone/Maps/Bookmarks/Categories/Sharing/Tags/TagsCollectionViewLayout.swift @@ -1,5 +1,4 @@ final class TagsCollectionViewLayout: UICollectionViewLayout { - private var headersCache: [IndexPath : UICollectionViewLayoutAttributes] = [:] private var cellsCache: [IndexPath : UICollectionViewLayoutAttributes] = [:] fileprivate var contentHeight: CGFloat = 0 @@ -40,8 +39,7 @@ final class TagsCollectionViewLayout: UICollectionViewLayout { let indexPath = IndexPath(item: 0, section: section) - if collectionView.supplementaryView(forElementKind: UICollectionElementKindSectionHeader, - at: indexPath) != nil { + if collectionView.numberOfSections > 0 { let headerSize = headersCache[indexPath]?.size ?? CGSize(width: contentWidth, height: itemHeight) let frame = CGRect(x: 0, y: yOffset, width: headerSize.width, height: headerSize.height) let attr = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, with: indexPath) @@ -90,6 +88,10 @@ final class TagsCollectionViewLayout: UICollectionViewLayout { return visibleLayoutAttributes } + + override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { + return cellsCache[indexPath] + } override public func shouldInvalidateLayout(forPreferredLayoutAttributes preferredAttributes: UICollectionViewLayoutAttributes, withOriginalAttributes originalAttributes: UICollectionViewLayoutAttributes) -> Bool { diff --git a/iphone/Maps/Bookmarks/Categories/Sharing/Tags/TagsDataSource.swift b/iphone/Maps/Bookmarks/Categories/Sharing/Tags/TagsDataSource.swift index e9b31113d3..569d1de523 100644 --- a/iphone/Maps/Bookmarks/Categories/Sharing/Tags/TagsDataSource.swift +++ b/iphone/Maps/Bookmarks/Categories/Sharing/Tags/TagsDataSource.swift @@ -1,21 +1,28 @@ final class TagsDataSource: NSObject { - private var tagGroups: [MWMTagGroup] = [] + private var maxTagsNumber: Int = 0 func loadTags(onComplete: @escaping (Bool) -> Void) { - MWMBookmarksManager.shared().loadTags { tags in + MWMBookmarksManager.shared().loadTags { tags, maxTagsNumber in if let tags = tags { self.tagGroups = tags + self.maxTagsNumber = maxTagsNumber } onComplete(!self.tagGroups.isEmpty) } } - var tagGroupsCount: NSInteger { + var tagGroupsCount: Int { get { return tagGroups.count } } + + var maxNumberOfTagsToSelect: Int { + get { + return maxTagsNumber + } + } func tagGroup(at index: Int) -> MWMTagGroup { return tagGroups[index] diff --git a/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.h b/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.h index 2811aae88f..62254baf7a 100644 --- a/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.h +++ b/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.h @@ -6,9 +6,10 @@ @class MWMTagGroup; @class MWMTag; -typedef void (^LoadTagsCompletionBlock)(NSArray * tags); - NS_ASSUME_NONNULL_BEGIN + +typedef void (^LoadTagsCompletionBlock)(NSArray * _Nullable tags, NSInteger maxTagsNumber); + @interface MWMBookmarksManager : NSObject + (MWMBookmarksManager *)sharedManager; diff --git a/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.mm b/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.mm index 38575a0f48..b8186b5b31 100644 --- a/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.mm +++ b/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.mm @@ -626,7 +626,6 @@ NSString * const CloudErrorToString(Cloud::SynchronizationResult result) - (void)loadTags:(LoadTagsCompletionBlock)completionBlock { auto onTagsCompletion = [completionBlock](bool success, BookmarkCatalog::TagGroups const & tagGroups, uint32_t maxTagsCount) { - //TODO(@beloal): Implement maxTagsCount usage. if (success) { NSMutableArray * groups = [NSMutableArray new]; @@ -636,9 +635,9 @@ NSString * const CloudErrorToString(Cloud::SynchronizationResult result) [groups addObject:tagGroup]; } - completionBlock([groups copy]); + completionBlock([groups copy], maxTagsCount); } else - completionBlock(nil); + completionBlock(nil, 0); }; self.bm.GetCatalog().RequestTagGroups([[AppInfo sharedInfo] languageId].UTF8String, std::move(onTagsCompletion));