From 595dbe57fe62dea54ecf4a8f3fbd225972f55c5a Mon Sep 17 00:00:00 2001 From: Oliver Wiese <oliver.wiese@fu-berlin.de> Date: Sun, 20 Jan 2019 09:20:22 +0100 Subject: [PATCH] add show password button --- enzevalos_iphone.xcodeproj/project.pbxproj | 12 +- .../passwordInput/Contents.json | 6 + .../ic_eye_closed.imageset/Contents.json | 23 +++ .../ic_eye_closed.imageset/ic_eye_closed.png | Bin 0 -> 527 bytes .../ic_eye_closed@2x.png | Bin 0 -> 1004 bytes .../ic_eye_closed@3x.png | Bin 0 -> 1529 bytes .../ic_eye_open.imageset/Contents.json | 23 +++ .../ic_eye_open.imageset/ic_eye_open.png | Bin 0 -> 489 bytes .../ic_eye_open.imageset/ic_eye_open@2x.png | Bin 0 -> 1004 bytes .../ic_eye_open.imageset/ic_eye_open@3x.png | Bin 0 -> 1481 bytes .../Contents.json | 23 +++ .../ic_password_checkmark.png | Bin 0 -> 449 bytes .../ic_password_checkmark@2x.png | Bin 0 -> 987 bytes .../ic_password_checkmark@3x.png | Bin 0 -> 1459 bytes .../HideShowPasswordTextField.swift | 135 ++++++++++++++++++ enzevalos_iphone/Onboarding.swift | 53 ++++++- .../PasswordToggleVisibilityView.swift | 100 +++++++++++++ 17 files changed, 368 insertions(+), 7 deletions(-) create mode 100644 enzevalos_iphone/Assets.xcassets/passwordInput/Contents.json create mode 100644 enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_closed.imageset/Contents.json create mode 100644 enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_closed.imageset/ic_eye_closed.png create mode 100644 enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_closed.imageset/ic_eye_closed@2x.png create mode 100644 enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_closed.imageset/ic_eye_closed@3x.png create mode 100644 enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_open.imageset/Contents.json create mode 100644 enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_open.imageset/ic_eye_open.png create mode 100644 enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_open.imageset/ic_eye_open@2x.png create mode 100644 enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_open.imageset/ic_eye_open@3x.png create mode 100644 enzevalos_iphone/Assets.xcassets/passwordInput/ic_password_checkmark.imageset/Contents.json create mode 100644 enzevalos_iphone/Assets.xcassets/passwordInput/ic_password_checkmark.imageset/ic_password_checkmark.png create mode 100644 enzevalos_iphone/Assets.xcassets/passwordInput/ic_password_checkmark.imageset/ic_password_checkmark@2x.png create mode 100644 enzevalos_iphone/Assets.xcassets/passwordInput/ic_password_checkmark.imageset/ic_password_checkmark@3x.png create mode 100644 enzevalos_iphone/HideShowPasswordTextField.swift create mode 100644 enzevalos_iphone/PasswordToggleVisibilityView.swift diff --git a/enzevalos_iphone.xcodeproj/project.pbxproj b/enzevalos_iphone.xcodeproj/project.pbxproj index 4c744e87..bd068601 100644 --- a/enzevalos_iphone.xcodeproj/project.pbxproj +++ b/enzevalos_iphone.xcodeproj/project.pbxproj @@ -161,6 +161,8 @@ 479B597B20691C1A00B3944D /* ObjectivePGP.framework in Resources */ = {isa = PBXBuildFile; fileRef = 47CEF4EA2052C3C700887CDB /* ObjectivePGP.framework */; }; 479C649621F2139B00A01071 /* support_pk.asc in Resources */ = {isa = PBXBuildFile; fileRef = 479C649521F2139B00A01071 /* support_pk.asc */; }; 479C649721F2139B00A01071 /* support_pk.asc in Resources */ = {isa = PBXBuildFile; fileRef = 479C649521F2139B00A01071 /* support_pk.asc */; }; + 479C649A21F45DAF00A01071 /* HideShowPasswordTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 479C649821F45DAF00A01071 /* HideShowPasswordTextField.swift */; }; + 479C649B21F45DAF00A01071 /* PasswordToggleVisibilityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 479C649921F45DAF00A01071 /* PasswordToggleVisibilityView.swift */; }; 47A7975B1FCD56B7006B3BC4 /* enzevalos_iphone.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = A135267F1D955BDF00D3BFE1 /* enzevalos_iphone.xcdatamodeld */; }; 47C22281218AFD6300BD2C2B /* AutocryptTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47C22280218AFD6300BD2C2B /* AutocryptTest.swift */; }; 47C22283218B02C700BD2C2B /* autocryptSimpleExample1.eml in Resources */ = {isa = PBXBuildFile; fileRef = 47C22282218B02C700BD2C2B /* autocryptSimpleExample1.eml */; }; @@ -243,7 +245,7 @@ F12041FD1DA409A5002E4940 /* ListViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F12041FC1DA409A5002E4940 /* ListViewCell.swift */; }; F12060801DA540FE00F6EF37 /* RefreshControlExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F120607F1DA540FE00F6EF37 /* RefreshControlExtension.swift */; }; F12060821DA552FC00F6EF37 /* MailHandlerDelegator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F12060811DA552FC00F6EF37 /* MailHandlerDelegator.swift */; }; - F120A7D31F7937BB006D5BF1 /* (null) in Frameworks */ = {isa = PBXBuildFile; }; + F120A7D31F7937BB006D5BF1 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; }; F12D8DBB2069422A0068788E /* About.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F12D8DBD2069422A0068788E /* About.storyboard */; }; F14239C11F30A99C00998A83 /* QRCodeGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F14239C01F30A99C00998A83 /* QRCodeGenerator.swift */; }; F1737ACB2031D7D70000312B /* StudySettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = A17FDFF2202C685800F7BA89 /* StudySettings.swift */; }; @@ -349,6 +351,8 @@ 47953AA81FD7000200D4631A /* bitcoinde.asc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = bitcoinde.asc; sourceTree = "<group>"; }; 479B5976206914BE00B3944D /* CryptoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoTests.swift; sourceTree = "<group>"; }; 479C649521F2139B00A01071 /* support_pk.asc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = support_pk.asc; sourceTree = "<group>"; }; + 479C649821F45DAF00A01071 /* HideShowPasswordTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HideShowPasswordTextField.swift; sourceTree = "<group>"; }; + 479C649921F45DAF00A01071 /* PasswordToggleVisibilityView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordToggleVisibilityView.swift; sourceTree = "<group>"; }; 47B2318A1F0D458100961B28 /* enzevalos_iphone 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "enzevalos_iphone 2.xcdatamodel"; sourceTree = "<group>"; }; 47C22280218AFD6300BD2C2B /* AutocryptTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutocryptTest.swift; sourceTree = "<group>"; }; 47C22282218B02C700BD2C2B /* autocryptSimpleExample1.eml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = autocryptSimpleExample1.eml; sourceTree = "<group>"; }; @@ -493,7 +497,7 @@ 47F867E42052B49800AA832F /* libbz2.tbd in Frameworks */, 47F867E22052B48E00AA832F /* libz.tbd in Frameworks */, 47F867E02052B47C00AA832F /* Security.framework in Frameworks */, - F120A7D31F7937BB006D5BF1 /* (null) in Frameworks */, + F120A7D31F7937BB006D5BF1 /* BuildFile in Frameworks */, 472F396E1E14F384009260FB /* CoreData.framework in Frameworks */, 9935BC866A86C4A4B9819F35 /* Pods_enzevalos_iphone.framework in Frameworks */, ); @@ -839,6 +843,8 @@ A18C76851E8185ED00B21414 /* onboarding */ = { isa = PBXGroup; children = ( + 479C649821F45DAF00A01071 /* HideShowPasswordTextField.swift */, + 479C649921F45DAF00A01071 /* PasswordToggleVisibilityView.swift */, A1083A531E8BFEA6003666B7 /* Onboarding.swift */, A102AA891EDDB4E80024B457 /* videoOnboarding2.m4v */, A1C62E992018F716000E5273 /* OnboardingValueState.swift */, @@ -1467,6 +1473,7 @@ A1EB05821D95685B008659C1 /* CollectionDataDelegate.swift in Sources */, 47D1302B1F7CEE6D007B14DF /* DebugSettings.swift in Sources */, A1EB05801D956851008659C1 /* SendViewController.swift in Sources */, + 479C649B21F45DAF00A01071 /* PasswordToggleVisibilityView.swift in Sources */, 47691A8C1ECC3EC7004BCFC5 /* EphemeralMail.swift in Sources */, 8428A8671F436A11007649A5 /* SubBadgeHeaderTableViewCell.swift in Sources */, A1EB05981D956947008659C1 /* InboxViewController.swift in Sources */, @@ -1499,6 +1506,7 @@ A12FC23120221A1400196008 /* ExportInfoViewController.swift in Sources */, 475DF47A1F0D54C9009D807F /* Folder+CoreDataProperties.swift in Sources */, 475B00431F7BB6D6006CDD41 /* PersistentKey+CoreDataProperties.swift in Sources */, + 479C649A21F45DAF00A01071 /* HideShowPasswordTextField.swift in Sources */, F119D2901E364B59001D732A /* AnimatedSendIcon.swift in Sources */, 4707096D1F8F9F4900657F41 /* ExportViewController.swift in Sources */, F12060801DA540FE00F6EF37 /* RefreshControlExtension.swift in Sources */, diff --git a/enzevalos_iphone/Assets.xcassets/passwordInput/Contents.json b/enzevalos_iphone/Assets.xcassets/passwordInput/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/enzevalos_iphone/Assets.xcassets/passwordInput/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_closed.imageset/Contents.json b/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_closed.imageset/Contents.json new file mode 100644 index 00000000..1bb26ac5 --- /dev/null +++ b/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_closed.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ic_eye_closed.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "ic_eye_closed@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_eye_closed@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_closed.imageset/ic_eye_closed.png b/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_closed.imageset/ic_eye_closed.png new file mode 100644 index 0000000000000000000000000000000000000000..10a89456c953256b948001ad9009ea4de285a457 GIT binary patch literal 527 zcmeAS@N?(olHy`uVBq!ia0y~yU=RecIoKE&82l?+r5G3(7>k44ofy`glX=O&z<AQr z#W6%fbZ+ooZ{<RPxj%E6+&rcfbhOT%kfRjE$(~-Bkh;)OP-M1ti?fS>qfSq+nH>9} z#JBPZiZPkRXBW0ky}_BZuZK}k`(ebBJ8$}oU#ZN_=9`n0UY2(6wz;v+0qZp(dvC6} z@@h3#Z^nXo9UEe@MHn)~IPIB(nu6t&=D6ubRevg+mmSY@<d{gaRLA-->BV*z>;!sS zJ_{*7GG{7iWmvpy!sfS|zDe+&x;pzS!;28k8Glc>d<^!t5$m7vqM-Xg#OVjD>Px-$ zuDBtt`qV4AUm@eH28*S-?MmNG%z+7vdY{_)Iv4!knzrw`?Cy>=3GLqx_~r_;`e~J_ zNvd`v<gDSWZ&%=`+iqRy!|ct*@$8Ui=i}Je>5mSx%=Eb*Yjm+z?<b$~4I`0-nfLxU z?|885Y-2s=l7A0&H9xeAGgF)?I@y1@KF<RY@&6vpF$+D<O5SYjQQ#8skju^1nP=J6 zm;66x?v9e$--0#yF%c!5c8gS%JD3z7aQp6QGEC^|jk$KOwsLy=tiFb#V+ZUr;vKCe zxNaD5#BaWNMgMG+ltyEZ!!&k*1xFXz8T3TlRc`L@Jt*&YEY3r%dcDZ?hfm{ITzz-{ g-TlB{?@t?FIlL>d;f;ML0|Nttr>mdKI;Vst0PI}d(*OVf literal 0 HcmV?d00001 diff --git a/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_closed.imageset/ic_eye_closed@2x.png b/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_closed.imageset/ic_eye_closed@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f8feed2ee39a7433e44e39b55189429d00f50c3c GIT binary patch literal 1004 zcmeAS@N?(olHy`uVBq!ia0y~yU{GRUV36WqV_;yol-I|^z`(#*9OUlAu<o49O9lq! zWu7jMAs)PY!+kS^9YyAud#=vp4dYTWojv1j$Gjy?4{q9vupDf*XP<cMk>|%J{6DxC zvDZ8FYlR(cZc=EH`+IP6)ra>AJ9cmM)N&PZxtw(Qjotm|xg~dfE`_XNet33I<@?$B z_o|II3qG<pyR9p?;qJoCyHp*Q&*7Av?C|A0Qv-kD#!Fty<6EwGwzIGO@;1qkT{NcM zX^rcFr%nfI8YRRT7B~E8JhtBPz~Xi5`q=N@y?bB6*vF|sqGM9R>}g6(TPA#7xTE=r zVq=n~wcpi@=gW)Jeq~H?(VM+*;pbeh7O}RPeOKOd{^t-p@rt3uilI<1J&kXhSCioq zzK+swA2vMP(b_KeEBrqzXZFOx$!1q?XV~ga{QmAj*vG}c+Fm92G9P~*bV|5TGTP33 zrpG6JwvBNUHpGf^sy*Cs^x&%Z_T_V&_VaDlGu;+#;nk*Ysmm)f&m-ft`Pq4jcWX>! zyI8p11b>UM54&dJHtE~1)mOz9x2iVAh%%M0Jh?*UvHG-`anfuYx3@SYU6Nb(+$Y%~ zk#%LFkl((Fy^@?vKh8}I=$qWIzba6u#%fN@LnjNN`d<(9X6;{5!YCLNqhw?~HAsD> z+PUqs`c5iy9kg9^I9Ybl4fmxR=Kub*H`>Cd>#j}4wIvO|cU8u!Op!hH!}e;v()k-d zAF**VeK$2+<y%^|?e^A#@BNI0a)gezNPq3@+o{viKV8$*fz|4-nJA~*9OLD$wl?`Z z|2&tcZ(_skV9P0|MZIrsacasv{q*Ck{!eQsGsFwMEpqszxxr^~|C7sBizgfsz9%HN z&8sQ5wsCfZSzf?Y!=1WQy{0w=JF93JdgLt&|Gf5G=l#B;Y0u7;c<gw0yyyMzgPj)= zH}R>w+i0}%_#OU^0`=K*zi(9*jCVc%(^zixH*<aoQH38Cj^8JFXvy^2%sHL5PNVj1 zT4>kAi4)I#ig>Emxc0xakfTb$BdNQ0SBs{FFr8>FSv`;Y_3MrgDibq`?_Lr+ZItJF zS#XbRNpeua{*ShbdvE#~MSgX2*S1{OdH>}Fw<fc1&RjdMoAe$u;Cz?esiCaPS>-An zfBV$txS+o`4K=r?Y+gD2>t^4MKh8pr6`m}ujFmlpb@}4Hj&HL~y_)X#1+AR2=!fbH z<;<prTO|pCcUfE$3&O1D81W=q7=@d!@$T(&xuHG({}zVAn#JuqX3d$-d7$-6SZUC| z<1B{^L|<xKb@dB({`fm@-n{dP_cOo#tY_cbF>kK^7vIx`YCUtE5|8>kFgyH*bB%~t Vt)+O%Ed~Y#22WQ%mvv4FO#qYh*Zlwh literal 0 HcmV?d00001 diff --git a/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_closed.imageset/ic_eye_closed@3x.png b/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_closed.imageset/ic_eye_closed@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..798f10fd18b30cbfb052cb6a615e4c262742f411 GIT binary patch literal 1529 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 F2>=an>#_g< literal 0 HcmV?d00001 diff --git a/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_open.imageset/Contents.json b/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_open.imageset/Contents.json new file mode 100644 index 00000000..63979ef4 --- /dev/null +++ b/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_open.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ic_eye_open.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "ic_eye_open@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_eye_open@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_open.imageset/ic_eye_open.png b/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_open.imageset/ic_eye_open.png new file mode 100644 index 0000000000000000000000000000000000000000..59f0c2c81cc86cebcbfae3ac00daedc7b7db8a30 GIT binary patch literal 489 zcmeAS@N?(olHy`uVBq!ia0y~yU=U<rVBqFpV_;yIsgTCbz`(#*9OUlAu<o49O9lqU z#hxyXAsV8+LDnA3jskOUx(GN0Ff~nZ6BO2VyyD0GQAkiX=Zap|!iWgYMXeqz(vBO2 zj;M)WX7%pX2#=1MEq~)igolbt%bj;SiZ^`};b#AqcK^2d`?TkL5Boiyd2woLF70Rg z+NF5WTER}?QEJH6)VEXb@z+cKa(uMN%4t=l8_VIkf5+uMS~hH`+Agx+aF4<4lR1UK zC!g&#ypX?FtZ~~#4-KJbXKq{;a$UNpDRp|8@7n90O2IZ^4zqQG#4S#LjBNJZ_U4hO z;8}?t1-`jcZ}?r<B+oBWE4_ii)!^*SQ{mPN9_l%0%qSQ8bx(ui_l1^eoQ=2qQoQ_s zS?xH%`tL;!zkOANw7`X(=}S5TEIu9meWWGJpT*(K%ahk@Y_8b7VwSrmtMEXo{LqfT z`oE8QB_=v_@aC%p?|ii5wGhAFndde~>d&$qowixVI;%EGJ6cX@605=sGdCOQeNyFa zr+jBGd^O!;?M1ea!v3fEg)jds3g4{g&zW$qVE<;b6(2<Bg#2G?nO&O1an5tMk&ffK x*Kb?m0$HjQFVyQeCazJR=IOuSw3YDu8ySm!Osy@mWME)m@O1TaS?83{1OU_O&BXu! literal 0 HcmV?d00001 diff --git a/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_open.imageset/ic_eye_open@2x.png b/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_open.imageset/ic_eye_open@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..1ec7263d1549f769fc6fef04025cffe1e0090918 GIT binary patch literal 1004 zcmeAS@N?(olHy`uVBq!ia0y~yU{GRUU=ZVAV_;xdy2h`Pfq{XsILO_JVcj{ImkbQd z%RF5iLp*r*hWUGlB#PAMr-d7D3~5o}a=a{h#rc8lrBVg{c}5y5?*_dI+HT;o#7cza zk|L9?*4<W~HQug~uhRl#7X=FjS}$E##-ZhVWXaaK*MGaE&%XP!>>8I;#J=x)>+k2^ z|6ZNX_K<)6vJWn{7m5};?qKdXCAeXVK#}FyaF!oD4(BH%*r==PS8ZRLlehMzrP=Sx zRz{P}x9_;(=+XZ3!>l)gZyI+TX<*yCVvaO#m|seFA*++iiq@}XMlVDdbIwikNqgQ^ z_;EpesF_^9j7IE~pB%An3TK<;y&nHic43KH_Q3w4@d8iQj|nOfUn9hppO_M*u}!=0 z<8(a*F^iX+tW(||{dtu2k$TF)$2HuW=CFk13D|z(f90N9=I$!hp0xbN#_2mBY*?#u z;Nu;c_Y13Yp9XJgIeT60bls8Z>y0v{Q@&l5NtcuR^7Y2slZRR4XF2_<jO)K48<Z;3 z&$jwchmZ4g_a~qDUj~L7bWC5|xXMp^dZnp)r%0}cd<i=v_adRN1>Agj5-JZ*+g-{w zO767UGNJC)sbr=~p-cKw4vgNK(LewFHi~UO6aS-2V&>UPhUvSuF5Lb$>HR~YZvv9C z(+n@KT2Y{VSIuLt!VZ-$T2ARI52SrRD(*RZUD;y#M^6TxAI`s~9J;QUT3Gd@?T*s% z03%0%+{C2(jSM#*f9jfRShibJxT2v)JH~d`8-su8ti{&LdRS}r`mB3>^W48}KXRjY z_3z+Id*=Sp_^C<z(wjTGOr|DxpLnlv_3}eOo_yJb58ix_&=h!6QW3?qL`*C`B6{Px zqNLTa)0Mg<w!69iSh?cVy%YbsUOtie*zc3m^8U1c<*aMVRDSP$`0eb<=<Mffc((n} z=F|T%_mEm4<BtysCNH?T*WTRc)bVcRjPL8hrFWb;e>CosNJpn;+tee|775vDUp8gt z`1Y*ae>$rZi}j?ehyFh~lmD@mA6hr%&B?R&eHH6kny%Q2t+1Qzqsgq)qb@)3`N=7E z2NKRCCi6#3J?g!lzrs)CnfN|&tI221aLNT8uh8Dhr}j+g|JQ993vL-smJyA#JrT3z z!tT4AM!zHjI%EHv8#T`e3(cwAaQ}Od*!(9QXCyd7?uCeMZM%3c;oXjp@nU(ej<gGw zKVx0*zV<YWlf|yEBlBXp_pdkAxOmj%&S~A38*ir=g)8_q9F`0CCC8#2f4b()E>q@> zO;K&?=DNDaXaD%UUa;}iP9N1f9j<r0x##4xt^dfYWw7g9_xJa2KG$x1v}x^r240`^ WBWrJ`1~V`)FnGH9xvX<aXaWFPDAwcv literal 0 HcmV?d00001 diff --git a/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_open.imageset/ic_eye_open@3x.png b/enzevalos_iphone/Assets.xcassets/passwordInput/ic_eye_open.imageset/ic_eye_open@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..1aa74e4b83f5898736dc1929020e36497b46f299 GIT binary patch literal 1481 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 HB{Ts5=!ekF literal 0 HcmV?d00001 diff --git a/enzevalos_iphone/Assets.xcassets/passwordInput/ic_password_checkmark.imageset/Contents.json b/enzevalos_iphone/Assets.xcassets/passwordInput/ic_password_checkmark.imageset/Contents.json new file mode 100644 index 00000000..85a76208 --- /dev/null +++ b/enzevalos_iphone/Assets.xcassets/passwordInput/ic_password_checkmark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ic_password_checkmark.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "ic_password_checkmark@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_password_checkmark@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/enzevalos_iphone/Assets.xcassets/passwordInput/ic_password_checkmark.imageset/ic_password_checkmark.png b/enzevalos_iphone/Assets.xcassets/passwordInput/ic_password_checkmark.imageset/ic_password_checkmark.png new file mode 100644 index 0000000000000000000000000000000000000000..05a5bccd35783d27d8904dbf4fc9b66c0343f23d GIT binary patch literal 449 zcmeAS@N?(olHy`uVBq!ia0y~yU=RSYIoKE&7#8e)r^3L%z*rpQ?!>U}oXkrG2F7Yn z7sn6{(YceXy$>gdw9WP|)UdGN5G$Ra<k7xp@`DKtdzY9CI4<4MWq;`8&G-chO&vQd zEKGf8`xabqjdhvOrO=^QCOCCV=lSVzjxE=i)!*-|d0*+j&xP~P;YAlSbVRsnuV-!5 z&kU&3nrf61d2gc1%S9J6a#l9;oJcXUJpcKdLi@o?w%Tud8xtkE1^5K!<aEw!mfqxX z>E#y#yW3fRn5wu}yjx_YIO{>^-njcZV%_{k?@ip^3T*G({K#Rw<2-fyL<bge>G;R3 zMLTQwcjc(&3qN_$tI@TI-%<H{Z=+$8a?PGd&N~bD<;_Z)dPmq)bD~E}XsB&kgC5t7 z$&W3(AFzKlE?Bnok4Np!pp|z5KA%iDu>VMkk!9DelLsvWkHiHQov2NHlx`EPH8pSc z+jpBki$41JBg8;ri-PN}-2aE}#aurdJ+1U+bpG*w;R2nxw?p&FSeH&O6RtTP{$HuP zcrLGtlFuEh=s7}sAD4?N+^$QW(7r6QGWPoQUl0E<@CdgmrLXvv#K6G7;OXk;vd$@? F2>_-Y#Jd0h literal 0 HcmV?d00001 diff --git a/enzevalos_iphone/Assets.xcassets/passwordInput/ic_password_checkmark.imageset/ic_password_checkmark@2x.png b/enzevalos_iphone/Assets.xcassets/passwordInput/ic_password_checkmark.imageset/ic_password_checkmark@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4bf6c49ebebc5f5cc258567ecb6d375432087d8e GIT binary patch literal 987 zcmeAS@N?(olHy`uVBq!ia0y~yU{GLSV36WqV_;yoHapIqfq{XsILO_JVcj{ImkbQd zQ$1ZALp*r*PP^+pIZ)<!>FmodpP9t3Q(=k}ue^Blkd*SQ##xFNPrHf-YV4cfp)c~4 zT_o^=Z>#HFmaw=I!4knAn-++3Xhk+n*?484NpOsKY=p>;wdeESNS^=v=4Q+#n-7oY ze6IdoSHHjb+-6acoCg~E`uADpIP+!(=6~Axt!ghH$Cl$s8&fBr{E}2r@uUC2%+H*w zp7=G**VWP4)B48UJ~Spqrpra?qSH~$_|4~^Z@!(g?J`3=lX75zja+=%{iAQrXR}Xw z@RuQ;&7kzon$ryVk1U!hl`mYn6qL3#%Acu@^?*_{-|Y+e=S~Z9SctC`-^sQil;7{` z>KDgeI{2^Bty=!|-QB$Ml{a(Vsr=KL#MY<h^;DkWy^O3Z@2nCBwR5?5m$2+vwrpAR zoa>C5*Pc$xo$^Y3!nuhPCoa$ka#uKT=h|9{>`J-!%#8>13s00**vLh@x*jcT$QMX9 z?hyWPGQ*@QDJSR6;w1l=Lv3wr*`c9V{hH(zYRh*2jV>+y`n<qGCw=QPfe)unol5rn z5Y*ft@nC*fc)0c7y8laV<xP8V>sFNf!S90NNk=Q!*J!+Y^=jXlvu9IP6+ikd|E%Ge zFBHAZZ(hvt8OvA198mvKCY)=1CRbLaqB|)i*PTtFaKYNOXJ6<Duak-9eBj<OU4Kq& zXZTqrxh0?SZpj6_4EEmHQX8UUFEq>1Nxk!ZLG<^Nf|)%zEOQDu_TSDiwKwpL&-~5v zF}7j<<>T7bn@>Nja-Afr@k-$AYKM5PPPJ8YT%L)Gi!WWo^wKLZ@S@|Ja>3;<t}s8a z_&uTF^Obuma(|UR5;ZY5->oBdTHxdziwqABhM$K#*w;VadibHi=crqO_Yd2zE#|T) zHurzK^hmn&%JdtzZta@Oe?ocAc11UpXDe3lU*Jk%Sb0g^uj%~b>&{Qle=S>F+tnbE z`BraPyN4}<)a)CKKTf6`oKj}UD)Tq|K=sO+kUzzev*Z`goH?_gw)Stjkf~y3diS}m zlwU!59_=e?EW{Izx;r~e*}QqPqDRY<Pa93EqP*5r#Vug`+h8B8T^zYwaDsvdi{i#3 zMf{@DwKs!yGRC?1UHrCO^QpZK52uICal@0se;FI^=6D-DiDCM~^T6Ne#`TbN6@`ft zI2@8#1@v7^R4%w)nEUwr)5oTPn=DdP6$&q3zWjK?kF%E+D}9{HT|Vzr`=%%7PHs_S zJn5u<&&g?D-Y1{%3Ed6+M)_|ta&q=Gl>GI-vOj54l+L5G7bY+;Ffe$!`njxgN@xNA D!8OcF literal 0 HcmV?d00001 diff --git a/enzevalos_iphone/Assets.xcassets/passwordInput/ic_password_checkmark.imageset/ic_password_checkmark@3x.png b/enzevalos_iphone/Assets.xcassets/passwordInput/ic_password_checkmark.imageset/ic_password_checkmark@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..7740a41d8e0daf48bdc11325356cb816dead3271 GIT binary patch literal 1459 zcmeAS@N?(olHy`uVBq!ia0y~yU@%}{U{L2^V_;zLym)#E0|NtNage(c!@6@aFBuqE zb3I)gLn1ie&Zzf@4i`D@yXaU_!1gi?mAQVsm+~TyYfLs;GIPJ^v4mtE?rCCCYKyg* z6YF`7J(FKtUlyPt-D<SO{@AutZU^Ttxx6(ty?yb!>9?;)9C;M7>(#MUlcc^|CLP)H zebSvHVV{rd#oViYKCk%Q_v&|*&+mPoH0fVHzdh5^rAyCyn$J3!q~fCz>Fay;b=c~y zs-~u27hHb%Cp#r2CBb%IiyFfZ=d{f~mz+#FwIKTCyFY*abY8r8QNCG4XqrQ8>|I8O zc|so?H^i(JC=wSDsfg^1cbzwZh2cNf4LhcqX$@Dl<erFEnA_IY-u~YplWqH-iCZcq z8+5;X(Mb3g85Nb~p~19u>sEcHUosD_FZWfEE1#^~oA*p2Gx%hUZb|3|&(o(*%c~vX z68QO-VZY0h?W@^z1vvKHzj^cKo~JA)e%6LeGi!K$gyA2{gZqMibyXd1y<t5(y<~So zV2=9j+qY+5h!y**s~iv;ySM#ByjpIV7L)ka%MJCDvlTKntLhtC?w4kWKf*Lm{M(x^ zU%o`YKFG}}%eeh^uD7>$_OYG0b#?#t-n)0t-u0v7)>Egv)c5H>Tpw^%{lWRgzmFX_ z&=8-!*{;<mG&Gd2`)E-c=PFmh!`U&ftgWonwzL)6%<lN3_r~t{{xuF)j{W(5aj%7` z=~a#&)oyGD7q`ruqr*_6&6euu`cD4&y{WTj-?lX~`<5Rdcl@f$R!ybn_D7d{AFUIu zxqatOOmcmF{f(Wi4Kq)?XZuq*XL`n5W#Ocwt5u$Deav-Ujg#+z{)5+%thIrWi{iii z{_Fnh*ROwlDanbE-UWIS>#gP}B_Ewo@Z{;!$~|%KlPqkRcdlHtC@I~`t4oHz<e=dN z@ryzi-zP1$x^wxmv9w#dZ_dMza?$7KOg(2vm&AOLojG&nyptzA@19Oc2@4BLd+zLV zV7gSV^a+(u@t37<tavBU^V%g%<$B^8mX4`bljhE?Z3^A|$|jQ~WV6h^CFhvp`Z%?G zvwm;q=H_nKkTTX{Ta>K0Xs+4pwE{xBXZUcqW~;t9bt?ApVkf0#*#b2^C%At^-CeLz zq2c`OCx00Gj|&GM-Rxm?<82v#<u4xLXOHc*IKOzk{LWBWoR+56;!;`p^V^drPx?Q8 zo@5v{H{`&5r>OgP@4mg<>n6BnO5ptS+aDBItTXs%*I>CJa=*RAu7pc}BO@crjg5@z z6gae_turSdRjZJaUoRz<+45t;=QH{>Gp>}Emhxt|O_g(Q2=bfX;38f3ok1z(%n9kL zpox9w&z;-0Z29ud3M-da<QZJLdWyv+_)ps(({twbna4xtmnxi$zp1MK=#S>Qz{{Ca zTjppKZwRbQ-1vKDQ00UZ{HvNwFI^TCPz_tuvg`h#wR56*N_*yLo>F<<{-RxT>V557 zEuq|Us!k$5-WTm&vEoJfhTW1UcqH!}U|yj5-2H_+<Nv#CF>7Z^2~7yBi>&zh-)NuL zp>1h`&(CUA=s$B``8oV?$zo$}ZwHf=pPjE%-xO5ce%VFLU-$z{lFV(l1M!{5-7RK! zupH@_x+63qVh2aV^U9uG%<VH@n0-oac+X)hx7|XE@#7h<FO&UN-g(#B5i?c#;QS@> z>d*HFnRPh^b~gM-UcB3H?s=A;H#fXgF3fe?-g%&2jCt9Nkg1#-qS-x`<}++*mVB~U zMfH+T!+z&_=?`lselfFJ=Hs9?>9F+kWpQQMmE!YS&X_4PFnqr_+hcaI+hhJ9F=57; zGp6o1Z~v>#Y?piGl>C_7QmORz+Uc_2nqJty5i@3FJmU6TeQsWXcKzk9$j+&+T&}3U zINR`_<>#_3J2*IuE@e(URnpuqW8Lr9aJudzV`j12G4s{AKju6x+9}s~#E{`P8$0{c h|7TBKtlG@+hdpY`Q$BSK#&`x$Y3%Cfvd$@?2>^5{zpelP literal 0 HcmV?d00001 diff --git a/enzevalos_iphone/HideShowPasswordTextField.swift b/enzevalos_iphone/HideShowPasswordTextField.swift new file mode 100644 index 00000000..451696a8 --- /dev/null +++ b/enzevalos_iphone/HideShowPasswordTextField.swift @@ -0,0 +1,135 @@ +// +// HideShowPasswordTextField.swift +// Guidebook +// +// Created by Mike Sprague on 4/15/16. +// See: https://github.com/Guidebook/HideShowPasswordTextField +// +// + +import Foundation +import UIKit + +protocol HideShowPasswordTextFieldDelegate: class { + func isValidPassword(password: String) -> Bool +} + +class HideShowPasswordTextField: UITextField { + + weak var passwordDelegate: HideShowPasswordTextFieldDelegate? + var preferredFont: UIFont? { + didSet { + self.font = preferredFont + + if self.isSecureTextEntry { + self.font = nil + } + } + } + + override var isSecureTextEntry: Bool { + didSet { + if !isSecureTextEntry { + self.font = nil + self.font = preferredFont + } + if isSecureTextEntry { + passwordToggleVisibilityView.eyeState = .closed + } + } + } + private var passwordToggleVisibilityView: PasswordToggleVisibilityView! + + override init(frame: CGRect) { + super.init(frame: frame) + super.isSecureTextEntry = true + setupViews() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setupViews() + } + + override func awakeFromNib() { + super.awakeFromNib() + setupViews() + } +} + +// MARK: UITextFieldDelegate needed calls +// Implement UITextFieldDelegate when you use this, and forward these calls to this class! +extension HideShowPasswordTextField { + func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { + // Hack to prevent text from getting cleared + // http://stackoverflow.com/a/29195723/1417922 + //Setting the new text. + let updatedString = (textField.text as NSString?)?.replacingCharacters(in: range, with: string) + textField.text = updatedString + + //Setting the cursor at the right place + let selectedRange = NSMakeRange(range.location + string.count, 0) + let from = textField.position(from: textField.beginningOfDocument, offset:selectedRange.location)! + let to = textField.position(from: from, offset:selectedRange.length)! + textField.selectedTextRange = textField.textRange(from: from, to: to) + + //Sending an action + textField.sendActions(for: .editingChanged) + + return false + } + + func textFieldDidEndEditing(textField: UITextField) { + passwordToggleVisibilityView.eyeState = PasswordToggleVisibilityView.EyeState.closed + self.isSecureTextEntry = !isSelected + } + +} + +// MARK: PasswordToggleVisibilityDelegate +extension HideShowPasswordTextField: PasswordToggleVisibilityDelegate { + func viewWasToggled(passwordToggleVisibilityView: PasswordToggleVisibilityView, isSelected selected: Bool) { + + // hack to fix a bug with padding when switching between secureTextEntry state + let hackString = self.text + self.text = " " + self.text = hackString + + // hack to save our correct font. The order here is VERY finicky + self.isSecureTextEntry = !selected + } +} + +// MARK: Control events +extension HideShowPasswordTextField { + @objc func passwordTextChanged(sender: AnyObject) { + if let password = self.text { + passwordToggleVisibilityView.checkmarkVisible = passwordDelegate?.isValidPassword(password: password) ?? false + } else { + passwordToggleVisibilityView.checkmarkVisible = false + } + } +} + +// MARK: Private helpers +extension HideShowPasswordTextField { + private func setupViews() { + let toggleFrame = CGRect(x: 0, y: 0, width: 66, height: frame.height) + passwordToggleVisibilityView = PasswordToggleVisibilityView(frame: toggleFrame) + passwordToggleVisibilityView.delegate = self + passwordToggleVisibilityView.checkmarkVisible = false + + self.keyboardType = .asciiCapable + self.rightView = passwordToggleVisibilityView + self.rightViewMode = .whileEditing + + self.font = self.preferredFont + self.addTarget(self, action: #selector(HideShowPasswordTextField.passwordTextChanged(sender:)), for: .editingChanged) + + // if we don't do this, the eye flies in on textfield focus! + self.rightView?.frame = self.rightViewRect(forBounds: self.bounds) + + // default eye state based on our initial secure text entry + passwordToggleVisibilityView.eyeState = isSecureTextEntry ? .closed : .open + } +} diff --git a/enzevalos_iphone/Onboarding.swift b/enzevalos_iphone/Onboarding.swift index c101aecf..5f117a4a 100644 --- a/enzevalos_iphone/Onboarding.swift +++ b/enzevalos_iphone/Onboarding.swift @@ -32,7 +32,7 @@ class Onboarding: NSObject { static let textColor = UIColor.white static var mailaddress = UITextField.init() static var username = UITextField.init() - static var password = UITextField.init() + static var password = HideShowPasswordTextField.init()//UITextField.init() static var googleButton = UIBarButtonItem.init() static var credentials: UIView? = nil static var imapServer = UITextField.init() @@ -66,7 +66,7 @@ class Onboarding: NSObject { static var transportRows: [Int: String] = [MCOConnectionType.clear.rawValue: NSLocalizedString("Plaintext", comment: ""), MCOConnectionType.startTLS.rawValue: "StartTLS", MCOConnectionType.TLS.rawValue: "TLS"] static func onboarding(_ callback: @escaping () -> ()) -> UIViewController { - + password.isSecureTextEntry = true doWhenDone = callback //Background @@ -149,18 +149,34 @@ class Onboarding: NSObject { let mailaddressUnderline = UIView.init(frame: CGRect.init(x: 0, y: mailaddress.frame.maxY, width: mailaddress.frame.width, height: 0.5)) mailaddressUnderline.backgroundColor = textColor - password = UITextField.init() + + // Create passwordinput view + let frame = CGRect.init(x: 0, y: mailaddress.frame.height + padding + mailaddressUnderline.frame.height, width: 50, height: 30) + password = HideShowPasswordTextField.init(frame: frame) + password.isSecureTextEntry = true password.textColor = textColor password.tintColor = textColor password.borderStyle = UITextBorderStyle.none - password.isSecureTextEntry = true password.returnKeyType = UIReturnKeyType.continue - password.frame = CGRect.init(x: 0, y: mailaddress.frame.height + padding + mailaddressUnderline.frame.height, width: 50, height: 30) + password.attributedPlaceholder = NSAttributedString.init(string: NSLocalizedString("Password", comment: ""), attributes: [NSAttributedStringKey.foregroundColor: textColor]) password.delegate = textDelegate + + password.rightView?.tintColor = UIColor(red: 0.204, green: 0.624, blue: 0.847, alpha: 1) + + + // left view hack to add padding + password.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 3)) + password.leftViewMode = .always + + let passwordUnderline = UIView.init(frame: CGRect.init(x: 0, y: mailaddress.frame.height + padding + mailaddressUnderline.frame.height + password.frame.height, width: password.frame.width, height: 0.5)) passwordUnderline.backgroundColor = textColor + + + + // End let keyboardToolbar = UIToolbar() keyboardToolbar.sizeToFit() @@ -227,6 +243,7 @@ class Onboarding: NSObject { loginViewController = vc! vc?.pageChanged = {(oldPage:Int, newPage: Int) -> () in + password.isSecureTextEntry = true // Logger.queue.async(flags: .barrier) { Logger.log(onboardingPageTransition: oldPage, to: newPage, onboardingSection: "intro") // } @@ -289,6 +306,7 @@ class Onboarding: NSObject { let start = OnboardingContentViewController.content(withTitle: NSLocalizedString("WhatAShame", comment: ""), body: NSLocalizedString("CouldNotConnect", comment: ""), videoURL: nil, inputView: nil, buttonText: nil, actionBlock: nil) Onboarding.password.returnKeyType = .done + password.isSecureTextEntry = true password.text = UserManager.loadUserValue(.userPW) as? String mailaddress.text = UserManager.loadUserValue(.userAddr) as? String doWhenDone = { () -> () in } @@ -699,6 +717,18 @@ class Onboarding: NSObject { } } +/* MARK: UITextFieldDelegate +extension ViewController: UITextFieldDelegate { + func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, textField string: String) -> Bool { + return passwordTextField.textField(textField, shouldChangeCharactersInRange: range, replacementString: string) + } + + func textFieldDidEndEditing(textField: UITextField) { + passwordTextField.textFieldDidEndEditing(textField) + } +} + */ + class TextFieldDelegate: NSObject, UITextFieldDelegate { func textFieldShouldReturn(_ textField: UITextField) -> Bool { @@ -721,6 +751,19 @@ class TextFieldDelegate: NSObject, UITextFieldDelegate { textField.endEditing(true) return true } + + func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, textField string: String) -> Bool { + if textField == Onboarding.password, let passwordTextField = textField as? HideShowPasswordTextField { + return passwordTextField.textField(textField: textField, shouldChangeCharactersInRange: range, replacementString: string) + } + return true + } + + func textFieldDidEndEditing(textField: UITextField) { + if textField == Onboarding.password, let passwordTextField = textField as? HideShowPasswordTextField { + return passwordTextField.textFieldDidEndEditing(textField: textField) + } + } } class PickerDataDelegate: NSObject, UIPickerViewDataSource { diff --git a/enzevalos_iphone/PasswordToggleVisibilityView.swift b/enzevalos_iphone/PasswordToggleVisibilityView.swift new file mode 100644 index 00000000..c39d6c2b --- /dev/null +++ b/enzevalos_iphone/PasswordToggleVisibilityView.swift @@ -0,0 +1,100 @@ +// +// PasswordToggleVisibilityView.swift +// Guidebook +// +// Created by Mike Sprague on 4/14/16. +// See: https://github.com/Guidebook/HideShowPasswordTextField +// +// + +import Foundation +import UIKit + +protocol PasswordToggleVisibilityDelegate: class { + func viewWasToggled(passwordToggleVisibilityView: PasswordToggleVisibilityView, isSelected selected: Bool) +} + +class PasswordToggleVisibilityView: UIView { + private let eyeOpenedImage: UIImage + private let eyeClosedImage: UIImage + private let checkmarkImage: UIImage + private let eyeButton: UIButton + private let checkmarkImageView: UIImageView + weak var delegate: PasswordToggleVisibilityDelegate? + + enum EyeState { + case open + case closed + } + + var eyeState: EyeState { + set { + eyeButton.isSelected = newValue == .open + } + get { + return eyeButton.isSelected ? .open : .closed + } + } + + var checkmarkVisible: Bool { + set { + checkmarkImageView.isHidden = !newValue + } + get { + return !checkmarkImageView.isHidden + } + } + + override var tintColor: UIColor! { + didSet { + eyeButton.tintColor = tintColor + checkmarkImageView.tintColor = tintColor + } + } + + override init(frame: CGRect) { + self.eyeOpenedImage = UIImage(named: "ic_eye_open")!.withRenderingMode(.alwaysTemplate) + self.eyeClosedImage = UIImage(named: "ic_eye_closed")! + self.checkmarkImage = UIImage(named: "ic_password_checkmark")!.withRenderingMode(.alwaysTemplate) + self.eyeButton = UIButton(type: .custom) + self.checkmarkImageView = UIImageView(image: self.checkmarkImage) + super.init(frame: frame) + setupViews() + } + + required init?(coder aDecoder: NSCoder) { + fatalError("Don't use init with coder.") + } + + private func setupViews() { + let padding: CGFloat = 10 + let buttonWidth = (frame.width / 2) - padding + let buttonFrame = CGRect(x: buttonWidth + padding, y: 0, width: buttonWidth, height: frame.height) + eyeButton.frame = buttonFrame + eyeButton.backgroundColor = UIColor.clear + eyeButton.adjustsImageWhenHighlighted = false + eyeButton.setImage(self.eyeClosedImage, for: .normal) + eyeButton.setImage(self.eyeOpenedImage.withRenderingMode(.alwaysTemplate), for: .selected) + eyeButton.addTarget(self, action: #selector(eyeButtonPressed), for: .touchUpInside) + eyeButton.autoresizingMask = [.flexibleWidth, .flexibleHeight] + eyeButton.tintColor = self.tintColor + self.addSubview(eyeButton) + + let checkmarkImageWidth = (frame.width / 2) - padding + let checkmarkFrame = CGRect(x: padding, y: 0, width: checkmarkImageWidth, height: frame.height) + checkmarkImageView.frame = checkmarkFrame + checkmarkImageView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + checkmarkImageView.contentMode = .center + checkmarkImageView.backgroundColor = UIColor.clear + checkmarkImageView.tintColor = self.tintColor + self.addSubview(checkmarkImageView) + } + + + @objc func eyeButtonPressed(sender: AnyObject) { + eyeButton.isSelected = !eyeButton.isSelected + delegate?.viewWasToggled(passwordToggleVisibilityView: self, isSelected: eyeButton.isSelected) + } +} + +// Animation helpers -- GitLab