Merge branch 'feature/tabs_list_item' into 'develop'
Tabs table cell See merge request BPHV_MIPS/mvm_core_ui!131
This commit is contained in:
commit
d62db8d5ac
@ -40,6 +40,7 @@
|
||||
D260D7B222D65BDD007E7233 /* MVMCoreUIPageControl.m in Sources */ = {isa = PBXBuildFile; fileRef = D260D7B022D65BDD007E7233 /* MVMCoreUIPageControl.m */; };
|
||||
D260D7B622D68514007E7233 /* MVMCoreUIPagingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D260D7B522D68509007E7233 /* MVMCoreUIPagingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D274CA332236A78900B01B62 /* StandardFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D274CA322236A78900B01B62 /* StandardFooterView.swift */; };
|
||||
D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */; };
|
||||
D282AAB4223FDDAE00C46919 /* MFLoadImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AAB3223FDDAE00C46919 /* MFLoadImageView.swift */; };
|
||||
D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */; };
|
||||
D282AACB2243C61700C46919 /* ButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AACA2243C61700C46919 /* ButtonView.swift */; };
|
||||
@ -222,6 +223,7 @@
|
||||
D260D7B022D65BDD007E7233 /* MVMCoreUIPageControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIPageControl.m; sourceTree = "<group>"; };
|
||||
D260D7B522D68509007E7233 /* MVMCoreUIPagingProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIPagingProtocol.h; sourceTree = "<group>"; };
|
||||
D274CA322236A78900B01B62 /* StandardFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardFooterView.swift; sourceTree = "<group>"; };
|
||||
D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D282AAB3223FDDAE00C46919 /* MFLoadImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MFLoadImageView.swift; sourceTree = "<group>"; };
|
||||
D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MFTransparentGIFView.swift; sourceTree = "<group>"; };
|
||||
D282AACA2243C61700C46919 /* ButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonView.swift; sourceTree = "<group>"; };
|
||||
@ -451,6 +453,7 @@
|
||||
D2A6390422CBCE160052ED1F /* MoleculeCollectionViewCell.swift */,
|
||||
D2E1FADC2268B25E00AEFD8C /* MoleculeTableViewCell.swift */,
|
||||
D224799A231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift */,
|
||||
D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */,
|
||||
);
|
||||
path = Items;
|
||||
sourceTree = "<group>";
|
||||
@ -997,6 +1000,7 @@
|
||||
DBC4391922442197001AB423 /* DashLine.swift in Sources */,
|
||||
D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */,
|
||||
D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */,
|
||||
D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */,
|
||||
D224799B231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift in Sources */,
|
||||
D22D1F1F220343560077CEC0 /* MVMCoreUICheckMarkView.m in Sources */,
|
||||
D282AAB4223FDDAE00C46919 /* MFLoadImageView.swift in Sources */,
|
||||
|
||||
@ -30,6 +30,9 @@
|
||||
|
||||
@property (nonatomic, readonly) NSInteger selectedIndex;
|
||||
|
||||
/// A flag for if there should be padding before the first item.
|
||||
@property (nonatomic) BOOL paddingBeforeFirstTab;
|
||||
|
||||
//method to set the height
|
||||
- (void)pinHeight:(CGFloat)height;
|
||||
|
||||
|
||||
@ -75,6 +75,7 @@ static NSString * const COLLECTION_CELL_ID = @"cell";
|
||||
}
|
||||
|
||||
- (void)setupView {
|
||||
self.paddingBeforeFirstTab = YES;
|
||||
self.maxHeight = BAR_HEIGHT;
|
||||
self.selectedIndex = 0;
|
||||
self.backgroundColor = [UIColor whiteColor];
|
||||
@ -229,6 +230,9 @@ static NSString * const COLLECTION_CELL_ID = @"cell";
|
||||
}
|
||||
|
||||
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
|
||||
if (!self.paddingBeforeFirstTab && section == 0) {
|
||||
return UIEdgeInsetsMake(SECTION_TOPPIN, 0,SECTION_BOTPIN, 0);
|
||||
}
|
||||
return UIEdgeInsetsMake(SECTION_TOPPIN, SECTION_PADDING,SECTION_BOTPIN, 0);
|
||||
}
|
||||
|
||||
@ -341,7 +345,7 @@ static NSString * const COLLECTION_CELL_ID = @"cell";
|
||||
}
|
||||
|
||||
- (void)selectIndex:(NSInteger)index animated:(BOOL)animated {
|
||||
if (self.collectionView) {
|
||||
if (self.collectionView && [self.datasource numberOfTopTabbarItems:self] > 0) {
|
||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
||||
NSInteger currentIndex = self.selectedIndex;
|
||||
self.selectedIndex = index;
|
||||
|
||||
@ -34,9 +34,9 @@ import UIKit
|
||||
}
|
||||
|
||||
if accordionButton.isSelected {
|
||||
delegateObject?.moleculeDelegate?.addMolecules?(molecules, senderIndexPath: indexPath)
|
||||
delegateObject?.moleculeDelegate?.addMolecules?(molecules, sender: self, animation: .automatic)
|
||||
} else {
|
||||
delegateObject?.moleculeDelegate?.removeMolecules?(molecules, senderIndexPath: indexPath)
|
||||
delegateObject?.moleculeDelegate?.removeMolecules?(molecules, sender: self, animation: .automatic)
|
||||
}
|
||||
|
||||
if (json?.boolForKey("hideSeparatorWhenExpanded") ?? false) && (self.bottomSeparatorView?.shouldBeVisible() ?? false) {
|
||||
|
||||
@ -137,7 +137,7 @@ import UIKit
|
||||
if let useHorizontalMargins = json?.optionalBoolForKey("useHorizontalMargins") {
|
||||
updateViewHorizontalDefaults = useHorizontalMargins
|
||||
}
|
||||
if json?.optionalBoolForKey("useVerticalMargins") ?? false {
|
||||
if (json?.optionalBoolForKey("useVerticalMargins") ?? true) == false {
|
||||
topMarginPadding = 0
|
||||
bottomMarginPadding = 0
|
||||
}
|
||||
|
||||
81
MVMCoreUI/Molecules/Items/TabsTableViewCell.swift
Normal file
81
MVMCoreUI/Molecules/Items/TabsTableViewCell.swift
Normal file
@ -0,0 +1,81 @@
|
||||
//
|
||||
// TabsTableViewCell.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 9/6/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@objcMembers public class TabsTableViewCell: MoleculeTableViewCell {
|
||||
let tabs = TopTabbar(frame: .zero)
|
||||
var delegateObject: MVMCoreUIDelegateObject?
|
||||
var previousTabIndex = 0
|
||||
|
||||
// MARK: - MFViewProtocol
|
||||
override public func setupView() {
|
||||
super.setupView()
|
||||
guard tabs.superview == nil else {
|
||||
return
|
||||
}
|
||||
tabs.paddingBeforeFirstTab = false
|
||||
topMarginPadding = 8
|
||||
bottomMarginPadding = 0
|
||||
|
||||
tabs.translatesAutoresizingMaskIntoConstraints = false
|
||||
tabs.delegate = self
|
||||
tabs.datasource = self
|
||||
contentView.addSubview(tabs)
|
||||
|
||||
NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: tabs, useMargins: true).values))
|
||||
tabs.reloadData()
|
||||
}
|
||||
|
||||
public override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
tabs.updateView(size)
|
||||
}
|
||||
|
||||
// MARK: - MoleculeDelegateProtocol
|
||||
public override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
self.delegateObject = delegateObject
|
||||
tabs.reloadData()
|
||||
}
|
||||
|
||||
public override func reset() {
|
||||
super.reset()
|
||||
topMarginPadding = 8
|
||||
bottomMarginPadding = 0
|
||||
}
|
||||
}
|
||||
|
||||
extension TabsTableViewCell: TopTabbarDelegate {
|
||||
public func shouldSelectItem(at index: Int, topTabbar: TopTabbar) -> Bool {
|
||||
if let moleculesArrays = json?.arrayForKey(KeyMolecules), let molecules = moleculesArrays[topTabbar.selectedIndex] as? [[AnyHashable: Any]] {
|
||||
delegateObject?.moleculeDelegate?.removeMolecules?(molecules, sender: self, animation: index < tabs.selectedIndex ? .right : .left)
|
||||
}
|
||||
previousTabIndex = tabs.selectedIndex
|
||||
return true
|
||||
}
|
||||
|
||||
public func topTabbar(_ topTabbar: TopTabbar, didSelectItemAt index: Int) {
|
||||
if let moleculesArrays = json?.arrayForKey(KeyMolecules), let molecules = moleculesArrays[index] as? [[AnyHashable: Any]] {
|
||||
delegateObject?.moleculeDelegate?.addMolecules?(molecules, sender: self, animation: index < previousTabIndex ? .left : .right)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension TabsTableViewCell: TopTabbarDataSource {
|
||||
public func number(ofTopTabbarItems topTabbar: TopTabbar) -> Int {
|
||||
return json?.optionalDictionaryForKey("tabs")?.optionalArrayForKey("tabs")?.count ?? 0
|
||||
}
|
||||
|
||||
public func topTabbar(_ topTabbar: TopTabbar, titleForItemAt index: Int) -> String? {
|
||||
guard let tabs = json?.optionalDictionaryForKey("tabs")?.arrayForKey("tabs"), let label = tabs[index] as? [AnyHashable: Any], let title = label.optionalStringForKey(KeyText) else {
|
||||
return "Select"
|
||||
}
|
||||
return title
|
||||
}
|
||||
}
|
||||
@ -58,7 +58,8 @@
|
||||
@"labelSwitch": LabelSwitch.class,
|
||||
@"headlineBodySwitch": HeadlineBodySwitch.class,
|
||||
@"headlineBodyTextButton": HeadlineBodyTextButton.class,
|
||||
@"headlineBodyTextButtonSwitch": HeadlineBodyTextButtonSwitch.class
|
||||
@"headlineBodyTextButtonSwitch": HeadlineBodyTextButtonSwitch.class,
|
||||
@"tabsListItem": TabsTableViewCell.class
|
||||
} mutableCopy];
|
||||
});
|
||||
return mapping;
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
- (void)moleculeLayoutUpdated:(nonnull UIView <MVMCoreUIMoleculeViewProtocol>*)molecule;
|
||||
|
||||
/// Asks the delegate to add or remove molecules.
|
||||
- (void)addMolecules:(nonnull NSArray <NSDictionary *>*)molecules senderIndexPath:(nonnull NSIndexPath *)indexPath;
|
||||
- (void)removeMolecules:(nonnull NSArray <NSDictionary *>*)molecules senderIndexPath:(nonnull NSIndexPath *)indexPath;
|
||||
- (void)addMolecules:(nonnull NSArray <NSDictionary *>*)molecules sender:(nonnull UITableViewCell *)sender animation:(UITableViewRowAnimation)animation;
|
||||
- (void)removeMolecules:(nonnull NSArray <NSDictionary *>*)molecules sender:(nonnull UITableViewCell *)sender animation:(UITableViewRowAnimation)animation;
|
||||
|
||||
@end
|
||||
|
||||
@ -117,34 +117,40 @@ open class MoleculeListTemplate: ThreeLayerTableViewController {
|
||||
}
|
||||
}
|
||||
|
||||
open override func addMolecules(_ molecules: [[AnyHashable: Any]], senderIndexPath indexPath: IndexPath) {
|
||||
var indexPaths: [IndexPath] = []
|
||||
var moleculeList: [(identifier: String, class: AnyClass, molecule: [AnyHashable: Any])] = []
|
||||
for (index, molecule) in molecules.enumerated() {
|
||||
if let info = getMoleculeInfo(with: molecule) {
|
||||
moleculeList.append(info)
|
||||
indexPaths.append(IndexPath(row: indexPath.row + 1 + index, section: 0))
|
||||
tableView?.register(info.class, forCellReuseIdentifier: info.identifier)
|
||||
open override func addMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
||||
// This dispatch is needed to fix a race condition that can occur if this function is called during the table setup.
|
||||
DispatchQueue.main.async {
|
||||
guard let cell = sender as? MoleculeTableViewCell, let indexPath = self.tableView?.indexPath(for: cell) else {
|
||||
return
|
||||
}
|
||||
var indexPaths: [IndexPath] = []
|
||||
for molecule in molecules {
|
||||
if let info = self.getMoleculeInfo(with: molecule) {
|
||||
self.tableView?.register(info.class, forCellReuseIdentifier: info.identifier)
|
||||
let index = indexPath.row + 1 + indexPaths.count
|
||||
self.moleculesInfo?.insert(info, at: index)
|
||||
indexPaths.append(IndexPath(row: index, section: 0))
|
||||
}
|
||||
}
|
||||
self.tableView?.insertRows(at: indexPaths, with: animation)
|
||||
self.updateViewConstraints()
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
moleculesInfo?.insert(contentsOf: moleculeList, at: indexPath.row + 1)
|
||||
tableView?.insertRows(at: indexPaths, with: .automatic)
|
||||
}
|
||||
|
||||
open override func removeMolecules(_ molecules: [[AnyHashable: Any]], senderIndexPath indexPath: IndexPath) {
|
||||
guard let moleculesList = moleculesInfo else {
|
||||
return
|
||||
}
|
||||
open override func removeMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {
|
||||
var indexPaths: [IndexPath] = []
|
||||
for (index, moleculeInfo) in moleculesList.enumerated() {
|
||||
if molecules.contains(where: { (molecule) -> Bool in
|
||||
for molecule in molecules {
|
||||
if let removeIndex = moleculesInfo?.firstIndex(where: { (moleculeInfo) -> Bool in
|
||||
return NSDictionary(dictionary: molecule).isEqual(to: moleculeInfo.molecule)
|
||||
}) {
|
||||
indexPaths.append(IndexPath(row: index, section: 0))
|
||||
moleculesInfo?.remove(at: index)
|
||||
moleculesInfo?.remove(at: removeIndex)
|
||||
indexPaths.append(IndexPath(row: removeIndex + indexPaths.count, section: 0))
|
||||
}
|
||||
}
|
||||
tableView?.deleteRows(at: indexPaths, with: .automatic)
|
||||
self.tableView?.deleteRows(at: indexPaths, with: animation)
|
||||
self.updateViewConstraints()
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
|
||||
// MARK: - Convenience
|
||||
|
||||
Loading…
Reference in New Issue
Block a user