Merge branch 'feature/mva_3_0' into 'develop'
Feature/mva 3 0 See merge request BPHV_MIPS/mvm_core_ui!162
This commit is contained in:
commit
fdaab40266
@ -266,7 +266,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":
|
||||
@ -278,7 +278,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":
|
||||
@ -300,8 +310,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
|
||||
@ -314,7 +344,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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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,
|
||||
@ -41,7 +41,7 @@
|
||||
@"checkbox" : Checkbox.class,
|
||||
@"checkboxWithLabelView" : CheckboxWithLabelView.class,
|
||||
@"cornerLabels" : CornerLabels.class,
|
||||
@"progressBar": ProgressBar.class,
|
||||
@"progressbar": ProgressBar.class,
|
||||
@"multiProgressBar": MultiProgress.class,
|
||||
@"checkbox": MVMCoreUICheckBox.class,
|
||||
@"radioButton": RadioButton.class,
|
||||
|
||||
@ -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()
|
||||
@ -153,6 +158,23 @@ open class MoleculeListTemplate: ThreeLayerTableViewController {
|
||||
}
|
||||
}
|
||||
self.tableView?.deleteRows(at: indexPaths, with: animation)
|
||||
// crash fix
|
||||
self.tableView?.reloadData()
|
||||
self.updateViewConstraints()
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
|
||||
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] ?? [:])
|
||||
}) {
|
||||
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()
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user