From 73226d45a29fb36527fc3cb51272ea4071aa66be Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Sat, 28 Mar 2020 19:28:26 -0400 Subject: [PATCH 01/14] Demo --- .../MVMCoreUISplitViewController.m | 64 +++++++++++++++++- .../Account.imageset/Account@1x.png | Bin 0 -> 978 bytes .../Account.imageset/Account@2x.png | Bin 0 -> 2136 bytes .../Account.imageset/Account@3x.png | Bin 0 -> 3355 bytes .../Account.imageset/Contents.json | 23 +++++++ .../Media.xcassets/Bag.imageset/Bag@1x.png | Bin 0 -> 394 bytes .../Media.xcassets/Bag.imageset/Bag@2x.png | Bin 0 -> 651 bytes .../Media.xcassets/Bag.imageset/Bag@3x.png | Bin 0 -> 897 bytes .../Media.xcassets/Bag.imageset/Contents.json | 23 +++++++ .../Home.imageset/Contents.json | 23 +++++++ .../Home.imageset/Home@1.5x.png | Bin 0 -> 450 bytes .../Media.xcassets/Home.imageset/Home@1x.png | Bin 0 -> 362 bytes .../Media.xcassets/Home.imageset/Home@3x.png | Bin 0 -> 919 bytes .../More.imageset/Contents.json | 23 +++++++ .../Media.xcassets/More.imageset/More@1x.png | Bin 0 -> 134 bytes .../Media.xcassets/More.imageset/More@2x.png | Bin 0 -> 160 bytes .../Media.xcassets/More.imageset/More@3x.png | Bin 0 -> 233 bytes .../Verizon Up.imageset/Contents.json | 23 +++++++ .../Verizon Up.imageset/Verizon Up@1x.png | Bin 0 -> 503 bytes .../Verizon Up.imageset/Verizon Up@2x.png | Bin 0 -> 915 bytes .../Verizon Up.imageset/Verizon Up@3x.png | Bin 0 -> 1409 bytes 21 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Account@1x.png create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Account@2x.png create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Account@3x.png create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Contents.json create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@1x.png create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@2x.png create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@3x.png create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Contents.json create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Contents.json create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Home@1.5x.png create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Home@1x.png create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Home@3x.png create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/More.imageset/Contents.json create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/More.imageset/More@1x.png create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/More.imageset/More@2x.png create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/More.imageset/More@3x.png create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Contents.json create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Verizon Up@1x.png create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Verizon Up@2x.png create mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Verizon Up@3x.png diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index 476e7264..34dc2342 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -843,11 +843,27 @@ CGFloat const PanelAnimationDuration = 0.2; bottomProgressHeight.active = YES; self.bottomProgressBarHeightConstraint = bottomProgressHeight; + UITabBar *tabs = [[UITabBar alloc] init]; + tabs.translatesAutoresizingMaskIntoConstraints = NO; + tabs.tintColor = [UIColor mfRedColor]; + tabs.backgroundColor = [UIColor whiteColor]; + NSArray *tabList = @[[[UITabBarItem alloc] initWithTitle:nil image:[[MVMCoreUIUtility imageNamed:@"Home"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] tag:0], + [[UITabBarItem alloc] initWithTitle:nil image:[[MVMCoreUIUtility imageNamed:@"Account"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] tag:1], + [[UITabBarItem alloc] initWithTitle:nil image:[[MVMCoreUIUtility imageNamed:@"Bag"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] tag:2], + [[UITabBarItem alloc] initWithTitle:nil image:[[MVMCoreUIUtility imageNamed:@"Verizon Up"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] tag:3], + [[UITabBarItem alloc] initWithTitle:nil image:[[MVMCoreUIUtility imageNamed:@"More"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] tag:4]]; + [tabs setItems:tabList animated:NO]; + [tabs setSelectedItem:tabList[0]]; + tabs.delegate = self; + [self.view addSubview:tabs]; + [NSLayoutConstraint constraintWithItem:tabs attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0].active = YES; + [NSLayoutConstraint constraintWithItem:tabs attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0].active = YES; if (topAlertView) { - [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[topAlertView]-0-[mainView]-0-[progressView]-0-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(topAlertView, mainView, progressView)]]; + [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[topAlertView]-0-[mainView]-0-[progressView]-0-[tabs]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(topAlertView, mainView, progressView, tabs)]]; } else { - [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[mainView]-0-[progressView]-0-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(mainView, progressView)]]; + [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[mainView]-0-[progressView]-0-[tabs]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(mainView, progressView, tabs)]]; } + [[self.view.safeAreaLayoutGuide.bottomAnchor constraintEqualToAnchor:tabs.bottomAnchor] setActive:YES]; // Cover View UIView *coverView = [MVMCoreUICommonViewsUtility commonView]; @@ -864,6 +880,50 @@ CGFloat const PanelAnimationDuration = 0.2; [self setupPanels]; } +- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item { + switch (item.tag) { + case 0:{ + MVMCoreRequestParameters *params = [[MVMCoreRequestParameters alloc] initWithPageType:@"myFeed" extraParameters:nil]; + params.loadStyle = MFLoadStyleBecomeRoot; + params.shouldNotAnimatePush = YES; + [[MVMCoreLoadHandler sharedGlobal] loadRequest:params dataForPage:nil delegateObject:nil]; + } + break; + case 1:{ + MVMCoreRequestParameters *params = [[MVMCoreRequestParameters alloc] initWithPageType:@"accountLanding" extraParameters:nil]; + params.loadStyle = MFLoadStyleBecomeRoot; + params.shouldNotAnimatePush = YES; + [[MVMCoreLoadHandler sharedGlobal] loadRequest:params dataForPage:nil delegateObject:nil]; + } + break; + case 2:{ + MVMCoreRequestParameters *params = [[MVMCoreRequestParameters alloc] initWithPageType:@"shopHomePage" extraParameters:nil]; + params.loadStyle = MFLoadStyleBecomeRoot; + params.shouldNotAnimatePush = YES; + [[MVMCoreLoadHandler sharedGlobal] loadRequest:params dataForPage:nil delegateObject:nil]; + } + break; + case 3:{ + MVMCoreRequestParameters *params = [[MVMCoreRequestParameters alloc] initWithPageType:@"loyaltyEligibiltySelector" extraParameters:nil]; + params.loadStyle = MFLoadStyleBecomeRoot; + params.shouldNotAnimatePush = YES; + [[MVMCoreLoadHandler sharedGlobal] loadRequest:params dataForPage:nil delegateObject:nil]; + } + break; + case 4:{ + UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"More" message:nil preferredStyle:UIAlertControllerStyleActionSheet]; + [controller addAction:[UIAlertAction actionWithTitle:@"Bill" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { + [[MVMCoreLoadHandler sharedGlobal] loadRequest:[[MVMCoreRequestParameters alloc] initWithPageType:@"billOverview" extraParameters:nil] dataForPage:nil delegateObject:nil]; + }]]; + [controller addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]]; + [[MVMCoreNavigationHandler sharedNavigationHandler] presentViewController:controller animated:YES]; + } + break; + default: + break; + } +} + - (void)viewDidLoad { [super viewDidLoad]; [self.topAlertView pinATopViewController:self]; diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Account@1x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Account@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..a77098c25cd82181cce01d235dd115837baf73bf GIT binary patch literal 978 zcmV;@11Px&j7da6R7efAmRYDxQ5eTv(@jZai0c8@REFG)g%px9L@6G;;FiLJ+Fga z+0=@#aWD%;Ko6*b-|#%*8tq}Y0>9v&)Q-_>;1!r8;KbVMi)_L70^16xgul{UMm+^5 z{07HhF;qia2r@xGSPCcMJ2>VE%!JHpN#sUwuurxNOqNvx2|NH{{JJayO}alC^qO{3 zmO%+IGq5*+H?SiireF?F`T$Gcg0;NU4bwE33SG+G1%9ft1%nD8!ag>CQohY$~OOu(@nDN0_ z(hlMJC)8nqw9Sx1(6^M*S#m!KEan0Pj*L-{85w`*i| zWs($pAvP|~BUQ~Z@$g(XU#(HMthpIk#*}#)4Z#;;8$FG^(@{6Kf>xzVReTIKhUR;H zXug2k!hWgTub<%~bT4%lU3aE$9bDJu775Gbb&^)&aFDUJ;Jd1ZCGZyXErm4s0M88a zDY7KC`ZvK3FiA1)i1knbX)^Is1MkBCaH*X%O`{3$l=D5gJ#N4*xD9FQNPw$z&A_wZ z-TT+}zhxnt>yTBQ%T7B5vdA%2U=@#o?vQ1P2`l8t;f*WY(r3E+RUxe=yn0QMwaZOxnxpLVZbP#GFtE}EoNG@;c zla@|A4MTX>-hfrQ5{7|CUr;AHo=B_UJQyn$QsO(s*R1@WS_X9xCJe2AgB~2=I<(%b zTc+8ftRNt(T<+Q6(^Y}{++@!qJO&SgpE#-d1I(!R literal 0 HcmV?d00001 diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Account@2x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Account@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..78ddbb80d0f55c0977cf64f680ef81a3c28a5549 GIT binary patch literal 2136 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 literal 0 HcmV?d00001 diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Contents.json b/MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Contents.json new file mode 100644 index 00000000..dd3bd4a8 --- /dev/null +++ b/MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Account@1x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Account@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "Account@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@1x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..08d4e5bd78af30805965e596b3b31151508919a5 GIT binary patch literal 394 zcmV;50d@X~P)Px$L`g(JR7eeDV89QIfYR%L_%RUwN5Y?g?1Mm@3dCfA6rir(K>QDgZvgQgBzzLc z{szP#3pW8V6A%*(G=M6<1Mw3eHpih$2q+FR7-T^S4mDVXd!U*;vC1L@d4SAkK>QFP zM3{8|s08G47Q#vymI2j(TrY~Q7FSpa0~LM*;y>sbu<+kP#Xx#c04~E(6p_mTdD{z! z&Cm=G1M<0nxB*QZ8yBWG2PpXlNx@eTdnynkr(tTbUm-_WKhTm(AlrbT1&DcpI3L6z z0Ahgh&OlrR#LuB>XF_SX%R#{d1DAn}7cdS1dNNQRS)u8Bsg*mdzQ52BD0lS>0NpaM0tkE(WETh4KH3YBHq)$07*qoM6N<$f?T?jf&c&j literal 0 HcmV?d00001 diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@2x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..640cf1ecf7561cd0a46da31ec12a4c873b227788 GIT binary patch literal 651 zcmV;60(AX}P)Px%MM*?KRA>e5SUXDtK@g7O0}H_i2wI4R;Hy&<5$r6)LbR~7(Z-+QPq48Nu@l7F zN)T)XZA6nsEG&E=7FsBZMEyn*ZgSjkx9&~i!3=!K?9A-9lW+Gfm*jGOR)^`cz&20- zo`G)xMZ_O~6JQ+}1ZrZFSoIW;8jXw72iXBSfvVXGR{8+qnoE+u2G5Xd=d{(XwuA}$ z0H6Dg@eyzdyZ}*Fk6;%t4UC2gZZRGQ?nCj^hJ9dq1-O#ba4+Cub10@}InS{Rfott< zXt529x$-W2?I@-l;?2*y5G1YbK;b7_=mLIo(#b;I7~-7sP^j|?FJm@WXU2;yn7qY! z>4I+!QnE)EOi~+Wg>=r-I+F*Cw+Vhf8;h<>5ww+f>5VS@SaWIoEtc(X1z(sZ{lFF( z?Tm}kC?!mBC1FKcQ(TlrDPf8$2`kc?;-WN42~%82SdrEg7o|~3nBq#pinOM(O>t2gr9@^GkNSUn0V0hk3FSk}|NPHI lHQobu!oRl69+k{C{sYaQea`QpFRK6m002ovPDHLkV1khQAvXX3 literal 0 HcmV?d00001 diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@3x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f621197f200f29ac556e58dd3fe2f024f20714d3 GIT binary patch literal 897 zcmeAS@N?(olHy`uVBq!ia0vp^u0R~c!3HGX@y<>MQjEnx?oJHr&dI!FU|_cPba4!+ zV0=6K>}uackz?m4x~Ls;=!kCn!T!WJ$w5-GYv)Q%i_-C^S=?<|G!!Nmie~#Z=ChU*vvk!-Aj2dRb@^M zQM1dqr2TSfiT^G=+i7ZMeJekyUs^v)wEEaRVbSQ&x6CW^Bwp4{R4(eRl?iN>U;2e* zmQ`QO#NwRCJG6dlnzAb7-#;O_GrO}+clV#0DeZN4CQf_$=BM93-b{s~zMuDos6A@i z6L?G8)qTxGjeRHYsNY?FP;bvwuU}D%w10a3i_B~dF-__>4tnFcb5YxhRGmkYRxMDP zf4aZ_@vh|AW;JSo=T$xp`D{>t-rZ}$tr`J_~W9dgHw>xicb)7J6NePkmIUNguJGAcp!R%X$=7dDAv|8n)IW^^ynj}|@p|hcg0>d=xqX7*J5ykS+>ZWF_ zkN0IOeC8Cy>Z|Ez(x8HMV=i=js|Gl~BVE?_RPv_C~@>>7K)%hB2Oe_bA zmNQJ*=`SxatCDBqWHz@w!Bw?YPb}j6ytmpmdwx4-y=PhDmTTRg^q%X^_`3L7#Wq|0 zt_6QCoO!tC=1u0Rvd>G8?0VyObXF{~6`9s~S`RO)WL^o=WQ&?>rz8<}tI$a7xaG3vwjXY@>&;sz!6m?O zdM-qB*Fpxy4RN Z@3qrEOP=WM+zQN744$rjF6*2UngGETmxKTS literal 0 HcmV?d00001 diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Contents.json b/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Contents.json new file mode 100644 index 00000000..ef86d034 --- /dev/null +++ b/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Bag@1x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Bag@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "Bag@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Contents.json b/MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Contents.json new file mode 100644 index 00000000..02784f80 --- /dev/null +++ b/MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Home@1x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Home@1.5x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "Home@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Home@1.5x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Home@1.5x.png new file mode 100644 index 0000000000000000000000000000000000000000..17dc8d9655ead06d4698b1ad0cd9c529c27296ae GIT binary patch literal 450 zcmV;z0X_bSP)Px$d`Uz>RA>e5m_2U7KoEru0;QoxzC{i|>h$U9attm)0d2Z;Kt+`tAe?|AH%O46 zgZEG@tyW&!S-j&}v?D$FZ|&J{W>(s9mW8(oTx_6GcvoRP5abs+LmyDIKqd%bq6I1g zi4y1uStv@207q#3mze_S6W8iX&dvxyo}nJJfC?BMRj(lz2=5ThdbO0<0duPCSj#}T*k2UF z{9sPbj&*>C56~1UY>$&2L>P_6@_L2dp`kIsoG@GCMl7cUTG^BB+c#pqPB2=tmok$w zBM^a9W&%O>a*;CQ6*hsFQf35#?Byb5#w%Px$BuPX;R9Fe^l{*RoK@5g{T|n>*9>mH*Y-|*4+g1sm3 z^#^t&#&Otn9$IYRXXlmVBQs=+IXf%BeFjyatzD?^y$NCg-Ju&4LBWkf5XetpIK%}I z9cU67Mnbd!pez`S2_hIw5(w`wX&}78d;{Se#s8b%7 literal 0 HcmV?d00001 diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Home@3x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Home@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..8d67c8010748b995eba018bbf483971e888bdda9 GIT binary patch literal 919 zcmeAS@N?(olHy`uVBq!ia0vp^X+Rvs!3HF~(v`OWDaPU;cPEB*=VV?oFfa#tx;TbZ zFuuKQndENg4Tb)Tzy`fr+Me1EZ`?|5hIG3)5`(ilJ4@P``mIe)i)Jv^;I zr)8=9ZVf)=IZIvF)Qfi&h_y*N37&JZkQ8}1p-=!w6f9f7k)Ae(=T!b|MTK2uf3;#I zG@C!&th%@TtCvOV<@c7cVo&c~{kT0x+|Pf;(s^!yi`Ew?bxM9)sbSa!WHkL=2w^Z) zYfh1HwU~H>u{smNXsOi$Ggvm9?-g3ip+3pujSfWSz&W?hz!qW8k~iK9k7yj~R4Mzm zG%!izp^MPA^{lFHLg%;wTQ(<6Syp)M+b27op9pwalS`y4yOd{i+JB%^M9H4 z{+m~SmplEI+iS7gAaV-(wWrzf>bC#mnf{4>Z{L>gRK&=R0MK(jORn|MA2?pRMc5;!T_u=PsYo zd~B;0yjm)WsY$V|cZ(3uB(aTQ21hnb3~O?{q;!p|O~UMwmw`vrk*I?Lhuxw$**v== zv?Y>mcxWF~$P~@-IRFzQCOe#QjEnx?oJHr&dIz4avVHe978Mw zlT#8BHn1nHVsu;J`F~}a)CC2#EGe_BYYM!L2j}NF=q<_elU!nGxMU7%*Ob3kN(`@F hRy=W_Dr=VjgX|QRqkFbYyaF_f!PC{xWt~$(6982hD)ayV literal 0 HcmV?d00001 diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/More.imageset/More@2x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/More.imageset/More@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..158c6636bd8a70a0116d6999a66312cd0dcd1a59 GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^8bGYV!3HFM+f;}FDaPU;cPEB*=VV?2IZ>W2jv*18 zZ>JsPWKiHavZ~v9*DXmtMUOw?Nm?_sen?KwpC~C^Fqu(Za@|dqCHWq9ycrJ6Qa|oC zm`={SG0T(p(PaC*3qDI-Xkat>aD(BWy5aUq;t6?6**<<|zh2BTdFQN2{Xkn7JYD@< J);T3K0RT%MHdX)t literal 0 HcmV?d00001 diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/More.imageset/More@3x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/More.imageset/More@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..54de11dc7af5b0cdc2287bbebebe1812b8d65e3e GIT binary patch literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^Hb88~!3HE}r~eWGQjEnx?oJHr&dIz4au$2KIEG}f zzP(|{)nFjN;vo9}>E)VP|9pHkmvNMB@0sh)^iC(@j!ESv)@SPXCdz)CyN-3=y~S^~ zt6JYPpL-yF@|w=J&A+C!F)%W*a0n9hZ)frbi`uSuxacTvec5mC_lK9uu2C;w{>;ys UTrk_X9OzsIPgg&ebxsLQ0O+GqjQ{`u literal 0 HcmV?d00001 diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Contents.json b/MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Contents.json new file mode 100644 index 00000000..11c37b59 --- /dev/null +++ b/MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Verizon Up@1x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Verizon Up@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "Verizon Up@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Verizon Up@1x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Verizon Up@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..aa034686f4d37e854d6c3fa1074d2e00a6f2c840 GIT binary patch literal 503 zcmVPx$u}MThR7ef&RnIF0Q5c;O3s#iaDN9O;va`0dRF?svT!e)j2$n2klM=tgx0eruTBVn2_n}s&qa9$Vugo)#B z3VD|NNaSX{| zeLLHCg>Rt9@%LW^y%HS^1#G8$G7MPcq7=mDwtk9Ipva_&osCD%xKEVO;OPl)dy@UZ zOYoKCf|@;do~vrwPO1^D>)xHc|L(o-b86q&-Yz^B_qD$I?fJd6;DtARo*Pckepl?!l{>R1oFf9J6@I)?b$69HxMfGTarw=)}xGrf{JB=tO%<|ZEDv7Ww6rESK;Nh+7nq-L-)__?1g2)I18O6KX>RVJsG zPFc;nuK(9ewe3@jqJqPZW=^TQz`L!XGC`(-Igdf|xnYL)mE-%TWb!eT)Gs~1{Y--X zoK35P-tRx26wg?G^w8>W_cy*}vom_apy1tB%l7%Jt!uNSu2k=lGLagF^v3NXZx>$G zim=_`9MU!?_~o&%s*6n1cGj`}KIpYU@DBSjpSBxmlQLgb#$EbqBD~?pn%3P*KTf~! zp5e3QM&@@jo=x{UYkc_Af{&t{A^c&t>e<{~43~8OQfc;H^Gvef(F3veY%#wTa_shZ z4_d!m#QNu!VerlNT&3zQ)1OFwC|E!9PpRDFjK`1mTl|?@vYbgSTQYG~tM{TbOPQGI z@2uPRPd+EK!N$cWGDBb!!)qQr-_UIf1I3Q>ioFxQQ_OvT(kY=2+}{1aA6#QT`O2t3 zw!+>q)0lM*`!Cf!ZNJJAPWg7sSDP7feiOg_!r)^6ISl2BnH#2j%li}7$ey4ygFC0w zlJmXpw!TSLmOak1Y{TNdY(7;Xb!zrBoi(|A(;uoHzL)e`XXWH}i#Z+zRsFT;P5ozU z1TTH-xlsE)=;j(>yQ*moOaI3v2v0arGVx42EB68A3+V^8&VTgH{oTiM&Iy;MICd~6 zSpLY6x_oW(ox`i%7i%z82ApNQe;{~4Q`UlV#`u>@4=Nc5pJDqHYQpeD`4M}D_btu{ z-aGwDFSeYR_IU4G6+G_*tX=uyzfnTv zWG=mra(w%qG_vzQ mU;XW_>$!D~UYILe9kWG6tN(e^MljKR~@&t;ucLK6T`ajHcC literal 0 HcmV?d00001 diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Verizon Up@3x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Verizon Up@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..072a2758e8af7fcc5a3a6e1c6ab408b6c8de84b3 GIT binary patch literal 1409 zcmV-{1%CR8P)Px)J4r-ARCodHolR^OMHt6hf*?vL6cddCDRRKZ)Sd`xOf<+>f(5T$2*zGe(gQcI zUJWFCc+qH6YmA98UKGMd_(-Zk(uUTQkaB=G1&kW2CQ39amH$6slV$eZnP+!qr|tHc z?BIGy5*IwWX!ye@Iic1jZIr8(*U*1Qc{aqT-{1t{89cGu$iNli3kig;W?^PhlriOlY;hVD2kw zQ3M4o!sPFyp#2$&A}DAPCVwXd?axpYK|zZ!`8z3Se}~F! zP72zep(uia7Gd&tQqcYkMG+LV2$R2)g7#-9ilCrHnEag-v_C^p1O+X^<2^vgf%klzDshE_w5 zKtDl~&~fNfr~y@;%$H}FFY^LTvp7lFw~njW0DI!w>}d99(BeOFudRo0JPJ))eA(6= z=n(WU6e7*57iii+>^tZ!sMSG_(`O$v0zKyNEp4vj9L-02=4rGh{OX>*Pm&)r1@Pcm;vwp}`hZ(!dyldV~+Wr$K{m=#IUx?F5 zFXWnw_roW>azWNF%~jA`Ex6LpaM%uAN;!Ux^Y@{X&{L^$^Rx#Aycs{5hO+s(P93}v zTc9-LgwYM0Y=$_(^AZOjeS)RBg62l#dkZCQfWENUX|ipg996UCx`O^7d#Ra{PckL< z7j)mB^~=>2^c4Y?YYrc7)q|zFf}Ru*`oZB7bmLM-(EkA7-wud0bLl5py$C|NU1kgD zMeeSOJs8WiPG&IfAZ_dM-{=%7#RAPIX}0vF%~-;=R#0b+!{=9ry^uK;=nhA(_?R?g zdPNZIC5O*thrN(FBxpWx&r5AEyqsfPh4S7UTiIeh9$jv!yco897CTLR%o;3(1U=>G z6(7Qz+g?5`<92w7qpoST&8_rZ263Idlo=!Onh!#c8s+IMza-D53w+NP`UXhV=T6Kv z?-BASGy+XRoe)8n>4RjoumiFA%g)=-5X3sqL2p7kAzL~HW5ec9)K=yq^V&EEgKKW& zNA~%9!lClig%-Xl(aPZxb*xoFP8|biNwR*mc4!tDzeFFt4&9HCpnpN<-Ywa|^QgyP zrlrX>NB|DNH!#BcIX}GM8Teo!~a$2uLAX4bM$V+a&58A<{Bt?5h`-S z%^11)(4hZAOFhsLi07{KF&sE&^SzId={kb(=csdnpuA}xL0rqTUL`5ymtoRDK2Yz2 z-h()@wn80HJH%}*p9OQO7=X9}NzxlQS(0RoBR|sVAvuM-u(|W)41pv zSs8_%qeG2~+Qm`Ok#4DiR?v|ML~2GybR^JKtfOOey&sKyV`=E7#Wo|RxeEFWXi;+} z>C_SFRw-x&9f?4sW^_a==tu-2HKQY1K}RAGsTm#73OW*jNX_VoR?v|ML~2Gyw1SRA zAW}0rq7`%`0+E{05v`yj5s1``j%WoPi9n=g__8414Kvde3L0ji=0yZL;bs1Fzp=a@ zXZiQ|n*L2bQB&%aA)s?~21zvq3c4DunWzdngQS`Q&e3Dlgx07j0uy%u1W?Mr7#WG% P00000NkvXXu0mjf61$WO literal 0 HcmV?d00001 From 059696141c6e5da69485499da22d91700e93fd89 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 29 May 2020 15:51:28 -0400 Subject: [PATCH 02/14] Tab updates --- MVMCoreUI.xcodeproj/project.pbxproj | 12 ++ .../HorizontalCombinationViews/TabBar.swift | 79 +++++++++++++ .../TabBarModel.swift | 104 ++++++++++++++++++ .../TabsModel.swift | 1 - .../Atomic/Protocols/TabBarProtocol.swift | 13 +++ MVMCoreUI/BaseClasses/Button.swift | 14 ++- .../MVMCoreUISplitViewController.h | 13 +++ .../MVMCoreUISplitViewController.m | 96 ++++++---------- 8 files changed, 264 insertions(+), 68 deletions(-) create mode 100644 MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift create mode 100644 MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift create mode 100644 MVMCoreUI/Atomic/Protocols/TabBarProtocol.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 34bfd8e7..0a3c0c85 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -329,6 +329,9 @@ D28A839123CD4FD400DFE4FC /* CornerLabelsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A839023CD4FD400DFE4FC /* CornerLabelsModel.swift */; }; D28A839323CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A839223CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift */; }; D28BA730247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28BA72F247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift */; }; + D28BA741248025A300B75CB8 /* TabBarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28BA740248025A300B75CB8 /* TabBarModel.swift */; }; + D28BA7432480284E00B75CB8 /* TabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28BA7422480284E00B75CB8 /* TabBar.swift */; }; + D28BA7452481652D00B75CB8 /* TabBarProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28BA7442481652D00B75CB8 /* TabBarProtocol.swift */; }; D296E14722A5984C0051EBE7 /* MVMCoreUIViewConstrainingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */; }; D29C94D5242901C9003813BA /* MVMCoreUICommonViewsUtility+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29C94D4242901C9003813BA /* MVMCoreUICommonViewsUtility+Extension.swift */; }; @@ -758,6 +761,9 @@ D28A839023CD4FD400DFE4FC /* CornerLabelsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CornerLabelsModel.swift; sourceTree = ""; }; D28A839223CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyCaretLinkImageModel.swift; sourceTree = ""; }; D28BA72F247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationButtomModelProtocol.swift; sourceTree = ""; }; + D28BA740248025A300B75CB8 /* TabBarModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarModel.swift; sourceTree = ""; }; + D28BA7422480284E00B75CB8 /* TabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBar.swift; sourceTree = ""; }; + D28BA7442481652D00B75CB8 /* TabBarProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarProtocol.swift; sourceTree = ""; }; D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIViewConstrainingProtocol.h; sourceTree = ""; }; D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModuleMolecule.swift; sourceTree = ""; }; D29C94D4242901C9003813BA /* MVMCoreUICommonViewsUtility+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreUICommonViewsUtility+Extension.swift"; sourceTree = ""; }; @@ -1219,6 +1225,8 @@ 017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */, D28764FA245A33A500CB882D /* TwoLinkViewModel.swift */, D28764F8245A327200CB882D /* TwoLinkView.swift */, + D28BA740248025A300B75CB8 /* TabBarModel.swift */, + D28BA7422480284E00B75CB8 /* TabBar.swift */, ); path = HorizontalCombinationViews; sourceTree = ""; @@ -1868,6 +1876,7 @@ 012A88C7238DB02000FE3DA1 /* MoleculeDelegateProtocol.swift */, 017BEB47236230DB0024EF95 /* MoleculeViewProtocol.swift */, 012A88AC238C418100FE3DA1 /* TemplateProtocol.swift */, + D28BA7442481652D00B75CB8 /* TabBarProtocol.swift */, 011B58EE23A2AA850085F53C /* ModelProtocols */, ); path = Protocols; @@ -2017,6 +2026,7 @@ D264FAAA2440F97600D98315 /* CollectionView.swift in Sources */, 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */, D2FB151D23A40F1500C20E10 /* MoleculeStackItem.swift in Sources */, + D28BA7452481652D00B75CB8 /* TabBarProtocol.swift in Sources */, AA11A41F23F15D3100D7962F /* ListRightVariablePayments.swift in Sources */, D28764AA2458980300CB882D /* ThreeLayerFillMiddleTemplate.swift in Sources */, 0116A4E5228B19640094F3ED /* RadioButtonSelectionHelper.swift in Sources */, @@ -2257,6 +2267,7 @@ D20FB165241A5D75004AFC3A /* NavigationItemModel.swift in Sources */, AA2AD118244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift in Sources */, DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */, + D28BA741248025A300B75CB8 /* TabBarModel.swift in Sources */, D224798A2314445E003FCCF9 /* LabelToggle.swift in Sources */, D2A92882241AAB67004E01C6 /* ScrollingViewController.swift in Sources */, C695A67F23C9830600BFB94E /* UnOrderedListModel.swift in Sources */, @@ -2355,6 +2366,7 @@ 0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */, D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */, 94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */, + D28BA7432480284E00B75CB8 /* TabBar.swift in Sources */, AA26850C244840AE00CE34CC /* HeadersH2TinyButton.swift in Sources */, 011D95AB2405C553000E3791 /* FormItemProtocol.swift in Sources */, D21EE53C23AD3AD4003D1A30 /* NSLayoutConstraintAxis+Extension.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift new file mode 100644 index 00000000..e5233ad8 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift @@ -0,0 +1,79 @@ +// +// TabBar.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/28/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class TabBar: UITabBar, MoleculeViewProtocol, TabBarProtocol, UITabBarDelegate { + + public var model: TabBarModel + public var delegateObject: MVMCoreUIDelegateObject? + + required public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + guard let model = model as? TabBarModel else { + fatalError("model is not TabBarModel") + } + self.model = model + super.init(frame: .zero) + translatesAutoresizingMaskIntoConstraints = false + delegate = self + set(with: model, delegateObject, additionalData) + } + + required public init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + guard let model = model as? TabBarModel else { return } + self.model = model + + // Set appearance + if #available(iOS 13.0, *) { + let appearance = UITabBarAppearance() + appearance.backgroundColor = model.backgroundColor?.uiColor + setTabBarItemColors(appearance.stackedLayoutAppearance, model: model) + setTabBarItemColors(appearance.inlineLayoutAppearance, model: model) + setTabBarItemColors(appearance.compactInlineLayoutAppearance, model: model) + standardAppearance = appearance + } else { + // Fallback on earlier versions + backgroundColor = model.backgroundColor?.uiColor + tintColor = model.selectedColor.uiColor + unselectedItemTintColor = model.unSelectedColor.uiColor + barTintColor = model.backgroundColor?.uiColor + isTranslucent = false + } + + // Add buttons + var tabs: [UITabBarItem] = [] + for (index, tab) in model.tabs.enumerated() { + let tabBarItem = UITabBarItem(title: tab.title, image: UIImage(named: tab.image, in: MVMCoreCache.shared()?.bundleToUseForImages(), compatibleWith: nil), tag: index) + tabs.append(tabBarItem) + } + setItems(tabs, animated: false) + selectedItem = tabs[model.selectedTab] + } + + /// Sets the item colors. + @available(iOS 13.0, *) + private func setTabBarItemColors(_ itemAppearance: UITabBarItemAppearance, model: TabBarModel) { + itemAppearance.normal.iconColor = model.unSelectedColor.uiColor + itemAppearance.normal.titleTextAttributes = [NSAttributedString.Key.foregroundColor: model.unSelectedColor.uiColor] + + itemAppearance.selected.iconColor = model.selectedColor.uiColor + itemAppearance.selected.titleTextAttributes = [NSAttributedString.Key.foregroundColor: model.selectedColor.uiColor] + } + + // MARK: - UITabBarDelegate + public func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) { + Button.performButtonAction(with: model.tabs[item.tag].action, button: item, delegateObject: delegateObject, additionalData: nil) + } +} + +extension UITabBarItem: MFButtonProtocol { +} diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift new file mode 100644 index 00000000..1bab1265 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift @@ -0,0 +1,104 @@ +// +// TabBarModel.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/28/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class TabBarModel: MoleculeModelProtocol { + public static var identifier: String = "tabBar" + public var backgroundColor: Color? = Color(uiColor: .white) + public var tabs: [TabBarItemModel] + public var selectedColor = Color(uiColor: .mvmBlack) + public var unSelectedColor = Color(uiColor: .mvmCoolGray3) + + // Must be capped to 0...(tabs.count - 1) + public var selectedTab: Int = 0 + + private enum CodingKeys: String, CodingKey { + case moleculeName + case backgroundColor + case tabs + case selectedColor + case unSelectedColor + case selectedTab + } + + public init(with tabs: [TabBarItemModel]) { + self.tabs = tabs + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + tabs = try typeContainer.decode([TabBarItemModel].self, forKey: .tabs) + if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) { + backgroundColor = color + } + if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .unSelectedColor) { + unSelectedColor = color + } + if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedColor) { + selectedColor = color + } + if let index = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedTab) { + selectedTab = index + } + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(tabs, forKey: .tabs) + try container.encode(backgroundColor, forKey: .backgroundColor) + try container.encode(selectedColor, forKey: .selectedColor) + try container.encode(unSelectedColor, forKey: .unSelectedColor) + try container.encode(selectedTab, forKey: .selectedTab) + } +} + +public class TabBarItemModel: Codable { + var title: String + var image: String + var action: ActionModelProtocol + + private enum CodingKeys: String, CodingKey { + case title + case image + case action + } + + public init(with title: String, image: String, action: ActionModelProtocol) { + self.title = title + self.image = image + self.action = action + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + title = try typeContainer.decode(String.self, forKey: .title) + image = try typeContainer.decode(String.self, forKey: .image) + action = try typeContainer.decodeModel(codingKey: .action) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(title, forKey: .title) + try container.encode(image, forKey: .image) + try container.encodeModel(action, forKey: .action) + } +} + +@objc public class TabBarHelper: NSObject { + @objc public class func get() -> UITabBar { + let model = TabBarModel(with: [TabBarItemModel(with: "Home", image: "Home", action: ActionOpenPageModel(pageType: "myFeed", presentationStyle: "root", tabBarIndex: 0)), + TabBarItemModel(with: "Account", image: "Account", action: ActionOpenPageModel(pageType: "account", presentationStyle: "root", tabBarIndex: 1)), + TabBarItemModel(with: "Shop", image: "Bag", action: ActionOpenPageModel(pageType: "shop", presentationStyle: "root", tabBarIndex: 2)), + TabBarItemModel(with: "Verizon Up", image: "Verizon Up", action: ActionOpenPageModel(pageType: "vzup", presentationStyle: "root", tabBarIndex: 3)), + TabBarItemModel(with: "More", image: "More", action: ActionOpenPageModel(pageType: "more", presentationStyle: "root", tabBarIndex: 4))]) + let tabBar = TabBar(model: model, nil, nil) + return tabBar + } +} diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift index d663a703..e318b47c 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift @@ -78,5 +78,4 @@ public class TabItemModel: Codable { try container.encodeModel(label, forKey: .label) try container.encodeModelIfPresent(action, forKey: .action) } - } diff --git a/MVMCoreUI/Atomic/Protocols/TabBarProtocol.swift b/MVMCoreUI/Atomic/Protocols/TabBarProtocol.swift new file mode 100644 index 00000000..fc172d0d --- /dev/null +++ b/MVMCoreUI/Atomic/Protocols/TabBarProtocol.swift @@ -0,0 +1,13 @@ +// +// TabBarProtocol.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/29/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objc public protocol TabBarProtocol { + +} diff --git a/MVMCoreUI/BaseClasses/Button.swift b/MVMCoreUI/BaseClasses/Button.swift index 5d42c5fb..38c48ddc 100644 --- a/MVMCoreUI/BaseClasses/Button.swift +++ b/MVMCoreUI/BaseClasses/Button.swift @@ -78,11 +78,15 @@ public typealias ButtonAction = (Button) -> () addActionBlock(event: .touchUpInside) { [weak self] sender in guard let self = self else { return } - if let data = try? actionModel.encode(using: JSONEncoder()), - let actionMap = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.init()) as? [AnyHashable: Any], - delegateObject?.buttonDelegate?.button?(self, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true { - MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) - } + Self.performButtonAction(with: actionModel, button: self, delegateObject: delegateObject, additionalData: additionalData) + } + } + + open class func performButtonAction(with model: ActionModelProtocol, button: MFButtonProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + if let data = try? model.encode(using: JSONEncoder()), + let actionMap = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.init()) as? [AnyHashable: Any], + delegateObject?.buttonDelegate?.button?(button, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true { + MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) } } diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h index e70a8b8b..ca06471d 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h @@ -11,9 +11,11 @@ @import MVMCore.MVMCoreActionDelegateProtocol; #import #import + @class MVMCoreUITopAlertView; @class MFViewController; @class NavigationController; +@protocol TabBarProtocol; typedef NS_ENUM(NSInteger, MFNumberOfDrawers) { MFNoDrawer = 0, @@ -47,6 +49,9 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) { @property (nonatomic, readonly) BOOL rightPanelIsAccessible; @property (nullable, weak, nonatomic, readonly) UIViewController *navigationItemViewController; +/// Reference to the tabbar. +@property (weak, nonatomic) UIView *tabBar; + // Convenience getter + (nullable instancetype)mainSplitViewController; @@ -141,4 +146,12 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) { - (IBAction)backButtonPressed:(nullable id)sender; - (IBAction)rightPanelButtonPressed:(nullable id)sender; +#pragma mark - TabBar + +/// Called when split view is loaded to create the initial tabbar. Default is nil. +- (nullable UIView *)createTabBar; + +/// Adds any tabbar at the bottom of the split view. +- (void)addTabBar:(nonnull UIView *)tabBar; + @end diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index 72879a98..3b0d5929 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -43,6 +43,8 @@ typedef NS_OPTIONS(NSInteger, MFExtendedDrawer) { @property (weak, nonatomic) UIView *leftPanelSeparator; @property (weak, nonatomic) UIView *rightPanelSeparator; +@property (weak, nonatomic) NSLayoutConstraint *bottomConstraint; + @property (weak, nonatomic, readwrite) NavigationController *navigationController; // A view that covers the detail view when the master is out. @@ -771,6 +773,26 @@ CGFloat const PanelAnimationDuration = 0.2; [self.view layoutIfNeeded]; } +#pragma mark - TabBar + +- (nullable UIView *)createTabBar { + return nil; +} + +- (void)addTabBar:(nonnull UIView *)tabBar { + [self.view addSubview:tabBar]; + [tabBar.topAnchor constraintEqualToAnchor:self.mainView.bottomAnchor].active = YES; + [NSLayoutConstraint constraintWithItem:tabBar attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0].active = YES; + [NSLayoutConstraint constraintWithItem:tabBar attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0].active = YES; + + self.bottomConstraint.active = NO; + NSLayoutConstraint *bottom = [self.view.safeAreaLayoutGuide.bottomAnchor constraintEqualToAnchor:tabBar.bottomAnchor]; + bottom.active = YES; + self.bottomConstraint = bottom; + + self.tabBar = tabBar; +} + #pragma mark - Bottom Progress Bar - (void)setBottomProgressBarProgress:(float)progress { @@ -840,27 +862,21 @@ CGFloat const PanelAnimationDuration = 0.2; bottomProgressHeight.active = YES; self.bottomProgressBarHeightConstraint = bottomProgressHeight; - UITabBar *tabs = [[UITabBar alloc] init]; - tabs.translatesAutoresizingMaskIntoConstraints = NO; - tabs.tintColor = [UIColor mfRedColor]; - tabs.backgroundColor = [UIColor whiteColor]; - NSArray *tabList = @[[[UITabBarItem alloc] initWithTitle:nil image:[[MVMCoreUIUtility imageNamed:@"Home"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] tag:0], - [[UITabBarItem alloc] initWithTitle:nil image:[[MVMCoreUIUtility imageNamed:@"Account"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] tag:1], - [[UITabBarItem alloc] initWithTitle:nil image:[[MVMCoreUIUtility imageNamed:@"Bag"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] tag:2], - [[UITabBarItem alloc] initWithTitle:nil image:[[MVMCoreUIUtility imageNamed:@"Verizon Up"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] tag:3], - [[UITabBarItem alloc] initWithTitle:nil image:[[MVMCoreUIUtility imageNamed:@"More"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] tag:4]]; - [tabs setItems:tabList animated:NO]; - [tabs setSelectedItem:tabList[0]]; - tabs.delegate = self; - [self.view addSubview:tabs]; - [NSLayoutConstraint constraintWithItem:tabs attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0].active = YES; - [NSLayoutConstraint constraintWithItem:tabs attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0].active = YES; if (topAlertView) { - [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[topAlertView]-0-[mainView]-0-[progressView]-0-[tabs]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(topAlertView, mainView, progressView, tabs)]]; + [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[topAlertView]-0-[mainView]-0-[progressView]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(topAlertView, mainView, progressView)]]; } else { - [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[mainView]-0-[progressView]-0-[tabs]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(mainView, progressView, tabs)]]; + [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[mainView]-0-[progressView]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(mainView, progressView)]]; + } + + // Add tabbar if we have it. + UIView *tabs = [self createTabBar]; + if (tabs) { + [self addTabBar:tabs]; + } else { + NSLayoutConstraint *bottom = [self.view.safeAreaLayoutGuide.bottomAnchor constraintEqualToAnchor:progressView.bottomAnchor]; + bottom.active = YES; + self.bottomConstraint = bottom; } - [[self.view.safeAreaLayoutGuide.bottomAnchor constraintEqualToAnchor:tabs.bottomAnchor] setActive:YES]; // Cover View UIView *coverView = [MVMCoreUICommonViewsUtility commonView]; @@ -877,50 +893,6 @@ CGFloat const PanelAnimationDuration = 0.2; [self setupPanels]; } -- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item { - switch (item.tag) { - case 0:{ - MVMCoreRequestParameters *params = [[MVMCoreRequestParameters alloc] initWithPageType:@"myFeed" extraParameters:nil]; - params.loadStyle = MFLoadStyleBecomeRoot; - params.shouldNotAnimatePush = YES; - [[MVMCoreLoadHandler sharedGlobal] loadRequest:params dataForPage:nil delegateObject:nil]; - } - break; - case 1:{ - MVMCoreRequestParameters *params = [[MVMCoreRequestParameters alloc] initWithPageType:@"accountLanding" extraParameters:nil]; - params.loadStyle = MFLoadStyleBecomeRoot; - params.shouldNotAnimatePush = YES; - [[MVMCoreLoadHandler sharedGlobal] loadRequest:params dataForPage:nil delegateObject:nil]; - } - break; - case 2:{ - MVMCoreRequestParameters *params = [[MVMCoreRequestParameters alloc] initWithPageType:@"shopHomePage" extraParameters:nil]; - params.loadStyle = MFLoadStyleBecomeRoot; - params.shouldNotAnimatePush = YES; - [[MVMCoreLoadHandler sharedGlobal] loadRequest:params dataForPage:nil delegateObject:nil]; - } - break; - case 3:{ - MVMCoreRequestParameters *params = [[MVMCoreRequestParameters alloc] initWithPageType:@"loyaltyEligibiltySelector" extraParameters:nil]; - params.loadStyle = MFLoadStyleBecomeRoot; - params.shouldNotAnimatePush = YES; - [[MVMCoreLoadHandler sharedGlobal] loadRequest:params dataForPage:nil delegateObject:nil]; - } - break; - case 4:{ - UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"More" message:nil preferredStyle:UIAlertControllerStyleActionSheet]; - [controller addAction:[UIAlertAction actionWithTitle:@"Bill" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { - [[MVMCoreLoadHandler sharedGlobal] loadRequest:[[MVMCoreRequestParameters alloc] initWithPageType:@"billOverview" extraParameters:nil] dataForPage:nil delegateObject:nil]; - }]]; - [controller addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]]; - [[MVMCoreNavigationHandler sharedNavigationHandler] presentViewController:controller animated:YES]; - } - break; - default: - break; - } -} - - (void)viewDidLoad { [super viewDidLoad]; [self.topAlertView pinATopViewController:self]; From 8fcc9463c88161425e1244a35f5e3aeacae0576d Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 29 May 2020 16:02:28 -0400 Subject: [PATCH 03/14] change bar button item to convenience function --- MVMCoreUI/BaseClasses/BarButtonItem.swift | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/MVMCoreUI/BaseClasses/BarButtonItem.swift b/MVMCoreUI/BaseClasses/BarButtonItem.swift index cbb6ba2d..93eb63a3 100644 --- a/MVMCoreUI/BaseClasses/BarButtonItem.swift +++ b/MVMCoreUI/BaseClasses/BarButtonItem.swift @@ -31,11 +31,7 @@ public typealias BarButtonAction = (BarButtonItem) -> () open func set(with actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { buttonDelegate = delegateObject?.buttonDelegate actionDelegate?.buttonAction = { sender in - if let data = try? actionModel.encode(using: JSONEncoder()), - let actionMap = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.init()) as? [AnyHashable: Any], - delegateObject?.buttonDelegate?.button?(sender, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true { - MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) - } + Button.performButtonAction(with: actionModel, button: sender, delegateObject: delegateObject, additionalData: additionalData) } } From d6761c055e22e78b189ad7e68f3e510d2a94ea5a Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 1 Jun 2020 11:45:47 -0400 Subject: [PATCH 04/14] tab bar selection logic --- .../HorizontalCombinationViews/TabBar.swift | 12 ++++++++++ .../Atomic/Protocols/TabBarProtocol.swift | 4 ++++ .../BaseControllers/ViewController.swift | 23 ++++++++++++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift index e5233ad8..a99d820f 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift @@ -73,6 +73,18 @@ import Foundation public func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) { Button.performButtonAction(with: model.tabs[item.tag].action, button: item, delegateObject: delegateObject, additionalData: nil) } + + // MARK: - TabBarProtocol + public func highlightTab(at index: Int) { + guard let newSelectedItem = items?[model.selectedTab] else { return } + selectedItem = newSelectedItem + } + + public func selectTab(at index: Int) { + guard let newSelectedItem = items?[model.selectedTab] else { return } + selectedItem = newSelectedItem + tabBar(self, didSelect: newSelectedItem) + } } extension UITabBarItem: MFButtonProtocol { diff --git a/MVMCoreUI/Atomic/Protocols/TabBarProtocol.swift b/MVMCoreUI/Atomic/Protocols/TabBarProtocol.swift index fc172d0d..1bf79795 100644 --- a/MVMCoreUI/Atomic/Protocols/TabBarProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/TabBarProtocol.swift @@ -9,5 +9,9 @@ import Foundation @objc public protocol TabBarProtocol { + /// Should visually select the given tab index. + @objc func highlightTab(at index: Int) + /// Should select the tab index. As if the user selected it. + @objc func selectTab(at index: Int) } diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 6ec63c24..92f26569 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -8,7 +8,7 @@ import UIKit -@objc open class ViewController: UIViewController, MVMCoreViewControllerProtocol, MVMCoreViewManagerViewControllerProtocol, MoleculeDelegateProtocol, FormHolderProtocol, MVMCoreActionDelegateProtocol, UITextFieldDelegate, UITextViewDelegate, ObservingTextFieldDelegate { +@objc open class ViewController: UIViewController, MVMCoreViewControllerProtocol, MVMCoreViewManagerViewControllerProtocol, MoleculeDelegateProtocol, FormHolderProtocol, MVMCoreActionDelegateProtocol, MVMCoreLoadDelegateProtocol, UITextFieldDelegate, UITextViewDelegate, ObservingTextFieldDelegate { @objc public var pageType: String? @objc public var loadObject: MVMCoreLoadObject? public var pageModel: MVMControllerModelProtocol? @@ -371,6 +371,27 @@ import UIKit MVMCoreUILoggingHandler.shared()?.defaultLogPageState(forController: self) } + // MARK: - MVMCoreLoadDelegateProtocol + // TODO: Move this function out of here after breaking down load operation into smaller tasks and remove protocol from base. + open func loadFinished(_ loadObject: MVMCoreLoadObject?, loadedViewController: (UIViewController & MVMCoreViewControllerProtocol)?, error: MVMCoreErrorObject?) { + + MVMCoreUILoggingHandler.log(withDelegateLoadFinished: loadObject, loadedViewController: loadedViewController, error: error) + + // Open the support panel + if error == nil, + loadObject?.requestParameters?.openSupportPanel ?? (loadObject?.systemParametersJSON?.boolForKey(KeyOpenSupport) ?? false) == true { + MVMCoreUISession.sharedGlobal()?.splitViewController?.showRightPanel(animated: true) + } + + // Selects the tab if needed. + if let tab: Int = loadObject?.pageJSON?["tabBarIndex"] as? Int { + MVMCoreUISplitViewController.main()?.tabBar.highlightTab(at: tab) + } else if let tab: Int = loadObject?.requestParameters?.actionMap?["tabBarIndex"] as? Int, + error == nil { + MVMCoreUISplitViewController.main()?.tabBar.highlightTab(at: tab) + } + } + // MARK: - MVMCoreActionDelegateProtocol open func handleOpenPage(for requestParameters: MVMCoreRequestParameters, actionInformation: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?) { formValidator?.addFormParams(requestParameters: requestParameters) From 40240f45019eebb8293963af9806348b0eafc8e9 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 1 Jun 2020 11:59:28 -0400 Subject: [PATCH 05/14] fix to bottom anchor --- .../SplitViewController/MVMCoreUISplitViewController.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index 3b0d5929..054fb88d 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -873,7 +873,7 @@ CGFloat const PanelAnimationDuration = 0.2; if (tabs) { [self addTabBar:tabs]; } else { - NSLayoutConstraint *bottom = [self.view.safeAreaLayoutGuide.bottomAnchor constraintEqualToAnchor:progressView.bottomAnchor]; + NSLayoutConstraint *bottom = [self.view.bottomAnchor constraintEqualToAnchor:progressView.bottomAnchor]; bottom.active = YES; self.bottomConstraint = bottom; } From 5227f53776fe68b27f33b2c76dfcffb5f286f82c Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 1 Jun 2020 13:53:08 -0400 Subject: [PATCH 06/14] view will appear tab change thread protection --- .../HorizontalCombinationViews/TabBar.swift | 14 +++++++++----- MVMCoreUI/BaseControllers/ViewController.swift | 18 ++++++++++++------ .../MVMCoreUISplitViewController.m | 10 +++++----- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift index a99d820f..9d5ab9a5 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift @@ -76,14 +76,18 @@ import Foundation // MARK: - TabBarProtocol public func highlightTab(at index: Int) { - guard let newSelectedItem = items?[model.selectedTab] else { return } - selectedItem = newSelectedItem + MVMCoreDispatchUtility.performBlock(onMainThread: { + guard let newSelectedItem = self.items?[index] else { return } + self.selectedItem = newSelectedItem + }) } public func selectTab(at index: Int) { - guard let newSelectedItem = items?[model.selectedTab] else { return } - selectedItem = newSelectedItem - tabBar(self, didSelect: newSelectedItem) + MVMCoreDispatchUtility.performBlock(onMainThread: { + guard let newSelectedItem = self.items?[index] else { return } + self.selectedItem = newSelectedItem + self.tabBar(self, didSelect: newSelectedItem) + }) } } diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 92f26569..51fc1b56 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -314,6 +314,11 @@ import UIKit open override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) + // Select tab if needed. + if let tab: Int = loadObject?.pageJSON?["tabBarIndex"] as? Int { + MVMCoreUISplitViewController.main()?.tabBar.highlightTab(at: tab) + } + // Update the navigation bar ui when view is appearing. Can remove check in the future, see viewControllerReady if manager == nil { setNavigationController() @@ -383,12 +388,13 @@ import UIKit MVMCoreUISession.sharedGlobal()?.splitViewController?.showRightPanel(animated: true) } - // Selects the tab if needed. - if let tab: Int = loadObject?.pageJSON?["tabBarIndex"] as? Int { - MVMCoreUISplitViewController.main()?.tabBar.highlightTab(at: tab) - } else if let tab: Int = loadObject?.requestParameters?.actionMap?["tabBarIndex"] as? Int, - error == nil { - MVMCoreUISplitViewController.main()?.tabBar.highlightTab(at: tab) + // Selects the tab if needed. Page driven takes priority over action driven (see viewWillAppear) + if let tab: Int = loadObject?.requestParameters?.actionMap?["tabBarIndex"] as? Int, + error == nil, + loadObject?.pageJSON?["tabBarIndex"] == nil { + MVMCoreDispatchUtility.performBlock(onMainThread: { + MVMCoreUISplitViewController.main()?.tabBar.highlightTab(at: tab) + }) } } diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index 054fb88d..b46bb184 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -718,7 +718,7 @@ CGFloat const PanelAnimationDuration = 0.2; self.leftPanelWidth = leftPanelWidth; [NSLayoutConstraint constraintWithItem:self.mainView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.leftView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0].active = YES; [NSLayoutConstraint constraintWithItem:self.leftView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES; - [NSLayoutConstraint constraintWithItem:self.leftView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES; + [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.leftView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES; if ([panel respondsToSelector:@selector(buttonForPanel)]) { self.leftPanelButton = [panel buttonForPanel]; @@ -753,7 +753,7 @@ CGFloat const PanelAnimationDuration = 0.2; self.rightPanelWidth = rightPanelWidth; [NSLayoutConstraint constraintWithItem:self.rightView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0].active = YES; [NSLayoutConstraint constraintWithItem:self.rightView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES; - [NSLayoutConstraint constraintWithItem:self.rightView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES; + [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.rightView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES; if ([panel respondsToSelector:@selector(buttonForPanel)]) { self.rightPanelButton = [panel buttonForPanel]; @@ -780,7 +780,7 @@ CGFloat const PanelAnimationDuration = 0.2; } - (void)addTabBar:(nonnull UIView *)tabBar { - [self.view addSubview:tabBar]; + [self.view insertSubview:tabBar atIndex:0]; [tabBar.topAnchor constraintEqualToAnchor:self.mainView.bottomAnchor].active = YES; [NSLayoutConstraint constraintWithItem:tabBar attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0].active = YES; [NSLayoutConstraint constraintWithItem:tabBar attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0].active = YES; @@ -887,8 +887,8 @@ CGFloat const PanelAnimationDuration = 0.2; self.mainViewCoverView = coverView; [NSLayoutConstraint constraintWithItem:coverView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0].active = YES; [NSLayoutConstraint constraintWithItem:coverView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0].active = YES; - [NSLayoutConstraint constraintWithItem:coverView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES; - [NSLayoutConstraint constraintWithItem:coverView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES; + [NSLayoutConstraint constraintWithItem:coverView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES; + [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:coverView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES; [self setupPanels]; } From e8d74bf0a50e3ef01c933c085d3ff28ef86ef827 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 1 Jun 2020 15:06:42 -0400 Subject: [PATCH 07/14] Setup listener for tab response --- .../HorizontalCombinationViews/TabBarModel.swift | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift index 1bab1265..0afb5ff5 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift @@ -90,15 +90,3 @@ public class TabBarItemModel: Codable { try container.encodeModel(action, forKey: .action) } } - -@objc public class TabBarHelper: NSObject { - @objc public class func get() -> UITabBar { - let model = TabBarModel(with: [TabBarItemModel(with: "Home", image: "Home", action: ActionOpenPageModel(pageType: "myFeed", presentationStyle: "root", tabBarIndex: 0)), - TabBarItemModel(with: "Account", image: "Account", action: ActionOpenPageModel(pageType: "account", presentationStyle: "root", tabBarIndex: 1)), - TabBarItemModel(with: "Shop", image: "Bag", action: ActionOpenPageModel(pageType: "shop", presentationStyle: "root", tabBarIndex: 2)), - TabBarItemModel(with: "Verizon Up", image: "Verizon Up", action: ActionOpenPageModel(pageType: "vzup", presentationStyle: "root", tabBarIndex: 3)), - TabBarItemModel(with: "More", image: "More", action: ActionOpenPageModel(pageType: "more", presentationStyle: "root", tabBarIndex: 4))]) - let tabBar = TabBar(model: model, nil, nil) - return tabBar - } -} From c5664d80e4eea93e8bd80ee89d44c632d6694743 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 1 Jun 2020 17:20:17 -0400 Subject: [PATCH 08/14] Tabs update --- MVMCoreUI.xcodeproj/project.pbxproj | 4 +++ .../ModelProtocols/TabPageModelProtocol.swift | 14 ++++++++++ .../Atomic/Templates/TemplateModel.swift | 13 +++++++++- .../BaseControllers/ViewController.swift | 22 +++++++++++----- .../MVMCoreUISplitViewController.h | 5 +++- .../MVMCoreUISplitViewController.m | 26 ++++++++++++------- 6 files changed, 66 insertions(+), 18 deletions(-) create mode 100644 MVMCoreUI/Atomic/Protocols/ModelProtocols/TabPageModelProtocol.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index ba6f08bd..331da73c 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -334,6 +334,7 @@ D28BA741248025A300B75CB8 /* TabBarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28BA740248025A300B75CB8 /* TabBarModel.swift */; }; D28BA7432480284E00B75CB8 /* TabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28BA7422480284E00B75CB8 /* TabBar.swift */; }; D28BA7452481652D00B75CB8 /* TabBarProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28BA7442481652D00B75CB8 /* TabBarProtocol.swift */; }; + D28BA74D248589C800B75CB8 /* TabPageModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28BA74C248589C800B75CB8 /* TabPageModelProtocol.swift */; }; D296E14722A5984C0051EBE7 /* MVMCoreUIViewConstrainingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */; }; D29C94D5242901C9003813BA /* MVMCoreUICommonViewsUtility+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29C94D4242901C9003813BA /* MVMCoreUICommonViewsUtility+Extension.swift */; }; @@ -768,6 +769,7 @@ D28BA740248025A300B75CB8 /* TabBarModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarModel.swift; sourceTree = ""; }; D28BA7422480284E00B75CB8 /* TabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBar.swift; sourceTree = ""; }; D28BA7442481652D00B75CB8 /* TabBarProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarProtocol.swift; sourceTree = ""; }; + D28BA74C248589C800B75CB8 /* TabPageModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabPageModelProtocol.swift; sourceTree = ""; }; D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIViewConstrainingProtocol.h; sourceTree = ""; }; D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModuleMolecule.swift; sourceTree = ""; }; D29C94D4242901C9003813BA /* MVMCoreUICommonViewsUtility+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreUICommonViewsUtility+Extension.swift"; sourceTree = ""; }; @@ -904,6 +906,7 @@ D2E2A9A223E096B1000B42E6 /* DisableableModelProtocol.swift */, D2092354244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift */, D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */, + D28BA74C248589C800B75CB8 /* TabPageModelProtocol.swift */, ); path = ModelProtocols; sourceTree = ""; @@ -2100,6 +2103,7 @@ BB1D17E0244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift in Sources */, D29DF2CF21E7C104003B2FB9 /* MFLoadingViewController.m in Sources */, D28A837B23C928DA00DFE4FC /* MoleculeListCellProtocol.swift in Sources */, + D28BA74D248589C800B75CB8 /* TabPageModelProtocol.swift in Sources */, 014AA72F23C5059B006F3E93 /* ThreeLayerPageTemplateModel.swift in Sources */, 0A21DB91235E0EDB00C160A2 /* DigitBox.swift in Sources */, BBAA4F04243D8E3B005AAD5F /* RadioBoxModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/TabPageModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TabPageModelProtocol.swift new file mode 100644 index 00000000..dbee61bd --- /dev/null +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TabPageModelProtocol.swift @@ -0,0 +1,14 @@ +// +// TabPageModelProtocol.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 6/1/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol TabPageModelProtocol { + var tabBarHidden: Bool { get set } + var tabBarIndex: Int? { get set } +} diff --git a/MVMCoreUI/Atomic/Templates/TemplateModel.swift b/MVMCoreUI/Atomic/Templates/TemplateModel.swift index b478167d..01753414 100644 --- a/MVMCoreUI/Atomic/Templates/TemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/TemplateModel.swift @@ -9,7 +9,7 @@ import Foundation -@objcMembers public class TemplateModel: MVMControllerModelProtocol { +@objcMembers public class TemplateModel: MVMControllerModelProtocol, TabPageModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- @@ -29,6 +29,9 @@ import Foundation public var navigationBar: (NavigationItemModelProtocol & MoleculeModelProtocol)? public var formRules: [FormGroupRule]? public var behaviors: [PageBehaviorProtocol]? + + public var tabBarHidden: Bool = false + public var tabBarIndex: Int? //-------------------------------------------------- // MARK: - Initializer @@ -50,6 +53,8 @@ import Foundation case formRules case behaviors case navigationBar + case tabBarHidden + case tabBarIndex } //-------------------------------------------------- @@ -64,6 +69,10 @@ import Foundation formRules = try typeContainer.decodeIfPresent([FormGroupRule].self, forKey: .formRules) behaviors = try typeContainer.decodeModelsIfPresent(codingKey: .behaviors) navigationBar = try typeContainer.decodeModelIfPresent(codingKey: .navigationBar) + if let tabBarHidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .tabBarHidden) { + self.tabBarHidden = tabBarHidden + } + tabBarIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .tabBarIndex) } public func encode(to encoder: Encoder) throws { @@ -74,5 +83,7 @@ import Foundation try container.encodeIfPresent(screenHeading, forKey: .screenHeading) try container.encodeIfPresent(formRules, forKey: .formRules) try container.encodeModelIfPresent(navigationBar, forKey: .navigationBar) + try container.encode(tabBarHidden, forKey: .tabBarHidden) + try container.encodeIfPresent(tabBarIndex, forKey: .tabBarIndex) } } diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 51fc1b56..717a5761 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -259,6 +259,16 @@ import UIKit MVMCoreUISplitViewController.main()?.setBottomProgressBarProgress(progress / Float(100)) } } + + // MARK: - TabBar + open func updateTabBar() { + guard MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() == self, + var tabModel = pageModel as? TabPageModelProtocol else { return } + if let index = tabModel.tabBarIndex { + MVMCoreUISplitViewController.main()?.tabBar?.highlightTab(at: index) + } + MVMCoreUISplitViewController.main()?.updateTabBarShowing(!tabModel.tabBarHidden) + } // MARK: - View lifecycle @@ -314,11 +324,6 @@ import UIKit open override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - // Select tab if needed. - if let tab: Int = loadObject?.pageJSON?["tabBarIndex"] as? Int { - MVMCoreUISplitViewController.main()?.tabBar.highlightTab(at: tab) - } - // Update the navigation bar ui when view is appearing. Can remove check in the future, see viewControllerReady if manager == nil { setNavigationController() @@ -328,6 +333,9 @@ import UIKit open override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) + // Update tab if needed. + updateTabBar() + if manager == nil { MVMCoreUISession.sharedGlobal()?.currentPageType = pageType MVMCoreUILoggingHandler.shared()?.defaultLogPageState(forController: self) @@ -377,7 +385,7 @@ import UIKit } // MARK: - MVMCoreLoadDelegateProtocol - // TODO: Move this function out of here after breaking down load operation into smaller tasks and remove protocol from base. + // TODO: Move this function out of here after architecture cleanup. open func loadFinished(_ loadObject: MVMCoreLoadObject?, loadedViewController: (UIViewController & MVMCoreViewControllerProtocol)?, error: MVMCoreErrorObject?) { MVMCoreUILoggingHandler.log(withDelegateLoadFinished: loadObject, loadedViewController: loadedViewController, error: error) @@ -393,7 +401,7 @@ import UIKit error == nil, loadObject?.pageJSON?["tabBarIndex"] == nil { MVMCoreDispatchUtility.performBlock(onMainThread: { - MVMCoreUISplitViewController.main()?.tabBar.highlightTab(at: tab) + MVMCoreUISplitViewController.main()?.tabBar?.highlightTab(at: tab) }) } } diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h index ca06471d..4d6b2cff 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h @@ -50,7 +50,7 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) { @property (nullable, weak, nonatomic, readonly) UIViewController *navigationItemViewController; /// Reference to the tabbar. -@property (weak, nonatomic) UIView *tabBar; +@property (nullable, weak, nonatomic) UIView *tabBar; // Convenience getter + (nullable instancetype)mainSplitViewController; @@ -154,4 +154,7 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) { /// Adds any tabbar at the bottom of the split view. - (void)addTabBar:(nonnull UIView *)tabBar; +/// Updates if the tab bar is showing or not. +- (void)updateTabBarShowing:(BOOL)showing; + @end diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index b46bb184..149000c0 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -781,16 +781,26 @@ CGFloat const PanelAnimationDuration = 0.2; - (void)addTabBar:(nonnull UIView *)tabBar { [self.view insertSubview:tabBar atIndex:0]; + self.tabBar = tabBar; [tabBar.topAnchor constraintEqualToAnchor:self.mainView.bottomAnchor].active = YES; [NSLayoutConstraint constraintWithItem:tabBar attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0].active = YES; [NSLayoutConstraint constraintWithItem:tabBar attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0].active = YES; - + [self updateTabBarShowing:YES]; +} + +- (void)updateTabBarShowing:(BOOL)showing { + self.tabBar.hidden = !showing; self.bottomConstraint.active = NO; - NSLayoutConstraint *bottom = [self.view.safeAreaLayoutGuide.bottomAnchor constraintEqualToAnchor:tabBar.bottomAnchor]; - bottom.active = YES; - self.bottomConstraint = bottom; - - self.tabBar = tabBar; + if (showing && self.tabBar) { + NSLayoutConstraint *bottom = [self.view.safeAreaLayoutGuide.bottomAnchor constraintEqualToAnchor:self.tabBar.bottomAnchor]; + bottom.active = YES; + self.bottomConstraint = bottom; + } else { + NSLayoutConstraint *bottom = [self.view.bottomAnchor constraintEqualToAnchor:self.bottomProgressBar.bottomAnchor]; + bottom.active = YES; + self.bottomConstraint = bottom; + } + [self.view layoutIfNeeded]; } #pragma mark - Bottom Progress Bar @@ -873,9 +883,7 @@ CGFloat const PanelAnimationDuration = 0.2; if (tabs) { [self addTabBar:tabs]; } else { - NSLayoutConstraint *bottom = [self.view.bottomAnchor constraintEqualToAnchor:progressView.bottomAnchor]; - bottom.active = YES; - self.bottomConstraint = bottom; + [self updateTabBarShowing:NO]; } // Cover View From e3edbef32c5a77ab95e2135084c9ceff8e9076c6 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Tue, 2 Jun 2020 13:11:26 +0530 Subject: [PATCH 09/14] Fix for defect CXTDT-83977: rightLabel not aligned with headline. --- ...eftVariableIconWithRightCaretBodyText.swift | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyText.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyText.swift index d05fea10..e508c8f4 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyText.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableIconWithRightCaretBodyText.swift @@ -14,15 +14,17 @@ import Foundation public let leftImage = LoadImageView() public let headlineBody = HeadlineBody() public let rightLabel = Label.createLabelRegularBodySmall(true) + public let rightLabelStackItem: StackItem public var stack: Stack //----------------------------------------------------- // MARK: - Initializers //----------------------------------------------------- public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - stack = Stack.createStack(with: [(view: leftImage, model: StackItemModel(horizontalAlignment: .fill)), - (view: headlineBody, model: StackItemModel(horizontalAlignment: .leading)), - (view: rightLabel, model: StackItemModel(horizontalAlignment: .fill, verticalAlignment: .leading))], axis: .horizontal) + rightLabelStackItem = StackItem(andContain: rightLabel) + let stackItems = [StackItem(andContain: leftImage), StackItem(andContain: headlineBody), rightLabelStackItem] + let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .fill), StackItemModel(horizontalAlignment: .fill), StackItemModel(horizontalAlignment: .fill)], axis: .horizontal) + stack = Stack(with: stackModel, stackItems: stackItems) super.init(style: style, reuseIdentifier: reuseIdentifier) } @@ -30,6 +32,16 @@ import Foundation fatalError("init(coder:) has not been implemented") } + open override func alignAccessoryToHero() -> CGPoint? { + // Ensures that the right label is centered vertically with headline. + let heroCenter = super.alignAccessoryToHero() + if let heroCenter = heroCenter { + let convertedPoint = stack.convert(heroCenter, from: self) + rightLabelStackItem.containerHelper.alignCenterVerticalConstraint?.constant = convertedPoint.y - stack.bounds.midY + } + return heroCenter + } + //----------------------------------------------------- // MARK: - View Lifecycle //------------------------------------------------------- From 0708b6eec0c504d93a1e460311a1070f107231c2 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 2 Jun 2020 10:59:40 -0400 Subject: [PATCH 10/14] Add line. --- .../Molecules/HorizontalCombinationViews/TabBar.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift index 9d5ab9a5..e9f6670c 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift @@ -12,6 +12,7 @@ import Foundation public var model: TabBarModel public var delegateObject: MVMCoreUIDelegateObject? + public let line = Line() required public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let model = model as? TabBarModel else { @@ -19,8 +20,11 @@ import Foundation } self.model = model super.init(frame: .zero) - translatesAutoresizingMaskIntoConstraints = false + delegate = self + translatesAutoresizingMaskIntoConstraints = false + line.addLine(to: self, edge: .top, useMargin: false) + line.backgroundColor = .mvmCoolGray3 set(with: model, delegateObject, additionalData) } From 67f2ee7aacf0dc3824587988067beb3ae8a2b6af Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 2 Jun 2020 11:16:49 -0400 Subject: [PATCH 11/14] remove images from core ui --- .../Account.imageset/Account@1x.png | Bin 978 -> 0 bytes .../Account.imageset/Account@2x.png | Bin 2136 -> 0 bytes .../Account.imageset/Account@3x.png | Bin 3355 -> 0 bytes .../Account.imageset/Contents.json | 23 ------------------ .../Media.xcassets/Bag.imageset/Bag@1x.png | Bin 394 -> 0 bytes .../Media.xcassets/Bag.imageset/Bag@2x.png | Bin 651 -> 0 bytes .../Media.xcassets/Bag.imageset/Bag@3x.png | Bin 897 -> 0 bytes .../Media.xcassets/Bag.imageset/Contents.json | 23 ------------------ .../Home.imageset/Contents.json | 23 ------------------ .../Home.imageset/Home@1.5x.png | Bin 450 -> 0 bytes .../Media.xcassets/Home.imageset/Home@1x.png | Bin 362 -> 0 bytes .../Media.xcassets/Home.imageset/Home@3x.png | Bin 919 -> 0 bytes .../More.imageset/Contents.json | 23 ------------------ .../Media.xcassets/More.imageset/More@1x.png | Bin 134 -> 0 bytes .../Media.xcassets/More.imageset/More@2x.png | Bin 160 -> 0 bytes .../Media.xcassets/More.imageset/More@3x.png | Bin 233 -> 0 bytes .../Verizon Up.imageset/Contents.json | 23 ------------------ .../Verizon Up.imageset/Verizon Up@1x.png | Bin 503 -> 0 bytes .../Verizon Up.imageset/Verizon Up@2x.png | Bin 915 -> 0 bytes .../Verizon Up.imageset/Verizon Up@3x.png | Bin 1409 -> 0 bytes 20 files changed, 115 deletions(-) delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Account@1x.png delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Account@2x.png delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Account@3x.png delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Contents.json delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@1x.png delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@2x.png delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@3x.png delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Contents.json delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Contents.json delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Home@1.5x.png delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Home@1x.png delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Home@3x.png delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/More.imageset/Contents.json delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/More.imageset/More@1x.png delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/More.imageset/More@2x.png delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/More.imageset/More@3x.png delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Contents.json delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Verizon Up@1x.png delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Verizon Up@2x.png delete mode 100644 MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Verizon Up@3x.png diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Account@1x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Account@1x.png deleted file mode 100644 index a77098c25cd82181cce01d235dd115837baf73bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 978 zcmV;@11Px&j7da6R7efAmRYDxQ5eTv(@jZai0c8@REFG)g%px9L@6G;;FiLJ+Fga z+0=@#aWD%;Ko6*b-|#%*8tq}Y0>9v&)Q-_>;1!r8;KbVMi)_L70^16xgul{UMm+^5 z{07HhF;qia2r@xGSPCcMJ2>VE%!JHpN#sUwuurxNOqNvx2|NH{{JJayO}alC^qO{3 zmO%+IGq5*+H?SiireF?F`T$Gcg0;NU4bwE33SG+G1%9ft1%nD8!ag>CQohY$~OOu(@nDN0_ z(hlMJC)8nqw9Sx1(6^M*S#m!KEan0Pj*L-{85w`*i| zWs($pAvP|~BUQ~Z@$g(XU#(HMthpIk#*}#)4Z#;;8$FG^(@{6Kf>xzVReTIKhUR;H zXug2k!hWgTub<%~bT4%lU3aE$9bDJu775Gbb&^)&aFDUJ;Jd1ZCGZyXErm4s0M88a zDY7KC`ZvK3FiA1)i1knbX)^Is1MkBCaH*X%O`{3$l=D5gJ#N4*xD9FQNPw$z&A_wZ z-TT+}zhxnt>yTBQ%T7B5vdA%2U=@#o?vQ1P2`l8t;f*WY(r3E+RUxe=yn0QMwaZOxnxpLVZbP#GFtE}EoNG@;c zla@|A4MTX>-hfrQ5{7|CUr;AHo=B_UJQyn$QsO(s*R1@WS_X9xCJe2AgB~2=I<(%b zTc+8ftRNt(T<+Q6(^Y}{++@!qJO&SgpE#-d1I(!R diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Account@2x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Account@2x.png deleted file mode 100644 index 78ddbb80d0f55c0977cf64f680ef81a3c28a5549..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2136 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 diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Contents.json b/MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Contents.json deleted file mode 100644 index dd3bd4a8..00000000 --- a/MVMCoreUI/SupportingFiles/Media.xcassets/Account.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "Account@1x.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Account@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "Account@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@1x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@1x.png deleted file mode 100644 index 08d4e5bd78af30805965e596b3b31151508919a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 394 zcmV;50d@X~P)Px$L`g(JR7eeDV89QIfYR%L_%RUwN5Y?g?1Mm@3dCfA6rir(K>QDgZvgQgBzzLc z{szP#3pW8V6A%*(G=M6<1Mw3eHpih$2q+FR7-T^S4mDVXd!U*;vC1L@d4SAkK>QFP zM3{8|s08G47Q#vymI2j(TrY~Q7FSpa0~LM*;y>sbu<+kP#Xx#c04~E(6p_mTdD{z! z&Cm=G1M<0nxB*QZ8yBWG2PpXlNx@eTdnynkr(tTbUm-_WKhTm(AlrbT1&DcpI3L6z z0Ahgh&OlrR#LuB>XF_SX%R#{d1DAn}7cdS1dNNQRS)u8Bsg*mdzQ52BD0lS>0NpaM0tkE(WETh4KH3YBHq)$07*qoM6N<$f?T?jf&c&j diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@2x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@2x.png deleted file mode 100644 index 640cf1ecf7561cd0a46da31ec12a4c873b227788..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 651 zcmV;60(AX}P)Px%MM*?KRA>e5SUXDtK@g7O0}H_i2wI4R;Hy&<5$r6)LbR~7(Z-+QPq48Nu@l7F zN)T)XZA6nsEG&E=7FsBZMEyn*ZgSjkx9&~i!3=!K?9A-9lW+Gfm*jGOR)^`cz&20- zo`G)xMZ_O~6JQ+}1ZrZFSoIW;8jXw72iXBSfvVXGR{8+qnoE+u2G5Xd=d{(XwuA}$ z0H6Dg@eyzdyZ}*Fk6;%t4UC2gZZRGQ?nCj^hJ9dq1-O#ba4+Cub10@}InS{Rfott< zXt529x$-W2?I@-l;?2*y5G1YbK;b7_=mLIo(#b;I7~-7sP^j|?FJm@WXU2;yn7qY! z>4I+!QnE)EOi~+Wg>=r-I+F*Cw+Vhf8;h<>5ww+f>5VS@SaWIoEtc(X1z(sZ{lFF( z?Tm}kC?!mBC1FKcQ(TlrDPf8$2`kc?;-WN42~%82SdrEg7o|~3nBq#pinOM(O>t2gr9@^GkNSUn0V0hk3FSk}|NPHI lHQobu!oRl69+k{C{sYaQea`QpFRK6m002ovPDHLkV1khQAvXX3 diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@3x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Bag@3x.png deleted file mode 100644 index f621197f200f29ac556e58dd3fe2f024f20714d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 897 zcmeAS@N?(olHy`uVBq!ia0vp^u0R~c!3HGX@y<>MQjEnx?oJHr&dI!FU|_cPba4!+ zV0=6K>}uackz?m4x~Ls;=!kCn!T!WJ$w5-GYv)Q%i_-C^S=?<|G!!Nmie~#Z=ChU*vvk!-Aj2dRb@^M zQM1dqr2TSfiT^G=+i7ZMeJekyUs^v)wEEaRVbSQ&x6CW^Bwp4{R4(eRl?iN>U;2e* zmQ`QO#NwRCJG6dlnzAb7-#;O_GrO}+clV#0DeZN4CQf_$=BM93-b{s~zMuDos6A@i z6L?G8)qTxGjeRHYsNY?FP;bvwuU}D%w10a3i_B~dF-__>4tnFcb5YxhRGmkYRxMDP zf4aZ_@vh|AW;JSo=T$xp`D{>t-rZ}$tr`J_~W9dgHw>xicb)7J6NePkmIUNguJGAcp!R%X$=7dDAv|8n)IW^^ynj}|@p|hcg0>d=xqX7*J5ykS+>ZWF_ zkN0IOeC8Cy>Z|Ez(x8HMV=i=js|Gl~BVE?_RPv_C~@>>7K)%hB2Oe_bA zmNQJ*=`SxatCDBqWHz@w!Bw?YPb}j6ytmpmdwx4-y=PhDmTTRg^q%X^_`3L7#Wq|0 zt_6QCoO!tC=1u0Rvd>G8?0VyObXF{~6`9s~S`RO)WL^o=WQ&?>rz8<}tI$a7xaG3vwjXY@>&;sz!6m?O zdM-qB*Fpxy4RN Z@3qrEOP=WM+zQN744$rjF6*2UngGETmxKTS diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Contents.json b/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Contents.json deleted file mode 100644 index ef86d034..00000000 --- a/MVMCoreUI/SupportingFiles/Media.xcassets/Bag.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "Bag@1x.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Bag@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "Bag@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Contents.json b/MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Contents.json deleted file mode 100644 index 02784f80..00000000 --- a/MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "Home@1x.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Home@1.5x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "Home@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Home@1.5x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Home@1.5x.png deleted file mode 100644 index 17dc8d9655ead06d4698b1ad0cd9c529c27296ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 450 zcmV;z0X_bSP)Px$d`Uz>RA>e5m_2U7KoEru0;QoxzC{i|>h$U9attm)0d2Z;Kt+`tAe?|AH%O46 zgZEG@tyW&!S-j&}v?D$FZ|&J{W>(s9mW8(oTx_6GcvoRP5abs+LmyDIKqd%bq6I1g zi4y1uStv@207q#3mze_S6W8iX&dvxyo}nJJfC?BMRj(lz2=5ThdbO0<0duPCSj#}T*k2UF z{9sPbj&*>C56~1UY>$&2L>P_6@_L2dp`kIsoG@GCMl7cUTG^BB+c#pqPB2=tmok$w zBM^a9W&%O>a*;CQ6*hsFQf35#?Byb5#w%Px$BuPX;R9Fe^l{*RoK@5g{T|n>*9>mH*Y-|*4+g1sm3 z^#^t&#&Otn9$IYRXXlmVBQs=+IXf%BeFjyatzD?^y$NCg-Ju&4LBWkf5XetpIK%}I z9cU67Mnbd!pez`S2_hIw5(w`wX&}78d;{Se#s8b%7 diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Home@3x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Home.imageset/Home@3x.png deleted file mode 100644 index 8d67c8010748b995eba018bbf483971e888bdda9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 919 zcmeAS@N?(olHy`uVBq!ia0vp^X+Rvs!3HF~(v`OWDaPU;cPEB*=VV?oFfa#tx;TbZ zFuuKQndENg4Tb)Tzy`fr+Me1EZ`?|5hIG3)5`(ilJ4@P``mIe)i)Jv^;I zr)8=9ZVf)=IZIvF)Qfi&h_y*N37&JZkQ8}1p-=!w6f9f7k)Ae(=T!b|MTK2uf3;#I zG@C!&th%@TtCvOV<@c7cVo&c~{kT0x+|Pf;(s^!yi`Ew?bxM9)sbSa!WHkL=2w^Z) zYfh1HwU~H>u{smNXsOi$Ggvm9?-g3ip+3pujSfWSz&W?hz!qW8k~iK9k7yj~R4Mzm zG%!izp^MPA^{lFHLg%;wTQ(<6Syp)M+b27op9pwalS`y4yOd{i+JB%^M9H4 z{+m~SmplEI+iS7gAaV-(wWrzf>bC#mnf{4>Z{L>gRK&=R0MK(jORn|MA2?pRMc5;!T_u=PsYo zd~B;0yjm)WsY$V|cZ(3uB(aTQ21hnb3~O?{q;!p|O~UMwmw`vrk*I?Lhuxw$**v== zv?Y>mcxWF~$P~@-IRFzQCOe#QjEnx?oJHr&dIz4avVHe978Mw zlT#8BHn1nHVsu;J`F~}a)CC2#EGe_BYYM!L2j}NF=q<_elU!nGxMU7%*Ob3kN(`@F hRy=W_Dr=VjgX|QRqkFbYyaF_f!PC{xWt~$(6982hD)ayV diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/More.imageset/More@2x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/More.imageset/More@2x.png deleted file mode 100644 index 158c6636bd8a70a0116d6999a66312cd0dcd1a59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^8bGYV!3HFM+f;}FDaPU;cPEB*=VV?2IZ>W2jv*18 zZ>JsPWKiHavZ~v9*DXmtMUOw?Nm?_sen?KwpC~C^Fqu(Za@|dqCHWq9ycrJ6Qa|oC zm`={SG0T(p(PaC*3qDI-Xkat>aD(BWy5aUq;t6?6**<<|zh2BTdFQN2{Xkn7JYD@< J);T3K0RT%MHdX)t diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/More.imageset/More@3x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/More.imageset/More@3x.png deleted file mode 100644 index 54de11dc7af5b0cdc2287bbebebe1812b8d65e3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^Hb88~!3HE}r~eWGQjEnx?oJHr&dIz4au$2KIEG}f zzP(|{)nFjN;vo9}>E)VP|9pHkmvNMB@0sh)^iC(@j!ESv)@SPXCdz)CyN-3=y~S^~ zt6JYPpL-yF@|w=J&A+C!F)%W*a0n9hZ)frbi`uSuxacTvec5mC_lK9uu2C;w{>;ys UTrk_X9OzsIPgg&ebxsLQ0O+GqjQ{`u diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Contents.json b/MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Contents.json deleted file mode 100644 index 11c37b59..00000000 --- a/MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "Verizon Up@1x.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "Verizon Up@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "Verizon Up@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Verizon Up@1x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Verizon Up@1x.png deleted file mode 100644 index aa034686f4d37e854d6c3fa1074d2e00a6f2c840..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 503 zcmVPx$u}MThR7ef&RnIF0Q5c;O3s#iaDN9O;va`0dRF?svT!e)j2$n2klM=tgx0eruTBVn2_n}s&qa9$Vugo)#B z3VD|NNaSX{| zeLLHCg>Rt9@%LW^y%HS^1#G8$G7MPcq7=mDwtk9Ipva_&osCD%xKEVO;OPl)dy@UZ zOYoKCf|@;do~vrwPO1^D>)xHc|L(o-b86q&-Yz^B_qD$I?fJd6;DtARo*Pckepl?!l{>R1oFf9J6@I)?b$69HxMfGTarw=)}xGrf{JB=tO%<|ZEDv7Ww6rESK;Nh+7nq-L-)__?1g2)I18O6KX>RVJsG zPFc;nuK(9ewe3@jqJqPZW=^TQz`L!XGC`(-Igdf|xnYL)mE-%TWb!eT)Gs~1{Y--X zoK35P-tRx26wg?G^w8>W_cy*}vom_apy1tB%l7%Jt!uNSu2k=lGLagF^v3NXZx>$G zim=_`9MU!?_~o&%s*6n1cGj`}KIpYU@DBSjpSBxmlQLgb#$EbqBD~?pn%3P*KTf~! zp5e3QM&@@jo=x{UYkc_Af{&t{A^c&t>e<{~43~8OQfc;H^Gvef(F3veY%#wTa_shZ z4_d!m#QNu!VerlNT&3zQ)1OFwC|E!9PpRDFjK`1mTl|?@vYbgSTQYG~tM{TbOPQGI z@2uPRPd+EK!N$cWGDBb!!)qQr-_UIf1I3Q>ioFxQQ_OvT(kY=2+}{1aA6#QT`O2t3 zw!+>q)0lM*`!Cf!ZNJJAPWg7sSDP7feiOg_!r)^6ISl2BnH#2j%li}7$ey4ygFC0w zlJmXpw!TSLmOak1Y{TNdY(7;Xb!zrBoi(|A(;uoHzL)e`XXWH}i#Z+zRsFT;P5ozU z1TTH-xlsE)=;j(>yQ*moOaI3v2v0arGVx42EB68A3+V^8&VTgH{oTiM&Iy;MICd~6 zSpLY6x_oW(ox`i%7i%z82ApNQe;{~4Q`UlV#`u>@4=Nc5pJDqHYQpeD`4M}D_btu{ z-aGwDFSeYR_IU4G6+G_*tX=uyzfnTv zWG=mra(w%qG_vzQ mU;XW_>$!D~UYILe9kWG6tN(e^MljKR~@&t;ucLK6T`ajHcC diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Verizon Up@3x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/Verizon Up.imageset/Verizon Up@3x.png deleted file mode 100644 index 072a2758e8af7fcc5a3a6e1c6ab408b6c8de84b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1409 zcmV-{1%CR8P)Px)J4r-ARCodHolR^OMHt6hf*?vL6cddCDRRKZ)Sd`xOf<+>f(5T$2*zGe(gQcI zUJWFCc+qH6YmA98UKGMd_(-Zk(uUTQkaB=G1&kW2CQ39amH$6slV$eZnP+!qr|tHc z?BIGy5*IwWX!ye@Iic1jZIr8(*U*1Qc{aqT-{1t{89cGu$iNli3kig;W?^PhlriOlY;hVD2kw zQ3M4o!sPFyp#2$&A}DAPCVwXd?axpYK|zZ!`8z3Se}~F! zP72zep(uia7Gd&tQqcYkMG+LV2$R2)g7#-9ilCrHnEag-v_C^p1O+X^<2^vgf%klzDshE_w5 zKtDl~&~fNfr~y@;%$H}FFY^LTvp7lFw~njW0DI!w>}d99(BeOFudRo0JPJ))eA(6= z=n(WU6e7*57iii+>^tZ!sMSG_(`O$v0zKyNEp4vj9L-02=4rGh{OX>*Pm&)r1@Pcm;vwp}`hZ(!dyldV~+Wr$K{m=#IUx?F5 zFXWnw_roW>azWNF%~jA`Ex6LpaM%uAN;!Ux^Y@{X&{L^$^Rx#Aycs{5hO+s(P93}v zTc9-LgwYM0Y=$_(^AZOjeS)RBg62l#dkZCQfWENUX|ipg996UCx`O^7d#Ra{PckL< z7j)mB^~=>2^c4Y?YYrc7)q|zFf}Ru*`oZB7bmLM-(EkA7-wud0bLl5py$C|NU1kgD zMeeSOJs8WiPG&IfAZ_dM-{=%7#RAPIX}0vF%~-;=R#0b+!{=9ry^uK;=nhA(_?R?g zdPNZIC5O*thrN(FBxpWx&r5AEyqsfPh4S7UTiIeh9$jv!yco897CTLR%o;3(1U=>G z6(7Qz+g?5`<92w7qpoST&8_rZ263Idlo=!Onh!#c8s+IMza-D53w+NP`UXhV=T6Kv z?-BASGy+XRoe)8n>4RjoumiFA%g)=-5X3sqL2p7kAzL~HW5ec9)K=yq^V&EEgKKW& zNA~%9!lClig%-Xl(aPZxb*xoFP8|biNwR*mc4!tDzeFFt4&9HCpnpN<-Ywa|^QgyP zrlrX>NB|DNH!#BcIX}GM8Teo!~a$2uLAX4bM$V+a&58A<{Bt?5h`-S z%^11)(4hZAOFhsLi07{KF&sE&^SzId={kb(=csdnpuA}xL0rqTUL`5ymtoRDK2Yz2 z-h()@wn80HJH%}*p9OQO7=X9}NzxlQS(0RoBR|sVAvuM-u(|W)41pv zSs8_%qeG2~+Qm`Ok#4DiR?v|ML~2GybR^JKtfOOey&sKyV`=E7#Wo|RxeEFWXi;+} z>C_SFRw-x&9f?4sW^_a==tu-2HKQY1K}RAGsTm#73OW*jNX_VoR?v|ML~2Gyw1SRA zAW}0rq7`%`0+E{05v`yj5s1``j%WoPi9n=g__8414Kvde3L0ji=0yZL;bs1Fzp=a@ zXZiQ|n*L2bQB&%aA)s?~21zvq3c4DunWzdngQS`Q&e3Dlgx07j0uy%u1W?Mr7#WG% P00000NkvXXu0mjf61$WO From b66f569e773c618d3386f80d7a97f9245ea8e299 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 2 Jun 2020 15:38:27 -0400 Subject: [PATCH 12/14] fix to anchor --- .../SplitViewController/MVMCoreUISplitViewController.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index 149000c0..1e04d987 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -782,7 +782,7 @@ CGFloat const PanelAnimationDuration = 0.2; - (void)addTabBar:(nonnull UIView *)tabBar { [self.view insertSubview:tabBar atIndex:0]; self.tabBar = tabBar; - [tabBar.topAnchor constraintEqualToAnchor:self.mainView.bottomAnchor].active = YES; + [tabBar.topAnchor constraintEqualToAnchor:self.bottomProgressBar.bottomAnchor].active = YES; [NSLayoutConstraint constraintWithItem:tabBar attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0].active = YES; [NSLayoutConstraint constraintWithItem:tabBar attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0].active = YES; [self updateTabBarShowing:YES]; From 05bf9cf5acb729565eb5c8c5a10c7d1d33048065 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 2 Jun 2020 15:50:14 -0400 Subject: [PATCH 13/14] set model as well --- .../Atomic/Molecules/HorizontalCombinationViews/TabBar.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift index e9f6670c..2216040d 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift @@ -82,6 +82,7 @@ import Foundation public func highlightTab(at index: Int) { MVMCoreDispatchUtility.performBlock(onMainThread: { guard let newSelectedItem = self.items?[index] else { return } + self.model.selectedTab = index self.selectedItem = newSelectedItem }) } @@ -89,6 +90,7 @@ import Foundation public func selectTab(at index: Int) { MVMCoreDispatchUtility.performBlock(onMainThread: { guard let newSelectedItem = self.items?[index] else { return } + self.model.selectedTab = index self.selectedItem = newSelectedItem self.tabBar(self, didSelect: newSelectedItem) }) From df980722fdd6c9f510cfed549bfdaff294c393a3 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 2 Jun 2020 15:53:56 -0400 Subject: [PATCH 14/14] move model update --- .../Atomic/Molecules/HorizontalCombinationViews/TabBar.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift index 2216040d..94e53790 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBar.swift @@ -75,6 +75,7 @@ import Foundation // MARK: - UITabBarDelegate public func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) { + self.model.selectedTab = item.tag Button.performButtonAction(with: model.tabs[item.tag].action, button: item, delegateObject: delegateObject, additionalData: nil) } @@ -90,7 +91,6 @@ import Foundation public func selectTab(at index: Int) { MVMCoreDispatchUtility.performBlock(onMainThread: { guard let newSelectedItem = self.items?[index] else { return } - self.model.selectedTab = index self.selectedItem = newSelectedItem self.tabBar(self, didSelect: newSelectedItem) })