From 07c18e7cef977f0fba1d4070bb257b64e827b7c0 Mon Sep 17 00:00:00 2001 From: Nicholas Entin Date: Wed, 24 May 2023 18:05:18 -0700 Subject: [PATCH 1/2] Add snapshots for horizontal distribution --- .../ViewDistributionSnapshotTests.swift | 75 ++++++++++++++++++ ...owsLayoutDirection.LTR_375x812-13-7-3x.png | Bin 0 -> 4685 bytes ...owsLayoutDirection.LTR_390x844-14-4-3x.png | Bin 0 -> 4685 bytes ...owsLayoutDirection.RTL_375x812-13-7-3x.png | Bin 0 -> 3436 bytes ...owsLayoutDirection.RTL_390x844-14-4-3x.png | Bin 0 -> 3436 bytes 5 files changed, 75 insertions(+) create mode 100644 Example/ParalayoutSnapshotTests/__Snapshots__/ViewDistributionSnapshotTests/testHorizontalDistributionFollowsLayoutDirection.LTR_375x812-13-7-3x.png create mode 100644 Example/ParalayoutSnapshotTests/__Snapshots__/ViewDistributionSnapshotTests/testHorizontalDistributionFollowsLayoutDirection.LTR_390x844-14-4-3x.png create mode 100644 Example/ParalayoutSnapshotTests/__Snapshots__/ViewDistributionSnapshotTests/testHorizontalDistributionFollowsLayoutDirection.RTL_375x812-13-7-3x.png create mode 100644 Example/ParalayoutSnapshotTests/__Snapshots__/ViewDistributionSnapshotTests/testHorizontalDistributionFollowsLayoutDirection.RTL_390x844-14-4-3x.png diff --git a/Example/ParalayoutSnapshotTests/ViewDistributionSnapshotTests.swift b/Example/ParalayoutSnapshotTests/ViewDistributionSnapshotTests.swift index 2f9ca51..7a63b0e 100644 --- a/Example/ParalayoutSnapshotTests/ViewDistributionSnapshotTests.swift +++ b/Example/ParalayoutSnapshotTests/ViewDistributionSnapshotTests.swift @@ -104,6 +104,21 @@ final class ViewDistributionSnapshotTests: SnapshotTestCase { assertSnapshot(matching: containerView, as: .image, named: nameForSnapshot(with: [])) } + func testHorizontalDistributionFollowsLayoutDirection() { + let view = HorizontalDistributionView(frame: CGRect(x: 0, y: 0, width: 160, height: 60)) + + assertSnapshot( + matching: view, + as: .image, + named: nameForSnapshot(with: ["LTR"]) + ) + assertSnapshot( + matching: view, + as: .image(traits: .init(layoutDirection: .rightToLeft)), + named: nameForSnapshot(with: ["RTL"]) + ) + } + } // MARK: - @@ -137,3 +152,63 @@ extension UIUserInterfaceLayoutDirection { } } + +// MARK: - + +final class HorizontalDistributionView: UIView { + + // MARK: - Life Cycle + + override init(frame: CGRect) { + super.init(frame: frame) + + firstView.bounds.size = .init(width: 40, height: 40) + firstView.backgroundColor = .red + addSubview(firstView) + + secondView.bounds.size = .init(width: 40, height: 40) + secondView.backgroundColor = .green + addSubview(secondView) + + thirdView.bounds.size = .init(width: 40, height: 40) + thirdView.backgroundColor = .blue + addSubview(thirdView) + + // Set arbitrary semantic content attributes to ensure the layout relies on the _receiver's_ effective layout + // direction, not that of the distributed views. + firstView.semanticContentAttribute = .forceLeftToRight + secondView.semanticContentAttribute = .forceRightToLeft + + backgroundColor = .white + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - Private Properties + + private let firstView: UIView = .init() + + private let secondView: UIView = .init() + + private let thirdView: UIView = .init() + + // MARK: - UIView + + override func layoutSubviews() { + applyHorizontalSubviewDistribution( + [ + 1.flexible, + firstView, + 1.flexible, + secondView, + 1.flexible, + thirdView, + 1.flexible, + ] + ) + } + +} diff --git a/Example/ParalayoutSnapshotTests/__Snapshots__/ViewDistributionSnapshotTests/testHorizontalDistributionFollowsLayoutDirection.LTR_375x812-13-7-3x.png b/Example/ParalayoutSnapshotTests/__Snapshots__/ViewDistributionSnapshotTests/testHorizontalDistributionFollowsLayoutDirection.LTR_375x812-13-7-3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9ed104544a69b7a2e2d907e4f92e4ef02aaa9152 GIT binary patch literal 4685 zcmeHL30D(Y7OqMn1O!1q8)Zu)LeOaiWKl#27?F&Gu-T%Z#tn_gW{|~ZNl>)GRs>v- zEkRMxQKUyuK$di?osl+xpaD?`Z4U%NK#UL&Azi5oGw&zNoMWBya;xgyTi^Y@ck8}7 zN%!^HtgX3J6M`UZnitg{g5X}{yppJf{Cd|Z1c-sz{+m6Z@@C_A$VL2tAX+G$4y{1W zi4Xx^3e8ixAj1_l`p>y1Oos62eH;XxWkB^)4hI{$= zxpSye8K!L@)JBX(l-G7P1bw?!Ip9r~Y?;VSV-}SWh*$&=J$4|!WMn8UGKlwG>}d!`Byk{I zichb!g*U)OFNmZMD>*deE^;MM!{OrbF_}~dCg@Tq5F51+SDQfipf+HdjyiFme${h~ zh{Rs))(v_}X9$L$VV2;it1B?#|6qZE;d1d9&Jhxc<3y2rq0R(?jk+?3pxcSyL~=&5 zFef5&figoPse;RadZ6xQ3sEOsfiY?+Ogs$N!L^&sQ6~~--TzAB@8|dO6qyr>8ZF0R zam!tWrG970#cPKrqw7Wg*r^k0f6ZuwzQF9>lsq-%Ud*hhZS9%tqMt%Pk*}q_ID&gx zEG~=ojyabeQ0-ViJFeLqpp`penx2%F_iAikZK|E$@2nwKku=Rbo9}DExiV=Vy(lyF zHf_s7hkVLg%C*p!I|ka9pfN>K_PD`A^nTKIr~8$%>kcWqW!53) z8k(DM@fq%=BERzvEbFVG`d-F|UKHHl)pKw-jsJ&tTL82s;m%X179h0mPL-rN`se&G z3-@9#Xms{t0B<)C?7cI9z4M!lQ)_4p_?e*jqT|nZeb=l{_TJ`edH7xKfU$mQ)L9F% zfdr7W{xttPYP@Er;04kuWkLhMwwsN=<9o=>N;QFqp!UV*^fTyK#)RFA8P*` z`5LKKevJ%Y{-xY#ofct6;Wlhx({Cd%Zp+oPa2)(@aYJim(2AQETjDw-QrXPsl+`Eb zyOJ7aJG_}W-|yPm*D>yRH+H7NGwhS5Jnxb4)ojrfddh5Yv0S35n27C=H1NcS&hBE? zfBTZo_-EPLoB@h8pw`?|;ejJaUNG8+u)JSaLQyA(Ev z-x>)ucCTwxBwi(NeB|mG=*0C^zx`(4Y~r)vYUb6GXSI44pYX|FW{|aF^qg7gH5b}+ zL2O-!&NRtOiOZyi(i`IaPn}BosVo9lydY@mdKE9M{7iRp!jNNcsqJ0NN$M#$f+>^MG1 zf7H_71<1F+dGW+{c6VK0M!KG(9Y-=!AW3ocEB-MsA@0jslRjFP5F=FL>N~C$bq4u5 za9^@?!uD#d#z|*pU#ZFJjz_LUl~(sGce`v{c=O}PWVCZrPG!p+p#UXvyuA6rtShLq zX@KPuUTbly;o}MF=_nGq2 zNDvvw|E__KRy?|HBbKT5ji&y26_bkI#KjF9c6E~GKJ^WMnj?8FtRT09p z%GsW?y68gj9(!8O)PTNrAx*w#$DQ>{(R$_#(SbT>I%Ni()u)QLO zXiY3KF#`@C0#PwS886gt^+4js57P~FfP72Or6q|&oFZ%XqBZqky;RO)1d`3S_L#W& zY);6Y7{dtN)CsJI-|TH=v3-G}VhMjAuh79^T0On}^qUr-rr0V%9Vl{7z3fgS16bWV z!WT8kb2@XwiYft_g%}|$()9`F{xJYG;q_Qd(ew$N{_-RHp|H2z)QrtQzQuEdZYXQ& z!|OuXbcSzFl2kITr#I~Z=O{+AoCbT2#aLc^21F4)Sg(E zLg_4DK-Dl>BFKw(%6hvH=#OP{gwUG$5-a^OD@(r$^qb5nnQi1Bsc6dx)^ZL%2No4Z zh=gf%#bN3#4XCNh;^gw0Rk7?RDDuO&hH*L2G8h;kmCjM3oJ)Yr^;p-&B1;Wh?}MoA z7$H?_t;_cs;{*B5b?udCO(j2MCo86?X+Xch2xX%!<2$uNM{q;nVO?9L)w8_BF)g5` z<_KY%N%wlm=V?%9tZQSjORM{7Mu5z~HYA^C75rO z;?zET*${(M&gdC>2_VyI)~fBu42RIKZ^My}7V9f#&I>4rqkztSs+_T~;c;M>6rDol z42PhmXTwpC$lG!WnIUnf2wJ^UKMW8s$Mc9|RC~xjkr`OynH3Xik!-Y5K7z#MB97er z{_N$-yqK;qK7Q8JnTtAVSui1;H};qRhGr~7GM33(HBbUf65`l#vaV|pu6*Zpr d`TwQ%1>RQmTbBCjm|^9AEwoKO)N&7I>R;(M7C!(0 literal 0 HcmV?d00001 diff --git a/Example/ParalayoutSnapshotTests/__Snapshots__/ViewDistributionSnapshotTests/testHorizontalDistributionFollowsLayoutDirection.LTR_390x844-14-4-3x.png b/Example/ParalayoutSnapshotTests/__Snapshots__/ViewDistributionSnapshotTests/testHorizontalDistributionFollowsLayoutDirection.LTR_390x844-14-4-3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9ed104544a69b7a2e2d907e4f92e4ef02aaa9152 GIT binary patch literal 4685 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 literal 0 HcmV?d00001 diff --git a/Example/ParalayoutSnapshotTests/__Snapshots__/ViewDistributionSnapshotTests/testHorizontalDistributionFollowsLayoutDirection.RTL_375x812-13-7-3x.png b/Example/ParalayoutSnapshotTests/__Snapshots__/ViewDistributionSnapshotTests/testHorizontalDistributionFollowsLayoutDirection.RTL_375x812-13-7-3x.png new file mode 100644 index 0000000000000000000000000000000000000000..bd9c577d82ad84138e3c23d7695f0cf2cece2496 GIT binary patch literal 3436 zcmeAS@N?(olHy`uVBq!ia0y~yV0-{%Z{c7Al0JL>9{^H}#X;^)4C~IxyaaM8QX@Rm ze0>?TfNTy17Dg!sR*(`Pwqulrv)vdq7?{E0ObiU|nG7sYHGV)E1a1H^NDqW&Ucd-d z4HR3z1XIoUU;#6X&9DWejaTG2FOcFa@Q5sCU{JIGVMfTi$YfLUba4!+V0?2u(Jv%WgyrGQ|I0423OFg`Yt{ZR`4>2ouk@DQ z``3s0Sp*yy7+C}=tQ)W27G_myU|`}2SIRF(fzfckc8>o;V3#J_u6dVpPmP`a2#v!nQ4`e8Zf`EX+1BP85 z5ZgH-*deaq;1DQah*g2u%(8|VqKSot!=gb?2;>3=My6{JnuUppMaDtA6YO3F#@7&f zV4d49Q1Lf^T70>rP0+0TnisDRpFhpAFR(HFpO;A(%bzor|Nks^t5y4J{`dHDtskjB zf82ADb!`@{JATzZap!vlfv+F(J z5AMG^*T3IRN{8v+$D=h5!&w&D2^%m9e=ulVZ}#+}eK%WogZ$oC_y2xaah}EJz~NsX zna+tB167~XtFyLvWy}av%rAT*%n(`V!-l#&4Vy!IfO}orda;QKyZD8Z`Nh zrZsxx(0{;6=>LDaY;hxCZD9_oE#6*t>Vn`oPPVe49w|aU`&6(stjs*?(u18h|jyf9n47qwk)0XB|t68 z2dPXfe~NzZlLc`UlpPL8RviR4KlOzb9!$Ue{VkXy$;fo>0=FBu#XOUNasQot`R*Xj z31GvuEzSVkc0SF*@#E>YT5Ax;!L6ae_)8PGNgSu9{^H}#X;^)4C~IxyaaM8QX@Rm ze0>?TfNTy17Dg!sR*(`Pwqulrv)vdq7?{E0ObiU|nG7sYHGV)E1a1H^NDqW&Ucd-d z4HR3z1XIoUU;#6X&9DWejaTG2FOcFa@Q5sCU{JIGVMfTi$YfLUba4!+V0?2u(Jv%WgyrGQ|I0423OFg`Yt{ZR`4>2ouk@DQ z``3s0Sp*yy7+C}=tQ)W27G_myU|`}2SIRF(fzfckc8>o;V3#J_u6dVpPmP`a2#v!nQ4`e8Zf`EX+1BP85 z5ZgH-*deaq;1DQah*g2u%(8|VqKSot!=gb?2;>3=My6{JnuUppMaDtA6YO3F#@7&f zV4d49Q1Lf^T70>rP0+0TnisDRpFhpAFR(HFpO;A(%bzor|Nks^t5y4J{`dHDtskjB zf82ADb!`@{JATzZap!vlfv+F(J z5AMG^*T3IRN{8v+$D=h5!&w&D2^%m9e=ulVZ}#+}eK%WogZ$oC_y2xaah}EJz~NsX zna+tB167~XtFyLvWy}av%rAT*%n(`V!-l#&4Vy!IfO}orda;QKyZD8Z`Nh zrZsxx(0{;6=>LDaY;hxCZD9_oE#6*t>Vn`oPPVe49w|aU`&6(stjs*?(u18h|jyf9n47qwk)0XB|t68 z2dPXfe~NzZlLc`UlpPL8RviR4KlOzb9!$Ue{VkXy$;fo>0=FBu#XOUNasQot`R*Xj z31GvuEzSVkc0SF*@#E>YT5Ax;!L6ae_)8PGNgSu Date: Wed, 24 May 2023 18:07:11 -0700 Subject: [PATCH 2/2] Fix horizontal distribution in RTL layout --- ...owsLayoutDirection.RTL_375x812-13-7-3x.png | Bin 3436 -> 3991 bytes ...owsLayoutDirection.RTL_390x844-14-4-3x.png | Bin 3436 -> 3991 bytes Paralayout/UIView+Distribution.swift | 20 +++++++++++------- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Example/ParalayoutSnapshotTests/__Snapshots__/ViewDistributionSnapshotTests/testHorizontalDistributionFollowsLayoutDirection.RTL_375x812-13-7-3x.png b/Example/ParalayoutSnapshotTests/__Snapshots__/ViewDistributionSnapshotTests/testHorizontalDistributionFollowsLayoutDirection.RTL_375x812-13-7-3x.png index bd9c577d82ad84138e3c23d7695f0cf2cece2496..4dba401ca7d4ebf9c6a563f9f37157920dc85c8f 100644 GIT binary patch literal 3991 zcmeHKc~BEq9DbV(M`%C>1p$?UMNkj~50Ik}0|=-bMHHeHBM8)@h#&%T804_hDkui1 z%4HRG8WBZC_PzbR-*3NfzxVC# zyrZ7(&dN&KN&o<5R~JVw01z=8-%yl?=M9xo9_)|^FK0R^Zk+!bUPK4_x(2zq0V6n8 z1Y|@T$YCk4*&*}(9Ir(d0~C*w064M>kYzdUu*Z%kuwgYsj}{=ZY#1vbO=TnE0(5E& zZeV4~bM7m{juPg=hyXxuHP#TPEORCd&fn$e;SGBTh#ycCKHtB%PKUP3$SE32gp=2(CM*`D5sXF zV99U}kmNO4{f3K(a(Q0`9GFG|2uh_%GI1!G#)@7 zO`a!s^FWV`G0MDlbY$O$=!drQBQ2lV3fQ9{ZqsNFwqJ z6V2P`=al+lOLCR~JsQYT4%>N?W;ah9PCDgtLXV*$EUR$v*J7gc+e|V9U86Cgq*(5f zs|y{%P3ZOAiTJ&)Z`I9L4zoh|KR?J=sxa`hQ|}tJ1UcTT0TCv8tDTRVe_h>@u5gfFVzMD~g#Z+W8PS&FjZ?apA=S)S^oA=Ax=;$;g-6^gOOgcSEL*h z_%!=*Hjy-WtK{M>Xg3Fn&jsmdZ>(u5(J?yJtwS1ocIevr;bYzW!AK90O7rXSL)$Lc zT6w*hbuvc6lkT*te6tUrw_a>-_1jb+I38gQ?=aAIFuLuXZU?%LC_4baKt{dBCaOOO~gEBW%-?S5wI%8KxA(NufmsJc>N z4CjivE&K4@%2@HT#XmZylFe8MRcubNZE9YZhdk3!+-Q|Or$LegpB(7a2pBip*qw2r zrnEelyG-GigLBypQ8n0{{9q3GPRKWbA_byGy|ER=;cEo^+_#*lJE6fTA~&KYtI@{+ zo5O3q4Z0vgi5d+-cap4zz!CD(xS0eu(|kdyf{a^S%L6`FrTR?L(^w<+2uz#j4?gj#%|rR9rv9-TI{H z>UmslOZKn%kAaNb$KA~KgjqO{aI*{7gZznbqgC;HCblWbzw1vt6tHB{S{>>J*TPlY z`m$^|f&gmqAG6ZJ^_(~xd1hN%gP^5sv~&*jWhW|q89rvdV5-LX`O}ZaiV|85KPGm~ zq`e+d!|Bix95ie;6x11}_+5-~NSU&M;;<`-s=n@TQdmtQp1m}*)VP8I!#)MAyB>P( zz`TUXOOIFM<(6=K*Iz0jtPLC<$jZYZ6 zVPR60dqAqvXEG&K-(-UR|k8WBE*2+#eFy(aKaQA zC%J>UbyQpsY-x3y4UrB?eOg&EF2mXJG42nRh6mgB0{79?`PrK%nJx+%e_Ne+K`n zHEV%NU+WEG7m=tz0k>++eUtI+LPr*0?X}rA&c^l(GgJSn8a#WSvbqx|jk2+AG;not KcPyqe5B~xFdQi;( literal 3436 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 KcPyqe5B~xFdQi;( literal 3436 zcmeAS@N?(olHy`uVBq!ia0y~yV0-{%Z{c7Al0JL>9{^H}#X;^)4C~IxyaaM8QX@Rm ze0>?TfNTy17Dg!sR*(`Pwqulrv)vdq7?{E0ObiU|nG7sYHGV)E1a1H^NDqW&Ucd-d z4HR3z1XIoUU;#6X&9DWejaTG2FOcFa@Q5sCU{JIGVMfTi$YfLUba4!+V0?2u(Jv%WgyrGQ|I0423OFg`Yt{ZR`4>2ouk@DQ z``3s0Sp*yy7+C}=tQ)W27G_myU|`}2SIRF(fzfckc8>o;V3#J_u6dVpPmP`a2#v!nQ4`e8Zf`EX+1BP85 z5ZgH-*deaq;1DQah*g2u%(8|VqKSot!=gb?2;>3=My6{JnuUppMaDtA6YO3F#@7&f zV4d49Q1Lf^T70>rP0+0TnisDRpFhpAFR(HFpO;A(%bzor|Nks^t5y4J{`dHDtskjB zf82ADb!`@{JATzZap!vlfv+F(J z5AMG^*T3IRN{8v+$D=h5!&w&D2^%m9e=ulVZ}#+}eK%WogZ$oC_y2xaah}EJz~NsX zna+tB167~XtFyLvWy}av%rAT*%n(`V!-l#&4Vy!IfO}orda;QKyZD8Z`Nh zrZsxx(0{;6=>LDaY;hxCZD9_oE#6*t>Vn`oPPVe49w|aU`&6(stjs*?(u18h|jyf9n47qwk)0XB|t68 z2dPXfe~NzZlLc`UlpPL8RviR4KlOzb9!$Ue{VkXy$;fo>0=FBu#XOUNasQot`R*Xj z31GvuEzSVkc0SF*@#E>YT5Ax;!L6ae_)8PGNgSu