From eee2a5f3ee518ae79a26e73369896ee375479c35 Mon Sep 17 00:00:00 2001 From: Gray Zhang Date: Fri, 17 Oct 2025 19:08:08 +0800 Subject: [PATCH 1/3] feat: replace custom tab bar with native iOS TabView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the custom bottom tab bar implementation with iOS native TabView component using SF Symbols icons. Changes: - Replace custom TabBar widget with native SwiftUI TabView - Use SF Symbols for tab icons (newspaper, safari, bell, person) - Add badge support for unread message count - Remove .hide() modifiers from page views (TabView handles visibility) - Move data loading logic to onAppear in each page view - Integrate TopBar within each tab using pageWithTopBar helper Cleanup: - Delete TabBar.swift (custom tab bar implementation) - Remove custom tab icon assets (feed_tab, explore_tab, message_tab, me_tab) - Removed ~150 lines of custom UI code Benefits: - Native iOS look and feel with standard tab bar behavior - Uses system SF Symbols icons instead of custom assets - Cleaner, more maintainable codebase - Better integration with iOS accessibility features - Automatic handling of safe areas and device variations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../explore_tab.imageset/Contents.json | 23 --- .../explore_tab.imageset/explore_tab.png | Bin 683 -> 0 bytes .../explore_tab.imageset/explore_tab@2x.png | Bin 1336 -> 0 bytes .../explore_tab.imageset/explore_tab@3x.png | Bin 2052 -> 0 bytes .../feed_tab.imageset/Contents.json | 23 --- .../feed_tab.imageset/feed_tab.png | Bin 675 -> 0 bytes .../feed_tab.imageset/feed_tab@2x.png | Bin 1172 -> 0 bytes .../feed_tab.imageset/feed_tab@3x.png | Bin 1771 -> 0 bytes .../me_tab.imageset/Contents.json | 23 --- .../me_tab.imageset/me_tab.png | Bin 755 -> 0 bytes .../me_tab.imageset/me_tab@2x.png | Bin 1514 -> 0 bytes .../me_tab.imageset/me_tab@3x.png | Bin 2304 -> 0 bytes .../message_tab.imageset/Contents.json | 23 --- .../message_tab.imageset/message_tab.png | Bin 622 -> 0 bytes .../message_tab.imageset/message_tab@2x.png | Bin 1241 -> 0 bytes .../message_tab.imageset/message_tab@3x.png | Bin 1888 -> 0 bytes V2er/View/Explore/ExplorePage.swift | 6 +- V2er/View/Feed/FeedPage.swift | 4 +- V2er/View/MainPage.swift | 65 ++++++-- V2er/View/Me/MePage.swift | 1 - V2er/View/Message/MessagePage.swift | 6 +- V2er/View/Widget/TabBar.swift | 146 ------------------ 22 files changed, 64 insertions(+), 256 deletions(-) delete mode 100644 V2er/Assets.xcassets/explore_tab.imageset/Contents.json delete mode 100644 V2er/Assets.xcassets/explore_tab.imageset/explore_tab.png delete mode 100644 V2er/Assets.xcassets/explore_tab.imageset/explore_tab@2x.png delete mode 100644 V2er/Assets.xcassets/explore_tab.imageset/explore_tab@3x.png delete mode 100644 V2er/Assets.xcassets/feed_tab.imageset/Contents.json delete mode 100644 V2er/Assets.xcassets/feed_tab.imageset/feed_tab.png delete mode 100644 V2er/Assets.xcassets/feed_tab.imageset/feed_tab@2x.png delete mode 100644 V2er/Assets.xcassets/feed_tab.imageset/feed_tab@3x.png delete mode 100644 V2er/Assets.xcassets/me_tab.imageset/Contents.json delete mode 100644 V2er/Assets.xcassets/me_tab.imageset/me_tab.png delete mode 100644 V2er/Assets.xcassets/me_tab.imageset/me_tab@2x.png delete mode 100644 V2er/Assets.xcassets/me_tab.imageset/me_tab@3x.png delete mode 100644 V2er/Assets.xcassets/message_tab.imageset/Contents.json delete mode 100644 V2er/Assets.xcassets/message_tab.imageset/message_tab.png delete mode 100644 V2er/Assets.xcassets/message_tab.imageset/message_tab@2x.png delete mode 100644 V2er/Assets.xcassets/message_tab.imageset/message_tab@3x.png delete mode 100644 V2er/View/Widget/TabBar.swift diff --git a/V2er/Assets.xcassets/explore_tab.imageset/Contents.json b/V2er/Assets.xcassets/explore_tab.imageset/Contents.json deleted file mode 100644 index fe661a8..0000000 --- a/V2er/Assets.xcassets/explore_tab.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "filename" : "explore_tab.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "explore_tab@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "explore_tab@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/V2er/Assets.xcassets/explore_tab.imageset/explore_tab.png b/V2er/Assets.xcassets/explore_tab.imageset/explore_tab.png deleted file mode 100644 index c9a59f6ab276b002af53d43db50b23e2b8e847cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 683 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1|*NXY)uAIjKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-uxqunL1}TjAJUxzqfl1WU#WBQ# zcki^b-XVb!?Z-tDpi}n6McW+f9pu{-@^V76 zJ6-Ph=*>BLMJ?#1^W7~P9UB($$9}OXTVK34E_F}%uY<;)=Y5}BeXsbP<#XHM$*WgL z7IU0);9hfpyMkr)gecR4lb`?G$L`B%TYIpaRZKW3boZQt+CLbKFR(5@*yp{VUX0H% z>+Zvo29C~a#MuM*9@TD)xO&#A?xoZU!5=#lL+$L6?b;G08q9w1W`9s`%>S|MA$!g# zmE+CVJ}oO>E%>Yd(Yt$6UOByw_e%H9cp^KesjPyt@MXAnK+7*#jR*E@?g_K=9v1pO zJ7C(eYU(j*gE~toj}7^3`*+LtTTX7jz}ff6(x)N)h-6G_^9F{=6TH-Z@-;u;_*5Xf z=u_#p!|PWR>u>YClD&hY&!+Ct{0GtPSGXqMXjGQv-mo{{YD2#5+e;VgJ%e_iW?03$ z^S7QOzYJUVn(P-lH(5P7q_t+QTNtB%Mf9P=@*j6tiQ+mW1XbSQ=Q$XKRacnR!@fl}GZrw!KXjU= zVl&^GbMXUH!RefN4u-Eg%h~)7*4dc%evn&s;D3R1_kZytRw+;1<`>C>5{jp*pUXO@ GgeCyVs1;KH diff --git a/V2er/Assets.xcassets/explore_tab.imageset/explore_tab@2x.png b/V2er/Assets.xcassets/explore_tab.imageset/explore_tab@2x.png deleted file mode 100644 index d2029409f09bc081367d259d6f8807b69680ac2a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1336 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 N002ovPDHLkV1gTLBMbll diff --git a/V2er/Assets.xcassets/me_tab.imageset/Contents.json b/V2er/Assets.xcassets/me_tab.imageset/Contents.json deleted file mode 100644 index 5501ecd..0000000 --- a/V2er/Assets.xcassets/me_tab.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "filename" : "me_tab.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "me_tab@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "me_tab@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/V2er/Assets.xcassets/me_tab.imageset/me_tab.png b/V2er/Assets.xcassets/me_tab.imageset/me_tab.png deleted file mode 100644 index b5342a8bfbd36ea340a9ef7465bb8ff4e72d1111..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 755 zcmeAS@N?(olHy`uVBq!ia0vp^Qa~)p!3HGt@7W~)DaPU;cPEB*=VV?2IWDOYo@u_m z3|c@o2Loe!CIbsd2@r$yF)%PMU}Rth(u^Rn1xyIp1(Gbs+pU_=Zcer}ab?fqXdnd2vvzcT3{mqnWfBKfG@eW5 zv_e)lAiY|TLr+l4KStA}-90+vT8u}Ha*WW;Uk9G@v4omkyjIt=;L_iUjNa6W z)0S@M{Ot83UNpS^(|J97YPSB~mfE;IyGqusJ;myMEnr#vw=cK%?pSeQ(d#wG+}|4h zm#m9<{C7k8)7eeV>4!rd^H)!wVv8A?x}XggxUKeE9W;%fp>VD1ZOJadKl=9S z5ij`X{`D&mt3N1y{K(xe*R9X~mB`%}eY#r0q(`_w=+PS^CfOCIJVTDiRZKb1r>J_r z$#nGz&hL-kH<~!HztYp#v|?(hOsRatBd(2n5x$?)G8%Md>{Z*rXPNz>Hbn8I(SnWd z8-k*If5q-#zV%{Zn3ko+J!fa@Ee&0-U%zRSRr+_G*YDN;tVHMKdzUf?PLAc@waTgTe~DWM4f7g;`3 diff --git a/V2er/Assets.xcassets/me_tab.imageset/me_tab@2x.png b/V2er/Assets.xcassets/me_tab.imageset/me_tab@2x.png deleted file mode 100644 index 523de7a4282a8cf2fe31e472e45edfd269819dc9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1514 zcmVPx#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91G@t_j1ONa40RR91G5`Po0Mh>$qW}N}R7pfZRA>e5m|Lh7RT#%TUDPZq zy4nRjCnHZv7DZ4|1adN>ddMd!BEyPQh@h8xsh6k-q&p?_5){=#MK94s@&>7?Nkm$v z(b2R#Wk}MovfJ;++2+i0&0e!-&)yWAKm3?kYu5VK`et3`ThlY9e)VDU8kh;EH#m*! ze%K8|uoG6n3it(TQ%_Bnj>pdJa05(j!RGIjT@A0m(iZ9!7H!v|u~@zp7Qu;yt(1GP zo??%|C*_LAOSR)rKPF#*$#K(_b6=uMY{ z(*_U~Q7qo6}&UhPQ(JR+Gb2cpE0cjG%Ha>0iNJFsUPwB}NL| z%%wLd`#0%(U`3E$HFFj3VJLh%pOM$jnxT53oPG~Pp1R|??Kf2!hum62IXX_cPRSkfoxr&3*zaFc zr5rk&+Wmorjigrxd7VhQ>xF9Dp_lBHl=;BoEAFmAK~r+uMP4uw;!>2MdeQvE@!z1XPz+d|5raEcj@81i>ZXGIzc zUvjQU%As#_rAN*|R|I*TOkNo=9`-3$B<0Y`TCZo!%R<+qOg6d^uuxK6$YP z8!1{T>rQHUdd+GpiM82`*nMh*tg{A|dy~<4?w5e`yl%M>#75_F^8ZXVR>mQ1Xe>Pc zOeb$K90hghTns%6VZYXqx3o+nWscz5@rR#b`^6?QvIFLQ2(GtwH$ z`;b&whcxsNTm(~0WHg!k>)$F`2kAPD-l+(}Mwv>8Gl{!?&x92abzC&5L zyOpG#0e`rMQ#4nQgj>H`vwx0aAr9GNo@(HIDYfd5MmrgQtrg7UfrQNLzj<+$em*b<1e_KB#omZ)FW-JMQ*rgL~jYsB8OP zi>(FVwUVliP_{95KO=|vP}Q+7sq2U@gSJ$MLkBx>0ync@0Ir4!&`g6oG?bAIQ0iwq z<(jHahq4X1#-@TBh8+JmKEuLzl8hrz!Z=jQJppH$!aLBWf7zwxmoDA-I zK65KKA~zKBqdDBbldw_5_wXIKS$O|5R90Ds>{K5ZT}v-aXbV9Dtxh~e(6|L{1-XLrT-;(SCPnItBz2L$RWk9TB zu05lOGhk8!j~0CmJZ`ii2WLQsT!78aHg@m}*wQF#dD#P1F#22s;LfJW;I|mG* z#5H|B_%e#L&59Ow+PQn}02i7I&c$aG{1g0FWPf`>$6W7jUf#P4zX=cj1LBq5zD7D! Q9{>OV07*qoM6N<$f=#5Zy#N3J diff --git a/V2er/Assets.xcassets/me_tab.imageset/me_tab@3x.png b/V2er/Assets.xcassets/me_tab.imageset/me_tab@3x.png deleted file mode 100644 index ce49ed0200ac2855bdc764088515c02847dba711..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2304 zcmV+b3IFzqP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91PM`w-1ONa40RR91O8@`>0C1&?Hvj+#YDq*vRCodHnt9A+;~mG}Va9Z* zE!J7e%ozJtk+vw&Hd>6WmWW#Z83dsS)k>rxZ5kB`x-!yeTH7CpCALmmZA7SPZNZq0 z@!A<-m|+%-em?Ww8*kowp5Hy^+;f+9?l1Yg=icY{Z0Gwv%kMnrjvDB$eVOLJ4tu~< zm;#%@1~pc3T?R|x6?h5e!@pnzp^vSOufbODZQ;DJWMX;hsp(t;a z!kt7zKaUz4;Zvx4;URc$gfIH)2JdlHl>2I;S_LcHZx+yJL;%-F3Qw`??cMEjyVk-{n1SNCVu;|2ufSjK%Po} zOD3NLBD)RePhnM*sY2gD)O9s%5Y)L0-yz^EC}r!EDm7Hd1-hANe<06Kpi`pRGoN37 z0MQQW;es(krzAT=qfRXXw)K*JWxV+}+^Gkx)js(bRh#7z$+BCnP#m3}m})v+2Oz zuuY;PlSzLZUQ76s$z|5KL#b^_vc`ddoAEhKdcj;KE{ABjIHycU%LsRD(2%>8J8du7 z3v|XfFJ=4Un2>U&(u)eW1r_a|s*LoRP~`C`sH#%eRn(T+*R75wC(|FIF=s`Vc|fpNmLru`M7S?e$)r?8r1!dTOX%ajgZ^(H_!?YAgo{EDPaFmt zYVW-Sci5Cg_t#LSh;Y$p>xE#q;pQ?DqJBpA*HBdv;e0So+2WL=$I^X&U7GSBwTb1)zGyf!bN#g!DT~(T~3Jl8Qot)w~J){sG;;130r>gv8O-z3oq9XT6UFl^=+2Y~b&< z>$^b*7UC-u#1|Frk)ZMQ@%8Gc^MK;upzqOrWfm(c+7EC zG2dcE5AZjX>1dhvsw-$n!BfZRiuM(F5V~!?Be@htB|740yBJm{{K@1p!dcm~a2%wz z_Z{(l3ekxx?zY-gYX391F{JDg9Io4it*mg0;ycu67j;C=fkJ^L`Kz#vsN`md9^z*Mf9BPSaG%rgf8b~s16gKh zG96qKAJ58Aahk9B9BIwoAN-CyZgQoq72$03U2rrV;g`U^fzO{+JqF8zd}UoO{wIJx zzi^sH=G!>ewwA0_;cVPB>=Q`svgXmI!HHm-ZZ58qRhT=cBS_(z-OoJooC>R;B};A7 zWh(s@g_@1Ldc8guUJLibJN3i@S5G?pv5X?@pR?S1L{B)CJmhPmM!2t{75DAwuVh^xe^6t3Q()A(>PxFM7=r;(%3^;2;a ztl7FnmZZ(ba~4EriOIq#M>~YGEl0$!A$rs?U%TyA8n_HxgDbUWi)q=$1}W(7wHu5t zTS*J$obEpZ|9OQUr}DJht`Rr9ZP%n9!_?u4ZTh^DdT)T4@L`+USW|5$gtH+>_VI8& zMDI3nmoi6{0qr&LR;d~a7V4C6^=|pV?Fc*u3?s^JAQW9=E(x9w%ByQqI`pU0!VSNz zP5818>A}#$tKo<7nZScX6+Epv$IJs8MX!Au}*-AwX1<|J4{hM&#UtapI@$F;H>zSSu4UhVzz^6!>&gE zlqo|W+aBRDhWxirGbTT@aR=fJSY-BL#R6Pi0f}d0N0S>q9dBd2`XGhlm zvN_ESv&0C(tHQ1eDVv4k%(_^LcMePj*Pl5x+>VWFoMLN>IqenDkZkwb)v3P%?uM&j a<$nP!V_#4!khHr10000EamT z!TWaFdF`}7iR16JojxT8R0XnCn_fy-`sc=t32D>*F>{{{x|x~Qm}Wci-dT;v&VWfd zn)Y2wW^9_rx^Y3~pC2{x&p%mNez&cN+7DvgAoG*GV#0X2bw|GC+3h+E+b7kg{(p#<c2U-adRe9 z_Lhfv%YLW5R(mWGk`i*W>iwU#4_p7t|EHUh^i%WX;hh#Ar!f9hiWa*rE8?7dL{h!; z>S6v1?yhD`RZ+_lSmTWU%E-LVTJOO9#;DdOWP$uQ$L^n;DXRsh&W>qbV)ST1e#^R` w@>yA@Eu2>}&-`LPY0b+Utbh4yn{7O@`K6e=`LsDsw}9f>)78&qol`;+0B#Kd9{>OV diff --git a/V2er/Assets.xcassets/message_tab.imageset/message_tab@2x.png b/V2er/Assets.xcassets/message_tab.imageset/message_tab@2x.png deleted file mode 100644 index 97ae815ab095dc159354913b89dbb0eabec03f7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1241 zcmV;~1Sb25P)FV00001b5ch_0Itp) z=>Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91FrWhf1ONa40RR91G5`Po0HOCkYybcRLrFwIRA>e5nOTTWQ5?sOU3S?b z$`XpKk!%mh0}&!gJdCowcu+(lkr&AW50ZrJ`<6)AMV1;#wg{0e86Ft>=bO3H>37%v z+&jb6|5u;6=l46m^E>;w_kX6KT6WTcP$OUnw1t+?9E#yByoQ@_2A)7BQjkHEfy7t< z{UK?*$M|l7!|)5rElDd3s-PprB``cFGokH1eyiYWLVurI4WA{ML5l1FfMO zxT0Bl19x3xRN6Ks%(pffs500&Kw5$Lfi zB(4K>38HTsSB|4-)Up;kDB1@)l_Djs16?SsPPlT`RWeL#Lw_>yQg=XKl&)xwrB4 ze#He$nQ!CU`hDT!I^ZktzZvo!_}4R%pMm@gq#S|#5=uFMsf*`lAoUQY3=lU1bxizk zM$cNc@$IL)ufDhrbTlPi8$D~)evR7tef33kK%;MejXm&1$kt%v>vOt$R25Mjm`uTj zrtk%$XRTf*pze%ZDRdQ^4(mW092Xkrr|3n-mbF?!KzkoF0o%~9ih??zQQrdg?s7A> ziu^U^wNdq0*?^(5HA=S~&@I_Uu-E1q`TbBCqW>9eHx+46w?YeJ_uad!!C{JV`iwpv zw1g^4>QT`l2pY(#*vs~bI|Fmbu#MME!Ca`!##3FjFEA5yiQtN^S=K{YyS>X@T_3J? zJxkMzd7ciiSB6P5e+@MIwVVn&k**JyWYdr4-mnL1gOy@y_y@WgtG#Ju8HSzezyauM zbE|-^85*p$)V>NdHmHd@nVP5ryMuD8fK7YgrIwKB13gO9JaUp5cz1A0TqJ$Y(Y>Tz zMDCrxPPm|h!}E`Nz991olxTDOhTEm^$XWVR!tH?0=xqT}W*eK1$RI!C7Oj?@r_pYa zxq3^xG780h#kR#}J7CMXF%qW>5_^U_s&QH}?op>}_dLYN?Sr!ruT|GAE!@DSxg0zxvYD zOg;B!mCusZ47jxqM$xZ1olg2kT`}B)V{jDI+05h*F@U1sq$axM00000NkvXXu0mjf D``RiB diff --git a/V2er/Assets.xcassets/message_tab.imageset/message_tab@3x.png b/V2er/Assets.xcassets/message_tab.imageset/message_tab@3x.png deleted file mode 100644 index c954fdab07e1d8bb98f868a342b7563df0d66681..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 zcmai#YdjMQ7{<3@X4!Pa!Q@hMzx<@RBpu_pY|Wg6xh0oljJefxN+eqpxrItC&596n zZC zoxE7i!Y+X1Gmf@^%HD%}iygre6O6+F^maW20K6Fr5Z|lp3b88yK#Tzdi0u-%moY&9 zUC|7&|2%fD$j`R21^~d_7&{xc%fOE`QmMSV;*Bpkp>r@S&g9GenXFSLbyS1nBbX=Z zP5pC@4j50gJ!3>7C&kDi<}vk_ks@(j+mMhAqL8n-}m7v9_iJdlAxiMcp8WMUvC&+mb=3vops*<9#{JcE@?7Bk`Xy-fSw3~ zk0xl1;SMv5kU3j?$W*C$;R3!h6!!cenpwjpG@46Uyq$CEc0b%Nhd6Hi~4pdG7O&7HX(X5I0rcrP>BqKYZ0!7gwj@2vxvs7l;;yQSF%*+C+)<& zaeR>8&LGiW=cjtR0w#}l9Z5IjUYL-2%Q&ZO`n+%k&L7J8CXe1&@;Q}vPRQpad18I+ zXPeRiMkecMfd_+E`q84WLlaz}S)qNGUTLH(F)}`vG7~Q`C_8Bqf%@V$Sy&zb4~<2B)`z)=a|$z-w#~0k<@sL%{#UC#*CiY?3+%E;cVed*t%A z!`lWD<=e8ycUZy!2i&4fZ0%%*f1^?}<_Ek6?tl~c&UY~{$FK0?Qsyv8PJyd|ITuOxIyF!QRz)Wn`G2c=<640s{bF{sYO{DFVr?SXTbyOW)=80g+EE9*@=-K09dOYhqK(scES^>DcL<;&iW%|jJmH&Z z%-3~F8swoJGe+iDugU4<<`vy&N%&{l0Tt371D!`w6mCkQ&z!@mF!K?Vd~a7~^sXY)iDMT!CeGSbq@5H5~j*8Se67-q|Y7X=Qp==v;aa z#qk~MOD?7r_som8vJ?%N?m$>qIolgnp<5Aueu$YE^MFb6mF~9>_$Wslv*NzU@_EVd=*@eRj(ADN@pX zl&K)R9_s1yP)9kHr&mFXC`vPKzuVPkp;cv zCHCGaI=u7Q)d8-*XNpYDmCunfvO_=X8>46uVVA5FoJ{nFZn0F+orb6<=^()YFSF4L zMLi)$G5Q}S{3RgYARxlQ!&D>H86)bV(h^5#P@g0l`)7W}c{!ybk%Va{6VQ{-+> zEMEi;?~u9=5G2n#OL7ZMo_^$>QGe44UIzb}*e4n;@7JC3z5R?}csueFxmq?KL^Df@ zcO0?JZ=m!&F>&Y4f6>QlfKOH+*vA>xLaDzJ9jc+iwGhFmRGCxcj+htp%ce2^;@ 0 { + Label("通知", systemImage: "bell") + .badge(unReadNums) + } else { + Label("通知", systemImage: "bell") + } + } + .tag(TabId.message) + + // Me Tab + pageWithTopBar( + MePage(selecedTab: state.selectedTab) + ) + .tabItem { + Label("我", systemImage: "person") + } + .tag(TabId.me) } // Filter menu overlay - only render when needed @@ -48,17 +83,19 @@ struct MainPage: StateView { .zIndex(1000) } } - .safeAreaInset(edge: .top, spacing: 0) { - TopBar(selectedTab: state.selectedTab) - } - .safeAreaInset(edge: .bottom, spacing: 0) { - TabBar(unReadNums) - } - .ignoresSafeArea(.container) .navigationBarHidden(true) } } - + + @ViewBuilder + private func pageWithTopBar(_ content: Content) -> some View { + VStack(spacing: 0) { + TopBar(selectedTab: state.selectedTab) + content + } + .ignoresSafeArea(.container, edges: .top) + } + } diff --git a/V2er/View/Me/MePage.swift b/V2er/View/Me/MePage.swift index 336f01a..3668c79 100644 --- a/V2er/View/Me/MePage.swift +++ b/V2er/View/Me/MePage.swift @@ -49,7 +49,6 @@ struct MePage: BaseHomePageView { .background(Color.dim) } } - .hide(selecedTab != .me) } @ViewBuilder diff --git a/V2er/View/Message/MessagePage.swift b/V2er/View/Message/MessagePage.swift index 4a7c579..ee66cd4 100644 --- a/V2er/View/Message/MessagePage.swift +++ b/V2er/View/Message/MessagePage.swift @@ -28,7 +28,11 @@ struct MessagePage: BaseHomePageView { var body: some View { contentView .background(Color.bgColor) - .hide(!isSelected) + .onAppear { + if !state.hasLoadedOnce { + dispatch(MessageActions.FetchStart(autoLoad: true)) + } + } } @ViewBuilder diff --git a/V2er/View/Widget/TabBar.swift b/V2er/View/Widget/TabBar.swift deleted file mode 100644 index fa4d84e..0000000 --- a/V2er/View/Widget/TabBar.swift +++ /dev/null @@ -1,146 +0,0 @@ -// -// TabBar.swift -// V2er -// -// Created by Seth on 2020/5/24. -// Copyright © 2020 lessmore.io. All rights reserved. -// - -import SwiftUI - -struct TabBar: View { - @EnvironmentObject private var store: Store - var selectedTab : TabId { - store.appState.globalState.selectedTab - } - var unReadMsg: Int = 0 - var tabs: [TabItem] - - init(_ unReadMsg: Int = 0) { - self.tabs = [TabItem(id: TabId.feed, text: "最新", icon: "feed_tab"), - TabItem(id: TabId.explore, text: "发现", icon: "explore_tab"), - TabItem(id: TabId.message, text: "通知", icon: "message_tab", badge: unReadMsg), - TabItem(id: TabId.me, text: "我", icon: "me_tab")] - } - - - var body: some View { - VStack(spacing: 0) { - Divider().frame(height: 0.1) - HStack(spacing: 0) { - ForEach (self.tabs, id: \.self) { tab in - let isSelected: Bool = self.selectedTab == tab.id - Button { - dispatch(TabbarClickAction(selectedTab: tab.id)) - } label: { - VStack (spacing: 0) { - Color(self.selectedTab == tab.id ? "indictor" : "clear") - .frame(height: 3) - .cornerRadius(0) - Image(tab.icon) - .renderingMode(.template) - .resizable() - .scaledToFit() - .frame(height: 18) - .padding(.bottom, 2.5) - .padding(.top, 8) - .padding(.horizontal, 8) - .overlay { - // badge - Group { - if tab.badge > 0 { - badgeView(num: tab.badge) - } - } - } - Text(tab.text) - .font(.caption) - .fontWeight(isSelected ? .semibold : .regular) - .padding(.bottom, 8) - } - .foregroundColor(isSelected ? Color.tintColor : Color.tintColor.opacity(0.6)) - .background(self.bg(isSelected: isSelected)) - .padding(.horizontal, 16) - .background(Color.almostClear) - - } - } - } - } - .padding(.bottom, topSafeAreaInset().bottom) - .background(VEBlur()) - } - - private func badgeView(num: Int) -> some View { - HStack(alignment: .top) { - Spacer() - VStack { - Text(num.string) - .font(.system(size: 10)) - .foregroundColor(.white) - .padding(4) - .background { - Circle() - .fill(Color.red) - } - Spacer() - } - } - } - - func bg(isSelected : Bool) -> some View { - return LinearGradient( - gradient:Gradient(colors: isSelected ? - [Color.hex(0xBFBFBF, alpha: 0.2), Color.hex(0xBFBFBF, alpha: 0.1), Color.hex(0xBFBFBF, alpha: 0.05), Color.hex(0xBFBFBF, alpha: 0.01)] : []) - , startPoint: .top, endPoint: .bottom) - .padding(.top, 3) - } - -} - - - -enum TabId: String { - case none - case feed, explore, message, me -} - -class TabItem : Hashable { - let id : TabId - var text : String - var icon : String - var badge: Int = 0 - - init(id: TabId, text : String, icon : String, badge: Int = 0) { - self.id = id - self.text = text - self.icon = icon - self.badge = badge - } - - static func == (lhs: TabItem, rhs: TabItem) -> Bool { - return lhs.id == rhs.id && - lhs.badge == rhs.badge - } - - func hash(into hasher: inout Hasher) { - hasher.combine(id) - } - -} - -struct TabBar_Previews : PreviewProvider { - // @State static var selected = TabId.feed - - static var previews: some View { - VStack { - Spacer() - TabBar() - .background(VEBlur()) - } - .edgesIgnoringSafeArea(.bottom) - .environmentObject(Store.shared) - } - -} - From 07dd8e521ce628ee153baabcc0ca7a28f3b4341a Mon Sep 17 00:00:00 2001 From: Gray Zhang Date: Fri, 17 Oct 2025 19:12:35 +0800 Subject: [PATCH 2/3] fix: remove TabBar.swift references from Xcode project MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove all references to the deleted TabBar.swift file from the Xcode project.pbxproj file to fix build failure. - Remove PBXBuildFile reference - Remove PBXFileReference - Remove from Widget group children - Remove from PBXSourcesBuildPhase Fixes CI build error: "Build input file cannot be found: TabBar.swift" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- V2er.xcodeproj/project.pbxproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/V2er.xcodeproj/project.pbxproj b/V2er.xcodeproj/project.pbxproj index 07f9f2f..d3fe54f 100644 --- a/V2er.xcodeproj/project.pbxproj +++ b/V2er.xcodeproj/project.pbxproj @@ -13,7 +13,6 @@ 4EC32AF229D818FC003A3BD4 /* WebBrowserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EC32AF129D818FC003A3BD4 /* WebBrowserView.swift */; }; 5D02BD5F26909146007B6A1B /* LoadmoreIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D02BD5E26909146007B6A1B /* LoadmoreIndicatorView.swift */; }; 5D04BF9726C9FB6E0005F7E3 /* FeedInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D04BF9626C9FB6E0005F7E3 /* FeedInfo.swift */; }; - 5D096A08247ABF5E00EF3E47 /* TabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D096A07247ABF5E00EF3E47 /* TabBar.swift */; }; 5D0A513726E0CBFC006F3D9B /* ExploreActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D0A513626E0CBFC006F3D9B /* ExploreActions.swift */; }; 5D0A513926E26473006F3D9B /* FeedDetailReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D0A513826E26473006F3D9B /* FeedDetailReducer.swift */; }; 5D0A513B26E26505006F3D9B /* FeedDetailInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D0A513A26E26505006F3D9B /* FeedDetailInfo.swift */; }; @@ -173,7 +172,6 @@ 4EC32AF129D818FC003A3BD4 /* WebBrowserView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebBrowserView.swift; sourceTree = ""; }; 5D02BD5E26909146007B6A1B /* LoadmoreIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadmoreIndicatorView.swift; sourceTree = ""; }; 5D04BF9626C9FB6E0005F7E3 /* FeedInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedInfo.swift; sourceTree = ""; }; - 5D096A07247ABF5E00EF3E47 /* TabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBar.swift; sourceTree = ""; }; 5D0A513626E0CBFC006F3D9B /* ExploreActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreActions.swift; sourceTree = ""; }; 5D0A513826E26473006F3D9B /* FeedDetailReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedDetailReducer.swift; sourceTree = ""; }; 5D0A513A26E26505006F3D9B /* FeedDetailInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedDetailInfo.swift; sourceTree = ""; }; @@ -350,7 +348,6 @@ children = ( 5D73FBD827284ACA004558E9 /* RichText */, 5DE5B4CB268466AF00569684 /* Updatable */, - 5D096A07247ABF5E00EF3E47 /* TabBar.swift */, 5D1F4264249713640043F604 /* VEBlur.swift */, 5DE5B4C92684601A00569684 /* TopBar.swift */, 5D4E43FB2699E20400650714 /* AvatarView.swift */, @@ -985,7 +982,6 @@ 5D1D7B8726FC9B61008E0C08 /* LoginReducer.swift in Sources */, 5DA2AD4826C18232007FB1EF /* MessageState.swift in Sources */, 5D0CFA8226B9935B001A8A7F /* UserFeedPage.swift in Sources */, - 5D096A08247ABF5E00EF3E47 /* TabBar.swift in Sources */, 5D91F8D926F22CEC0089D72E /* TagDetailReducer.swift in Sources */, 5D45FC2B26CD3FCF0055C336 /* SwiftSoupExtention.swift in Sources */, ); From 4f27f8e8c19799a84fb37475a2dacfd768ff6103 Mon Sep 17 00:00:00 2001 From: Gray Zhang Date: Fri, 17 Oct 2025 19:15:07 +0800 Subject: [PATCH 3/3] fix: restore TabId enum definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restore the TabId enum definition that was removed with TabBar.swift. The enum is now defined in GlobalState.swift where it's primarily used. Fixes build errors: "cannot find type 'TabId' in scope" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- V2er/State/DataFlow/State/GlobalState.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/V2er/State/DataFlow/State/GlobalState.swift b/V2er/State/DataFlow/State/GlobalState.swift index 05924c2..95901a1 100644 --- a/V2er/State/DataFlow/State/GlobalState.swift +++ b/V2er/State/DataFlow/State/GlobalState.swift @@ -9,6 +9,11 @@ import Foundation import SwiftUI +enum TabId: String { + case none + case feed, explore, message, me +} + struct GlobalState: FluxState { var selectedTab: TabId = .feed var lastSelectedTab: TabId = .none @@ -18,7 +23,7 @@ struct GlobalState: FluxState { static var account: AccountInfo? { AccountState.getAccount() } - + static var hasSignIn: Bool { AccountState.hasSignIn() }