From 0b0c53b8ec18fe037295b02099e8414d2c088974 Mon Sep 17 00:00:00 2001 From: Bradley Dowling <34559056+btdow@users.noreply.github.com> Date: Fri, 30 Mar 2018 16:58:40 -0400 Subject: [PATCH 1/8] Add files via upload Updated to Swift 3.2 --- .../GradientSlider/AppDelegate.swift | 47 ++ .../AppIcon.appiconset/Contents.json | 48 ++ .../Assets.xcassets/Contents.json | 6 + .../drop.imageset/Contents.json | 23 + .../Assets.xcassets/drop.imageset/drop.png | Bin 0 -> 471 bytes .../Assets.xcassets/drop.imageset/drop@2x.png | Bin 0 -> 1050 bytes .../Assets.xcassets/drop.imageset/drop@3x.png | Bin 0 -> 1566 bytes .../moon.imageset/Contents.json | 23 + .../Assets.xcassets/moon.imageset/moon.png | Bin 0 -> 526 bytes .../Assets.xcassets/moon.imageset/moon@2x.png | Bin 0 -> 1109 bytes .../Assets.xcassets/moon.imageset/moon@3x.png | Bin 0 -> 1561 bytes .../smallSun.imageset/Contents.json | 23 + .../smallSun.imageset/smallSun.png | Bin 0 -> 404 bytes .../smallSun.imageset/smallSun@2x.png | Bin 0 -> 813 bytes .../smallSun.imageset/smallSun@3x.png | Bin 0 -> 1358 bytes .../sun.imageset/Contents.json | 23 + .../Assets.xcassets/sun.imageset/sun.png | Bin 0 -> 587 bytes .../Assets.xcassets/sun.imageset/sun@2x.png | Bin 0 -> 1253 bytes .../Assets.xcassets/sun.imageset/sun@3x.png | Bin 0 -> 1733 bytes .../Base.lproj/LaunchScreen.storyboard | 49 ++ .../GradientSlider/Base.lproj/Main.storyboard | 115 +++++ .../GradientSlider/GradientSlider3.swift | 431 ++++++++++++++++++ GradientSlider3/GradientSlider/Info.plist | 42 ++ .../GradientSlider/ViewController.swift | 39 ++ .../GradientSlider3.xcodeproj/project.pbxproj | 307 +++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/GradientSlider.xccheckout | 41 ++ .../UserInterfaceState.xcuserstate | Bin 0 -> 20622 bytes .../UserInterfaceState.xcuserstate | Bin 0 -> 28924 bytes .../xcschemes/GradientSlider.xcscheme | 91 ++++ .../xcschemes/xcschememanagement.plist | 22 + .../xcdebugger/Breakpoints_v2.xcbkptlist | 5 + .../xcschemes/GradientSlider.xcscheme | 91 ++++ .../xcschemes/xcschememanagement.plist | 22 + GradientSlider3/LICENSE.txt | 21 + GradientSlider3/README.md | 133 ++++++ 36 files changed, 1609 insertions(+) create mode 100644 GradientSlider3/GradientSlider/AppDelegate.swift create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/Contents.json create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/drop.imageset/Contents.json create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/drop.imageset/drop.png create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/drop.imageset/drop@2x.png create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/drop.imageset/drop@3x.png create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/moon.imageset/Contents.json create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/moon.imageset/moon.png create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/moon.imageset/moon@2x.png create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/moon.imageset/moon@3x.png create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/smallSun.imageset/Contents.json create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/smallSun.imageset/smallSun.png create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/smallSun.imageset/smallSun@2x.png create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/smallSun.imageset/smallSun@3x.png create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/sun.imageset/Contents.json create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/sun.imageset/sun.png create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/sun.imageset/sun@2x.png create mode 100644 GradientSlider3/GradientSlider/Assets.xcassets/sun.imageset/sun@3x.png create mode 100644 GradientSlider3/GradientSlider/Base.lproj/LaunchScreen.storyboard create mode 100644 GradientSlider3/GradientSlider/Base.lproj/Main.storyboard create mode 100644 GradientSlider3/GradientSlider/GradientSlider3.swift create mode 100644 GradientSlider3/GradientSlider/Info.plist create mode 100644 GradientSlider3/GradientSlider/ViewController.swift create mode 100644 GradientSlider3/GradientSlider3.xcodeproj/project.pbxproj create mode 100644 GradientSlider3/GradientSlider3.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 GradientSlider3/GradientSlider3.xcodeproj/project.xcworkspace/xcshareddata/GradientSlider.xccheckout create mode 100644 GradientSlider3/GradientSlider3.xcodeproj/project.xcworkspace/xcuserdata/brad.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 GradientSlider3/GradientSlider3.xcodeproj/project.xcworkspace/xcuserdata/jon.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 GradientSlider3/GradientSlider3.xcodeproj/xcuserdata/brad.xcuserdatad/xcschemes/GradientSlider.xcscheme create mode 100644 GradientSlider3/GradientSlider3.xcodeproj/xcuserdata/brad.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 GradientSlider3/GradientSlider3.xcodeproj/xcuserdata/jon.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist create mode 100644 GradientSlider3/GradientSlider3.xcodeproj/xcuserdata/jon.xcuserdatad/xcschemes/GradientSlider.xcscheme create mode 100644 GradientSlider3/GradientSlider3.xcodeproj/xcuserdata/jon.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 GradientSlider3/LICENSE.txt create mode 100644 GradientSlider3/README.md diff --git a/GradientSlider3/GradientSlider/AppDelegate.swift b/GradientSlider3/GradientSlider/AppDelegate.swift new file mode 100644 index 0000000..f5d68cc --- /dev/null +++ b/GradientSlider3/GradientSlider/AppDelegate.swift @@ -0,0 +1,47 @@ +// +// AppDelegate.swift +// GradientSlider +// +// Created by Jonathan Hull on 8/5/15. +// Copyright © 2015 Jonathan Hull. All rights reserved. +// +// Updated to Swift 3.2 by Brad Dowling + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/GradientSlider3/GradientSlider/Assets.xcassets/AppIcon.appiconset/Contents.json b/GradientSlider3/GradientSlider/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b8236c6 --- /dev/null +++ b/GradientSlider3/GradientSlider/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,48 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GradientSlider3/GradientSlider/Assets.xcassets/Contents.json b/GradientSlider3/GradientSlider/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/GradientSlider3/GradientSlider/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GradientSlider3/GradientSlider/Assets.xcassets/drop.imageset/Contents.json b/GradientSlider3/GradientSlider/Assets.xcassets/drop.imageset/Contents.json new file mode 100644 index 0000000..54761a7 --- /dev/null +++ b/GradientSlider3/GradientSlider/Assets.xcassets/drop.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "drop.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "drop@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "drop@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GradientSlider3/GradientSlider/Assets.xcassets/drop.imageset/drop.png b/GradientSlider3/GradientSlider/Assets.xcassets/drop.imageset/drop.png new file mode 100644 index 0000000000000000000000000000000000000000..9e3dd2c9d33ec0e4a093cac13277da286ea111ec GIT binary patch literal 471 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 QC;$Ke07*qoM6N<$f*!BeO8@`> literal 0 HcmV?d00001 diff --git a/GradientSlider3/GradientSlider/Assets.xcassets/moon.imageset/Contents.json b/GradientSlider3/GradientSlider/Assets.xcassets/moon.imageset/Contents.json new file mode 100644 index 0000000..19ea450 --- /dev/null +++ b/GradientSlider3/GradientSlider/Assets.xcassets/moon.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "moon.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "moon@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "moon@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GradientSlider3/GradientSlider/Assets.xcassets/moon.imageset/moon.png b/GradientSlider3/GradientSlider/Assets.xcassets/moon.imageset/moon.png new file mode 100644 index 0000000000000000000000000000000000000000..b087c1b58a99fed38b38ef5ea6c229878f75b595 GIT binary patch literal 526 zcmV+p0`dKcP)L)lZ0yQ547V&-`f^f2O8p!R$oJLdt@aSXe34ShJFq z&caHuP*Stzq$nk#Sj=i-HdeBsXjV!|%7WQh_%j(ZEbjB_@p_(V-kIO(_MCgZoqO)@ z+^5eniiiR1!67VV=JnBe8z#=x{>Pn%F;E33bCm6$e{KPX{?giY}1)acs z4A)}w*qNChS5WVL5vR5e8aUoRk`6YI3%Yy)%&(=EVr7*Q^D67TQs=~ z)p5GDh)*rx2a30kVmmfrIwD5?g0T(1S^#a}(>SkK@f&7w5nt=zzQ)w{?<&|0+{7zv z!LiI->TDRqd(ET$yGm%%qSDh@<>IDr{J*Lq;th5+R27+dXPL@d)fteN4Y6U(Zs`ep zTd`Mn?8KVDnfV-#m6xop(THfW;>y64LU|kN8o-4$firUsXYfOD1m#gW6%pgB23PP$ zIEXpL{1oTht0r`H;0pd)vEGc*^93BirCz{||Gdonf|C(3guOVdee4_c2WOykZ&d#Q QX#fBK07*qoM6N<$f-(*L^Z)<= literal 0 HcmV?d00001 diff --git a/GradientSlider3/GradientSlider/Assets.xcassets/moon.imageset/moon@2x.png b/GradientSlider3/GradientSlider/Assets.xcassets/moon.imageset/moon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..302861dd7a245544c2859e0d6270acee7fa65b3a GIT binary patch literal 1109 zcmV-b1giUqP)_P;IK|M$h75^@DeMksO2x@{Xk;IB}4-}$c!DvQgBS_Lhc@S>!H zX4VbNlk{C#o6bVx1;FyiKDR~4^#H={hA&Gx0o)F30LIPiY2b69&&)2Cbf8t9;*_{9 zQuYsEXGDB2um*Sm_}I+mFj3ug0AwSx$<8HJupa&QQ z76EqvH%t1fEKj59@2OxDa1SsJyyHK63-uI!S}TG5`5blD@*t?J;0pS%Q2HPi2Iog(dA~ zVkH2#RSyAQ`0Lxu>;jy0OLF1ExH;7w(SOKuUM2o1WoOf8zg4wq_@F<5Pb2%A%9LoE z;_47wd3hF^*%>KiLTE?08@MW=OAtljVcZQ6!}SSWg7{C^Z=X*^w*UWxJ%hlWi1rKp zx!WmYlCU4;O_4bUlGy~%s)l$UcTyS31~cob4@<*I!hV$R!`*}-%mwaFDOE*jRb*yM zfG?SNP^{ty;F7AcFcqa`rKE3g71Z&7JQo6YrIM;5!}G2WCWSN!bu;6c*CMurPb6T@{qnKI}8sGvhqY zoV|C=C4Vs7GiUZ*YtR4g$2x1DGjIX`y2W;2X5E0nz#w2i*=q+dSJE%B+fk2`V;MHH zLBQCxptQXJ*+zDKfvD*5OZOBUyA(HOj20RP&ZJ_D`NuPvh zgD>7fnAs5EMd0cNtF8f_@bw>x+>@o5od!GxJOZ53VD;_5Xi0zM^&gsCJ;KadfH#53 zIjSE7ZfPbFAcqiU)(2P(jLzxvK1rK$){RC(L&MDa0q+Ata{5~@X=2X0QOVpRlDObQ zpr41o`5twn(mhKdGdlw}C-{i40a)u%KPs7o0G8PiTXw((L%w_`fJpF70 zKJc^=m70^KnGFUu0cU#pnI`EyPa9FG+9Q&%`BnTy_#78SHZ`?|#&lpz03XYmd2T3D zQHZ2BJRZo$>Ogj)Qmsc!14ad~|DB|71K5eqaYFnbdjnLCEGGf2f$T>W!pz11uK?cw zGb9~O&i4k!0&6Ah%VMjN5N(0lc@S9VYb3e8xfl4j!V+w_>z*ON1YoV14Zy`M=K!za zQiXLX5h58D*ZMWRll77g1hBIdm(CHmbZT?Fd{iV1U#A5Nx7j=y#ZWA8iEIaWvTc5aYJA-rIGRV zz^v5!`z3vr)k#btcGfRaA4wgO?gs7v_9mxK2i^wyq>9c>9WRmeQX_skg-FKNxO~m6 zNYG6iN$t4U=BMOT4@zU5;&<7I>qQNbo-8k-@g!_D4gi^!ty-AbK-?|FTX2qBP$Sc zzQN4S#x0vgyL)iK-`}ZXYk-GR@23MxlGUd!T|x-pL5?k>hkzR;ZKX8sIV5QjurPIQ z4lW|COIH!1I2RlRW=r}gd7oZhi$T+)z{{!ggR?kD3lVaH3oXQRxYb~&q!p?2i-6yN z<&w66TXunaaJ^_DWvfm#(vjsQz*k|~%|1yjfo#>p%({ihlBb1e!38Ac@q1ocvZl$J zfzF{JsRMWA7K)H@Np#9%hmhNHq34OH#1vvg{UXgnxe%Lhm#rZPneB>Bi4c;G5N^YE zQgY{Am!Q)1#p{7=_atoUFDjLUcnA10ko{?a>_q1{A(G+oR3Q6ZSBQj_xO|~6L(S~M z0Cu8NQHZ2hRLcT2N|#tYY9(XZDNTIjWmf$n|2sb%Tua&m+zkBb;cKdy zg}NmvIGI!U$$T*$w{w)2rtK9C?PVmHkGOVMEAv literal 0 HcmV?d00001 diff --git a/GradientSlider3/GradientSlider/Assets.xcassets/smallSun.imageset/Contents.json b/GradientSlider3/GradientSlider/Assets.xcassets/smallSun.imageset/Contents.json new file mode 100644 index 0000000..f18a75b --- /dev/null +++ b/GradientSlider3/GradientSlider/Assets.xcassets/smallSun.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "smallSun.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "smallSun@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "smallSun@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GradientSlider3/GradientSlider/Assets.xcassets/smallSun.imageset/smallSun.png b/GradientSlider3/GradientSlider/Assets.xcassets/smallSun.imageset/smallSun.png new file mode 100644 index 0000000000000000000000000000000000000000..8b276f02ac76d2b874b76f2007ccd01919942d92 GIT binary patch literal 404 zcmV;F0c-w=P)5lR<6*F$_iDq_aWvJitYIfg*Jl;IiZlEYXJrmD&q% z5un!@$^tcXfzxKv3aOSNIp6k=o&3NJGqbsw&2Qy|q9B;rC4(M(rTE3nIyIe*r09wI zqnlNp(;+BWN5Is~`alopxjzAhdA9(y??259U?gepew&fDe)_@8hQQA8s>&DzOut(T zp@}iRx<8IFZZg7^Bm<~25O1{&AvDY7@+FVWX0s(9H^3PDbf|!wupCx2k-?X0-{oDYF%3Z0000=fU5qBX%U$!>RCkYCfTSv07J*FT{&97`7vND(A|Fks`>#~wB=HsJg{uv1=G#M zPWD>DH78w}h_nEIY*_|2fIeW(cmu#Z& z=#DLyfKBHdqc@%NYUo@6(>YG`Gt4@f3eXMQa=a;3z3KfWRxr!tCE#?h^#Zu6 zs^3!dP5@7VE5X(}P*&C7p-yHA6_GN#zbimnn)4utuZ~q#)#Wt#yl42u(Sv!;0ZeAd zu{N^g^8)B|^jxacUU=EwEWsvgr!!eX0IFJ7$FnDwhmj(s_&|}Dg#GMZXKVcI@*pCu zz;|2rtLpPK*}NN=cl1CJ=Lxc}vjp=3Xm|9iJ+VxPNE`4Z#l{|F6`~d3WU!T2h}wt> z(dA(4Gti}~zj6bxVPed&suqkd#Y04;_=oAV5?#ALd4;HRPB@;b>Ud%RHpBVRYXP_v zHzN_b20RJ_PC-RgADdna@DjM-_B-Pl(|5y3N0(IfV_>wqpmTt(n6Lx%Sc_jX_5?5r zjSVEdz%%3Z6J>kd14*IkCL(Wu^T4{Qo^kw|ozfrV6L5-XB+D$rP+%q$kq&bX(dqLL zUw=H!C3FWdk%%8ah#G9! zSWJqMM0*fd;5U$!#iw0JK%(M8QPEhwKn(pC%no>;x15gBsB(#ydF?%B_HYFb0G#Y@uWNZMNAvxv~Xvvt7ZUf1?2hE!UBq}#wNUe|@Zxpi>fYxg_O zXf%Z#&W+8L*-kU_mG((GYG!MIjlcl#q#OGd7y`~n`q9jG03W1+k`~yJp=&9ySkgr9 z0$d;&cb|U(%jzw}%({W^y{>P7rweQe=X6WTy+>x&23!N~b6xF{uB7AP5qijLHv`wr z>@zdV{DmZ)rPgm386VD>$ur)}7Ma->z;B-M0E_*3H4BjR6RX8jpTdP71F z*MJl5-?f}MEoRmecAD8vl6Vv5P+OgicaVGb%xn;NBV(vr(m7}RC&Ablun#y1Tum>g z+rbsUCg5$LBarKrbS&dYrWlm;W|p0GFOLf}=Yc1Jp;;gdU_-z@NizkUEx>-@^@i(I@d-(Hf0tbSC)T6e*vDr-JYAVuYh2F@Twk zG9L@ZNRqosvB1n)fwRo#TBDMliQ$M1WIL!0WE~`lSyk+(Hc{N{(v{NqFDG;BBwZ}x zDU(iL1Re{9W`Ho*43nhOHw!phNq+e-iOb@=OtO&pblO$Sc4rKgdC;5!CV~geN|Fm( z??JPk+y2=H{2fY2j;f%RkC5`wU zVO64&q)P1L7_dDrV7b_k_bx8NjHK2a-X^DeTQIcRe;0>d=y$LE2hb*|w~q1M)EYlp z!f1a^i#s+8AnCTG7lAh5mN!&Wy$-7qzW}S8;SZK5Zut-JKIg;N0xyxI1Sw9tzO`=7 z%idVlnfGnFA?X3PkX3$72r2}!6t47f$Ws&^$5(;(+~+Py2ZM2cS9eN!zlt4|vQc+F z4|!edD$w{chx3YOMW~ui`(9(LOuz}@WG;JMp-V1>Du3i_qt-KIUc!>_ccI4>aHCLV z2mCVOV7(|=1Sk8h*EJc-5u3~{#VfStmHT2K$uD2tAG-^&JK+2Lun7Eb;B!R<#n{5u z1kg?r4M&RRNAQjSt4V7AQ7^pa3d*h&&x%J_HZO}tRwa(-wEsW27ysSnA1cbuWnnoW QEC2ui07*qoM6N<$g7FoChX4Qo literal 0 HcmV?d00001 diff --git a/GradientSlider3/GradientSlider/Assets.xcassets/sun.imageset/Contents.json b/GradientSlider3/GradientSlider/Assets.xcassets/sun.imageset/Contents.json new file mode 100644 index 0000000..1efe4d4 --- /dev/null +++ b/GradientSlider3/GradientSlider/Assets.xcassets/sun.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "sun.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "sun@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "sun@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GradientSlider3/GradientSlider/Assets.xcassets/sun.imageset/sun.png b/GradientSlider3/GradientSlider/Assets.xcassets/sun.imageset/sun.png new file mode 100644 index 0000000000000000000000000000000000000000..379e9be38c9e449b3b243f55b08f7fa0646ce79e GIT binary patch literal 587 zcmV-R0<`^!P)Lm9cIUK@>&LpctjV?vgZd=U<4BO%S5Wcc1{>a}=87 z6Ve5I%V7A9lnAgv`Gr*2MdVb(6o?c~dckaG<@7^)2ILz$G%#K#Y z-^-A6%xt^1eBw_Pw{2#fm5G5*z{Jc#E+dakfRFz|yyNe)95FDgVgF7nX##u&_RXxB z$hHMM1ICi3DURU44#n|zoD?%_0KXjf1~^E}?@PLMd>gm`b|qb|Ip8O-1$;BJG4Mpv zt(jc|8xf)cV&}n_lByG7tJ^-ck+LETF z^VWeY3QJG@V~q;wDR5YuZ<<-dE#0eFdVQ%B^D08SllTWsbG$Hm!b(dXW_9n@HiD;OD#&eOe`NKaLG#^ Z;5Vo=*;rq1wEX}8002ovPDHLkV1mYi2Gall literal 0 HcmV?d00001 diff --git a/GradientSlider3/GradientSlider/Assets.xcassets/sun.imageset/sun@2x.png b/GradientSlider3/GradientSlider/Assets.xcassets/sun.imageset/sun@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..59f3eb1f836e1faa45c7f3559c0b10ae96bc04b7 GIT binary patch literal 1253 zcmV{r?Mjr32jg8sZKa?IHxk68^&bJLikj3W;9+Ok>D%9* z_cptU-(-_{^P8ESeZTkS-$EN8BAZ2Ib31HzwA!GE+z0$&%hjs-XDjV@w$hm4(Hy!Z zNOD+2DkAbhtG--B#zbT?MJL)}5$OY71rCVFzEtNj>aVL^vCLo$adgfTP~{VH>uy>m0`3GxKeVi)&aj6JqvW$ ztKJPf?d0~0$a>(csxAQM+_UvXj)_Po(5tGKJ-;Ims!$DG03*Sf4Go?F_S$kDc(}*` zsz+g?(Vwd7%LTSafDdh1QPn$PG~8i-CdWl&92m%Xb%V~~GG}ql0%XQ<5g7oc1GYc& zjkSa&g)n3-0qa!thRHk#d`9D?xdu!D7i_%^*afT&Dr1eRsBIkR#Sc?_EX=5Z7uk2U*#PGj+e++j|70V;)OBL zs;-*D(U+tE-o_U(F&NUK#92qLwb0ZQOm~fAMPK5So^FBV)!Ye7w@EOala4hP8-pP- z(^;o*E?{q=S{o##X5b+8EC6Ok4Na(x5IRI;7#KJ91~1bYDC`3s0ag?_Yp-yx)7u1e1J6>; zS~VOqUbm|HAM}#h$b@z4D}X*#9rDi_!df^7$bqk{`b}>E_}r?lT1Gq`gsLZ~hsU3R zdkUPs1$-a!lZzh_*$Lcb%fD1Lx^h$1S>PXA-Yp_KisZA8`o`u~e|{&o8w#Fd>yM&nv` P00000NkvXXu0mjf7h+X$ literal 0 HcmV?d00001 diff --git a/GradientSlider3/GradientSlider/Assets.xcassets/sun.imageset/sun@3x.png b/GradientSlider3/GradientSlider/Assets.xcassets/sun.imageset/sun@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..460d8817f2afab62d262caf706fbdeaa99dd2fd2 GIT binary patch literal 1733 zcmV;$20HnPP)K)V4^q7kG>F`6hvG{Lks;>V)O(zFCv zD4;~x9upQQEMQ?wAjX*B*_bE>EwWGuRF?=wqG(zW4FQEji9kUh3Vr~KQgm^rc;DQa zckjD1k7rE($xGgRoip!r=FIsji~@i$jbtt&?ZAL(cBtz9M(t&6qZk_uc)s6oG+Ge< z8H@_TpedAqh;#wFO>>H>o(rW}knd#RtZ8SrPJVw{NGsqbgKv*IJoYfmV#=vPBT zUWiT8!DB^inlS|Nu+`oqB6WL~MPw}Sw$2A;FJ_r;fVFn02I{`Hvtz!WJ?jNQB^MkT99@v z*r=*k@+OJM7!lbDT%b}2Uibtt#nZnSxF#Ztb2c&=m{nv0HDb1i+@8aGDR2#V#xrHI ztF!7~*Emp{s!VB9)gP=ibAV4sl%Wf!fj(dtZ~{1E`lkY|z&xNEXz{Ec1fEvagBD+x zl1^i}s=n(R%suAD$@vgi;F)q9n60Xp%}F?j`$rrF)&PB~daVG@ZeRm&uVcy}@Q|vW z6Or-2VJek#8ry+Ic{WGk=hN8vXMu5^DQ}V}$tN9SYk>{vC$u2XW?(h&ieq>;$q5k8 z@*&_3RV}2XYqled*<93OybL_6s(rQcv3T~7_%h=QE}5&UU)92+v_WMo#@BMD^@Iu` z#jgk0kuz5K3!w=zZfYn_M50qGj}sz3+o~!$ zRCWKziHMnrw(oB}a5^Hb0T@jJU&n|bIwI1X8j+R{LHfW#2N)e;Dpkt(9j#>Jj;%m& z<|zlQu0B;gS(aev)fgljSe+M0vj}V+Lj>xLP!oHYB+!~hw}~gz1*up?8b{KR?=pz7 z;muaN1-JhZ3q54@kiCbRQ4c`?tT&!%RG2``ddJXvp|nFy>?V@cMXB1^Hc8h7Zf zFI4cQ?Q;=%i6n93(%=AHot>TE_V@Qk$w-OFeBdq5@C;yGXJ_Z7{{H?_`PMQ|=3KG~ zSs(s?p*j=1Jzr(bMv^R)D|ow(BzS8-wRt@Ag13i(7d^{|NviyQEyAm4IDZ@2N|h1( z2t1&wS4=qn8{9dKV0(Y7mQ<@xFzdJCz9u2~ltky8 zuflr?kg3y1!C4gRdp>cFAEZOfcE@BKw#`a{VTz`&G4YSwL6nd%LRMQbTP7B-%WUy}+%&O5i)Pj#?T+ zX3k2p<_l~5P|;1O>P1z(naVIjmuqe#ONUy>hTK|#(*;V0GDY0 zzsEcg_S=0`Rlkl!Tvhjxlmw*_?0%0RiXhB0W!F{t>aap!*FP;ayn_+zM4YnP+lyAJ z)B@u`*)5RneDC47rQ=~lr)t3AVgpCMD$zj|>j9!nvHAkrqQvzW6^NGoHf*<1@6{lDQASIFfI-6)JEfel6lVbEwnba=jx bqEYw<^MEO#ej3n$00000NkvXXu0mjf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GradientSlider3/GradientSlider/Base.lproj/Main.storyboard b/GradientSlider3/GradientSlider/Base.lproj/Main.storyboard new file mode 100644 index 0000000..ef1df4e --- /dev/null +++ b/GradientSlider3/GradientSlider/Base.lproj/Main.storyboard @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GradientSlider3/GradientSlider/GradientSlider3.swift b/GradientSlider3/GradientSlider/GradientSlider3.swift new file mode 100644 index 0000000..3950f93 --- /dev/null +++ b/GradientSlider3/GradientSlider/GradientSlider3.swift @@ -0,0 +1,431 @@ +// +// GradientSlider.swift +// GradientSlider +// +// Created by Jonathan Hull on 8/5/15. +// Copyright © 2015 Jonathan Hull. All rights reserved. +// +// Updated to Swift 3.2 by Brad Dowling + +import UIKit + +@IBDesignable class GradientSlider: UIControl { + + static var defaultThickness:CGFloat = 2.0 + static var defaultThumbSize:CGFloat = 28.0 + + //MARK: Properties + @IBInspectable var hasRainbow:Bool = false {didSet{updateTrackColors()}}//Uses saturation & lightness from minColor + @IBInspectable var minColor:UIColor = UIColor.blue {didSet{updateTrackColors()}} + @IBInspectable var maxColor:UIColor = UIColor.orange {didSet{updateTrackColors()}} + + @IBInspectable var value: CGFloat { + get{return _value} + set{setValue(newValue, animated:true)} + } + + func setValue(_ value:CGFloat, animated:Bool = true) { + _value = max(min(value,self.maximumValue),self.minimumValue) + updateThumbPosition(animated: animated) + } + + @IBInspectable var minimumValue: CGFloat = 0.0 // default 0.0. the current value may change if outside new min value + @IBInspectable var maximumValue: CGFloat = 1.0 // default 1.0. the current value may change if outside new max value + + @IBInspectable var minimumValueImage: UIImage? = nil { // default is nil. image that appears to left of control (e.g. speaker off) + didSet{ + if let img = minimumValueImage { + let imgLayer = _minTrackImageLayer ?? { + let l = CALayer() + l.anchorPoint = CGPoint(x: 0.0, y: 0.5) + self.layer.addSublayer(l) + return l + }() + imgLayer.contents = img.cgImage + imgLayer.bounds = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height) + _minTrackImageLayer = imgLayer + + }else{ + _minTrackImageLayer?.removeFromSuperlayer() + _minTrackImageLayer = nil + } + self.layer.needsLayout() + } + } + @IBInspectable var maximumValueImage: UIImage? = nil { // default is nil. image that appears to right of control (e.g. speaker max) + didSet{ + if let img = maximumValueImage { + let imgLayer = _maxTrackImageLayer ?? { + let l = CALayer() + l.anchorPoint = CGPoint(x: 1.0, y: 0.5) + self.layer.addSublayer(l) + return l + }() + imgLayer.contents = img.cgImage + imgLayer.bounds = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height) + _maxTrackImageLayer = imgLayer + + }else{ + _maxTrackImageLayer?.removeFromSuperlayer() + _maxTrackImageLayer = nil + } + self.layer.needsLayout() + } + } + + var continuous: Bool = true // if set, value change events are generated any time the value changes due to dragging. default = YES + + var actionBlock:(GradientSlider,CGFloat)->() = {slider,newValue in } + + @IBInspectable var thickness:CGFloat = defaultThickness { + didSet{ + _trackLayer.cornerRadius = thickness / 2.0 + self.layer.setNeedsLayout() + } + } + + var trackBorderColor:UIColor? { + set{ + _trackLayer.borderColor = newValue?.cgColor + } + get{ + if let color = _trackLayer.borderColor { + return UIColor(cgColor: color) + } + return nil + } + } + + var trackBorderWidth:CGFloat { + set{ + _trackLayer.borderWidth = newValue + } + get{ + return _trackLayer.borderWidth + } + } + + var thumbSize:CGFloat = defaultThumbSize { + didSet{ + _thumbLayer.cornerRadius = thumbSize / 2.0 + _thumbLayer.bounds = CGRect(x: 0, y: 0, width: thumbSize, height: thumbSize) + self.invalidateIntrinsicContentSize() + } + } + + @IBInspectable var thumbIcon:UIImage? = nil { + didSet{ + _thumbIconLayer.contents = thumbIcon?.cgImage + } + } + + var thumbColor:UIColor { + get { + if let color = _thumbIconLayer.backgroundColor { + return UIColor(cgColor: color) + } + return UIColor.white + } + set { + _thumbIconLayer.backgroundColor = newValue.cgColor + thumbIcon = nil + } + } + + //MARK: - Convienience Colors + + func setGradientForHueWithSaturation(_ saturation:CGFloat,brightness:CGFloat){ + minColor = UIColor(hue: 0.0, saturation: saturation, brightness: brightness, alpha: 1.0) + hasRainbow = true + } + + func setGradientForSaturationWithHue(_ hue:CGFloat,brightness:CGFloat){ + hasRainbow = false + minColor = UIColor(hue: hue, saturation: 0.0, brightness: brightness, alpha: 1.0) + maxColor = UIColor(hue: hue, saturation: 1.0, brightness: brightness, alpha: 1.0) + } + + func setGradientForBrightnessWithHue(_ hue:CGFloat,saturation:CGFloat){ + hasRainbow = false + minColor = UIColor.black + maxColor = UIColor(hue: hue, saturation: saturation, brightness: 1.0, alpha: 1.0) + } + + func setGradientForRedWithGreen(_ green:CGFloat,blue:CGFloat){ + hasRainbow = false + minColor = UIColor(red: 0.0, green: green, blue: blue, alpha: 1.0) + maxColor = UIColor(red: 1.0, green: green, blue: blue, alpha: 1.0) + } + + func setGradientForGreenWithRed(_ red:CGFloat,blue:CGFloat){ + hasRainbow = false + minColor = UIColor(red: red, green: 0.0, blue: blue, alpha: 1.0) + maxColor = UIColor(red: red, green: 1.0, blue: blue, alpha: 1.0) + } + + func setGradientForBlueWithRed(_ red:CGFloat,green:CGFloat){ + hasRainbow = false + minColor = UIColor(red: red, green: green, blue: 0.0, alpha: 1.0) + maxColor = UIColor(red: red, green: green, blue: 1.0, alpha: 1.0) + } + + func setGradientForGrayscale(){ + hasRainbow = false + minColor = UIColor.black + maxColor = UIColor.white + } + + + //MARK: - Private Properties + + fileprivate var _value:CGFloat = 0.0 // default 0.0. this value will be pinned to min/max + + fileprivate var _thumbLayer:CALayer = { + let thumb = CALayer() + thumb.cornerRadius = defaultThumbSize/2.0 + thumb.bounds = CGRect(x: 0, y: 0, width: defaultThumbSize, height: defaultThumbSize) + thumb.backgroundColor = UIColor.white.cgColor + thumb.shadowColor = UIColor.black.cgColor + thumb.shadowOffset = CGSize(width: 0.0, height: 2.5) + thumb.shadowRadius = 2.0 + thumb.shadowOpacity = 0.25 + thumb.borderColor = UIColor.black.withAlphaComponent(0.15).cgColor + thumb.borderWidth = 0.5 + return thumb + }() + + fileprivate var _trackLayer:CAGradientLayer = { + let track = CAGradientLayer() + track.cornerRadius = defaultThickness / 2.0 + track.startPoint = CGPoint(x: 0.0, y: 0.5) + track.endPoint = CGPoint(x: 1.0, y: 0.5) + track.locations = [0.0,1.0] + track.colors = [UIColor.blue.cgColor,UIColor.orange.cgColor] + track.borderColor = UIColor.black.cgColor + return track + }() + + fileprivate var _minTrackImageLayer:CALayer? = nil + fileprivate var _maxTrackImageLayer:CALayer? = nil + + fileprivate var _thumbIconLayer:CALayer = { + let size = defaultThumbSize - 4 + let iconLayer = CALayer() + iconLayer.cornerRadius = size/2.0 + iconLayer.bounds = CGRect(x: 0, y: 0, width: size, height: size) + iconLayer.backgroundColor = UIColor.white.cgColor + return iconLayer + }() + + //MARK: - Init + + override init(frame: CGRect) { + super.init(frame: frame) + commonSetup() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + minColor = aDecoder.decodeObject(forKey: "minColor") as? UIColor ?? UIColor.lightGray + maxColor = aDecoder.decodeObject(forKey: "maxColor") as? UIColor ?? UIColor.darkGray + + value = aDecoder.decodeObject(forKey: "value") as? CGFloat ?? 0.0 + minimumValue = aDecoder.decodeObject(forKey: "minimumValue") as? CGFloat ?? 0.0 + maximumValue = aDecoder.decodeObject(forKey: "maximumValue") as? CGFloat ?? 1.0 + + minimumValueImage = aDecoder.decodeObject(forKey: "minimumValueImage") as? UIImage + maximumValueImage = aDecoder.decodeObject(forKey: "maximumValueImage") as? UIImage + + thickness = aDecoder.decodeObject(forKey: "thickness") as? CGFloat ?? 2.0 + + thumbIcon = aDecoder.decodeObject(forKey: "thumbIcon") as? UIImage + + commonSetup() + } + + override func encode(with aCoder: NSCoder) { + super.encode(with: aCoder) + + aCoder.encode(minColor, forKey: "minColor") + aCoder.encode(maxColor, forKey: "maxColor") + + aCoder.encode(value, forKey: "value") + aCoder.encode(minimumValue, forKey: "minimumValue") + aCoder.encode(maximumValue, forKey: "maximumValue") + + aCoder.encode(minimumValueImage, forKey: "minimumValueImage") + aCoder.encode(maximumValueImage, forKey: "maximumValueImage") + + aCoder.encode(thickness, forKey: "thickness") + + aCoder.encode(thumbIcon, forKey: "thumbIcon") + + } + + fileprivate func commonSetup() { + self.layer.delegate = self + self.layer.addSublayer(_trackLayer) + self.layer.addSublayer(_thumbLayer) + _thumbLayer.addSublayer(_thumbIconLayer) + } + + //MARK: - Layout + + override var intrinsicContentSize:CGSize { + return CGSize(width: UIViewNoIntrinsicMetric, height: thumbSize) + } + + override var alignmentRectInsets : UIEdgeInsets { + return UIEdgeInsetsMake(4.0, 2.0, 4.0, 2.0) + } + + override func layoutSublayers(of layer: CALayer) { +// super.layoutSublayersOfLayer(layer) + + if layer != self.layer {return} + + var w = self.bounds.width + let h = self.bounds.height + var left:CGFloat = 2.0 + + if let minImgLayer = _minTrackImageLayer { + minImgLayer.position = CGPoint(x: 0.0, y: h/2.0) + left = minImgLayer.bounds.width + 13.0 + } + w -= left + + if let maxImgLayer = _maxTrackImageLayer { + maxImgLayer.position = CGPoint(x: self.bounds.width, y: h/2.0) + w -= (maxImgLayer.bounds.width + 13.0) + }else{ + w -= 2.0 + } + + _trackLayer.bounds = CGRect(x: 0, y: 0, width: w, height: thickness) + _trackLayer.position = CGPoint(x: w/2.0 + left, y: h/2.0) + + let halfSize = thumbSize/2.0 + var layerSize = thumbSize - 4.0 + if let icon = thumbIcon { + layerSize = min(max(icon.size.height,icon.size.width),layerSize) + _thumbIconLayer.cornerRadius = 0.0 + _thumbIconLayer.backgroundColor = UIColor.clear.cgColor + }else{ + _thumbIconLayer.cornerRadius = layerSize/2.0 + } + _thumbIconLayer.position = CGPoint(x: halfSize, y: halfSize) + _thumbIconLayer.bounds = CGRect(x: 0, y: 0, width: layerSize, height: layerSize) + + + updateThumbPosition(animated: false) + } + + + + //MARK: - Touch Tracking + + override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { + let pt = touch.location(in: self) + + let center = _thumbLayer.position + let diameter = max(thumbSize,44.0) + let r = CGRect(x: center.x - diameter/2.0, y: center.y - diameter/2.0, width: diameter, height: diameter) + if r.contains(pt){ + sendActions(for: UIControlEvents.touchDown) + return true + } + return false + } + + override func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { + let pt = touch.location(in: self) + let newValue = valueForLocation(pt) + setValue(newValue, animated: false) + if(continuous){ + sendActions(for: UIControlEvents.valueChanged) + actionBlock(self,newValue) + } + return true + } + + override func endTracking(_ touch: UITouch?, with event: UIEvent?) { + if let pt = touch?.location(in: self){ + let newValue = valueForLocation(pt) + setValue(newValue, animated: false) + } + actionBlock(self,_value) + sendActions(for: [UIControlEvents.valueChanged, UIControlEvents.touchUpInside]) + + } + + //MARK: - Private Functions + + fileprivate func updateThumbPosition(animated:Bool){ + let diff = maximumValue - minimumValue + let perc = CGFloat((value - minimumValue) / diff) + + let halfHeight = self.bounds.height / 2.0 + let trackWidth = _trackLayer.bounds.width - thumbSize + let left = _trackLayer.position.x - trackWidth/2.0 + + if !animated{ + CATransaction.begin() //Move the thumb position without animations + CATransaction.setValue(true, forKey: kCATransactionDisableActions) + _thumbLayer.position = CGPoint(x: left + (trackWidth * perc), y: halfHeight) + CATransaction.commit() + }else{ + _thumbLayer.position = CGPoint(x: left + (trackWidth * perc), y: halfHeight) + } + } + + fileprivate func valueForLocation(_ point:CGPoint)->CGFloat { + + var left = self.bounds.origin.x + var w = self.bounds.width + if let minImgLayer = _minTrackImageLayer { + let amt = minImgLayer.bounds.width + 13.0 + w -= amt + left += amt + }else{ + w -= 2.0 + left += 2.0 + } + + if let maxImgLayer = _maxTrackImageLayer { + w -= (maxImgLayer.bounds.width + 13.0) + }else{ + w -= 2.0 + } + + let diff = CGFloat(self.maximumValue - self.minimumValue) + + let perc = max(min((point.x - left) / w ,1.0), 0.0) + + return (perc * diff) + CGFloat(self.minimumValue) + } + + fileprivate func updateTrackColors() { + if !hasRainbow { + _trackLayer.colors = [minColor.cgColor,maxColor.cgColor] + _trackLayer.locations = [0.0,1.0] + return + } + //Otherwise make a rainbow with the saturation & lightness of the min color + var h:CGFloat = 0.0 + var s:CGFloat = 0.0 + var l:CGFloat = 0.0 + var a:CGFloat = 1.0 + + minColor.getHue(&h, saturation: &s, brightness: &l, alpha: &a) + + let cnt = 40 + let step:CGFloat = 1.0 / CGFloat(cnt) + let locations:[CGFloat] = (0...cnt).map({ i in return (step * CGFloat(i))}) + _trackLayer.colors = locations.map({return UIColor(hue: $0, saturation: s, brightness: l, alpha: a).cgColor}) + _trackLayer.locations = locations as [NSNumber] + } +} + + + diff --git a/GradientSlider3/GradientSlider/Info.plist b/GradientSlider3/GradientSlider/Info.plist new file mode 100644 index 0000000..caf9621 --- /dev/null +++ b/GradientSlider3/GradientSlider/Info.plist @@ -0,0 +1,42 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + GradientSlider3 + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/GradientSlider3/GradientSlider/ViewController.swift b/GradientSlider3/GradientSlider/ViewController.swift new file mode 100644 index 0000000..6ef4428 --- /dev/null +++ b/GradientSlider3/GradientSlider/ViewController.swift @@ -0,0 +1,39 @@ +// +// ViewController.swift +// GradientSlider +// +// Created by Jonathan Hull on 8/5/15. +// Copyright © 2015 Jonathan Hull. All rights reserved. +// +// Updated to Swift 3.2 by Brad Dowling + +import UIKit + +class ViewController: UIViewController { + + @IBOutlet weak var hueSlider: GradientSlider! + @IBOutlet weak var brightnessSlider: GradientSlider! + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib. + + hueSlider.actionBlock = {slider,newValue in + CATransaction.begin() + CATransaction.setValue(true, forKey: kCATransactionDisableActions) + self.brightnessSlider.maxColor = UIColor(hue: newValue, saturation: 1.0, brightness: 1.0, alpha: 1.0) + slider.thumbColor = UIColor(hue: newValue, saturation: 1.0, brightness: 1.0, alpha: 1.0) + CATransaction.commit() + } + + hueSlider.thumbColor = UIColor(hue: 0.5, saturation: 1.0, brightness: 1.0, alpha: 1.0) + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + +} + diff --git a/GradientSlider3/GradientSlider3.xcodeproj/project.pbxproj b/GradientSlider3/GradientSlider3.xcodeproj/project.pbxproj new file mode 100644 index 0000000..7fa01b0 --- /dev/null +++ b/GradientSlider3/GradientSlider3.xcodeproj/project.pbxproj @@ -0,0 +1,307 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + FC1C417D1B730A410083C062 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC1C417C1B730A410083C062 /* AppDelegate.swift */; }; + FC1C417F1B730A410083C062 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC1C417E1B730A410083C062 /* ViewController.swift */; }; + FC1C41821B730A410083C062 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FC1C41801B730A410083C062 /* Main.storyboard */; }; + FC1C41841B730A410083C062 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FC1C41831B730A410083C062 /* Assets.xcassets */; }; + FC1C41871B730A410083C062 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FC1C41851B730A410083C062 /* LaunchScreen.storyboard */; }; + FC1C418F1B730E530083C062 /* GradientSlider3.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC1C418E1B730E530083C062 /* GradientSlider3.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + FC1C41791B730A410083C062 /* GradientSlider3.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GradientSlider3.app; sourceTree = BUILT_PRODUCTS_DIR; }; + FC1C417C1B730A410083C062 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + FC1C417E1B730A410083C062 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + FC1C41811B730A410083C062 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + FC1C41831B730A410083C062 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + FC1C41861B730A410083C062 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + FC1C41881B730A410083C062 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + FC1C418E1B730E530083C062 /* GradientSlider3.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GradientSlider3.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + FC1C41761B730A410083C062 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + FC1C41701B730A410083C062 = { + isa = PBXGroup; + children = ( + FC1C417B1B730A410083C062 /* GradientSlider3 */, + FC1C417A1B730A410083C062 /* Products */, + ); + sourceTree = ""; + }; + FC1C417A1B730A410083C062 /* Products */ = { + isa = PBXGroup; + children = ( + FC1C41791B730A410083C062 /* GradientSlider3.app */, + ); + name = Products; + sourceTree = ""; + }; + FC1C417B1B730A410083C062 /* GradientSlider3 */ = { + isa = PBXGroup; + children = ( + FC1C417C1B730A410083C062 /* AppDelegate.swift */, + FC1C417E1B730A410083C062 /* ViewController.swift */, + FC1C41801B730A410083C062 /* Main.storyboard */, + FC1C418E1B730E530083C062 /* GradientSlider3.swift */, + FC1C41831B730A410083C062 /* Assets.xcassets */, + FC1C41851B730A410083C062 /* LaunchScreen.storyboard */, + FC1C41881B730A410083C062 /* Info.plist */, + ); + name = GradientSlider3; + path = GradientSlider; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + FC1C41781B730A410083C062 /* GradientSlider3 */ = { + isa = PBXNativeTarget; + buildConfigurationList = FC1C418B1B730A410083C062 /* Build configuration list for PBXNativeTarget "GradientSlider3" */; + buildPhases = ( + FC1C41751B730A410083C062 /* Sources */, + FC1C41761B730A410083C062 /* Frameworks */, + FC1C41771B730A410083C062 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GradientSlider3; + productName = GradientSlider; + productReference = FC1C41791B730A410083C062 /* GradientSlider3.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + FC1C41711B730A410083C062 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0830; + ORGANIZATIONNAME = "Jonathan Hull"; + TargetAttributes = { + FC1C41781B730A410083C062 = { + CreatedOnToolsVersion = 7.0; + DevelopmentTeam = 29Y384GTLV; + LastSwiftMigration = 0830; + }; + }; + }; + buildConfigurationList = FC1C41741B730A410083C062 /* Build configuration list for PBXProject "GradientSlider3" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = FC1C41701B730A410083C062; + productRefGroup = FC1C417A1B730A410083C062 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + FC1C41781B730A410083C062 /* GradientSlider3 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + FC1C41771B730A410083C062 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FC1C41871B730A410083C062 /* LaunchScreen.storyboard in Resources */, + FC1C41841B730A410083C062 /* Assets.xcassets in Resources */, + FC1C41821B730A410083C062 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + FC1C41751B730A410083C062 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FC1C417F1B730A410083C062 /* ViewController.swift in Sources */, + FC1C418F1B730E530083C062 /* GradientSlider3.swift in Sources */, + FC1C417D1B730A410083C062 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + FC1C41801B730A410083C062 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + FC1C41811B730A410083C062 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + FC1C41851B730A410083C062 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + FC1C41861B730A410083C062 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + FC1C41891B730A410083C062 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + FC1C418A1B730A410083C062 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + FC1C418C1B730A410083C062 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = 29Y384GTLV; + INFOPLIST_FILE = GradientSlider/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.Brad.GradientSlider3; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + FC1C418D1B730A410083C062 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = 29Y384GTLV; + INFOPLIST_FILE = GradientSlider/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.Brad.GradientSlider3; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + FC1C41741B730A410083C062 /* Build configuration list for PBXProject "GradientSlider3" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FC1C41891B730A410083C062 /* Debug */, + FC1C418A1B730A410083C062 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FC1C418B1B730A410083C062 /* Build configuration list for PBXNativeTarget "GradientSlider3" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FC1C418C1B730A410083C062 /* Debug */, + FC1C418D1B730A410083C062 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = FC1C41711B730A410083C062 /* Project object */; +} diff --git a/GradientSlider3/GradientSlider3.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/GradientSlider3/GradientSlider3.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..3da9c67 --- /dev/null +++ b/GradientSlider3/GradientSlider3.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/GradientSlider3/GradientSlider3.xcodeproj/project.xcworkspace/xcshareddata/GradientSlider.xccheckout b/GradientSlider3/GradientSlider3.xcodeproj/project.xcworkspace/xcshareddata/GradientSlider.xccheckout new file mode 100644 index 0000000..56b8062 --- /dev/null +++ b/GradientSlider3/GradientSlider3.xcodeproj/project.xcworkspace/xcshareddata/GradientSlider.xccheckout @@ -0,0 +1,41 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 58D24B13-25F1-469C-B6C0-C0D2BE294047 + IDESourceControlProjectName + GradientSlider + IDESourceControlProjectOriginsDictionary + + 340883B9DF0F7567157D9FDF3AA826EDD0DE698F + https://github.com/jonhull/GradientSlider.git + + IDESourceControlProjectPath + GradientSlider.xcodeproj + IDESourceControlProjectRelativeInstallPathDictionary + + 340883B9DF0F7567157D9FDF3AA826EDD0DE698F + ../.. + + IDESourceControlProjectURL + https://github.com/jonhull/GradientSlider.git + IDESourceControlProjectVersion + 111 + IDESourceControlProjectWCCIdentifier + 340883B9DF0F7567157D9FDF3AA826EDD0DE698F + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + 340883B9DF0F7567157D9FDF3AA826EDD0DE698F + IDESourceControlWCCName + GradientSlider + + + + diff --git a/GradientSlider3/GradientSlider3.xcodeproj/project.xcworkspace/xcuserdata/brad.xcuserdatad/UserInterfaceState.xcuserstate b/GradientSlider3/GradientSlider3.xcodeproj/project.xcworkspace/xcuserdata/brad.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..7740ea95492ad3360b5860b5ec2a9fc03c92a528 GIT binary patch literal 20622 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¥Eaoenp-qza}q`7s*THH{`eEW%4`n3VD@5n;5i} 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%0AM?(wU~?;d}6{OO52 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 np01CpPp?qB{mS~aeeq$O`zu)H5FW + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GradientSlider3/GradientSlider3.xcodeproj/xcuserdata/brad.xcuserdatad/xcschemes/xcschememanagement.plist b/GradientSlider3/GradientSlider3.xcodeproj/xcuserdata/brad.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..73853ce --- /dev/null +++ b/GradientSlider3/GradientSlider3.xcodeproj/xcuserdata/brad.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + GradientSlider.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + FC1C41781B730A410083C062 + + primary + + + + + diff --git a/GradientSlider3/GradientSlider3.xcodeproj/xcuserdata/jon.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/GradientSlider3/GradientSlider3.xcodeproj/xcuserdata/jon.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..fe2b454 --- /dev/null +++ b/GradientSlider3/GradientSlider3.xcodeproj/xcuserdata/jon.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,5 @@ + + + diff --git a/GradientSlider3/GradientSlider3.xcodeproj/xcuserdata/jon.xcuserdatad/xcschemes/GradientSlider.xcscheme b/GradientSlider3/GradientSlider3.xcodeproj/xcuserdata/jon.xcuserdatad/xcschemes/GradientSlider.xcscheme new file mode 100644 index 0000000..9f2d009 --- /dev/null +++ b/GradientSlider3/GradientSlider3.xcodeproj/xcuserdata/jon.xcuserdatad/xcschemes/GradientSlider.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GradientSlider3/GradientSlider3.xcodeproj/xcuserdata/jon.xcuserdatad/xcschemes/xcschememanagement.plist b/GradientSlider3/GradientSlider3.xcodeproj/xcuserdata/jon.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..73853ce --- /dev/null +++ b/GradientSlider3/GradientSlider3.xcodeproj/xcuserdata/jon.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + GradientSlider.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + FC1C41781B730A410083C062 + + primary + + + + + diff --git a/GradientSlider3/LICENSE.txt b/GradientSlider3/LICENSE.txt new file mode 100644 index 0000000..5c45511 --- /dev/null +++ b/GradientSlider3/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Jonathan Hull + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/GradientSlider3/README.md b/GradientSlider3/README.md new file mode 100644 index 0000000..9bf9087 --- /dev/null +++ b/GradientSlider3/README.md @@ -0,0 +1,133 @@ +# GradientSlider +![alt tag](https://cloud.githubusercontent.com/assets/167242/9134671/522e2f8a-3cbb-11e5-9d38-a0f1064a3e43.png) + +GradientSlider is a UIControl subclass which is similar to UISlider, but with a linear gradient coloring the slider’s track. Useful for creating color pickers. It is written in Swift 2 and requires it. + +**Features** +- Easily define a gradient by setting the min & max (i.e. left & right) colors +- Rainbow gradients (with customizable saturation & brightness) for making Hue selection sliders +- IBDesignable/Inspectable for direct use within Interface Builder +- Add an icon or color to the slider thumb +- Min/Max images (similar to UISlider) +- Both Target/Action and Block-based callbacks +- Customizable track thickness +- Customizable track border and thumb size +- Looks like UISlider by default, so they can be intermixed in the UI + +## Installation +Drag the “GradientSlider.swift” file into your Xcode project + +## Usage via Interface Builder +Drag a custom view into your storyboard and change it’s class to “GradientSlider”. Use the attributes inspector to optionally set the slider’s basic properties: +- min/max color +- hasRainbow (Note: the min color’s saturation & brightness are used) +- value +- minimum/maximum value +- minimum/maximum images +- thickness +- thumbIcon + +## Setting the Track Gradient Programmatically +### Min/Max Color +The track displays a linear gradient with the minColor corresponding to the minimumValue and the maxColor corresponding to the maximumValue. + + slider.minValue = UIColor.blueColor() + slider.maxValue = UIColor.orangeColor() + +![img alt](https://cloud.githubusercontent.com/assets/167242/9134778/8c34e16e-3cbc-11e5-9c54-452e8d3a2af7.png) + +### Rainbow +When the `hasRainbow` property is set to true, the track displays a rainbow gradient which moves around the color wheel (starting and ending with red). The saturation & brightness are both pulled from the color in `minValue`. + + slider.minValue = UIColor.blueColor() //This has full saturation & brightness + slider.hasRainbow = true + +![img alt](https://cloud.githubusercontent.com/assets/167242/9134881/5269de02-3cbd-11e5-9d78-056aca2b42d9.png) + +### Convenience Methods +Since one of the primary uses of the gradient sliders is to create color pickers, a few convenience methods have been provided for updating the colors. + +**HSB** + +`setGradientForHueWithSaturation(saturation:CGFloat,brightness:CGFloat)` This method sets the track to a rainbow gradient with the given saturation and brightness. This is useful for choosing a hue in the context of the current saturation and brightness settings. + +`setGradientForSaturationWithHue(hue:CGFloat,brightness:CGFloat)` This method sets the track to a gradient varying from grey to fully saturated with the hue and brightness provided. This is useful for choosing a saturation value in the context of the current hue and brightness settings. + +`setGradientForBrightnessWithHue(hue:CGFloat,saturation:CGFloat)` This method sets the track to a gradient varying from black to full brightness with the hue and saturation provided. This is useful for choosing a brightness value in the context of the current hue and saturation settings. + +**RGB** + +`setGradientForRedWithGreen(green:CGFloat, blue:CGFloat)` This method sets the track to a gradient with varying red for the given green & blue values. + +`setGradientForGreenWithRed(red:CGFloat, blue:CGFloat)` This method sets the track to a gradient with varying green for the given red & blue values. + +`setGradientForBlueWithRed(red:CGFloat, green:CGFloat)` This method sets the track to a gradient with varying blue for the given red & green values. + +**Grayscale** + +`setGradientForGrayscale()` This method sets the track to a gradient from black to white. + +## Responding to User Interaction +### Target/Action +As a UIControl subclass, the traditional target/action approach is fully supported. The slider will send TouchDown, ValueChanged, and TouchUpInside actions. If the `continuous` property is set to true (which it is by default), then the slider will send ValueChanged actions as the slider changes, otherwise a ValueChanged action is only sent when the user releases the slider. + +### ActionBlock +The slider will also call it’s actionBlock when its value is changed. If the `continuous` property is set to true (which it is by default), then the slider will call its actionBlock as the slider changes, otherwise it will only call it once when the slider is released. +The `actionBlock` property takes a closure which takes 2 parameters: The slider being changed and the new value, and has no return value. +It’s signature is: `(GradientSlider,CGFloat)->()` + +Here is an example of a hue slider which updates it’s own `thumbColor` to the value it is pointing to and updates sliders representing saturation & brightness to reflect it’s new value: + + //There are 3 @IBOutlets: hueSlide,satSlide, and brightSlide + + hueSlide.actionBlock = { slider, value in + let curSat = satSlide.value + let curBright = brightSlide.value + + //First disable animations so we get instantaneous updates + CATransaction.begin() + CATransaction.setValue(true, forKey: kCATransactionDisableActions) + + //Reflect the new hue in the saturation slider + satSlide.setGradientForSaturationWithHue(value, brightness:curBright) + + //Reflect the new hue in the brightness slider + brightSlide.setGradientForBrightnessWithHue(value, saturation:curSat) + + //Update hueSlider's thumb color to match our new value + slider.thumbColor = UIColor(hue: value, saturation: curSat, brightness: curBright, alpha: 1.0) + // (Note: We use the slider variable passed instead of 'hueSlide' to avoid retain cycles) + + CATransaction.commit() + } + +Images showing the effect of dragging the hue slider +![img alt](https://cloud.githubusercontent.com/assets/167242/9134674/55ae1c60-3cbb-11e5-888b-515dfc76898a.png) + +![img alt](https://cloud.githubusercontent.com/assets/167242/9134675/57c3043e-3cbb-11e5-8fa6-71b0f55b1105.png) + +## Customizing the Track +Besides the background gradient, the track is customizable in several ways using the following properties: +- `thickness:CGFloat` This sets the track’s thickness. The default value is 2pts +- `borderColor:UIColor` This sets the color of the track’s border. The default value is black. +- `borderWidth:CGFloat` This sets the width of the track’s border. The default value is 0 (i.e. no border). +- `minimumValueImage:UIImage?` This places an image to the left of the track. Setting it to nil removes any image which is there. The default value is nil (i.e. no image). +- `maximumValueImage:UIImage?` This places an image to the right of the track. Setting it to nil removes any image which is there. The default value is nil (i.e. no image). + +## Customizing the Thumb +The thumb can be resized, given a custom color or an icon (it can not have both a color and an icon at the same time). To customize the thumb, use the following properties: +- `thumbSize:CGFloat` This sets the diameter of the thumb. Note: Resizing the thumb may change the slider’s intrisicContentSize. The default is 28.0 pts. +- `thumbColor:UIColor` This sets the color displayed by the thumb. When the thumb has an associated icon, the color is automatically set to clearColor, and setting a new color removes the icon. The default value is White. +- `thumbIcon:UIImage?` This sets the image to display inside the slider’s thumb. Setting an image automatically removes the thumbColor, and setting a color removes the icon. The default value is nil (i.e. no image) + +## License +The MIT License (MIT) + +Copyright (c) 2015 Jonathan Hull + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file From 16598a2a0b1d9eadf6d61b7e2b96f9d2dfc82668 Mon Sep 17 00:00:00 2001 From: Bradley Dowling <34559056+btdow@users.noreply.github.com> Date: Fri, 30 Mar 2018 17:10:24 -0400 Subject: [PATCH 2/8] Add files via upload Updated to Swift 4.1 --- .../GradientSlider/AppDelegate.swift | 47 ++ .../AppIcon.appiconset/Contents.json | 48 ++ .../Assets.xcassets/Contents.json | 6 + .../drop.imageset/Contents.json | 23 + .../Assets.xcassets/drop.imageset/drop.png | Bin 0 -> 471 bytes .../Assets.xcassets/drop.imageset/drop@2x.png | Bin 0 -> 1050 bytes .../Assets.xcassets/drop.imageset/drop@3x.png | Bin 0 -> 1566 bytes .../moon.imageset/Contents.json | 23 + .../Assets.xcassets/moon.imageset/moon.png | Bin 0 -> 526 bytes .../Assets.xcassets/moon.imageset/moon@2x.png | Bin 0 -> 1109 bytes .../Assets.xcassets/moon.imageset/moon@3x.png | Bin 0 -> 1561 bytes .../smallSun.imageset/Contents.json | 23 + .../smallSun.imageset/smallSun.png | Bin 0 -> 404 bytes .../smallSun.imageset/smallSun@2x.png | Bin 0 -> 813 bytes .../smallSun.imageset/smallSun@3x.png | Bin 0 -> 1358 bytes .../sun.imageset/Contents.json | 23 + .../Assets.xcassets/sun.imageset/sun.png | Bin 0 -> 587 bytes .../Assets.xcassets/sun.imageset/sun@2x.png | Bin 0 -> 1253 bytes .../Assets.xcassets/sun.imageset/sun@3x.png | Bin 0 -> 1733 bytes .../Base.lproj/LaunchScreen.storyboard | 49 ++ .../GradientSlider/Base.lproj/Main.storyboard | 115 +++++ .../GradientSlider/GradientSlider4.swift | 431 ++++++++++++++++++ GradientSlider4/GradientSlider/Info.plist | 42 ++ .../GradientSlider/ViewController.swift | 39 ++ .../GradientSlider4.xcodeproj/project.pbxproj | 327 +++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/GradientSlider.xccheckout | 41 ++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../UserInterfaceState.xcuserstate | Bin 0 -> 32617 bytes .../UserInterfaceState.xcuserstate | Bin 0 -> 28924 bytes .../xcschemes/GradientSlider.xcscheme | 91 ++++ .../xcschemes/xcschememanagement.plist | 22 + .../xcdebugger/Breakpoints_v2.xcbkptlist | 5 + .../xcschemes/GradientSlider.xcscheme | 91 ++++ .../xcschemes/xcschememanagement.plist | 22 + GradientSlider4/LICENSE.txt | 21 + GradientSlider4/README.md | 133 ++++++ 37 files changed, 1637 insertions(+) create mode 100644 GradientSlider4/GradientSlider/AppDelegate.swift create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/Contents.json create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/drop.imageset/Contents.json create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/drop.imageset/drop.png create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/drop.imageset/drop@2x.png create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/drop.imageset/drop@3x.png create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/moon.imageset/Contents.json create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/moon.imageset/moon.png create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/moon.imageset/moon@2x.png create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/moon.imageset/moon@3x.png create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/smallSun.imageset/Contents.json create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/smallSun.imageset/smallSun.png create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/smallSun.imageset/smallSun@2x.png create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/smallSun.imageset/smallSun@3x.png create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/sun.imageset/Contents.json create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/sun.imageset/sun.png create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/sun.imageset/sun@2x.png create mode 100644 GradientSlider4/GradientSlider/Assets.xcassets/sun.imageset/sun@3x.png create mode 100644 GradientSlider4/GradientSlider/Base.lproj/LaunchScreen.storyboard create mode 100644 GradientSlider4/GradientSlider/Base.lproj/Main.storyboard create mode 100644 GradientSlider4/GradientSlider/GradientSlider4.swift create mode 100644 GradientSlider4/GradientSlider/Info.plist create mode 100644 GradientSlider4/GradientSlider/ViewController.swift create mode 100644 GradientSlider4/GradientSlider4.xcodeproj/project.pbxproj create mode 100644 GradientSlider4/GradientSlider4.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 GradientSlider4/GradientSlider4.xcodeproj/project.xcworkspace/xcshareddata/GradientSlider.xccheckout create mode 100644 GradientSlider4/GradientSlider4.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 GradientSlider4/GradientSlider4.xcodeproj/project.xcworkspace/xcuserdata/brad.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 GradientSlider4/GradientSlider4.xcodeproj/project.xcworkspace/xcuserdata/jon.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 GradientSlider4/GradientSlider4.xcodeproj/xcuserdata/brad.xcuserdatad/xcschemes/GradientSlider.xcscheme create mode 100644 GradientSlider4/GradientSlider4.xcodeproj/xcuserdata/brad.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 GradientSlider4/GradientSlider4.xcodeproj/xcuserdata/jon.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist create mode 100644 GradientSlider4/GradientSlider4.xcodeproj/xcuserdata/jon.xcuserdatad/xcschemes/GradientSlider.xcscheme create mode 100644 GradientSlider4/GradientSlider4.xcodeproj/xcuserdata/jon.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 GradientSlider4/LICENSE.txt create mode 100644 GradientSlider4/README.md diff --git a/GradientSlider4/GradientSlider/AppDelegate.swift b/GradientSlider4/GradientSlider/AppDelegate.swift new file mode 100644 index 0000000..79edc5a --- /dev/null +++ b/GradientSlider4/GradientSlider/AppDelegate.swift @@ -0,0 +1,47 @@ +// +// AppDelegate.swift +// GradientSlider +// +// Created by Jonathan Hull on 8/5/15. +// Copyright © 2015 Jonathan Hull. All rights reserved. +// +// Updated to Swift 4.1 by Brad Dowling + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/GradientSlider4/GradientSlider/Assets.xcassets/AppIcon.appiconset/Contents.json b/GradientSlider4/GradientSlider/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b8236c6 --- /dev/null +++ b/GradientSlider4/GradientSlider/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,48 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GradientSlider4/GradientSlider/Assets.xcassets/Contents.json b/GradientSlider4/GradientSlider/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/GradientSlider4/GradientSlider/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GradientSlider4/GradientSlider/Assets.xcassets/drop.imageset/Contents.json b/GradientSlider4/GradientSlider/Assets.xcassets/drop.imageset/Contents.json new file mode 100644 index 0000000..54761a7 --- /dev/null +++ b/GradientSlider4/GradientSlider/Assets.xcassets/drop.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "drop.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "drop@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "drop@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GradientSlider4/GradientSlider/Assets.xcassets/drop.imageset/drop.png b/GradientSlider4/GradientSlider/Assets.xcassets/drop.imageset/drop.png new file mode 100644 index 0000000000000000000000000000000000000000..9e3dd2c9d33ec0e4a093cac13277da286ea111ec GIT binary patch literal 471 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 QC;$Ke07*qoM6N<$f*!BeO8@`> literal 0 HcmV?d00001 diff --git a/GradientSlider4/GradientSlider/Assets.xcassets/moon.imageset/Contents.json b/GradientSlider4/GradientSlider/Assets.xcassets/moon.imageset/Contents.json new file mode 100644 index 0000000..19ea450 --- /dev/null +++ b/GradientSlider4/GradientSlider/Assets.xcassets/moon.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "moon.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "moon@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "moon@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GradientSlider4/GradientSlider/Assets.xcassets/moon.imageset/moon.png b/GradientSlider4/GradientSlider/Assets.xcassets/moon.imageset/moon.png new file mode 100644 index 0000000000000000000000000000000000000000..b087c1b58a99fed38b38ef5ea6c229878f75b595 GIT binary patch literal 526 zcmV+p0`dKcP)L)lZ0yQ547V&-`f^f2O8p!R$oJLdt@aSXe34ShJFq z&caHuP*Stzq$nk#Sj=i-HdeBsXjV!|%7WQh_%j(ZEbjB_@p_(V-kIO(_MCgZoqO)@ z+^5eniiiR1!67VV=JnBe8z#=x{>Pn%F;E33bCm6$e{KPX{?giY}1)acs z4A)}w*qNChS5WVL5vR5e8aUoRk`6YI3%Yy)%&(=EVr7*Q^D67TQs=~ z)p5GDh)*rx2a30kVmmfrIwD5?g0T(1S^#a}(>SkK@f&7w5nt=zzQ)w{?<&|0+{7zv z!LiI->TDRqd(ET$yGm%%qSDh@<>IDr{J*Lq;th5+R27+dXPL@d)fteN4Y6U(Zs`ep zTd`Mn?8KVDnfV-#m6xop(THfW;>y64LU|kN8o-4$firUsXYfOD1m#gW6%pgB23PP$ zIEXpL{1oTht0r`H;0pd)vEGc*^93BirCz{||Gdonf|C(3guOVdee4_c2WOykZ&d#Q QX#fBK07*qoM6N<$f-(*L^Z)<= literal 0 HcmV?d00001 diff --git a/GradientSlider4/GradientSlider/Assets.xcassets/moon.imageset/moon@2x.png b/GradientSlider4/GradientSlider/Assets.xcassets/moon.imageset/moon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..302861dd7a245544c2859e0d6270acee7fa65b3a GIT binary patch literal 1109 zcmV-b1giUqP)_P;IK|M$h75^@DeMksO2x@{Xk;IB}4-}$c!DvQgBS_Lhc@S>!H zX4VbNlk{C#o6bVx1;FyiKDR~4^#H={hA&Gx0o)F30LIPiY2b69&&)2Cbf8t9;*_{9 zQuYsEXGDB2um*Sm_}I+mFj3ug0AwSx$<8HJupa&QQ z76EqvH%t1fEKj59@2OxDa1SsJyyHK63-uI!S}TG5`5blD@*t?J;0pS%Q2HPi2Iog(dA~ zVkH2#RSyAQ`0Lxu>;jy0OLF1ExH;7w(SOKuUM2o1WoOf8zg4wq_@F<5Pb2%A%9LoE z;_47wd3hF^*%>KiLTE?08@MW=OAtljVcZQ6!}SSWg7{C^Z=X*^w*UWxJ%hlWi1rKp zx!WmYlCU4;O_4bUlGy~%s)l$UcTyS31~cob4@<*I!hV$R!`*}-%mwaFDOE*jRb*yM zfG?SNP^{ty;F7AcFcqa`rKE3g71Z&7JQo6YrIM;5!}G2WCWSN!bu;6c*CMurPb6T@{qnKI}8sGvhqY zoV|C=C4Vs7GiUZ*YtR4g$2x1DGjIX`y2W;2X5E0nz#w2i*=q+dSJE%B+fk2`V;MHH zLBQCxptQXJ*+zDKfvD*5OZOBUyA(HOj20RP&ZJ_D`NuPvh zgD>7fnAs5EMd0cNtF8f_@bw>x+>@o5od!GxJOZ53VD;_5Xi0zM^&gsCJ;KadfH#53 zIjSE7ZfPbFAcqiU)(2P(jLzxvK1rK$){RC(L&MDa0q+Ata{5~@X=2X0QOVpRlDObQ zpr41o`5twn(mhKdGdlw}C-{i40a)u%KPs7o0G8PiTXw((L%w_`fJpF70 zKJc^=m70^KnGFUu0cU#pnI`EyPa9FG+9Q&%`BnTy_#78SHZ`?|#&lpz03XYmd2T3D zQHZ2BJRZo$>Ogj)Qmsc!14ad~|DB|71K5eqaYFnbdjnLCEGGf2f$T>W!pz11uK?cw zGb9~O&i4k!0&6Ah%VMjN5N(0lc@S9VYb3e8xfl4j!V+w_>z*ON1YoV14Zy`M=K!za zQiXLX5h58D*ZMWRll77g1hBIdm(CHmbZT?Fd{iV1U#A5Nx7j=y#ZWA8iEIaWvTc5aYJA-rIGRV zz^v5!`z3vr)k#btcGfRaA4wgO?gs7v_9mxK2i^wyq>9c>9WRmeQX_skg-FKNxO~m6 zNYG6iN$t4U=BMOT4@zU5;&<7I>qQNbo-8k-@g!_D4gi^!ty-AbK-?|FTX2qBP$Sc zzQN4S#x0vgyL)iK-`}ZXYk-GR@23MxlGUd!T|x-pL5?k>hkzR;ZKX8sIV5QjurPIQ z4lW|COIH!1I2RlRW=r}gd7oZhi$T+)z{{!ggR?kD3lVaH3oXQRxYb~&q!p?2i-6yN z<&w66TXunaaJ^_DWvfm#(vjsQz*k|~%|1yjfo#>p%({ihlBb1e!38Ac@q1ocvZl$J zfzF{JsRMWA7K)H@Np#9%hmhNHq34OH#1vvg{UXgnxe%Lhm#rZPneB>Bi4c;G5N^YE zQgY{Am!Q)1#p{7=_atoUFDjLUcnA10ko{?a>_q1{A(G+oR3Q6ZSBQj_xO|~6L(S~M z0Cu8NQHZ2hRLcT2N|#tYY9(XZDNTIjWmf$n|2sb%Tua&m+zkBb;cKdy zg}NmvIGI!U$$T*$w{w)2rtK9C?PVmHkGOVMEAv literal 0 HcmV?d00001 diff --git a/GradientSlider4/GradientSlider/Assets.xcassets/smallSun.imageset/Contents.json b/GradientSlider4/GradientSlider/Assets.xcassets/smallSun.imageset/Contents.json new file mode 100644 index 0000000..f18a75b --- /dev/null +++ b/GradientSlider4/GradientSlider/Assets.xcassets/smallSun.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "smallSun.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "smallSun@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "smallSun@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GradientSlider4/GradientSlider/Assets.xcassets/smallSun.imageset/smallSun.png b/GradientSlider4/GradientSlider/Assets.xcassets/smallSun.imageset/smallSun.png new file mode 100644 index 0000000000000000000000000000000000000000..8b276f02ac76d2b874b76f2007ccd01919942d92 GIT binary patch literal 404 zcmV;F0c-w=P)5lR<6*F$_iDq_aWvJitYIfg*Jl;IiZlEYXJrmD&q% z5un!@$^tcXfzxKv3aOSNIp6k=o&3NJGqbsw&2Qy|q9B;rC4(M(rTE3nIyIe*r09wI zqnlNp(;+BWN5Is~`alopxjzAhdA9(y??259U?gepew&fDe)_@8hQQA8s>&DzOut(T zp@}iRx<8IFZZg7^Bm<~25O1{&AvDY7@+FVWX0s(9H^3PDbf|!wupCx2k-?X0-{oDYF%3Z0000=fU5qBX%U$!>RCkYCfTSv07J*FT{&97`7vND(A|Fks`>#~wB=HsJg{uv1=G#M zPWD>DH78w}h_nEIY*_|2fIeW(cmu#Z& z=#DLyfKBHdqc@%NYUo@6(>YG`Gt4@f3eXMQa=a;3z3KfWRxr!tCE#?h^#Zu6 zs^3!dP5@7VE5X(}P*&C7p-yHA6_GN#zbimnn)4utuZ~q#)#Wt#yl42u(Sv!;0ZeAd zu{N^g^8)B|^jxacUU=EwEWsvgr!!eX0IFJ7$FnDwhmj(s_&|}Dg#GMZXKVcI@*pCu zz;|2rtLpPK*}NN=cl1CJ=Lxc}vjp=3Xm|9iJ+VxPNE`4Z#l{|F6`~d3WU!T2h}wt> z(dA(4Gti}~zj6bxVPed&suqkd#Y04;_=oAV5?#ALd4;HRPB@;b>Ud%RHpBVRYXP_v zHzN_b20RJ_PC-RgADdna@DjM-_B-Pl(|5y3N0(IfV_>wqpmTt(n6Lx%Sc_jX_5?5r zjSVEdz%%3Z6J>kd14*IkCL(Wu^T4{Qo^kw|ozfrV6L5-XB+D$rP+%q$kq&bX(dqLL zUw=H!C3FWdk%%8ah#G9! zSWJqMM0*fd;5U$!#iw0JK%(M8QPEhwKn(pC%no>;x15gBsB(#ydF?%B_HYFb0G#Y@uWNZMNAvxv~Xvvt7ZUf1?2hE!UBq}#wNUe|@Zxpi>fYxg_O zXf%Z#&W+8L*-kU_mG((GYG!MIjlcl#q#OGd7y`~n`q9jG03W1+k`~yJp=&9ySkgr9 z0$d;&cb|U(%jzw}%({W^y{>P7rweQe=X6WTy+>x&23!N~b6xF{uB7AP5qijLHv`wr z>@zdV{DmZ)rPgm386VD>$ur)}7Ma->z;B-M0E_*3H4BjR6RX8jpTdP71F z*MJl5-?f}MEoRmecAD8vl6Vv5P+OgicaVGb%xn;NBV(vr(m7}RC&Ablun#y1Tum>g z+rbsUCg5$LBarKrbS&dYrWlm;W|p0GFOLf}=Yc1Jp;;gdU_-z@NizkUEx>-@^@i(I@d-(Hf0tbSC)T6e*vDr-JYAVuYh2F@Twk zG9L@ZNRqosvB1n)fwRo#TBDMliQ$M1WIL!0WE~`lSyk+(Hc{N{(v{NqFDG;BBwZ}x zDU(iL1Re{9W`Ho*43nhOHw!phNq+e-iOb@=OtO&pblO$Sc4rKgdC;5!CV~geN|Fm( z??JPk+y2=H{2fY2j;f%RkC5`wU zVO64&q)P1L7_dDrV7b_k_bx8NjHK2a-X^DeTQIcRe;0>d=y$LE2hb*|w~q1M)EYlp z!f1a^i#s+8AnCTG7lAh5mN!&Wy$-7qzW}S8;SZK5Zut-JKIg;N0xyxI1Sw9tzO`=7 z%idVlnfGnFA?X3PkX3$72r2}!6t47f$Ws&^$5(;(+~+Py2ZM2cS9eN!zlt4|vQc+F z4|!edD$w{chx3YOMW~ui`(9(LOuz}@WG;JMp-V1>Du3i_qt-KIUc!>_ccI4>aHCLV z2mCVOV7(|=1Sk8h*EJc-5u3~{#VfStmHT2K$uD2tAG-^&JK+2Lun7Eb;B!R<#n{5u z1kg?r4M&RRNAQjSt4V7AQ7^pa3d*h&&x%J_HZO}tRwa(-wEsW27ysSnA1cbuWnnoW QEC2ui07*qoM6N<$g7FoChX4Qo literal 0 HcmV?d00001 diff --git a/GradientSlider4/GradientSlider/Assets.xcassets/sun.imageset/Contents.json b/GradientSlider4/GradientSlider/Assets.xcassets/sun.imageset/Contents.json new file mode 100644 index 0000000..1efe4d4 --- /dev/null +++ b/GradientSlider4/GradientSlider/Assets.xcassets/sun.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "sun.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "sun@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "sun@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GradientSlider4/GradientSlider/Assets.xcassets/sun.imageset/sun.png b/GradientSlider4/GradientSlider/Assets.xcassets/sun.imageset/sun.png new file mode 100644 index 0000000000000000000000000000000000000000..379e9be38c9e449b3b243f55b08f7fa0646ce79e GIT binary patch literal 587 zcmV-R0<`^!P)Lm9cIUK@>&LpctjV?vgZd=U<4BO%S5Wcc1{>a}=87 z6Ve5I%V7A9lnAgv`Gr*2MdVb(6o?c~dckaG<@7^)2ILz$G%#K#Y z-^-A6%xt^1eBw_Pw{2#fm5G5*z{Jc#E+dakfRFz|yyNe)95FDgVgF7nX##u&_RXxB z$hHMM1ICi3DURU44#n|zoD?%_0KXjf1~^E}?@PLMd>gm`b|qb|Ip8O-1$;BJG4Mpv zt(jc|8xf)cV&}n_lByG7tJ^-ck+LETF z^VWeY3QJG@V~q;wDR5YuZ<<-dE#0eFdVQ%B^D08SllTWsbG$Hm!b(dXW_9n@HiD;OD#&eOe`NKaLG#^ Z;5Vo=*;rq1wEX}8002ovPDHLkV1mYi2Gall literal 0 HcmV?d00001 diff --git a/GradientSlider4/GradientSlider/Assets.xcassets/sun.imageset/sun@2x.png b/GradientSlider4/GradientSlider/Assets.xcassets/sun.imageset/sun@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..59f3eb1f836e1faa45c7f3559c0b10ae96bc04b7 GIT binary patch literal 1253 zcmV{r?Mjr32jg8sZKa?IHxk68^&bJLikj3W;9+Ok>D%9* z_cptU-(-_{^P8ESeZTkS-$EN8BAZ2Ib31HzwA!GE+z0$&%hjs-XDjV@w$hm4(Hy!Z zNOD+2DkAbhtG--B#zbT?MJL)}5$OY71rCVFzEtNj>aVL^vCLo$adgfTP~{VH>uy>m0`3GxKeVi)&aj6JqvW$ ztKJPf?d0~0$a>(csxAQM+_UvXj)_Po(5tGKJ-;Ims!$DG03*Sf4Go?F_S$kDc(}*` zsz+g?(Vwd7%LTSafDdh1QPn$PG~8i-CdWl&92m%Xb%V~~GG}ql0%XQ<5g7oc1GYc& zjkSa&g)n3-0qa!thRHk#d`9D?xdu!D7i_%^*afT&Dr1eRsBIkR#Sc?_EX=5Z7uk2U*#PGj+e++j|70V;)OBL zs;-*D(U+tE-o_U(F&NUK#92qLwb0ZQOm~fAMPK5So^FBV)!Ye7w@EOala4hP8-pP- z(^;o*E?{q=S{o##X5b+8EC6Ok4Na(x5IRI;7#KJ91~1bYDC`3s0ag?_Yp-yx)7u1e1J6>; zS~VOqUbm|HAM}#h$b@z4D}X*#9rDi_!df^7$bqk{`b}>E_}r?lT1Gq`gsLZ~hsU3R zdkUPs1$-a!lZzh_*$Lcb%fD1Lx^h$1S>PXA-Yp_KisZA8`o`u~e|{&o8w#Fd>yM&nv` P00000NkvXXu0mjf7h+X$ literal 0 HcmV?d00001 diff --git a/GradientSlider4/GradientSlider/Assets.xcassets/sun.imageset/sun@3x.png b/GradientSlider4/GradientSlider/Assets.xcassets/sun.imageset/sun@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..460d8817f2afab62d262caf706fbdeaa99dd2fd2 GIT binary patch literal 1733 zcmV;$20HnPP)K)V4^q7kG>F`6hvG{Lks;>V)O(zFCv zD4;~x9upQQEMQ?wAjX*B*_bE>EwWGuRF?=wqG(zW4FQEji9kUh3Vr~KQgm^rc;DQa zckjD1k7rE($xGgRoip!r=FIsji~@i$jbtt&?ZAL(cBtz9M(t&6qZk_uc)s6oG+Ge< z8H@_TpedAqh;#wFO>>H>o(rW}knd#RtZ8SrPJVw{NGsqbgKv*IJoYfmV#=vPBT zUWiT8!DB^inlS|Nu+`oqB6WL~MPw}Sw$2A;FJ_r;fVFn02I{`Hvtz!WJ?jNQB^MkT99@v z*r=*k@+OJM7!lbDT%b}2Uibtt#nZnSxF#Ztb2c&=m{nv0HDb1i+@8aGDR2#V#xrHI ztF!7~*Emp{s!VB9)gP=ibAV4sl%Wf!fj(dtZ~{1E`lkY|z&xNEXz{Ec1fEvagBD+x zl1^i}s=n(R%suAD$@vgi;F)q9n60Xp%}F?j`$rrF)&PB~daVG@ZeRm&uVcy}@Q|vW z6Or-2VJek#8ry+Ic{WGk=hN8vXMu5^DQ}V}$tN9SYk>{vC$u2XW?(h&ieq>;$q5k8 z@*&_3RV}2XYqled*<93OybL_6s(rQcv3T~7_%h=QE}5&UU)92+v_WMo#@BMD^@Iu` z#jgk0kuz5K3!w=zZfYn_M50qGj}sz3+o~!$ zRCWKziHMnrw(oB}a5^Hb0T@jJU&n|bIwI1X8j+R{LHfW#2N)e;Dpkt(9j#>Jj;%m& z<|zlQu0B;gS(aev)fgljSe+M0vj}V+Lj>xLP!oHYB+!~hw}~gz1*up?8b{KR?=pz7 z;muaN1-JhZ3q54@kiCbRQ4c`?tT&!%RG2``ddJXvp|nFy>?V@cMXB1^Hc8h7Zf zFI4cQ?Q;=%i6n93(%=AHot>TE_V@Qk$w-OFeBdq5@C;yGXJ_Z7{{H?_`PMQ|=3KG~ zSs(s?p*j=1Jzr(bMv^R)D|ow(BzS8-wRt@Ag13i(7d^{|NviyQEyAm4IDZ@2N|h1( z2t1&wS4=qn8{9dKV0(Y7mQ<@xFzdJCz9u2~ltky8 zuflr?kg3y1!C4gRdp>cFAEZOfcE@BKw#`a{VTz`&G4YSwL6nd%LRMQbTP7B-%WUy}+%&O5i)Pj#?T+ zX3k2p<_l~5P|;1O>P1z(naVIjmuqe#ONUy>hTK|#(*;V0GDY0 zzsEcg_S=0`Rlkl!Tvhjxlmw*_?0%0RiXhB0W!F{t>aap!*FP;ayn_+zM4YnP+lyAJ z)B@u`*)5RneDC47rQ=~lr)t3AVgpCMD$zj|>j9!nvHAkrqQvzW6^NGoHf*<1@6{lDQASIFfI-6)JEfel6lVbEwnba=jx bqEYw<^MEO#ej3n$00000NkvXXu0mjf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GradientSlider4/GradientSlider/Base.lproj/Main.storyboard b/GradientSlider4/GradientSlider/Base.lproj/Main.storyboard new file mode 100644 index 0000000..ef1df4e --- /dev/null +++ b/GradientSlider4/GradientSlider/Base.lproj/Main.storyboard @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GradientSlider4/GradientSlider/GradientSlider4.swift b/GradientSlider4/GradientSlider/GradientSlider4.swift new file mode 100644 index 0000000..188298f --- /dev/null +++ b/GradientSlider4/GradientSlider/GradientSlider4.swift @@ -0,0 +1,431 @@ +// +// GradientSlider.swift +// GradientSlider +// +// Created by Jonathan Hull on 8/5/15. +// Copyright © 2015 Jonathan Hull. All rights reserved. +// +// Updated to Swift 4.1 by Brad Dowling + +import UIKit + +@IBDesignable class GradientSlider: UIControl { + + static var defaultThickness:CGFloat = 2.0 + static var defaultThumbSize:CGFloat = 28.0 + + //MARK: Properties + @IBInspectable var hasRainbow:Bool = false {didSet{updateTrackColors()}}//Uses saturation & lightness from minColor + @IBInspectable var minColor:UIColor = UIColor.blue {didSet{updateTrackColors()}} + @IBInspectable var maxColor:UIColor = UIColor.orange {didSet{updateTrackColors()}} + + @IBInspectable var value: CGFloat { + get{return _value} + set{setValue(newValue, animated:true)} + } + + func setValue(_ value:CGFloat, animated:Bool = true) { + _value = max(min(value,self.maximumValue),self.minimumValue) + updateThumbPosition(animated: animated) + } + + @IBInspectable var minimumValue: CGFloat = 0.0 // default 0.0. the current value may change if outside new min value + @IBInspectable var maximumValue: CGFloat = 1.0 // default 1.0. the current value may change if outside new max value + + @IBInspectable var minimumValueImage: UIImage? = nil { // default is nil. image that appears to left of control (e.g. speaker off) + didSet{ + if let img = minimumValueImage { + let imgLayer = _minTrackImageLayer ?? { + let l = CALayer() + l.anchorPoint = CGPoint(x: 0.0, y: 0.5) + self.layer.addSublayer(l) + return l + }() + imgLayer.contents = img.cgImage + imgLayer.bounds = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height) + _minTrackImageLayer = imgLayer + + }else{ + _minTrackImageLayer?.removeFromSuperlayer() + _minTrackImageLayer = nil + } + self.layer.needsLayout() + } + } + @IBInspectable var maximumValueImage: UIImage? = nil { // default is nil. image that appears to right of control (e.g. speaker max) + didSet{ + if let img = maximumValueImage { + let imgLayer = _maxTrackImageLayer ?? { + let l = CALayer() + l.anchorPoint = CGPoint(x: 1.0, y: 0.5) + self.layer.addSublayer(l) + return l + }() + imgLayer.contents = img.cgImage + imgLayer.bounds = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height) + _maxTrackImageLayer = imgLayer + + }else{ + _maxTrackImageLayer?.removeFromSuperlayer() + _maxTrackImageLayer = nil + } + self.layer.needsLayout() + } + } + + var continuous: Bool = true // if set, value change events are generated any time the value changes due to dragging. default = YES + + var actionBlock:(GradientSlider,CGFloat)->() = {slider,newValue in } + + @IBInspectable var thickness:CGFloat = defaultThickness { + didSet{ + _trackLayer.cornerRadius = thickness / 2.0 + self.layer.setNeedsLayout() + } + } + + var trackBorderColor:UIColor? { + set{ + _trackLayer.borderColor = newValue?.cgColor + } + get{ + if let color = _trackLayer.borderColor { + return UIColor(cgColor: color) + } + return nil + } + } + + var trackBorderWidth:CGFloat { + set{ + _trackLayer.borderWidth = newValue + } + get{ + return _trackLayer.borderWidth + } + } + + var thumbSize:CGFloat = defaultThumbSize { + didSet{ + _thumbLayer.cornerRadius = thumbSize / 2.0 + _thumbLayer.bounds = CGRect(x: 0, y: 0, width: thumbSize, height: thumbSize) + self.invalidateIntrinsicContentSize() + } + } + + @IBInspectable var thumbIcon:UIImage? = nil { + didSet{ + _thumbIconLayer.contents = thumbIcon?.cgImage + } + } + + var thumbColor:UIColor { + get { + if let color = _thumbIconLayer.backgroundColor { + return UIColor(cgColor: color) + } + return UIColor.white + } + set { + _thumbIconLayer.backgroundColor = newValue.cgColor + thumbIcon = nil + } + } + + //MARK: - Convienience Colors + + func setGradientForHueWithSaturation(_ saturation:CGFloat,brightness:CGFloat){ + minColor = UIColor(hue: 0.0, saturation: saturation, brightness: brightness, alpha: 1.0) + hasRainbow = true + } + + func setGradientForSaturationWithHue(_ hue:CGFloat,brightness:CGFloat){ + hasRainbow = false + minColor = UIColor(hue: hue, saturation: 0.0, brightness: brightness, alpha: 1.0) + maxColor = UIColor(hue: hue, saturation: 1.0, brightness: brightness, alpha: 1.0) + } + + func setGradientForBrightnessWithHue(_ hue:CGFloat,saturation:CGFloat){ + hasRainbow = false + minColor = UIColor.black + maxColor = UIColor(hue: hue, saturation: saturation, brightness: 1.0, alpha: 1.0) + } + + func setGradientForRedWithGreen(_ green:CGFloat,blue:CGFloat){ + hasRainbow = false + minColor = UIColor(red: 0.0, green: green, blue: blue, alpha: 1.0) + maxColor = UIColor(red: 1.0, green: green, blue: blue, alpha: 1.0) + } + + func setGradientForGreenWithRed(_ red:CGFloat,blue:CGFloat){ + hasRainbow = false + minColor = UIColor(red: red, green: 0.0, blue: blue, alpha: 1.0) + maxColor = UIColor(red: red, green: 1.0, blue: blue, alpha: 1.0) + } + + func setGradientForBlueWithRed(_ red:CGFloat,green:CGFloat){ + hasRainbow = false + minColor = UIColor(red: red, green: green, blue: 0.0, alpha: 1.0) + maxColor = UIColor(red: red, green: green, blue: 1.0, alpha: 1.0) + } + + func setGradientForGrayscale(){ + hasRainbow = false + minColor = UIColor.black + maxColor = UIColor.white + } + + + //MARK: - Private Properties + + fileprivate var _value:CGFloat = 0.0 // default 0.0. this value will be pinned to min/max + + fileprivate var _thumbLayer:CALayer = { + let thumb = CALayer() + thumb.cornerRadius = defaultThumbSize/2.0 + thumb.bounds = CGRect(x: 0, y: 0, width: defaultThumbSize, height: defaultThumbSize) + thumb.backgroundColor = UIColor.white.cgColor + thumb.shadowColor = UIColor.black.cgColor + thumb.shadowOffset = CGSize(width: 0.0, height: 2.5) + thumb.shadowRadius = 2.0 + thumb.shadowOpacity = 0.25 + thumb.borderColor = UIColor.black.withAlphaComponent(0.15).cgColor + thumb.borderWidth = 0.5 + return thumb + }() + + fileprivate var _trackLayer:CAGradientLayer = { + let track = CAGradientLayer() + track.cornerRadius = defaultThickness / 2.0 + track.startPoint = CGPoint(x: 0.0, y: 0.5) + track.endPoint = CGPoint(x: 1.0, y: 0.5) + track.locations = [0.0,1.0] + track.colors = [UIColor.blue.cgColor,UIColor.orange.cgColor] + track.borderColor = UIColor.black.cgColor + return track + }() + + fileprivate var _minTrackImageLayer:CALayer? = nil + fileprivate var _maxTrackImageLayer:CALayer? = nil + + fileprivate var _thumbIconLayer:CALayer = { + let size = defaultThumbSize - 4 + let iconLayer = CALayer() + iconLayer.cornerRadius = size/2.0 + iconLayer.bounds = CGRect(x: 0, y: 0, width: size, height: size) + iconLayer.backgroundColor = UIColor.white.cgColor + return iconLayer + }() + + //MARK: - Init + + override init(frame: CGRect) { + super.init(frame: frame) + commonSetup() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + minColor = aDecoder.decodeObject(forKey: "minColor") as? UIColor ?? UIColor.lightGray + maxColor = aDecoder.decodeObject(forKey: "maxColor") as? UIColor ?? UIColor.darkGray + + value = aDecoder.decodeObject(forKey: "value") as? CGFloat ?? 0.0 + minimumValue = aDecoder.decodeObject(forKey: "minimumValue") as? CGFloat ?? 0.0 + maximumValue = aDecoder.decodeObject(forKey: "maximumValue") as? CGFloat ?? 1.0 + + minimumValueImage = aDecoder.decodeObject(forKey: "minimumValueImage") as? UIImage + maximumValueImage = aDecoder.decodeObject(forKey: "maximumValueImage") as? UIImage + + thickness = aDecoder.decodeObject(forKey: "thickness") as? CGFloat ?? 2.0 + + thumbIcon = aDecoder.decodeObject(forKey: "thumbIcon") as? UIImage + + commonSetup() + } + + override func encode(with aCoder: NSCoder) { + super.encode(with: aCoder) + + aCoder.encode(minColor, forKey: "minColor") + aCoder.encode(maxColor, forKey: "maxColor") + + aCoder.encode(value, forKey: "value") + aCoder.encode(minimumValue, forKey: "minimumValue") + aCoder.encode(maximumValue, forKey: "maximumValue") + + aCoder.encode(minimumValueImage, forKey: "minimumValueImage") + aCoder.encode(maximumValueImage, forKey: "maximumValueImage") + + aCoder.encode(thickness, forKey: "thickness") + + aCoder.encode(thumbIcon, forKey: "thumbIcon") + + } + + fileprivate func commonSetup() { + self.layer.delegate = self + self.layer.addSublayer(_trackLayer) + self.layer.addSublayer(_thumbLayer) + _thumbLayer.addSublayer(_thumbIconLayer) + } + + //MARK: - Layout + + override var intrinsicContentSize:CGSize { + return CGSize(width: UIViewNoIntrinsicMetric, height: thumbSize) + } + + override var alignmentRectInsets : UIEdgeInsets { + return UIEdgeInsetsMake(4.0, 2.0, 4.0, 2.0) + } + + override func layoutSublayers(of layer: CALayer) { +// super.layoutSublayersOfLayer(layer) + + if layer != self.layer {return} + + var w = self.bounds.width + let h = self.bounds.height + var left:CGFloat = 2.0 + + if let minImgLayer = _minTrackImageLayer { + minImgLayer.position = CGPoint(x: 0.0, y: h/2.0) + left = minImgLayer.bounds.width + 13.0 + } + w -= left + + if let maxImgLayer = _maxTrackImageLayer { + maxImgLayer.position = CGPoint(x: self.bounds.width, y: h/2.0) + w -= (maxImgLayer.bounds.width + 13.0) + }else{ + w -= 2.0 + } + + _trackLayer.bounds = CGRect(x: 0, y: 0, width: w, height: thickness) + _trackLayer.position = CGPoint(x: w/2.0 + left, y: h/2.0) + + let halfSize = thumbSize/2.0 + var layerSize = thumbSize - 4.0 + if let icon = thumbIcon { + layerSize = min(max(icon.size.height,icon.size.width),layerSize) + _thumbIconLayer.cornerRadius = 0.0 + _thumbIconLayer.backgroundColor = UIColor.clear.cgColor + }else{ + _thumbIconLayer.cornerRadius = layerSize/2.0 + } + _thumbIconLayer.position = CGPoint(x: halfSize, y: halfSize) + _thumbIconLayer.bounds = CGRect(x: 0, y: 0, width: layerSize, height: layerSize) + + + updateThumbPosition(animated: false) + } + + + + //MARK: - Touch Tracking + + override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { + let pt = touch.location(in: self) + + let center = _thumbLayer.position + let diameter = max(thumbSize,44.0) + let r = CGRect(x: center.x - diameter/2.0, y: center.y - diameter/2.0, width: diameter, height: diameter) + if r.contains(pt){ + sendActions(for: UIControlEvents.touchDown) + return true + } + return false + } + + override func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { + let pt = touch.location(in: self) + let newValue = valueForLocation(pt) + setValue(newValue, animated: false) + if(continuous){ + sendActions(for: UIControlEvents.valueChanged) + actionBlock(self,newValue) + } + return true + } + + override func endTracking(_ touch: UITouch?, with event: UIEvent?) { + if let pt = touch?.location(in: self){ + let newValue = valueForLocation(pt) + setValue(newValue, animated: false) + } + actionBlock(self,_value) + sendActions(for: [UIControlEvents.valueChanged, UIControlEvents.touchUpInside]) + + } + + //MARK: - Private Functions + + fileprivate func updateThumbPosition(animated:Bool){ + let diff = maximumValue - minimumValue + let perc = CGFloat((value - minimumValue) / diff) + + let halfHeight = self.bounds.height / 2.0 + let trackWidth = _trackLayer.bounds.width - thumbSize + let left = _trackLayer.position.x - trackWidth/2.0 + + if !animated{ + CATransaction.begin() //Move the thumb position without animations + CATransaction.setValue(true, forKey: kCATransactionDisableActions) + _thumbLayer.position = CGPoint(x: left + (trackWidth * perc), y: halfHeight) + CATransaction.commit() + }else{ + _thumbLayer.position = CGPoint(x: left + (trackWidth * perc), y: halfHeight) + } + } + + fileprivate func valueForLocation(_ point:CGPoint)->CGFloat { + + var left = self.bounds.origin.x + var w = self.bounds.width + if let minImgLayer = _minTrackImageLayer { + let amt = minImgLayer.bounds.width + 13.0 + w -= amt + left += amt + }else{ + w -= 2.0 + left += 2.0 + } + + if let maxImgLayer = _maxTrackImageLayer { + w -= (maxImgLayer.bounds.width + 13.0) + }else{ + w -= 2.0 + } + + let diff = CGFloat(self.maximumValue - self.minimumValue) + + let perc = max(min((point.x - left) / w ,1.0), 0.0) + + return (perc * diff) + CGFloat(self.minimumValue) + } + + fileprivate func updateTrackColors() { + if !hasRainbow { + _trackLayer.colors = [minColor.cgColor,maxColor.cgColor] + _trackLayer.locations = [0.0,1.0] + return + } + //Otherwise make a rainbow with the saturation & lightness of the min color + var h:CGFloat = 0.0 + var s:CGFloat = 0.0 + var l:CGFloat = 0.0 + var a:CGFloat = 1.0 + + minColor.getHue(&h, saturation: &s, brightness: &l, alpha: &a) + + let cnt = 40 + let step:CGFloat = 1.0 / CGFloat(cnt) + let locations:[CGFloat] = (0...cnt).map({ i in return (step * CGFloat(i))}) + _trackLayer.colors = locations.map({return UIColor(hue: $0, saturation: s, brightness: l, alpha: a).cgColor}) + _trackLayer.locations = locations as [NSNumber] + } +} + + + diff --git a/GradientSlider4/GradientSlider/Info.plist b/GradientSlider4/GradientSlider/Info.plist new file mode 100644 index 0000000..465b1b9 --- /dev/null +++ b/GradientSlider4/GradientSlider/Info.plist @@ -0,0 +1,42 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + GradientSlider4 + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/GradientSlider4/GradientSlider/ViewController.swift b/GradientSlider4/GradientSlider/ViewController.swift new file mode 100644 index 0000000..034f4ca --- /dev/null +++ b/GradientSlider4/GradientSlider/ViewController.swift @@ -0,0 +1,39 @@ +// +// ViewController.swift +// GradientSlider +// +// Created by Jonathan Hull on 8/5/15. +// Copyright © 2015 Jonathan Hull. All rights reserved. +// +// Updated to Swift 4.1 by Brad Dowling + +import UIKit + +class ViewController: UIViewController { + + @IBOutlet weak var hueSlider: GradientSlider! + @IBOutlet weak var brightnessSlider: GradientSlider! + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib. + + hueSlider.actionBlock = {slider,newValue in + CATransaction.begin() + CATransaction.setValue(true, forKey: kCATransactionDisableActions) + self.brightnessSlider.maxColor = UIColor(hue: newValue, saturation: 1.0, brightness: 1.0, alpha: 1.0) + slider.thumbColor = UIColor(hue: newValue, saturation: 1.0, brightness: 1.0, alpha: 1.0) + CATransaction.commit() + } + + hueSlider.thumbColor = UIColor(hue: 0.5, saturation: 1.0, brightness: 1.0, alpha: 1.0) + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + +} + diff --git a/GradientSlider4/GradientSlider4.xcodeproj/project.pbxproj b/GradientSlider4/GradientSlider4.xcodeproj/project.pbxproj new file mode 100644 index 0000000..5c77e9e --- /dev/null +++ b/GradientSlider4/GradientSlider4.xcodeproj/project.pbxproj @@ -0,0 +1,327 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + FC1C417D1B730A410083C062 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC1C417C1B730A410083C062 /* AppDelegate.swift */; }; + FC1C417F1B730A410083C062 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC1C417E1B730A410083C062 /* ViewController.swift */; }; + FC1C41821B730A410083C062 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FC1C41801B730A410083C062 /* Main.storyboard */; }; + FC1C41841B730A410083C062 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FC1C41831B730A410083C062 /* Assets.xcassets */; }; + FC1C41871B730A410083C062 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FC1C41851B730A410083C062 /* LaunchScreen.storyboard */; }; + FC1C418F1B730E530083C062 /* GradientSlider4.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC1C418E1B730E530083C062 /* GradientSlider4.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + FC1C41791B730A410083C062 /* GradientSlider4.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GradientSlider4.app; sourceTree = BUILT_PRODUCTS_DIR; }; + FC1C417C1B730A410083C062 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + FC1C417E1B730A410083C062 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + FC1C41811B730A410083C062 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + FC1C41831B730A410083C062 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + FC1C41861B730A410083C062 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + FC1C41881B730A410083C062 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + FC1C418E1B730E530083C062 /* GradientSlider4.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GradientSlider4.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + FC1C41761B730A410083C062 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + FC1C41701B730A410083C062 = { + isa = PBXGroup; + children = ( + FC1C417B1B730A410083C062 /* GradientSlider4 */, + FC1C417A1B730A410083C062 /* Products */, + ); + sourceTree = ""; + }; + FC1C417A1B730A410083C062 /* Products */ = { + isa = PBXGroup; + children = ( + FC1C41791B730A410083C062 /* GradientSlider4.app */, + ); + name = Products; + sourceTree = ""; + }; + FC1C417B1B730A410083C062 /* GradientSlider4 */ = { + isa = PBXGroup; + children = ( + FC1C417C1B730A410083C062 /* AppDelegate.swift */, + FC1C417E1B730A410083C062 /* ViewController.swift */, + FC1C41801B730A410083C062 /* Main.storyboard */, + FC1C418E1B730E530083C062 /* GradientSlider4.swift */, + FC1C41831B730A410083C062 /* Assets.xcassets */, + FC1C41851B730A410083C062 /* LaunchScreen.storyboard */, + FC1C41881B730A410083C062 /* Info.plist */, + ); + name = GradientSlider4; + path = GradientSlider; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + FC1C41781B730A410083C062 /* GradientSlider4 */ = { + isa = PBXNativeTarget; + buildConfigurationList = FC1C418B1B730A410083C062 /* Build configuration list for PBXNativeTarget "GradientSlider4" */; + buildPhases = ( + FC1C41751B730A410083C062 /* Sources */, + FC1C41761B730A410083C062 /* Frameworks */, + FC1C41771B730A410083C062 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GradientSlider4; + productName = GradientSlider; + productReference = FC1C41791B730A410083C062 /* GradientSlider4.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + FC1C41711B730A410083C062 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = "Jonathan Hull"; + TargetAttributes = { + FC1C41781B730A410083C062 = { + CreatedOnToolsVersion = 7.0; + DevelopmentTeam = 29Y384GTLV; + LastSwiftMigration = 0930; + }; + }; + }; + buildConfigurationList = FC1C41741B730A410083C062 /* Build configuration list for PBXProject "GradientSlider4" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = FC1C41701B730A410083C062; + productRefGroup = FC1C417A1B730A410083C062 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + FC1C41781B730A410083C062 /* GradientSlider4 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + FC1C41771B730A410083C062 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FC1C41871B730A410083C062 /* LaunchScreen.storyboard in Resources */, + FC1C41841B730A410083C062 /* Assets.xcassets in Resources */, + FC1C41821B730A410083C062 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + FC1C41751B730A410083C062 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FC1C417F1B730A410083C062 /* ViewController.swift in Sources */, + FC1C418F1B730E530083C062 /* GradientSlider4.swift in Sources */, + FC1C417D1B730A410083C062 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + FC1C41801B730A410083C062 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + FC1C41811B730A410083C062 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + FC1C41851B730A410083C062 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + FC1C41861B730A410083C062 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + FC1C41891B730A410083C062 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + FC1C418A1B730A410083C062 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + FC1C418C1B730A410083C062 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = 29Y384GTLV; + INFOPLIST_FILE = GradientSlider/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.Brad.GradientSlider4; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = On; + SWIFT_VERSION = 4.0; + }; + name = Debug; + }; + FC1C418D1B730A410083C062 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = 29Y384GTLV; + INFOPLIST_FILE = GradientSlider/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.Brad.GradientSlider4; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = On; + SWIFT_VERSION = 4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + FC1C41741B730A410083C062 /* Build configuration list for PBXProject "GradientSlider4" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FC1C41891B730A410083C062 /* Debug */, + FC1C418A1B730A410083C062 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FC1C418B1B730A410083C062 /* Build configuration list for PBXNativeTarget "GradientSlider4" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FC1C418C1B730A410083C062 /* Debug */, + FC1C418D1B730A410083C062 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = FC1C41711B730A410083C062 /* Project object */; +} diff --git a/GradientSlider4/GradientSlider4.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/GradientSlider4/GradientSlider4.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..c5d4ba9 --- /dev/null +++ b/GradientSlider4/GradientSlider4.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/GradientSlider4/GradientSlider4.xcodeproj/project.xcworkspace/xcshareddata/GradientSlider.xccheckout b/GradientSlider4/GradientSlider4.xcodeproj/project.xcworkspace/xcshareddata/GradientSlider.xccheckout new file mode 100644 index 0000000..56b8062 --- /dev/null +++ b/GradientSlider4/GradientSlider4.xcodeproj/project.xcworkspace/xcshareddata/GradientSlider.xccheckout @@ -0,0 +1,41 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 58D24B13-25F1-469C-B6C0-C0D2BE294047 + IDESourceControlProjectName + GradientSlider + IDESourceControlProjectOriginsDictionary + + 340883B9DF0F7567157D9FDF3AA826EDD0DE698F + https://github.com/jonhull/GradientSlider.git + + IDESourceControlProjectPath + GradientSlider.xcodeproj + IDESourceControlProjectRelativeInstallPathDictionary + + 340883B9DF0F7567157D9FDF3AA826EDD0DE698F + ../.. + + IDESourceControlProjectURL + https://github.com/jonhull/GradientSlider.git + IDESourceControlProjectVersion + 111 + IDESourceControlProjectWCCIdentifier + 340883B9DF0F7567157D9FDF3AA826EDD0DE698F + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + 340883B9DF0F7567157D9FDF3AA826EDD0DE698F + IDESourceControlWCCName + GradientSlider + + + + diff --git a/GradientSlider4/GradientSlider4.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/GradientSlider4/GradientSlider4.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/GradientSlider4/GradientSlider4.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/GradientSlider4/GradientSlider4.xcodeproj/project.xcworkspace/xcuserdata/brad.xcuserdatad/UserInterfaceState.xcuserstate b/GradientSlider4/GradientSlider4.xcodeproj/project.xcworkspace/xcuserdata/brad.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..7ded16067047359decf7bf279e1bb46d59283823 GIT binary patch literal 32617 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¥Eaoenp-qza}q`7s*THH{`eEW%4`n3VD@5n;5i} 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%0AM?(wU~?;d}6{OO52 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 np01CpPp?qB{mS~aeeq$O`zu)H5FW + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GradientSlider4/GradientSlider4.xcodeproj/xcuserdata/brad.xcuserdatad/xcschemes/xcschememanagement.plist b/GradientSlider4/GradientSlider4.xcodeproj/xcuserdata/brad.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..73853ce --- /dev/null +++ b/GradientSlider4/GradientSlider4.xcodeproj/xcuserdata/brad.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + GradientSlider.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + FC1C41781B730A410083C062 + + primary + + + + + diff --git a/GradientSlider4/GradientSlider4.xcodeproj/xcuserdata/jon.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/GradientSlider4/GradientSlider4.xcodeproj/xcuserdata/jon.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..fe2b454 --- /dev/null +++ b/GradientSlider4/GradientSlider4.xcodeproj/xcuserdata/jon.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,5 @@ + + + diff --git a/GradientSlider4/GradientSlider4.xcodeproj/xcuserdata/jon.xcuserdatad/xcschemes/GradientSlider.xcscheme b/GradientSlider4/GradientSlider4.xcodeproj/xcuserdata/jon.xcuserdatad/xcschemes/GradientSlider.xcscheme new file mode 100644 index 0000000..9f2d009 --- /dev/null +++ b/GradientSlider4/GradientSlider4.xcodeproj/xcuserdata/jon.xcuserdatad/xcschemes/GradientSlider.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GradientSlider4/GradientSlider4.xcodeproj/xcuserdata/jon.xcuserdatad/xcschemes/xcschememanagement.plist b/GradientSlider4/GradientSlider4.xcodeproj/xcuserdata/jon.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..73853ce --- /dev/null +++ b/GradientSlider4/GradientSlider4.xcodeproj/xcuserdata/jon.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + GradientSlider.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + FC1C41781B730A410083C062 + + primary + + + + + diff --git a/GradientSlider4/LICENSE.txt b/GradientSlider4/LICENSE.txt new file mode 100644 index 0000000..5c45511 --- /dev/null +++ b/GradientSlider4/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Jonathan Hull + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/GradientSlider4/README.md b/GradientSlider4/README.md new file mode 100644 index 0000000..9bf9087 --- /dev/null +++ b/GradientSlider4/README.md @@ -0,0 +1,133 @@ +# GradientSlider +![alt tag](https://cloud.githubusercontent.com/assets/167242/9134671/522e2f8a-3cbb-11e5-9d38-a0f1064a3e43.png) + +GradientSlider is a UIControl subclass which is similar to UISlider, but with a linear gradient coloring the slider’s track. Useful for creating color pickers. It is written in Swift 2 and requires it. + +**Features** +- Easily define a gradient by setting the min & max (i.e. left & right) colors +- Rainbow gradients (with customizable saturation & brightness) for making Hue selection sliders +- IBDesignable/Inspectable for direct use within Interface Builder +- Add an icon or color to the slider thumb +- Min/Max images (similar to UISlider) +- Both Target/Action and Block-based callbacks +- Customizable track thickness +- Customizable track border and thumb size +- Looks like UISlider by default, so they can be intermixed in the UI + +## Installation +Drag the “GradientSlider.swift” file into your Xcode project + +## Usage via Interface Builder +Drag a custom view into your storyboard and change it’s class to “GradientSlider”. Use the attributes inspector to optionally set the slider’s basic properties: +- min/max color +- hasRainbow (Note: the min color’s saturation & brightness are used) +- value +- minimum/maximum value +- minimum/maximum images +- thickness +- thumbIcon + +## Setting the Track Gradient Programmatically +### Min/Max Color +The track displays a linear gradient with the minColor corresponding to the minimumValue and the maxColor corresponding to the maximumValue. + + slider.minValue = UIColor.blueColor() + slider.maxValue = UIColor.orangeColor() + +![img alt](https://cloud.githubusercontent.com/assets/167242/9134778/8c34e16e-3cbc-11e5-9c54-452e8d3a2af7.png) + +### Rainbow +When the `hasRainbow` property is set to true, the track displays a rainbow gradient which moves around the color wheel (starting and ending with red). The saturation & brightness are both pulled from the color in `minValue`. + + slider.minValue = UIColor.blueColor() //This has full saturation & brightness + slider.hasRainbow = true + +![img alt](https://cloud.githubusercontent.com/assets/167242/9134881/5269de02-3cbd-11e5-9d78-056aca2b42d9.png) + +### Convenience Methods +Since one of the primary uses of the gradient sliders is to create color pickers, a few convenience methods have been provided for updating the colors. + +**HSB** + +`setGradientForHueWithSaturation(saturation:CGFloat,brightness:CGFloat)` This method sets the track to a rainbow gradient with the given saturation and brightness. This is useful for choosing a hue in the context of the current saturation and brightness settings. + +`setGradientForSaturationWithHue(hue:CGFloat,brightness:CGFloat)` This method sets the track to a gradient varying from grey to fully saturated with the hue and brightness provided. This is useful for choosing a saturation value in the context of the current hue and brightness settings. + +`setGradientForBrightnessWithHue(hue:CGFloat,saturation:CGFloat)` This method sets the track to a gradient varying from black to full brightness with the hue and saturation provided. This is useful for choosing a brightness value in the context of the current hue and saturation settings. + +**RGB** + +`setGradientForRedWithGreen(green:CGFloat, blue:CGFloat)` This method sets the track to a gradient with varying red for the given green & blue values. + +`setGradientForGreenWithRed(red:CGFloat, blue:CGFloat)` This method sets the track to a gradient with varying green for the given red & blue values. + +`setGradientForBlueWithRed(red:CGFloat, green:CGFloat)` This method sets the track to a gradient with varying blue for the given red & green values. + +**Grayscale** + +`setGradientForGrayscale()` This method sets the track to a gradient from black to white. + +## Responding to User Interaction +### Target/Action +As a UIControl subclass, the traditional target/action approach is fully supported. The slider will send TouchDown, ValueChanged, and TouchUpInside actions. If the `continuous` property is set to true (which it is by default), then the slider will send ValueChanged actions as the slider changes, otherwise a ValueChanged action is only sent when the user releases the slider. + +### ActionBlock +The slider will also call it’s actionBlock when its value is changed. If the `continuous` property is set to true (which it is by default), then the slider will call its actionBlock as the slider changes, otherwise it will only call it once when the slider is released. +The `actionBlock` property takes a closure which takes 2 parameters: The slider being changed and the new value, and has no return value. +It’s signature is: `(GradientSlider,CGFloat)->()` + +Here is an example of a hue slider which updates it’s own `thumbColor` to the value it is pointing to and updates sliders representing saturation & brightness to reflect it’s new value: + + //There are 3 @IBOutlets: hueSlide,satSlide, and brightSlide + + hueSlide.actionBlock = { slider, value in + let curSat = satSlide.value + let curBright = brightSlide.value + + //First disable animations so we get instantaneous updates + CATransaction.begin() + CATransaction.setValue(true, forKey: kCATransactionDisableActions) + + //Reflect the new hue in the saturation slider + satSlide.setGradientForSaturationWithHue(value, brightness:curBright) + + //Reflect the new hue in the brightness slider + brightSlide.setGradientForBrightnessWithHue(value, saturation:curSat) + + //Update hueSlider's thumb color to match our new value + slider.thumbColor = UIColor(hue: value, saturation: curSat, brightness: curBright, alpha: 1.0) + // (Note: We use the slider variable passed instead of 'hueSlide' to avoid retain cycles) + + CATransaction.commit() + } + +Images showing the effect of dragging the hue slider +![img alt](https://cloud.githubusercontent.com/assets/167242/9134674/55ae1c60-3cbb-11e5-888b-515dfc76898a.png) + +![img alt](https://cloud.githubusercontent.com/assets/167242/9134675/57c3043e-3cbb-11e5-8fa6-71b0f55b1105.png) + +## Customizing the Track +Besides the background gradient, the track is customizable in several ways using the following properties: +- `thickness:CGFloat` This sets the track’s thickness. The default value is 2pts +- `borderColor:UIColor` This sets the color of the track’s border. The default value is black. +- `borderWidth:CGFloat` This sets the width of the track’s border. The default value is 0 (i.e. no border). +- `minimumValueImage:UIImage?` This places an image to the left of the track. Setting it to nil removes any image which is there. The default value is nil (i.e. no image). +- `maximumValueImage:UIImage?` This places an image to the right of the track. Setting it to nil removes any image which is there. The default value is nil (i.e. no image). + +## Customizing the Thumb +The thumb can be resized, given a custom color or an icon (it can not have both a color and an icon at the same time). To customize the thumb, use the following properties: +- `thumbSize:CGFloat` This sets the diameter of the thumb. Note: Resizing the thumb may change the slider’s intrisicContentSize. The default is 28.0 pts. +- `thumbColor:UIColor` This sets the color displayed by the thumb. When the thumb has an associated icon, the color is automatically set to clearColor, and setting a new color removes the icon. The default value is White. +- `thumbIcon:UIImage?` This sets the image to display inside the slider’s thumb. Setting an image automatically removes the thumbColor, and setting a color removes the icon. The default value is nil (i.e. no image) + +## License +The MIT License (MIT) + +Copyright (c) 2015 Jonathan Hull + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file From 5786b1b8b81ca1653d1702df1fc1d6fd48935ae6 Mon Sep 17 00:00:00 2001 From: Bradley Dowling <34559056+btdow@users.noreply.github.com> Date: Fri, 30 Mar 2018 17:45:42 -0400 Subject: [PATCH 3/8] Update AppDelegate.swift --- GradientSlider3/GradientSlider/AppDelegate.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GradientSlider3/GradientSlider/AppDelegate.swift b/GradientSlider3/GradientSlider/AppDelegate.swift index f5d68cc..2bf4f14 100644 --- a/GradientSlider3/GradientSlider/AppDelegate.swift +++ b/GradientSlider3/GradientSlider/AppDelegate.swift @@ -5,7 +5,7 @@ // Created by Jonathan Hull on 8/5/15. // Copyright © 2015 Jonathan Hull. All rights reserved. // -// Updated to Swift 3.2 by Brad Dowling +// Updated to Swift 3.2 import UIKit From d6acb9deaf3ae08f9706ad8c593a159e8f2c806c Mon Sep 17 00:00:00 2001 From: Bradley Dowling <34559056+btdow@users.noreply.github.com> Date: Fri, 30 Mar 2018 17:46:10 -0400 Subject: [PATCH 4/8] Update GradientSlider3.swift --- GradientSlider3/GradientSlider/GradientSlider3.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GradientSlider3/GradientSlider/GradientSlider3.swift b/GradientSlider3/GradientSlider/GradientSlider3.swift index 3950f93..014bd12 100644 --- a/GradientSlider3/GradientSlider/GradientSlider3.swift +++ b/GradientSlider3/GradientSlider/GradientSlider3.swift @@ -5,7 +5,7 @@ // Created by Jonathan Hull on 8/5/15. // Copyright © 2015 Jonathan Hull. All rights reserved. // -// Updated to Swift 3.2 by Brad Dowling +// Updated to Swift 3.2 import UIKit From 5333393e3887b024748541bfbd7b1a18a4772af7 Mon Sep 17 00:00:00 2001 From: Bradley Dowling <34559056+btdow@users.noreply.github.com> Date: Fri, 30 Mar 2018 17:46:26 -0400 Subject: [PATCH 5/8] Update ViewController.swift --- GradientSlider3/GradientSlider/ViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GradientSlider3/GradientSlider/ViewController.swift b/GradientSlider3/GradientSlider/ViewController.swift index 6ef4428..4951478 100644 --- a/GradientSlider3/GradientSlider/ViewController.swift +++ b/GradientSlider3/GradientSlider/ViewController.swift @@ -5,7 +5,7 @@ // Created by Jonathan Hull on 8/5/15. // Copyright © 2015 Jonathan Hull. All rights reserved. // -// Updated to Swift 3.2 by Brad Dowling +// Updated to Swift 3.2 import UIKit From 9ddbc276edd8d4c0ef1b0e25b5a0a0db57539f64 Mon Sep 17 00:00:00 2001 From: Bradley Dowling <34559056+btdow@users.noreply.github.com> Date: Fri, 30 Mar 2018 17:47:03 -0400 Subject: [PATCH 6/8] Update AppDelegate.swift --- GradientSlider4/GradientSlider/AppDelegate.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GradientSlider4/GradientSlider/AppDelegate.swift b/GradientSlider4/GradientSlider/AppDelegate.swift index 79edc5a..8236618 100644 --- a/GradientSlider4/GradientSlider/AppDelegate.swift +++ b/GradientSlider4/GradientSlider/AppDelegate.swift @@ -5,7 +5,7 @@ // Created by Jonathan Hull on 8/5/15. // Copyright © 2015 Jonathan Hull. All rights reserved. // -// Updated to Swift 4.1 by Brad Dowling +// Updated to Swift 4.1 import UIKit From d9a25dccecea72d4b48d23368d368fcf5f8116ad Mon Sep 17 00:00:00 2001 From: Bradley Dowling <34559056+btdow@users.noreply.github.com> Date: Fri, 30 Mar 2018 17:47:17 -0400 Subject: [PATCH 7/8] Update GradientSlider4.swift --- GradientSlider4/GradientSlider/GradientSlider4.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GradientSlider4/GradientSlider/GradientSlider4.swift b/GradientSlider4/GradientSlider/GradientSlider4.swift index 188298f..7b8c6fd 100644 --- a/GradientSlider4/GradientSlider/GradientSlider4.swift +++ b/GradientSlider4/GradientSlider/GradientSlider4.swift @@ -5,7 +5,7 @@ // Created by Jonathan Hull on 8/5/15. // Copyright © 2015 Jonathan Hull. All rights reserved. // -// Updated to Swift 4.1 by Brad Dowling +// Updated to Swift 4.1 import UIKit From 38e0df46bd9a00bc7eb99a1804d554bc307abba9 Mon Sep 17 00:00:00 2001 From: Bradley Dowling <34559056+btdow@users.noreply.github.com> Date: Fri, 30 Mar 2018 17:47:37 -0400 Subject: [PATCH 8/8] Update ViewController.swift --- GradientSlider4/GradientSlider/ViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GradientSlider4/GradientSlider/ViewController.swift b/GradientSlider4/GradientSlider/ViewController.swift index 034f4ca..9c32169 100644 --- a/GradientSlider4/GradientSlider/ViewController.swift +++ b/GradientSlider4/GradientSlider/ViewController.swift @@ -5,7 +5,7 @@ // Created by Jonathan Hull on 8/5/15. // Copyright © 2015 Jonathan Hull. All rights reserved. // -// Updated to Swift 4.1 by Brad Dowling +// Updated to Swift 4.1 import UIKit