From b51f1b82f5439450a18b8fa3f67bd1efa8e7d1ac Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Sat, 14 Sep 2019 04:55:40 +0530 Subject: [PATCH 1/8] adding action block, which should only call after user interaction, but not at the time of initial loading. Fixing apple crash, where even after deletion, apple not updating number of rows, which is leading to index out of bounds crash. Adding remove list item method which has specific molecule inside. --- MVMCoreUI/Atoms/Views/MVMCoreUISwitch.h | 1 + MVMCoreUI/Atoms/Views/MVMCoreUISwitch.m | 12 ++++++++++++ MVMCoreUI/Templates/MoleculeListTemplate.swift | 17 +++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.h b/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.h index 32e98f2a..256aabfa 100644 --- a/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.h +++ b/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.h @@ -24,6 +24,7 @@ typedef void(^ValueChangeBlock)(void); @property (nonatomic) BOOL shouldTouchToSwitch; @property (nullable, copy, nonatomic) ValueChangeBlock valueChangedBlock; +@property (nullable, copy, nonatomic) ValueChangeBlock actionBlock; + (nonnull instancetype)mvmSwitchDefault; + (nonnull instancetype)mvmSwitchDefaultWithValueChangeBlock:(nullable ValueChangeBlock)block; diff --git a/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.m b/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.m index f994b320..a3bbea81 100644 --- a/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.m +++ b/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.m @@ -169,6 +169,18 @@ const CGFloat SwitchShakeIntensity = 2; } [self setState:[json boolForKey:@"state"] animated:false]; + + self.delegate = delegateObject; + NSDictionary *actionMap = [json dict:@"actionMap"]; + if (actionMap) { + [self addTarget:self action:@selector(addCustomAction) forControlEvents:UIControlEventTouchUpInside]; + } +} + +- (void)addCustomAction { + if (self.actionBlock) { + self.actionBlock(); + } } + (CGFloat)estimatedHeightForRow:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject { diff --git a/MVMCoreUI/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Templates/MoleculeListTemplate.swift index 0270cb63..4fb10ed0 100644 --- a/MVMCoreUI/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Templates/MoleculeListTemplate.swift @@ -149,6 +149,23 @@ open class MoleculeListTemplate: ThreeLayerTableViewController { } } self.tableView?.deleteRows(at: indexPaths, with: animation) + // crash fix + self.tableView?.reloadData() + self.updateViewConstraints() + self.view.layoutIfNeeded() + } + + public func removeListItemWhichHas(_ molecule: [AnyHashable : Any], animation: UITableView.RowAnimation) { + var indexPaths: [IndexPath] = [] + if let removeIndex = moleculesInfo?.firstIndex(where: { (moleculeInfo) -> Bool in + return NSDictionary(dictionary: molecule).isEqual(to: moleculeInfo.molecule["molecule"] as? [AnyHashable : Any] ?? [:]) + }) { + moleculesInfo?.remove(at: removeIndex) + indexPaths.append(IndexPath(row: removeIndex + indexPaths.count, section: 0)) + } + self.tableView?.deleteRows(at: indexPaths, with: animation) + // crash fix + self.tableView?.reloadData() self.updateViewConstraints() self.view.layoutIfNeeded() } From decf0bf9e6ce3646711be0c6831ba225e847d1fd Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Wed, 18 Sep 2019 21:58:30 +0530 Subject: [PATCH 2/8] adding settingsList template --- MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m | 1 + 1 file changed, 1 insertion(+) diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m index e770ede5..4b89ae5a 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m @@ -23,6 +23,7 @@ @"moleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackTemplate class]], @"centerMoleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackCenteredTemplate class]], @"moleculeList" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeListTemplate class]], + @"settingsList" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeListTemplate class]], @"threeLayer" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[ThreeLayerTemplate class]] } mutableCopy]; From fe7fb2db03d2fbc2a500b5ec600b755c1cc302cb Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Mon, 30 Sep 2019 22:01:11 +0530 Subject: [PATCH 3/8] changing separator to line mapping as per server and Android confirmation. --- MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m index 945eb7bf..4760de89 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m @@ -27,7 +27,7 @@ dispatch_once(&onceToken, ^{ mapping = [@{ @"label": Label.class, - @"separator": SeparatorView.class, + @"line": SeparatorView.class, @"button": ButtonView.class, @"textButton": MFTextButton.class, @"header": StandardHeaderView.class, From 3606ce4c8255dd1e0fe748a70ef38f495c431670 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Wed, 9 Oct 2019 13:53:10 +0530 Subject: [PATCH 4/8] VQA bug fix for bottom spacing below tableview. --- .../BaseControllers/ThreeLayerTableViewController.swift | 7 ++++++- MVMCoreUI/Templates/MoleculeListTemplate.swift | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift b/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift index 0293e860..d4a2c452 100644 --- a/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift +++ b/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift @@ -61,6 +61,11 @@ open class ThreeLayerTableViewController: MFProgrammaticTableViewController { return nil } + /// Space between the bottom view and the table sections, nil to fill. nil default + open func spaceBelowBottomView() -> CGFloat? { + return nil + } + /// can override to return a minimum fill space. open func minimumFillSpace() -> CGFloat { return 0 @@ -154,7 +159,7 @@ open class ThreeLayerTableViewController: MFProgrammaticTableViewController { bottomViewTopConstraint?.isActive = true bottomView.leftAnchor.constraint(equalTo: footerView.leftAnchor).isActive = true footerView.rightAnchor.constraint(equalTo: bottomView.rightAnchor).isActive = true - footerView.bottomAnchor.constraint(equalTo: bottomView.bottomAnchor).isActive = true + footerView.bottomAnchor.constraint(equalTo: bottomView.bottomAnchor, constant: spaceBelowBottomView() ?? 0).isActive = true self.footerView = footerView showFooter(nil) } diff --git a/MVMCoreUI/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Templates/MoleculeListTemplate.swift index 4fb10ed0..b2c89d4b 100644 --- a/MVMCoreUI/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Templates/MoleculeListTemplate.swift @@ -42,6 +42,11 @@ open class MoleculeListTemplate: ThreeLayerTableViewController { return molecule } + // for bottom gutter/free space + open override func spaceBelowBottomView() -> CGFloat? { + return PaddingDefaultVerticalSpacing + } + open override func newDataBuildScreen() { super.newDataBuildScreen() setup() From c1adbe2f2ee5abe7662eab1920cea1cde56aae97 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Fri, 25 Oct 2019 01:17:54 +0530 Subject: [PATCH 5/8] Crash fixes in Label update molecule name from progressBar to progressbar as per oneconfluence mapping name and Android mapping name. --- MVMCoreUI/Atoms/Views/Label.swift | 50 +++++++++++++++++-- .../MVMCoreUIMoleculeMappingObject.m | 2 +- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/Label.swift b/MVMCoreUI/Atoms/Views/Label.swift index 6fc496bd..620b3caa 100644 --- a/MVMCoreUI/Atoms/Views/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label.swift @@ -252,7 +252,7 @@ public typealias ActionBlock = () -> () let length = attribute["length"] as? Int else { continue } - let range = NSRange(location: location, length: length) + var range = NSRange(location: location, length: length) switch attributeType { case "underline": @@ -264,7 +264,17 @@ public typealias ActionBlock = () -> () case "color": if let colorHex = attribute.optionalStringForKey(KeyTextColor), !colorHex.isEmpty { - attributedString.removeAttribute(.foregroundColor, range: range) + // crash fix: removing attribute, even though it does not exists + let foregroundColorAttributesArray = attributedString.attributes(at: location, effectiveRange: &range).filter { (attribute) -> Bool in + if attribute.key == .foregroundColor { + return true + } else { + return false + } + } + if foregroundColorAttributesArray.isEmpty == false { + attributedString.removeAttribute(.foregroundColor, range: range) + } attributedString.addAttribute(.foregroundColor, value: UIColor.mfGet(forHex: colorHex), range: range) } case "image": @@ -286,8 +296,28 @@ public typealias ActionBlock = () -> () case "font": if let fontStyle = attribute.optionalStringForKey("style") { let styles = MFStyler.styleGetAttributedString("0", withStyle: fontStyle) - attributedString.removeAttribute(.font, range: range) - attributedString.removeAttribute(.foregroundColor, range: range) + // crash fix: removing font attribute, even though it does not exists + let fontAttributesArray = attributedString.attributes(at: location, effectiveRange: &range).filter { (attribute) -> Bool in + if attribute.key == .font { + return true + } else { + return false + } + } + if fontAttributesArray.isEmpty == false { + attributedString.removeAttribute(.font, range: range) + } + // crash fix: removing attribute, even though it does not exists + let foregroundColorAttributesArray = attributedString.attributes(at: location, effectiveRange: &range).filter { (attribute) -> Bool in + if attribute.key == .foregroundColor { + return true + } else { + return false + } + } + if foregroundColorAttributesArray.isEmpty == false { + attributedString.removeAttribute(.foregroundColor, range: range) + } attributedString.addAttributes(styles.attributes(at: 0, effectiveRange: nil), range: range) } else { let fontSize = attribute["size"] as? CGFloat @@ -300,7 +330,17 @@ public typealias ActionBlock = () -> () } if let font = font { - attributedString.removeAttribute(.font, range: range) + // crash fix: removing font attribute, even though it does not exists + let fontAttributesArray = attributedString.attributes(at: location, effectiveRange: &range).filter { (attribute) -> Bool in + if attribute.key == .font { + return true + } else { + return false + } + } + if fontAttributesArray.isEmpty == false { + attributedString.removeAttribute(.font, range: range) + } attributedString.addAttribute(.font, value: font, range: range) } } diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m index bad7a224..c8679a56 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m @@ -41,7 +41,7 @@ @"checkbox" : Checkbox.class, @"checkboxWithLabelView" : CheckboxWithLabelView.class, @"cornerLabels" : CornerLabels.class, - @"progressBar": ProgressBar.class, + @"progressbar": ProgressBar.class, @"multiProgressBar": MultiProgress.class, @"listItem": MoleculeTableViewCell.class, @"accordionListItem": AccordionMoleculeTableViewCell.class, From da8dded2e18c2eae5814d1da9fd432cd2047c0cd Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Fri, 25 Oct 2019 04:10:24 +0530 Subject: [PATCH 6/8] opening HeadlineBodySwitch to reuse in MF --- .../SwitchMolecules/HeadlineBodySwitch.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Molecules/LeftRightViews/SwitchMolecules/HeadlineBodySwitch.swift b/MVMCoreUI/Molecules/LeftRightViews/SwitchMolecules/HeadlineBodySwitch.swift index d373ce87..f585c2da 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/SwitchMolecules/HeadlineBodySwitch.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/SwitchMolecules/HeadlineBodySwitch.swift @@ -8,9 +8,9 @@ import UIKit -@objcMembers public class HeadlineBodySwitch: ViewConstrainingView { - let headlineBody = HeadlineBody(frame: .zero) - let mvmSwitch = MVMCoreUISwitch.mvmSwitchDefault() +@objcMembers open class HeadlineBodySwitch: ViewConstrainingView { + public let headlineBody = HeadlineBody(frame: .zero) + public let mvmSwitch = MVMCoreUISwitch.mvmSwitchDefault() // MARK: - MVMCoreViewProtocol open override func updateView(_ size: CGFloat) { @@ -35,7 +35,7 @@ import UIKit } // MARK: - MVMCoreUIMoleculeViewProtocol - public override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { + open override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) headlineBody.setWithJSON(json?.optionalDictionaryForKey("headlineBody"), delegateObject: delegateObject, additionalData: additionalData) mvmSwitch.setWithJSON(json?.optionalDictionaryForKey("switch"), delegateObject: delegateObject, additionalData: additionalData) From 45b0b01646d65bc99115bbcc25399059f2deb3ec Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Fri, 25 Oct 2019 21:04:53 +0530 Subject: [PATCH 7/8] implemented feedback --- MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m | 1 - 1 file changed, 1 deletion(-) diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m index 4b89ae5a..e770ede5 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject.m @@ -23,7 +23,6 @@ @"moleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackTemplate class]], @"centerMoleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackCenteredTemplate class]], @"moleculeList" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeListTemplate class]], - @"settingsList" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeListTemplate class]], @"threeLayer" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[ThreeLayerTemplate class]] } mutableCopy]; From 8ea52a21f725002e8462dc1d444ecba9ae2decb0 Mon Sep 17 00:00:00 2001 From: "Khan, Arshad" Date: Fri, 25 Oct 2019 23:07:42 +0530 Subject: [PATCH 8/8] Rename method name to removeListItem --- MVMCoreUI/Templates/MoleculeListTemplate.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Templates/MoleculeListTemplate.swift index d8e3be20..9df9fbc2 100644 --- a/MVMCoreUI/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Templates/MoleculeListTemplate.swift @@ -164,7 +164,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController { self.view.layoutIfNeeded() } - public func removeListItemWhichHas(_ molecule: [AnyHashable : Any], animation: UITableView.RowAnimation) { + public func removeListItem(_ molecule: [AnyHashable : Any], animation: UITableView.RowAnimation) { var indexPaths: [IndexPath] = [] if let removeIndex = moleculesInfo?.firstIndex(where: { (moleculeInfo) -> Bool in return NSDictionary(dictionary: molecule).isEqual(to: moleculeInfo.molecule["molecule"] as? [AnyHashable : Any] ?? [:])