Moving Pow to @emergetools (#36)
Co-authored-by: Robert Böhnke <robb@robb.is> Co-authored-by: Kasper Lahti <kasper@lahti.email>
61
0.x.x to 1.0.0 Update Guide/README.md
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
# 1.0 Update Guide
|
||||||
|
|
||||||
|
If you are moving from a version of Pow below 1.0.0 the first thing you'll notice is that Pow is now open source. 🎉🎉🎉
|
||||||
|
|
||||||
|
Previously Pow was a paid product, and now it is a a community project operated and sponsored by [Emerge Tools](https://github.com/EmergeTools).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Pow's version number has been bumped from 0.3.1 to 1.0.0, and despite this being a new major version there are **no breaking changes**.
|
||||||
|
>
|
||||||
|
> Now that the Pow project is run by EmergeTools you should use the URL https://github.com/EmergeTools/Pow rather than https://github.com/movingparts-io/Pow.
|
||||||
|
|
||||||
|
|
||||||
|
### Integrate Pow 1.0.0+ into your app.
|
||||||
|
|
||||||
|
If you've integrated Pow through Xcode's Package Dependencies you will need to update the Pow package dependency to point to 1.0.0.
|
||||||
|
|
||||||
|
If you're using the default Up to Next Major Version rule you may need to manually update the version number to 1.0.0. Going from 0.x.x to 1.0.0 is considered a major version update, so Xcode will not do it automatically on your behalf for fear of breaking changes.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
When you set Pow to version 1.0.0 in your Package Dependencies list it will now look like this.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
If you're using Swift Package Manager you should update the URL and version number of any references you have to Pow.
|
||||||
|
|
||||||
|
> Before
|
||||||
|
> ```swift
|
||||||
|
> .package(url: "https://github.com/movingparts-io/Pow", from: Version(0, 3, 1))
|
||||||
|
> ```
|
||||||
|
|
||||||
|
> After
|
||||||
|
> ```swift
|
||||||
|
> .package(url: "https://github.com/EmergeTools/Pow", from: Version(1, 0, 0))
|
||||||
|
> ```
|
||||||
|
|
||||||
|
Sometimes Swift Package Manager will show errors like this after upgrading a dependency.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
This is a long-standing issue with Xcode, not Pow. The solution of course is to close and re-open Xcode.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
To confirm that Pow has been updated you can look at the list of installed Swift Packages in your project's File Navigator. (The first tab of Xcode's left sidebar.) If everything has gone correctly you will see Pow 1.0.0, and now that the framework is open source you will also see all of the source code.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Remove Pow's License
|
||||||
|
|
||||||
|
Now that Pow is free, you too are free to remove this line of code that would validate your purchase of a Pow license.
|
||||||
|
|
||||||
|
```swift
|
||||||
|
Pow.unlockPow(reason: .iDidBuyTheLicense)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
And that's it, easy as 0.1, 0.2, 0.3. If you run into any problems upgrading please file an [issue](gihtub.com/EmergeTools/Pow/issues), we're more than happy to help.
|
||||||
BIN
0.x.x to 1.0.0 Update Guide/images/pow-source-after-update.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
0.x.x to 1.0.0 Update Guide/images/pow-version-updated-after.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 66 KiB |
BIN
0.x.x to 1.0.0 Update Guide/images/xcode-errors.png
Normal file
|
After Width: | Height: | Size: 124 KiB |
790
Example/Pow Example.xcodeproj/project.pbxproj
Normal file
|
|
@ -0,0 +1,790 @@
|
||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 56;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
236B13462940BAFD0022AF1F /* CheckoutExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 236B13452940BAFD0022AF1F /* CheckoutExample.swift */; };
|
||||||
|
541356DC293E91A000EC0F1A /* SoundEffectsExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 541356DB293E91A000EC0F1A /* SoundEffectsExample.swift */; };
|
||||||
|
54135714293E941000EC0F1A /* pick.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 54135708293E93D600EC0F1A /* pick.m4a */; };
|
||||||
|
54135715293E941000EC0F1A /* reel.falling.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356E4293E93D400EC0F1A /* reel.falling.m4a */; };
|
||||||
|
54135716293E941000EC0F1A /* latch1.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356EA293E93D400EC0F1A /* latch1.m4a */; };
|
||||||
|
54135717293E941000EC0F1A /* pick.falling.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356E5293E93D400EC0F1A /* pick.falling.m4a */; };
|
||||||
|
54135718293E941000EC0F1A /* brush.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 54135704293E93D600EC0F1A /* brush.m4a */; };
|
||||||
|
54135719293E941000EC0F1A /* pop4.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356FF293E93D600EC0F1A /* pop4.m4a */; };
|
||||||
|
5413571A293E941000EC0F1A /* reel.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356DF293E93D400EC0F1A /* reel.m4a */; };
|
||||||
|
5413571B293E941000EC0F1A /* sparkle.rising.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356F9293E93D500EC0F1A /* sparkle.rising.m4a */; };
|
||||||
|
5413571C293E941000EC0F1A /* wip.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356EB293E93D400EC0F1A /* wip.m4a */; };
|
||||||
|
5413571D293E941000EC0F1A /* tock.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356F0293E93D500EC0F1A /* tock.m4a */; };
|
||||||
|
5413571E293E941000EC0F1A /* pick.flat.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356ED293E93D400EC0F1A /* pick.flat.m4a */; };
|
||||||
|
5413571F293E941000EC0F1A /* chime.falling.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 5413570F293E93D700EC0F1A /* chime.falling.m4a */; };
|
||||||
|
54135720293E941000EC0F1A /* chime.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356F7293E93D500EC0F1A /* chime.m4a */; };
|
||||||
|
54135721293E941000EC0F1A /* swipe.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 54135709293E93D600EC0F1A /* swipe.m4a */; };
|
||||||
|
54135722293E941000EC0F1A /* tick.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 54135705293E93D600EC0F1A /* tick.m4a */; };
|
||||||
|
54135723293E941000EC0F1A /* lock1.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 54135701293E93D600EC0F1A /* lock1.m4a */; };
|
||||||
|
54135724293E941000EC0F1A /* pick.rising.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 54135706293E93D600EC0F1A /* pick.rising.m4a */; };
|
||||||
|
54135725293E941000EC0F1A /* plop.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356F6293E93D500EC0F1A /* plop.m4a */; };
|
||||||
|
54135726293E941000EC0F1A /* detach.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 54135710293E93D700EC0F1A /* detach.m4a */; };
|
||||||
|
54135727293E941000EC0F1A /* swish.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356FA293E93D500EC0F1A /* swish.m4a */; };
|
||||||
|
54135728293E941000EC0F1A /* snap.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 54135707293E93D600EC0F1A /* snap.m4a */; };
|
||||||
|
54135729293E941000EC0F1A /* drip.falling.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 5413570C293E93D600EC0F1A /* drip.falling.m4a */; };
|
||||||
|
5413572A293E941000EC0F1A /* chime.rising.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356E3293E93D400EC0F1A /* chime.rising.m4a */; };
|
||||||
|
5413572B293E941000EC0F1A /* notfound.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356EC293E93D400EC0F1A /* notfound.m4a */; };
|
||||||
|
5413572C293E941000EC0F1A /* pluck.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 5413570E293E93D600EC0F1A /* pluck.m4a */; };
|
||||||
|
5413572D293E941000EC0F1A /* dial.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356E9293E93D400EC0F1A /* dial.m4a */; };
|
||||||
|
5413572E293E941000EC0F1A /* shake.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356E7293E93D400EC0F1A /* shake.m4a */; };
|
||||||
|
5413572F293E941000EC0F1A /* tink.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356F1293E93D500EC0F1A /* tink.m4a */; };
|
||||||
|
54135730293E941000EC0F1A /* lock4.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356F2293E93D500EC0F1A /* lock4.m4a */; };
|
||||||
|
54135731293E941000EC0F1A /* boop.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356FB293E93D500EC0F1A /* boop.m4a */; };
|
||||||
|
54135732293E941000EC0F1A /* drip.flat.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 54135713293E93D700EC0F1A /* drip.flat.m4a */; };
|
||||||
|
54135733293E941000EC0F1A /* latch2.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 54135702293E93D600EC0F1A /* latch2.m4a */; };
|
||||||
|
54135734293E941000EC0F1A /* lock2.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356E1293E93D400EC0F1A /* lock2.m4a */; };
|
||||||
|
54135735293E941000EC0F1A /* pop5.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356F5293E93D500EC0F1A /* pop5.m4a */; };
|
||||||
|
54135736293E941000EC0F1A /* latch4.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356E8293E93D400EC0F1A /* latch4.m4a */; };
|
||||||
|
54135737293E941000EC0F1A /* glass.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 54135700293E93D600EC0F1A /* glass.m4a */; };
|
||||||
|
54135738293E941000EC0F1A /* zing.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356EE293E93D400EC0F1A /* zing.m4a */; };
|
||||||
|
54135739293E941000EC0F1A /* pong.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356E2293E93D400EC0F1A /* pong.m4a */; };
|
||||||
|
5413573A293E941000EC0F1A /* drip.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 54135711293E93D700EC0F1A /* drip.m4a */; };
|
||||||
|
5413573B293E941000EC0F1A /* beep.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356FC293E93D500EC0F1A /* beep.m4a */; };
|
||||||
|
5413573C293E941000EC0F1A /* latch3.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356F3293E93D500EC0F1A /* latch3.m4a */; };
|
||||||
|
5413573D293E941000EC0F1A /* reel.rising.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 5413570D293E93D600EC0F1A /* reel.rising.m4a */; };
|
||||||
|
5413573E293E941000EC0F1A /* sparkle.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 5413570A293E93D600EC0F1A /* sparkle.m4a */; };
|
||||||
|
5413573F293E941000EC0F1A /* sparkle.flat.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356FD293E93D500EC0F1A /* sparkle.flat.m4a */; };
|
||||||
|
54135740293E941000EC0F1A /* reel.flat.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356DE293E93D300EC0F1A /* reel.flat.m4a */; };
|
||||||
|
54135741293E941000EC0F1A /* pop2.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 54135703293E93D600EC0F1A /* pop2.m4a */; };
|
||||||
|
54135742293E941000EC0F1A /* chime.flat.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356EF293E93D500EC0F1A /* chime.flat.m4a */; };
|
||||||
|
54135743293E941000EC0F1A /* whop.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356FE293E93D500EC0F1A /* whop.m4a */; };
|
||||||
|
54135744293E941000EC0F1A /* drip.rising.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 5413570B293E93D600EC0F1A /* drip.rising.m4a */; };
|
||||||
|
54135745293E941000EC0F1A /* ping.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356F8293E93D500EC0F1A /* ping.m4a */; };
|
||||||
|
54135746293E941000EC0F1A /* lock3.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356F4293E93D500EC0F1A /* lock3.m4a */; };
|
||||||
|
54135747293E941000EC0F1A /* pop1.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 54135712293E93D700EC0F1A /* pop1.m4a */; };
|
||||||
|
54135748293E941000EC0F1A /* sparkle.falling.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356E6293E93D400EC0F1A /* sparkle.falling.m4a */; };
|
||||||
|
54135749293E941000EC0F1A /* pop3.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356E0293E93D400EC0F1A /* pop3.m4a */; };
|
||||||
|
5413574A293E941000EC0F1A /* biip.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 541356DD293E93D300EC0F1A /* biip.m4a */; };
|
||||||
|
546A298A292A31BB00A80DE2 /* PowExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A2989292A31BB00A80DE2 /* PowExampleApp.swift */; };
|
||||||
|
546A298C292A31BB00A80DE2 /* ExampleList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A298B292A31BB00A80DE2 /* ExampleList.swift */; };
|
||||||
|
546A298E292A31BC00A80DE2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 546A298D292A31BC00A80DE2 /* Assets.xcassets */; };
|
||||||
|
546A2991292A31BC00A80DE2 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 546A2990292A31BC00A80DE2 /* Preview Assets.xcassets */; };
|
||||||
|
546A299B292A332900A80DE2 /* AnvilExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A299A292A332900A80DE2 /* AnvilExample.swift */; };
|
||||||
|
546A299E292A335600A80DE2 /* PlaceholderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A299D292A335600A80DE2 /* PlaceholderView.swift */; };
|
||||||
|
546A29A0292A341700A80DE2 /* Example.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A299F292A341700A80DE2 /* Example.swift */; };
|
||||||
|
546A29A2292A349900A80DE2 /* BlindsExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29A1292A349900A80DE2 /* BlindsExample.swift */; };
|
||||||
|
546A29A4292A34A600A80DE2 /* ClockExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29A3292A34A600A80DE2 /* ClockExample.swift */; };
|
||||||
|
546A29A6292A355400A80DE2 /* BoingExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29A5292A355400A80DE2 /* BoingExample.swift */; };
|
||||||
|
546A29AA292A397100A80DE2 /* BlurExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29A9292A397100A80DE2 /* BlurExample.swift */; };
|
||||||
|
546A29AC292A3B9D00A80DE2 /* FilmExposureExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29AB292A3B9D00A80DE2 /* FilmExposureExample.swift */; };
|
||||||
|
546A29AE292A3D8900A80DE2 /* FlipExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29AD292A3D8900A80DE2 /* FlipExample.swift */; };
|
||||||
|
546A29B0292A3DA800A80DE2 /* FlickerExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29AF292A3DA800A80DE2 /* FlickerExample.swift */; };
|
||||||
|
546A29B2292A3ED800A80DE2 /* GlareExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29B1292A3ED800A80DE2 /* GlareExample.swift */; };
|
||||||
|
546A29B4292A401500A80DE2 /* PopExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29B3292A401500A80DE2 /* PopExample.swift */; };
|
||||||
|
546A29B6292A406E00A80DE2 /* IrisExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29B5292A406E00A80DE2 /* IrisExample.swift */; };
|
||||||
|
546A29B8292A40B000A80DE2 /* MoveExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29B7292A40AF00A80DE2 /* MoveExample.swift */; };
|
||||||
|
546A29BA292A40D800A80DE2 /* PoofExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29B9292A40D800A80DE2 /* PoofExample.swift */; };
|
||||||
|
546A29BC292A414A00A80DE2 /* SnapshotExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29BB292A414A00A80DE2 /* SnapshotExample.swift */; };
|
||||||
|
546A29BE292A41CF00A80DE2 /* VanishExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29BD292A41CF00A80DE2 /* VanishExample.swift */; };
|
||||||
|
546A29C0292A420F00A80DE2 /* SwooshExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29BF292A420E00A80DE2 /* SwooshExample.swift */; };
|
||||||
|
546A29C2292A431800A80DE2 /* WipeExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29C1292A431800A80DE2 /* WipeExample.swift */; };
|
||||||
|
546A29C6292A4BC100A80DE2 /* JumpExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29C5292A4BC100A80DE2 /* JumpExample.swift */; };
|
||||||
|
546A29C8292A4BFA00A80DE2 /* PingExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29C7292A4BFA00A80DE2 /* PingExample.swift */; };
|
||||||
|
546A29CA292A4DBD00A80DE2 /* RiseExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29C9292A4DBD00A80DE2 /* RiseExample.swift */; };
|
||||||
|
546A29CC292A559A00A80DE2 /* ShakeExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29CB292A559A00A80DE2 /* ShakeExample.swift */; };
|
||||||
|
546A29CE292A591F00A80DE2 /* ShineExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29CD292A591F00A80DE2 /* ShineExample.swift */; };
|
||||||
|
546A29D0292A676200A80DE2 /* SkidExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29CF292A676200A80DE2 /* SkidExample.swift */; };
|
||||||
|
546A29D2292A68E100A80DE2 /* SpinExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29D1292A68E100A80DE2 /* SpinExample.swift */; };
|
||||||
|
546A29D4292A6B1200A80DE2 /* SprayExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 546A29D3292A6B1200A80DE2 /* SprayExample.swift */; };
|
||||||
|
549BF5F5293642BC00B2DCCF /* SocialFeedExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 549BF5F4293642BC00B2DCCF /* SocialFeedExample.swift */; };
|
||||||
|
54A962302934CC4400BBD5FE /* GithubButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54A9622F2934CC4400BBD5FE /* GithubButton.swift */; };
|
||||||
|
54B7259729F9C70900C17B99 /* PushDownExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B7259629F9C70900C17B99 /* PushDownExample.swift */; };
|
||||||
|
54F15E5029D598150054690B /* RepeatExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F15E4F29D598150054690B /* RepeatExample.swift */; };
|
||||||
|
54F15E5229D59A920054690B /* SmokeExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F15E5129D59A920054690B /* SmokeExample.swift */; };
|
||||||
|
54F15E5429D59D250054690B /* PulseExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F15E5329D59D250054690B /* PulseExample.swift */; };
|
||||||
|
54F15E5629D5A0D70054690B /* GlowExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F15E5529D5A0D70054690B /* GlowExample.swift */; };
|
||||||
|
B7A5DA8D2B0E853A0035FC0A /* Pow in Frameworks */ = {isa = PBXBuildFile; productRef = B7A5DA8C2B0E853A0035FC0A /* Pow */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
236B13452940BAFD0022AF1F /* CheckoutExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckoutExample.swift; sourceTree = "<group>"; };
|
||||||
|
541356DB293E91A000EC0F1A /* SoundEffectsExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoundEffectsExample.swift; sourceTree = "<group>"; };
|
||||||
|
541356DD293E93D300EC0F1A /* biip.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = biip.m4a; sourceTree = "<group>"; };
|
||||||
|
541356DE293E93D300EC0F1A /* reel.flat.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = reel.flat.m4a; sourceTree = "<group>"; };
|
||||||
|
541356DF293E93D400EC0F1A /* reel.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = reel.m4a; sourceTree = "<group>"; };
|
||||||
|
541356E0293E93D400EC0F1A /* pop3.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = pop3.m4a; sourceTree = "<group>"; };
|
||||||
|
541356E1293E93D400EC0F1A /* lock2.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = lock2.m4a; sourceTree = "<group>"; };
|
||||||
|
541356E2293E93D400EC0F1A /* pong.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = pong.m4a; sourceTree = "<group>"; };
|
||||||
|
541356E3293E93D400EC0F1A /* chime.rising.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = chime.rising.m4a; sourceTree = "<group>"; };
|
||||||
|
541356E4293E93D400EC0F1A /* reel.falling.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = reel.falling.m4a; sourceTree = "<group>"; };
|
||||||
|
541356E5293E93D400EC0F1A /* pick.falling.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = pick.falling.m4a; sourceTree = "<group>"; };
|
||||||
|
541356E6293E93D400EC0F1A /* sparkle.falling.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = sparkle.falling.m4a; sourceTree = "<group>"; };
|
||||||
|
541356E7293E93D400EC0F1A /* shake.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = shake.m4a; sourceTree = "<group>"; };
|
||||||
|
541356E8293E93D400EC0F1A /* latch4.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = latch4.m4a; sourceTree = "<group>"; };
|
||||||
|
541356E9293E93D400EC0F1A /* dial.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = dial.m4a; sourceTree = "<group>"; };
|
||||||
|
541356EA293E93D400EC0F1A /* latch1.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = latch1.m4a; sourceTree = "<group>"; };
|
||||||
|
541356EB293E93D400EC0F1A /* wip.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = wip.m4a; sourceTree = "<group>"; };
|
||||||
|
541356EC293E93D400EC0F1A /* notfound.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = notfound.m4a; sourceTree = "<group>"; };
|
||||||
|
541356ED293E93D400EC0F1A /* pick.flat.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = pick.flat.m4a; sourceTree = "<group>"; };
|
||||||
|
541356EE293E93D400EC0F1A /* zing.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = zing.m4a; sourceTree = "<group>"; };
|
||||||
|
541356EF293E93D500EC0F1A /* chime.flat.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = chime.flat.m4a; sourceTree = "<group>"; };
|
||||||
|
541356F0293E93D500EC0F1A /* tock.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = tock.m4a; sourceTree = "<group>"; };
|
||||||
|
541356F1293E93D500EC0F1A /* tink.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = tink.m4a; sourceTree = "<group>"; };
|
||||||
|
541356F2293E93D500EC0F1A /* lock4.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = lock4.m4a; sourceTree = "<group>"; };
|
||||||
|
541356F3293E93D500EC0F1A /* latch3.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = latch3.m4a; sourceTree = "<group>"; };
|
||||||
|
541356F4293E93D500EC0F1A /* lock3.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = lock3.m4a; sourceTree = "<group>"; };
|
||||||
|
541356F5293E93D500EC0F1A /* pop5.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = pop5.m4a; sourceTree = "<group>"; };
|
||||||
|
541356F6293E93D500EC0F1A /* plop.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = plop.m4a; sourceTree = "<group>"; };
|
||||||
|
541356F7293E93D500EC0F1A /* chime.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = chime.m4a; sourceTree = "<group>"; };
|
||||||
|
541356F8293E93D500EC0F1A /* ping.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = ping.m4a; sourceTree = "<group>"; };
|
||||||
|
541356F9293E93D500EC0F1A /* sparkle.rising.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = sparkle.rising.m4a; sourceTree = "<group>"; };
|
||||||
|
541356FA293E93D500EC0F1A /* swish.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = swish.m4a; sourceTree = "<group>"; };
|
||||||
|
541356FB293E93D500EC0F1A /* boop.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = boop.m4a; sourceTree = "<group>"; };
|
||||||
|
541356FC293E93D500EC0F1A /* beep.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = beep.m4a; sourceTree = "<group>"; };
|
||||||
|
541356FD293E93D500EC0F1A /* sparkle.flat.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = sparkle.flat.m4a; sourceTree = "<group>"; };
|
||||||
|
541356FE293E93D500EC0F1A /* whop.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = whop.m4a; sourceTree = "<group>"; };
|
||||||
|
541356FF293E93D600EC0F1A /* pop4.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = pop4.m4a; sourceTree = "<group>"; };
|
||||||
|
54135700293E93D600EC0F1A /* glass.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = glass.m4a; sourceTree = "<group>"; };
|
||||||
|
54135701293E93D600EC0F1A /* lock1.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = lock1.m4a; sourceTree = "<group>"; };
|
||||||
|
54135702293E93D600EC0F1A /* latch2.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = latch2.m4a; sourceTree = "<group>"; };
|
||||||
|
54135703293E93D600EC0F1A /* pop2.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = pop2.m4a; sourceTree = "<group>"; };
|
||||||
|
54135704293E93D600EC0F1A /* brush.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = brush.m4a; sourceTree = "<group>"; };
|
||||||
|
54135705293E93D600EC0F1A /* tick.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = tick.m4a; sourceTree = "<group>"; };
|
||||||
|
54135706293E93D600EC0F1A /* pick.rising.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = pick.rising.m4a; sourceTree = "<group>"; };
|
||||||
|
54135707293E93D600EC0F1A /* snap.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = snap.m4a; sourceTree = "<group>"; };
|
||||||
|
54135708293E93D600EC0F1A /* pick.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = pick.m4a; sourceTree = "<group>"; };
|
||||||
|
54135709293E93D600EC0F1A /* swipe.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = swipe.m4a; sourceTree = "<group>"; };
|
||||||
|
5413570A293E93D600EC0F1A /* sparkle.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = sparkle.m4a; sourceTree = "<group>"; };
|
||||||
|
5413570B293E93D600EC0F1A /* drip.rising.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = drip.rising.m4a; sourceTree = "<group>"; };
|
||||||
|
5413570C293E93D600EC0F1A /* drip.falling.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = drip.falling.m4a; sourceTree = "<group>"; };
|
||||||
|
5413570D293E93D600EC0F1A /* reel.rising.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = reel.rising.m4a; sourceTree = "<group>"; };
|
||||||
|
5413570E293E93D600EC0F1A /* pluck.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = pluck.m4a; sourceTree = "<group>"; };
|
||||||
|
5413570F293E93D700EC0F1A /* chime.falling.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = chime.falling.m4a; sourceTree = "<group>"; };
|
||||||
|
54135710293E93D700EC0F1A /* detach.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = detach.m4a; sourceTree = "<group>"; };
|
||||||
|
54135711293E93D700EC0F1A /* drip.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = drip.m4a; sourceTree = "<group>"; };
|
||||||
|
54135712293E93D700EC0F1A /* pop1.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = pop1.m4a; sourceTree = "<group>"; };
|
||||||
|
54135713293E93D700EC0F1A /* drip.flat.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = drip.flat.m4a; sourceTree = "<group>"; };
|
||||||
|
546A2986292A31BB00A80DE2 /* Pow Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Pow Example.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
546A2989292A31BB00A80DE2 /* PowExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PowExampleApp.swift; sourceTree = "<group>"; };
|
||||||
|
546A298B292A31BB00A80DE2 /* ExampleList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleList.swift; sourceTree = "<group>"; };
|
||||||
|
546A298D292A31BC00A80DE2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
|
546A2990292A31BC00A80DE2 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
||||||
|
546A299A292A332900A80DE2 /* AnvilExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnvilExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A299D292A335600A80DE2 /* PlaceholderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaceholderView.swift; sourceTree = "<group>"; };
|
||||||
|
546A299F292A341700A80DE2 /* Example.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Example.swift; sourceTree = "<group>"; };
|
||||||
|
546A29A1292A349900A80DE2 /* BlindsExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlindsExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29A3292A34A600A80DE2 /* ClockExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClockExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29A5292A355400A80DE2 /* BoingExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoingExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29A9292A397100A80DE2 /* BlurExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29AB292A3B9D00A80DE2 /* FilmExposureExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilmExposureExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29AD292A3D8900A80DE2 /* FlipExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlipExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29AF292A3DA800A80DE2 /* FlickerExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlickerExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29B1292A3ED800A80DE2 /* GlareExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlareExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29B3292A401500A80DE2 /* PopExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29B5292A406E00A80DE2 /* IrisExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IrisExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29B7292A40AF00A80DE2 /* MoveExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoveExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29B9292A40D800A80DE2 /* PoofExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PoofExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29BB292A414A00A80DE2 /* SnapshotExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnapshotExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29BD292A41CF00A80DE2 /* VanishExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VanishExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29BF292A420E00A80DE2 /* SwooshExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwooshExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29C1292A431800A80DE2 /* WipeExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WipeExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29C5292A4BC100A80DE2 /* JumpExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JumpExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29C7292A4BFA00A80DE2 /* PingExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PingExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29C9292A4DBD00A80DE2 /* RiseExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiseExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29CB292A559A00A80DE2 /* ShakeExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShakeExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29CD292A591F00A80DE2 /* ShineExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShineExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29CF292A676200A80DE2 /* SkidExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkidExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29D1292A68E100A80DE2 /* SpinExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpinExample.swift; sourceTree = "<group>"; };
|
||||||
|
546A29D3292A6B1200A80DE2 /* SprayExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SprayExample.swift; sourceTree = "<group>"; };
|
||||||
|
549BF5F4293642BC00B2DCCF /* SocialFeedExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocialFeedExample.swift; sourceTree = "<group>"; };
|
||||||
|
54A9622F2934CC4400BBD5FE /* GithubButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GithubButton.swift; sourceTree = "<group>"; };
|
||||||
|
54B7259629F9C70900C17B99 /* PushDownExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushDownExample.swift; sourceTree = "<group>"; };
|
||||||
|
54D37CAD292F9C4A00788E8A /* Pow-Example-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "Pow-Example-Info.plist"; sourceTree = SOURCE_ROOT; };
|
||||||
|
54F15E4F29D598150054690B /* RepeatExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepeatExample.swift; sourceTree = "<group>"; };
|
||||||
|
54F15E5129D59A920054690B /* SmokeExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmokeExample.swift; sourceTree = "<group>"; };
|
||||||
|
54F15E5329D59D250054690B /* PulseExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PulseExample.swift; sourceTree = "<group>"; };
|
||||||
|
54F15E5529D5A0D70054690B /* GlowExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlowExample.swift; sourceTree = "<group>"; };
|
||||||
|
B7A5DA8A2B0E85260035FC0A /* Pow */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Pow; path = ..; sourceTree = "<group>"; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
546A2983292A31BB00A80DE2 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
B7A5DA8D2B0E853A0035FC0A /* Pow in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
5413566C293E917E00EC0F1A /* Sounds */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
541356FC293E93D500EC0F1A /* beep.m4a */,
|
||||||
|
541356DD293E93D300EC0F1A /* biip.m4a */,
|
||||||
|
541356FB293E93D500EC0F1A /* boop.m4a */,
|
||||||
|
54135704293E93D600EC0F1A /* brush.m4a */,
|
||||||
|
5413570F293E93D700EC0F1A /* chime.falling.m4a */,
|
||||||
|
541356EF293E93D500EC0F1A /* chime.flat.m4a */,
|
||||||
|
541356F7293E93D500EC0F1A /* chime.m4a */,
|
||||||
|
541356E3293E93D400EC0F1A /* chime.rising.m4a */,
|
||||||
|
54135710293E93D700EC0F1A /* detach.m4a */,
|
||||||
|
541356E9293E93D400EC0F1A /* dial.m4a */,
|
||||||
|
5413570C293E93D600EC0F1A /* drip.falling.m4a */,
|
||||||
|
54135713293E93D700EC0F1A /* drip.flat.m4a */,
|
||||||
|
54135711293E93D700EC0F1A /* drip.m4a */,
|
||||||
|
5413570B293E93D600EC0F1A /* drip.rising.m4a */,
|
||||||
|
54135700293E93D600EC0F1A /* glass.m4a */,
|
||||||
|
541356EA293E93D400EC0F1A /* latch1.m4a */,
|
||||||
|
54135702293E93D600EC0F1A /* latch2.m4a */,
|
||||||
|
541356F3293E93D500EC0F1A /* latch3.m4a */,
|
||||||
|
541356E8293E93D400EC0F1A /* latch4.m4a */,
|
||||||
|
54135701293E93D600EC0F1A /* lock1.m4a */,
|
||||||
|
541356E1293E93D400EC0F1A /* lock2.m4a */,
|
||||||
|
541356F4293E93D500EC0F1A /* lock3.m4a */,
|
||||||
|
541356F2293E93D500EC0F1A /* lock4.m4a */,
|
||||||
|
541356EC293E93D400EC0F1A /* notfound.m4a */,
|
||||||
|
541356E5293E93D400EC0F1A /* pick.falling.m4a */,
|
||||||
|
541356ED293E93D400EC0F1A /* pick.flat.m4a */,
|
||||||
|
54135708293E93D600EC0F1A /* pick.m4a */,
|
||||||
|
54135706293E93D600EC0F1A /* pick.rising.m4a */,
|
||||||
|
541356F8293E93D500EC0F1A /* ping.m4a */,
|
||||||
|
541356F6293E93D500EC0F1A /* plop.m4a */,
|
||||||
|
5413570E293E93D600EC0F1A /* pluck.m4a */,
|
||||||
|
541356E2293E93D400EC0F1A /* pong.m4a */,
|
||||||
|
54135712293E93D700EC0F1A /* pop1.m4a */,
|
||||||
|
54135703293E93D600EC0F1A /* pop2.m4a */,
|
||||||
|
541356E0293E93D400EC0F1A /* pop3.m4a */,
|
||||||
|
541356FF293E93D600EC0F1A /* pop4.m4a */,
|
||||||
|
541356F5293E93D500EC0F1A /* pop5.m4a */,
|
||||||
|
541356E4293E93D400EC0F1A /* reel.falling.m4a */,
|
||||||
|
541356DE293E93D300EC0F1A /* reel.flat.m4a */,
|
||||||
|
541356DF293E93D400EC0F1A /* reel.m4a */,
|
||||||
|
5413570D293E93D600EC0F1A /* reel.rising.m4a */,
|
||||||
|
541356E7293E93D400EC0F1A /* shake.m4a */,
|
||||||
|
54135707293E93D600EC0F1A /* snap.m4a */,
|
||||||
|
541356E6293E93D400EC0F1A /* sparkle.falling.m4a */,
|
||||||
|
541356FD293E93D500EC0F1A /* sparkle.flat.m4a */,
|
||||||
|
5413570A293E93D600EC0F1A /* sparkle.m4a */,
|
||||||
|
541356F9293E93D500EC0F1A /* sparkle.rising.m4a */,
|
||||||
|
54135709293E93D600EC0F1A /* swipe.m4a */,
|
||||||
|
541356FA293E93D500EC0F1A /* swish.m4a */,
|
||||||
|
54135705293E93D600EC0F1A /* tick.m4a */,
|
||||||
|
541356F1293E93D500EC0F1A /* tink.m4a */,
|
||||||
|
541356F0293E93D500EC0F1A /* tock.m4a */,
|
||||||
|
541356FE293E93D500EC0F1A /* whop.m4a */,
|
||||||
|
541356EB293E93D400EC0F1A /* wip.m4a */,
|
||||||
|
541356EE293E93D400EC0F1A /* zing.m4a */,
|
||||||
|
);
|
||||||
|
path = Sounds;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
546A297D292A31BB00A80DE2 = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
B7A5DA8A2B0E85260035FC0A /* Pow */,
|
||||||
|
546A2988292A31BB00A80DE2 /* Pow Example */,
|
||||||
|
546A2987292A31BB00A80DE2 /* Products */,
|
||||||
|
B7A5DA8B2B0E853A0035FC0A /* Frameworks */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
546A2987292A31BB00A80DE2 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
546A2986292A31BB00A80DE2 /* Pow Example.app */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
546A2988292A31BB00A80DE2 /* Pow Example */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
54D37CAD292F9C4A00788E8A /* Pow-Example-Info.plist */,
|
||||||
|
546A2989292A31BB00A80DE2 /* PowExampleApp.swift */,
|
||||||
|
546A298B292A31BB00A80DE2 /* ExampleList.swift */,
|
||||||
|
546A299D292A335600A80DE2 /* PlaceholderView.swift */,
|
||||||
|
54A9622F2934CC4400BBD5FE /* GithubButton.swift */,
|
||||||
|
546A299C292A332C00A80DE2 /* Examples */,
|
||||||
|
546A298D292A31BC00A80DE2 /* Assets.xcassets */,
|
||||||
|
5413566C293E917E00EC0F1A /* Sounds */,
|
||||||
|
546A298F292A31BC00A80DE2 /* Preview Content */,
|
||||||
|
);
|
||||||
|
path = "Pow Example";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
546A298F292A31BC00A80DE2 /* Preview Content */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
546A2990292A31BC00A80DE2 /* Preview Assets.xcassets */,
|
||||||
|
);
|
||||||
|
path = "Preview Content";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
546A299C292A332C00A80DE2 /* Examples */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
546A299F292A341700A80DE2 /* Example.swift */,
|
||||||
|
546A29C3292A4B9000A80DE2 /* Transitions */,
|
||||||
|
546A29C4292A4B9F00A80DE2 /* Change Effects */,
|
||||||
|
54F15E4E29D598020054690B /* Conditional Effects */,
|
||||||
|
549BF5F6293642BE00B2DCCF /* Screens */,
|
||||||
|
);
|
||||||
|
path = Examples;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
546A29C3292A4B9000A80DE2 /* Transitions */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
546A299A292A332900A80DE2 /* AnvilExample.swift */,
|
||||||
|
546A29A1292A349900A80DE2 /* BlindsExample.swift */,
|
||||||
|
546A29A9292A397100A80DE2 /* BlurExample.swift */,
|
||||||
|
546A29A5292A355400A80DE2 /* BoingExample.swift */,
|
||||||
|
546A29A3292A34A600A80DE2 /* ClockExample.swift */,
|
||||||
|
546A29AB292A3B9D00A80DE2 /* FilmExposureExample.swift */,
|
||||||
|
546A29AF292A3DA800A80DE2 /* FlickerExample.swift */,
|
||||||
|
546A29AD292A3D8900A80DE2 /* FlipExample.swift */,
|
||||||
|
546A29B1292A3ED800A80DE2 /* GlareExample.swift */,
|
||||||
|
546A29B5292A406E00A80DE2 /* IrisExample.swift */,
|
||||||
|
546A29B7292A40AF00A80DE2 /* MoveExample.swift */,
|
||||||
|
546A29B9292A40D800A80DE2 /* PoofExample.swift */,
|
||||||
|
546A29B3292A401500A80DE2 /* PopExample.swift */,
|
||||||
|
546A29CF292A676200A80DE2 /* SkidExample.swift */,
|
||||||
|
546A29BB292A414A00A80DE2 /* SnapshotExample.swift */,
|
||||||
|
546A29BF292A420E00A80DE2 /* SwooshExample.swift */,
|
||||||
|
546A29BD292A41CF00A80DE2 /* VanishExample.swift */,
|
||||||
|
546A29C1292A431800A80DE2 /* WipeExample.swift */,
|
||||||
|
);
|
||||||
|
path = Transitions;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
546A29C4292A4B9F00A80DE2 /* Change Effects */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
546A29C5292A4BC100A80DE2 /* JumpExample.swift */,
|
||||||
|
546A29C7292A4BFA00A80DE2 /* PingExample.swift */,
|
||||||
|
546A29C9292A4DBD00A80DE2 /* RiseExample.swift */,
|
||||||
|
546A29CB292A559A00A80DE2 /* ShakeExample.swift */,
|
||||||
|
546A29CD292A591F00A80DE2 /* ShineExample.swift */,
|
||||||
|
54F15E5529D5A0D70054690B /* GlowExample.swift */,
|
||||||
|
541356DB293E91A000EC0F1A /* SoundEffectsExample.swift */,
|
||||||
|
546A29D1292A68E100A80DE2 /* SpinExample.swift */,
|
||||||
|
546A29D3292A6B1200A80DE2 /* SprayExample.swift */,
|
||||||
|
54F15E5329D59D250054690B /* PulseExample.swift */,
|
||||||
|
);
|
||||||
|
path = "Change Effects";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
549BF5F6293642BE00B2DCCF /* Screens */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
236B13452940BAFD0022AF1F /* CheckoutExample.swift */,
|
||||||
|
549BF5F4293642BC00B2DCCF /* SocialFeedExample.swift */,
|
||||||
|
);
|
||||||
|
path = Screens;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
54F15E4E29D598020054690B /* Conditional Effects */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
54B7259629F9C70900C17B99 /* PushDownExample.swift */,
|
||||||
|
54F15E4F29D598150054690B /* RepeatExample.swift */,
|
||||||
|
54F15E5129D59A920054690B /* SmokeExample.swift */,
|
||||||
|
);
|
||||||
|
path = "Conditional Effects";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
B7A5DA8B2B0E853A0035FC0A /* Frameworks */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
);
|
||||||
|
name = Frameworks;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
546A2985292A31BB00A80DE2 /* Pow Example */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 546A2994292A31BC00A80DE2 /* Build configuration list for PBXNativeTarget "Pow Example" */;
|
||||||
|
buildPhases = (
|
||||||
|
546A2982292A31BB00A80DE2 /* Sources */,
|
||||||
|
546A2983292A31BB00A80DE2 /* Frameworks */,
|
||||||
|
546A2984292A31BB00A80DE2 /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = "Pow Example";
|
||||||
|
packageProductDependencies = (
|
||||||
|
B7A5DA8C2B0E853A0035FC0A /* Pow */,
|
||||||
|
);
|
||||||
|
productName = "Pow Example";
|
||||||
|
productReference = 546A2986292A31BB00A80DE2 /* Pow Example.app */;
|
||||||
|
productType = "com.apple.product-type.application";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
546A297E292A31BB00A80DE2 /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
BuildIndependentTargetsInParallel = 1;
|
||||||
|
LastSwiftUpdateCheck = 1410;
|
||||||
|
LastUpgradeCheck = 1500;
|
||||||
|
TargetAttributes = {
|
||||||
|
546A2985292A31BB00A80DE2 = {
|
||||||
|
CreatedOnToolsVersion = 14.1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
buildConfigurationList = 546A2981292A31BB00A80DE2 /* Build configuration list for PBXProject "Pow Example" */;
|
||||||
|
compatibilityVersion = "Xcode 14.0";
|
||||||
|
developmentRegion = en;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
Base,
|
||||||
|
);
|
||||||
|
mainGroup = 546A297D292A31BB00A80DE2;
|
||||||
|
packageReferences = (
|
||||||
|
);
|
||||||
|
productRefGroup = 546A2987292A31BB00A80DE2 /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
546A2985292A31BB00A80DE2 /* Pow Example */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
546A2984292A31BB00A80DE2 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
5413571B293E941000EC0F1A /* sparkle.rising.m4a in Resources */,
|
||||||
|
5413573D293E941000EC0F1A /* reel.rising.m4a in Resources */,
|
||||||
|
54135732293E941000EC0F1A /* drip.flat.m4a in Resources */,
|
||||||
|
54135721293E941000EC0F1A /* swipe.m4a in Resources */,
|
||||||
|
5413571E293E941000EC0F1A /* pick.flat.m4a in Resources */,
|
||||||
|
54135728293E941000EC0F1A /* snap.m4a in Resources */,
|
||||||
|
54135725293E941000EC0F1A /* plop.m4a in Resources */,
|
||||||
|
54135733293E941000EC0F1A /* latch2.m4a in Resources */,
|
||||||
|
5413573A293E941000EC0F1A /* drip.m4a in Resources */,
|
||||||
|
5413571D293E941000EC0F1A /* tock.m4a in Resources */,
|
||||||
|
546A2991292A31BC00A80DE2 /* Preview Assets.xcassets in Resources */,
|
||||||
|
5413571F293E941000EC0F1A /* chime.falling.m4a in Resources */,
|
||||||
|
54135731293E941000EC0F1A /* boop.m4a in Resources */,
|
||||||
|
54135742293E941000EC0F1A /* chime.flat.m4a in Resources */,
|
||||||
|
5413572E293E941000EC0F1A /* shake.m4a in Resources */,
|
||||||
|
5413571A293E941000EC0F1A /* reel.m4a in Resources */,
|
||||||
|
54135730293E941000EC0F1A /* lock4.m4a in Resources */,
|
||||||
|
54135734293E941000EC0F1A /* lock2.m4a in Resources */,
|
||||||
|
5413573B293E941000EC0F1A /* beep.m4a in Resources */,
|
||||||
|
54135720293E941000EC0F1A /* chime.m4a in Resources */,
|
||||||
|
54135716293E941000EC0F1A /* latch1.m4a in Resources */,
|
||||||
|
5413571C293E941000EC0F1A /* wip.m4a in Resources */,
|
||||||
|
54135746293E941000EC0F1A /* lock3.m4a in Resources */,
|
||||||
|
54135726293E941000EC0F1A /* detach.m4a in Resources */,
|
||||||
|
54135737293E941000EC0F1A /* glass.m4a in Resources */,
|
||||||
|
5413574A293E941000EC0F1A /* biip.m4a in Resources */,
|
||||||
|
5413573F293E941000EC0F1A /* sparkle.flat.m4a in Resources */,
|
||||||
|
54135749293E941000EC0F1A /* pop3.m4a in Resources */,
|
||||||
|
54135736293E941000EC0F1A /* latch4.m4a in Resources */,
|
||||||
|
54135745293E941000EC0F1A /* ping.m4a in Resources */,
|
||||||
|
54135747293E941000EC0F1A /* pop1.m4a in Resources */,
|
||||||
|
54135741293E941000EC0F1A /* pop2.m4a in Resources */,
|
||||||
|
54135748293E941000EC0F1A /* sparkle.falling.m4a in Resources */,
|
||||||
|
54135717293E941000EC0F1A /* pick.falling.m4a in Resources */,
|
||||||
|
54135727293E941000EC0F1A /* swish.m4a in Resources */,
|
||||||
|
54135724293E941000EC0F1A /* pick.rising.m4a in Resources */,
|
||||||
|
5413572A293E941000EC0F1A /* chime.rising.m4a in Resources */,
|
||||||
|
54135719293E941000EC0F1A /* pop4.m4a in Resources */,
|
||||||
|
5413572D293E941000EC0F1A /* dial.m4a in Resources */,
|
||||||
|
54135718293E941000EC0F1A /* brush.m4a in Resources */,
|
||||||
|
54135744293E941000EC0F1A /* drip.rising.m4a in Resources */,
|
||||||
|
5413573E293E941000EC0F1A /* sparkle.m4a in Resources */,
|
||||||
|
54135739293E941000EC0F1A /* pong.m4a in Resources */,
|
||||||
|
54135738293E941000EC0F1A /* zing.m4a in Resources */,
|
||||||
|
5413572B293E941000EC0F1A /* notfound.m4a in Resources */,
|
||||||
|
54135729293E941000EC0F1A /* drip.falling.m4a in Resources */,
|
||||||
|
54135735293E941000EC0F1A /* pop5.m4a in Resources */,
|
||||||
|
54135723293E941000EC0F1A /* lock1.m4a in Resources */,
|
||||||
|
54135714293E941000EC0F1A /* pick.m4a in Resources */,
|
||||||
|
5413573C293E941000EC0F1A /* latch3.m4a in Resources */,
|
||||||
|
5413572C293E941000EC0F1A /* pluck.m4a in Resources */,
|
||||||
|
546A298E292A31BC00A80DE2 /* Assets.xcassets in Resources */,
|
||||||
|
54135715293E941000EC0F1A /* reel.falling.m4a in Resources */,
|
||||||
|
54135740293E941000EC0F1A /* reel.flat.m4a in Resources */,
|
||||||
|
5413572F293E941000EC0F1A /* tink.m4a in Resources */,
|
||||||
|
54135743293E941000EC0F1A /* whop.m4a in Resources */,
|
||||||
|
54135722293E941000EC0F1A /* tick.m4a in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
546A2982292A31BB00A80DE2 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
546A298C292A31BB00A80DE2 /* ExampleList.swift in Sources */,
|
||||||
|
54F15E5229D59A920054690B /* SmokeExample.swift in Sources */,
|
||||||
|
546A29CE292A591F00A80DE2 /* ShineExample.swift in Sources */,
|
||||||
|
546A29C0292A420F00A80DE2 /* SwooshExample.swift in Sources */,
|
||||||
|
546A29BA292A40D800A80DE2 /* PoofExample.swift in Sources */,
|
||||||
|
546A29B2292A3ED800A80DE2 /* GlareExample.swift in Sources */,
|
||||||
|
546A29B6292A406E00A80DE2 /* IrisExample.swift in Sources */,
|
||||||
|
546A29A4292A34A600A80DE2 /* ClockExample.swift in Sources */,
|
||||||
|
546A29D2292A68E100A80DE2 /* SpinExample.swift in Sources */,
|
||||||
|
546A29BE292A41CF00A80DE2 /* VanishExample.swift in Sources */,
|
||||||
|
541356DC293E91A000EC0F1A /* SoundEffectsExample.swift in Sources */,
|
||||||
|
546A29C8292A4BFA00A80DE2 /* PingExample.swift in Sources */,
|
||||||
|
546A29C2292A431800A80DE2 /* WipeExample.swift in Sources */,
|
||||||
|
546A298A292A31BB00A80DE2 /* PowExampleApp.swift in Sources */,
|
||||||
|
549BF5F5293642BC00B2DCCF /* SocialFeedExample.swift in Sources */,
|
||||||
|
546A299E292A335600A80DE2 /* PlaceholderView.swift in Sources */,
|
||||||
|
54B7259729F9C70900C17B99 /* PushDownExample.swift in Sources */,
|
||||||
|
546A29D0292A676200A80DE2 /* SkidExample.swift in Sources */,
|
||||||
|
546A29C6292A4BC100A80DE2 /* JumpExample.swift in Sources */,
|
||||||
|
546A29AA292A397100A80DE2 /* BlurExample.swift in Sources */,
|
||||||
|
546A29A0292A341700A80DE2 /* Example.swift in Sources */,
|
||||||
|
54F15E5629D5A0D70054690B /* GlowExample.swift in Sources */,
|
||||||
|
236B13462940BAFD0022AF1F /* CheckoutExample.swift in Sources */,
|
||||||
|
546A29BC292A414A00A80DE2 /* SnapshotExample.swift in Sources */,
|
||||||
|
54A962302934CC4400BBD5FE /* GithubButton.swift in Sources */,
|
||||||
|
546A29B4292A401500A80DE2 /* PopExample.swift in Sources */,
|
||||||
|
546A29CC292A559A00A80DE2 /* ShakeExample.swift in Sources */,
|
||||||
|
546A29AE292A3D8900A80DE2 /* FlipExample.swift in Sources */,
|
||||||
|
546A29A6292A355400A80DE2 /* BoingExample.swift in Sources */,
|
||||||
|
54F15E5429D59D250054690B /* PulseExample.swift in Sources */,
|
||||||
|
546A299B292A332900A80DE2 /* AnvilExample.swift in Sources */,
|
||||||
|
546A29A2292A349900A80DE2 /* BlindsExample.swift in Sources */,
|
||||||
|
546A29AC292A3B9D00A80DE2 /* FilmExposureExample.swift in Sources */,
|
||||||
|
546A29B0292A3DA800A80DE2 /* FlickerExample.swift in Sources */,
|
||||||
|
54F15E5029D598150054690B /* RepeatExample.swift in Sources */,
|
||||||
|
546A29D4292A6B1200A80DE2 /* SprayExample.swift in Sources */,
|
||||||
|
546A29CA292A4DBD00A80DE2 /* RiseExample.swift in Sources */,
|
||||||
|
546A29B8292A40B000A80DE2 /* MoveExample.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
546A2992292A31BC00A80DE2 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = 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_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_TESTABILITY = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
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 = 16.1;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
546A2993292A31BC00A80DE2 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = 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_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
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 = 16.1;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
|
VALIDATE_PRODUCT = YES;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
546A2995292A31BC00A80DE2 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 8;
|
||||||
|
DEVELOPMENT_ASSET_PATHS = "\"Pow Example/Preview Content\"";
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
ENABLE_PREVIEWS = YES;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = "Pow-Example-Info.plist";
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = Pow;
|
||||||
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
|
||||||
|
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||||
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||||
|
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||||
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||||
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 16;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = "io.movingparts.Pow-Example";
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
546A2996292A31BC00A80DE2 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 8;
|
||||||
|
DEVELOPMENT_ASSET_PATHS = "\"Pow Example/Preview Content\"";
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
ENABLE_PREVIEWS = YES;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = "Pow-Example-Info.plist";
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = Pow;
|
||||||
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
|
||||||
|
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||||
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||||
|
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||||
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||||
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 16;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = "io.movingparts.Pow-Example";
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
546A2981292A31BB00A80DE2 /* Build configuration list for PBXProject "Pow Example" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
546A2992292A31BC00A80DE2 /* Debug */,
|
||||||
|
546A2993292A31BC00A80DE2 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
546A2994292A31BC00A80DE2 /* Build configuration list for PBXNativeTarget "Pow Example" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
546A2995292A31BC00A80DE2 /* Debug */,
|
||||||
|
546A2996292A31BC00A80DE2 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
|
B7A5DA8C2B0E853A0035FC0A /* Pow */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
productName = Pow;
|
||||||
|
};
|
||||||
|
/* End XCSwiftPackageProductDependency section */
|
||||||
|
};
|
||||||
|
rootObject = 546A297E292A31BB00A80DE2 /* Project object */;
|
||||||
|
}
|
||||||
7
Example/Pow Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "self:">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>IDEDidComputeMac32BitWarning</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "icon.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"platform" : "ios",
|
||||||
|
"size" : "1024x1024"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Example/Pow Example/Assets.xcassets/AppIcon.appiconset/icon.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
6
Example/Pow Example/Assets.xcassets/Contents.json
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Example/Pow Example/Assets.xcassets/disco.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "disco.jpg",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Example/Pow Example/Assets.xcassets/disco.imageset/disco.jpg
vendored
Normal file
|
After Width: | Height: | Size: 27 KiB |
12
Example/Pow Example/Assets.xcassets/mvp.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "mvp.png",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Example/Pow Example/Assets.xcassets/mvp.imageset/mvp.png
vendored
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
158
Example/Pow Example/ExampleList.swift
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
import Pow
|
||||||
|
import MessageUI
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct ExampleList: View {
|
||||||
|
var body: some View {
|
||||||
|
List {
|
||||||
|
Section {
|
||||||
|
VStack(alignment: .leading, spacing: 12) {
|
||||||
|
Text("This is the official example app for Pow, the Surprise and Delight framework for SwiftUI.")
|
||||||
|
|
||||||
|
Text("Tap the individual examples to see the effects and transitions in action.")
|
||||||
|
|
||||||
|
Text("**Note:** While this app requires iOS 16, Pow itself supports iOS 15 and above.")
|
||||||
|
}
|
||||||
|
.font(.subheadline.leading(.loose))
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
|
||||||
|
Link(destination: URL(string: "https://movingparts.io/pow")!) {
|
||||||
|
ViewThatFits {
|
||||||
|
Label("Pow Website", systemImage: "safari")
|
||||||
|
Label("Pow Website", systemImage: "safari")
|
||||||
|
Label("Pow Website", systemImage: "safari")
|
||||||
|
Label("Pow Website", systemImage: "safari")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Link(destination: URL(string: "https://github.com/movingparts-io/Pow-Examples")!) {
|
||||||
|
ViewThatFits {
|
||||||
|
Label("GitHub Repository for this App", systemImage: "terminal")
|
||||||
|
Label("GitHub Repo for this App", systemImage: "terminal")
|
||||||
|
Label("Repo for this App", systemImage: "terminal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if MFMailComposeViewController.canSendMail() {
|
||||||
|
Link(destination: URL(string: "mailto:hello@movingparts.io")!) {
|
||||||
|
Label("Support", systemImage: "envelope")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Section {
|
||||||
|
SocialFeedExample.navigationLink
|
||||||
|
CheckoutExample.navigationLink
|
||||||
|
} header: {
|
||||||
|
Label("Screens", systemImage: "iphone")
|
||||||
|
} footer: {
|
||||||
|
Text("Pre-composed screens that show how to use Pow in context. Use them as inspiration for your app.")
|
||||||
|
}
|
||||||
|
|
||||||
|
Section {
|
||||||
|
PushDownExample.navigationLink
|
||||||
|
RepeatExample.navigationLink
|
||||||
|
SmokeExample.navigationLink
|
||||||
|
} header: {
|
||||||
|
Label("Conditional Effects", systemImage: "checklist")
|
||||||
|
} footer: {
|
||||||
|
Text("Conditional Effects are triggered continously, as long as a condition is met.")
|
||||||
|
}
|
||||||
|
|
||||||
|
Section {
|
||||||
|
GlowExample.navigationLink
|
||||||
|
PulseExample.navigationLink
|
||||||
|
JumpExample.navigationLink
|
||||||
|
PingExample.navigationLink
|
||||||
|
RiseExample.navigationLink
|
||||||
|
ShakeExample.navigationLink
|
||||||
|
ShineExample.navigationLink
|
||||||
|
SoundEffectExample.navigationLink
|
||||||
|
SpinExample.navigationLink
|
||||||
|
SprayExample.navigationLink
|
||||||
|
} header: {
|
||||||
|
Label("Change Effects", systemImage: "sparkles")
|
||||||
|
} footer: {
|
||||||
|
Text("Change Effects can be triggered whenever a value changes.")
|
||||||
|
}
|
||||||
|
|
||||||
|
Section {
|
||||||
|
Group {
|
||||||
|
AnvilExample.navigationLink
|
||||||
|
BlindsExample.navigationLink
|
||||||
|
BlurExample.navigationLink
|
||||||
|
BoingExample.navigationLink
|
||||||
|
ClockExample.navigationLink
|
||||||
|
FilmExposureExample.navigationLink
|
||||||
|
FlickerExample.navigationLink
|
||||||
|
FlipExample.navigationLink
|
||||||
|
GlareExample.navigationLink
|
||||||
|
}
|
||||||
|
Group {
|
||||||
|
IrisExample.navigationLink
|
||||||
|
MoveExample.navigationLink
|
||||||
|
PoofExample.navigationLink
|
||||||
|
PopExample.navigationLink
|
||||||
|
SkidExample.navigationLink
|
||||||
|
SnapshotExample.navigationLink
|
||||||
|
SwooshExample.navigationLink
|
||||||
|
VanishExample.navigationLink
|
||||||
|
WipeExample.navigationLink
|
||||||
|
}
|
||||||
|
} header: {
|
||||||
|
Label("Transitions", systemImage: "arrow.forward.square")
|
||||||
|
} footer: {
|
||||||
|
Text("Transitions use the existing SwiftUI `.transition(_:)` API.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.navigationTitle("Pow Examples")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PresentInfoAction {
|
||||||
|
var action: (any Example.Type) -> ()
|
||||||
|
|
||||||
|
init(action: @escaping (any Example.Type) -> Void) {
|
||||||
|
self.action = action
|
||||||
|
}
|
||||||
|
|
||||||
|
func callAsFunction<T: Example>(_ type: T.Type) {
|
||||||
|
action(type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension EnvironmentValues {
|
||||||
|
struct PresentInfoActionKey: EnvironmentKey {
|
||||||
|
static var defaultValue: PresentInfoAction? = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var presentInfoAction: PresentInfoAction? {
|
||||||
|
get { self[PresentInfoActionKey.self] }
|
||||||
|
set { self[PresentInfoActionKey.self] = newValue }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct InfoButton<T: Example>: View {
|
||||||
|
var type: T.Type
|
||||||
|
|
||||||
|
@Environment(\.presentInfoAction)
|
||||||
|
var presentInfoAction
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
if let presentInfoAction {
|
||||||
|
Button {
|
||||||
|
presentInfoAction(type)
|
||||||
|
} label: {
|
||||||
|
Label("About", systemImage: "info.circle")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ExampleList_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
NavigationStack {
|
||||||
|
ExampleList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct GlowExample: View, Example {
|
||||||
|
@State
|
||||||
|
var changes: Int = 0
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
// GroupBox {
|
||||||
|
// LabeledContent("Drawing Mode") {
|
||||||
|
// Picker("Drawing Mode", selection: $drawingMode) {
|
||||||
|
// Text("Fill").tag(AnyChangeEffect.PulseDrawingMode.fill)
|
||||||
|
// Text("Stroke").tag(AnyChangeEffect.PulseDrawingMode.stroke)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// .padding(.horizontal)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
ZStack {
|
||||||
|
PlaceholderView()
|
||||||
|
.overlay(alignment: .badgeAlignment) {
|
||||||
|
let shape = Capsule()
|
||||||
|
|
||||||
|
Text(changes.formatted())
|
||||||
|
.font(.body.bold().monospacedDigit())
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.padding(.vertical, 8)
|
||||||
|
.padding(.horizontal, 16)
|
||||||
|
.background {
|
||||||
|
shape.fill(.pink)
|
||||||
|
.changeEffect(.glow(color: .pink, radius: 20), value: changes)
|
||||||
|
}
|
||||||
|
.alignmentGuide(HorizontalAlignment.badgeAlignment) { d in
|
||||||
|
d[HorizontalAlignment.center]
|
||||||
|
}
|
||||||
|
.alignmentGuide(VerticalAlignment.badgeAlignment) { d in
|
||||||
|
d[VerticalAlignment.center]
|
||||||
|
}
|
||||||
|
.allowsHitTesting(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
changes += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static var description: some View {
|
||||||
|
Text("""
|
||||||
|
Makes the view glow whenever a value changes
|
||||||
|
|
||||||
|
- Parameters:
|
||||||
|
- `color`: The color to use.
|
||||||
|
- `radius`: The radius of the glow.
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "dot.radiowaves.left.and.right")
|
||||||
|
}
|
||||||
|
|
||||||
|
static var newIn0_3_0: Bool { true }
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct JumpExample: View, Example {
|
||||||
|
@State
|
||||||
|
var changes: Int = 0
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
PlaceholderView()
|
||||||
|
.changeEffect(.jump(height: 40), value: changes)
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
changes += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static var description: some View {
|
||||||
|
Text("""
|
||||||
|
Makes the view jump the given height and then bounces a few times before settling.
|
||||||
|
|
||||||
|
- `height`: The height of the jump.
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "figure.jumprope")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct PingExample: View, Example {
|
||||||
|
@State
|
||||||
|
var changes: Int = 0
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
PlaceholderView()
|
||||||
|
.overlay(alignment: .badgeAlignment) {
|
||||||
|
let shape = Capsule()
|
||||||
|
|
||||||
|
Text(changes.formatted())
|
||||||
|
.font(.body.bold().monospacedDigit())
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.padding(.vertical, 8)
|
||||||
|
.padding(.horizontal, 16)
|
||||||
|
.background {
|
||||||
|
shape.fill(.pink)
|
||||||
|
.changeEffect(.pulse(shape: shape, style: .pink, count: 3), value: changes)
|
||||||
|
}
|
||||||
|
.alignmentGuide(HorizontalAlignment.badgeAlignment) { d in
|
||||||
|
d[HorizontalAlignment.center]
|
||||||
|
}
|
||||||
|
.alignmentGuide(VerticalAlignment.badgeAlignment) { d in
|
||||||
|
d[VerticalAlignment.center]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
changes += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static var description: some View {
|
||||||
|
Text("""
|
||||||
|
Adds one or more shapes that slowly grow and fade-out behind the view.
|
||||||
|
|
||||||
|
The shape will be colored by the current tint style.
|
||||||
|
|
||||||
|
-Parameters:
|
||||||
|
- `shape`: The shape to use for the effect.
|
||||||
|
- `style`: The style to use for the effect.
|
||||||
|
- `count`: The number of shapes to emit.
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "dot.radiowaves.left.and.right")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension VerticalAlignment {
|
||||||
|
struct BadgeAlignmentID: AlignmentID {
|
||||||
|
static func defaultValue(in d: ViewDimensions) -> CGFloat {
|
||||||
|
d[.top]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static let badgeAlignment = VerticalAlignment(BadgeAlignmentID.self)
|
||||||
|
}
|
||||||
|
|
||||||
|
extension HorizontalAlignment {
|
||||||
|
struct BadgeAlignmentID: AlignmentID {
|
||||||
|
static func defaultValue(in d: ViewDimensions) -> CGFloat {
|
||||||
|
d[.trailing]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static let badgeAlignment = HorizontalAlignment(BadgeAlignmentID.self)
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Alignment {
|
||||||
|
static let badgeAlignment = Alignment(horizontal: .badgeAlignment, vertical: .badgeAlignment)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct PulseExample: View, Example {
|
||||||
|
@State
|
||||||
|
var changes: Int = 0
|
||||||
|
|
||||||
|
@State
|
||||||
|
var drawingMode: AnyChangeEffect.PulseDrawingMode = .fill
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
GroupBox {
|
||||||
|
LabeledContent("Drawing Mode") {
|
||||||
|
Picker("Drawing Mode", selection: $drawingMode) {
|
||||||
|
Text("Fill").tag(AnyChangeEffect.PulseDrawingMode.fill)
|
||||||
|
Text("Stroke").tag(AnyChangeEffect.PulseDrawingMode.stroke)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.horizontal)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
ZStack {
|
||||||
|
PlaceholderView()
|
||||||
|
.overlay(alignment: .badgeAlignment) {
|
||||||
|
let shape = Capsule()
|
||||||
|
|
||||||
|
Text(changes.formatted())
|
||||||
|
.font(.body.bold().monospacedDigit())
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.padding(.vertical, 8)
|
||||||
|
.padding(.horizontal, 16)
|
||||||
|
.background {
|
||||||
|
shape.fill(.pink)
|
||||||
|
.changeEffect(.pulse(shape: shape, style: .pink, drawingMode: drawingMode, count: 1), value: changes)
|
||||||
|
}
|
||||||
|
.alignmentGuide(HorizontalAlignment.badgeAlignment) { d in
|
||||||
|
d[HorizontalAlignment.center]
|
||||||
|
}
|
||||||
|
.alignmentGuide(VerticalAlignment.badgeAlignment) { d in
|
||||||
|
d[VerticalAlignment.center]
|
||||||
|
}
|
||||||
|
.allowsHitTesting(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
changes += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static var description: some View {
|
||||||
|
Text("""
|
||||||
|
Adds one or more shapes that are emitted from the view.
|
||||||
|
|
||||||
|
By default, the shape will be colored in the current tint style.
|
||||||
|
|
||||||
|
- Parameters:
|
||||||
|
- `shape`: The shape to use for the effect.
|
||||||
|
- `style`: The style to use for the effect.
|
||||||
|
- `drawingMode` Changes between filled or stroked shapes. Default is `.fill`.
|
||||||
|
- `count`: The number of shapes to emit.
|
||||||
|
- `layer` The particle layer to use. Prevents the shape from being clipped by the parent view. (Optional)
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "dot.radiowaves.left.and.right")
|
||||||
|
}
|
||||||
|
|
||||||
|
static var newIn0_3_0: Bool { true }
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct RiseExample: View, Example {
|
||||||
|
@State
|
||||||
|
var changes: Int = 0
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
let colors = [Color.red, .orange, .yellow, .green, .blue, .indigo, .purple]
|
||||||
|
|
||||||
|
ZStack {
|
||||||
|
Label {
|
||||||
|
Text(changes.formatted())
|
||||||
|
.contentTransition(.identity)
|
||||||
|
.monospacedDigit()
|
||||||
|
.changeEffect(.rise {
|
||||||
|
// Rise will cycle through provided views
|
||||||
|
ForEach(colors, id: \.self) { color in
|
||||||
|
Text("+1")
|
||||||
|
.foregroundStyle(color.gradient)
|
||||||
|
.shadow(color: color.opacity(0.4), radius: 0.5, y: 0.5)
|
||||||
|
}
|
||||||
|
.font(.system(.body, design: .rounded, weight: .bold))
|
||||||
|
}, value: changes)
|
||||||
|
} icon: {
|
||||||
|
Image(systemName: "star.fill")
|
||||||
|
.foregroundStyle(
|
||||||
|
LinearGradient(colors: colors, startPoint: UnitPoint(x: 0.2, y: 0.2), endPoint: UnitPoint(x: 0.8, y: 0.8))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.padding(.vertical, 8)
|
||||||
|
.padding(.leading, 16)
|
||||||
|
.padding(.trailing, 20)
|
||||||
|
.background(.thinMaterial, in: Capsule())
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
.font(.system(.title, design: .rounded, weight: .bold))
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation {
|
||||||
|
changes += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static var description: some View {
|
||||||
|
Text("""
|
||||||
|
An effect that emits the provided particles from the origin point and slowly float up while moving side to side.
|
||||||
|
|
||||||
|
- Parameters:
|
||||||
|
- `origin`: The origin of the particle.
|
||||||
|
- `particles`: The particles to emit.
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "arrow.up.and.down.and.sparkles")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct ShakeExample: View, Example {
|
||||||
|
@State var password = ""
|
||||||
|
|
||||||
|
@State var loginAttempts = 0
|
||||||
|
|
||||||
|
@State var isProcessing = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
GroupBox("Sign In") {
|
||||||
|
VStack(alignment: .leading, spacing: 12) {
|
||||||
|
SecureField("Password", text: $password)
|
||||||
|
.changeEffect(.shake(rate: .fast), value: loginAttempts)
|
||||||
|
.onSubmit {
|
||||||
|
Task {
|
||||||
|
isProcessing = true
|
||||||
|
defer { isProcessing = false }
|
||||||
|
|
||||||
|
try? await Task.sleep(for: .seconds(1))
|
||||||
|
|
||||||
|
loginAttempts += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.disabled(isProcessing)
|
||||||
|
.textFieldStyle(.roundedBorder)
|
||||||
|
.changeEffect(.shake(rate: .fast), value: loginAttempts)
|
||||||
|
|
||||||
|
Text("Submit the form to see the effect.").font(.caption).foregroundColor(.secondary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(maxWidth: 320)
|
||||||
|
.padding(24)
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
}
|
||||||
|
|
||||||
|
static var description: some View {
|
||||||
|
Text("""
|
||||||
|
An effect that shakes the view when a change happens.
|
||||||
|
|
||||||
|
- `rate`: The rate of the shake.
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "arrow.left.arrow.right")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct ShineExample: View, Example {
|
||||||
|
@State var name = ""
|
||||||
|
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
GroupBox("Sign In") {
|
||||||
|
TextField("Name", text: $name)
|
||||||
|
.textFieldStyle(.roundedBorder)
|
||||||
|
.padding(.bottom, 24)
|
||||||
|
|
||||||
|
Button {
|
||||||
|
|
||||||
|
} label: {
|
||||||
|
Spacer()
|
||||||
|
Text("Submit")
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.disabled(name.isEmpty)
|
||||||
|
.changeEffect(.shine.delay(1), value: name.isEmpty, isEnabled: !name.isEmpty)
|
||||||
|
.buttonStyle(.borderedProminent)
|
||||||
|
}
|
||||||
|
.frame(maxWidth: 320)
|
||||||
|
.padding(24)
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
if name.isEmpty {
|
||||||
|
name = "Jay Appleseed"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static var description: some View {
|
||||||
|
Text("""
|
||||||
|
Highlights the view with a shine moving over the view.
|
||||||
|
|
||||||
|
The angle is relative to the current `layoutDirection`, such that 0° represents sweeping towards the trailing edge and 90° represents sweeping towards the top edge.
|
||||||
|
|
||||||
|
- Parameters:
|
||||||
|
- `angle`: The angle of the animation.
|
||||||
|
- `duration`: The duration of the animation.
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "sparkles")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,182 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct SoundEffectExample: View, Example {
|
||||||
|
var body: some View {
|
||||||
|
// All `SoundEffects` used here can be found in the
|
||||||
|
// `Pow Example/Sounds/` folder and are free to use with any licensed
|
||||||
|
// copy of Pow.
|
||||||
|
ScrollView {
|
||||||
|
VStack {
|
||||||
|
GroupBox("Alerts") {
|
||||||
|
HStack {
|
||||||
|
SoundEffectPad("Not Found", SoundEffect("notfound"))
|
||||||
|
SoundEffectPad("Pluck", SoundEffect("pluck"))
|
||||||
|
SoundEffectPad("Pong", SoundEffect("pong"))
|
||||||
|
SoundEffectPad("Ping", SoundEffect("ping"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupBox("Blips") {
|
||||||
|
HStack {
|
||||||
|
SoundEffectPad("Boop", SoundEffect("boop"))
|
||||||
|
SoundEffectPad("Beep", SoundEffect("beep"))
|
||||||
|
SoundEffectPad("Biip", SoundEffect("biip"))
|
||||||
|
SoundEffectPad("Biip", SoundEffect("biip")).hidden()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupBox("Clicks & Plops") {
|
||||||
|
HStack {
|
||||||
|
SoundEffectPad("Dial", SoundEffect("dial"))
|
||||||
|
SoundEffectPad("Tock", SoundEffect("tock"))
|
||||||
|
SoundEffectPad("Plop", SoundEffect("plop"))
|
||||||
|
SoundEffectPad("Pop", SoundEffect("pop1", "pop2", "pop3", "pop4", "pop5"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupBox("Drips") {
|
||||||
|
HStack {
|
||||||
|
SoundEffectPad("Drip", SoundEffect("drip"))
|
||||||
|
SoundEffectPad("Drip\nFlat", SoundEffect("drip.flat"))
|
||||||
|
SoundEffectPad("Drip\nRising", SoundEffect("drip.rising"))
|
||||||
|
SoundEffectPad("Drip\nFalling", SoundEffect("drip.falling"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupBox("Glas") {
|
||||||
|
HStack {
|
||||||
|
SoundEffectPad("Tink", SoundEffect("tink"))
|
||||||
|
SoundEffectPad("Zing", SoundEffect("zing"))
|
||||||
|
SoundEffectPad("Glass", SoundEffect("glass"))
|
||||||
|
SoundEffectPad("Tick", SoundEffect("tick"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupBox("Metal") {
|
||||||
|
HStack {
|
||||||
|
SoundEffectPad("Latch", SoundEffect("latch1", "latch2", "latch3", "latch4"))
|
||||||
|
SoundEffectPad("Lock", SoundEffect("lock1", "lock2", "lock3", "lock4"))
|
||||||
|
SoundEffectPad("Snap", SoundEffect("snap"))
|
||||||
|
SoundEffectPad("Snap", SoundEffect("snap")).hidden()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupBox("Notifications") {
|
||||||
|
HStack {
|
||||||
|
SoundEffectPad("Chime", SoundEffect("chime"))
|
||||||
|
SoundEffectPad("Chime\nFlat", SoundEffect("chime.flat"))
|
||||||
|
SoundEffectPad("Chime\nRising", SoundEffect("chime.rising"))
|
||||||
|
SoundEffectPad("Chime\nFalling", SoundEffect("chime.falling"))
|
||||||
|
}
|
||||||
|
HStack {
|
||||||
|
SoundEffectPad("Pick", SoundEffect("pick"))
|
||||||
|
SoundEffectPad("Pick\nFlat", SoundEffect("pick.flat"))
|
||||||
|
SoundEffectPad("Pick\nRising", SoundEffect("pick.rising"))
|
||||||
|
SoundEffectPad("Pick\nFalling", SoundEffect("pick.falling"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupBox("Results") {
|
||||||
|
HStack {
|
||||||
|
SoundEffectPad("Sparkle", SoundEffect("sparkle"))
|
||||||
|
SoundEffectPad("Sparkle\nFlat", SoundEffect("sparkle.flat"))
|
||||||
|
SoundEffectPad("Sparkle\nRising", SoundEffect("sparkle.rising"))
|
||||||
|
SoundEffectPad("Sparkle\nFalling", SoundEffect("sparkle.falling"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupBox("Tension/Release") {
|
||||||
|
HStack {
|
||||||
|
SoundEffectPad("Reel", SoundEffect("reel"))
|
||||||
|
SoundEffectPad("Reel\nFlat", SoundEffect("reel.flat"))
|
||||||
|
SoundEffectPad("Reel\nRising", SoundEffect("reel.rising"))
|
||||||
|
SoundEffectPad("Reel\nFalling", SoundEffect("reel.falling"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupBox("Undo/Redo") {
|
||||||
|
HStack {
|
||||||
|
SoundEffectPad("Brush", SoundEffect("brush"))
|
||||||
|
SoundEffectPad("Shake", SoundEffect("shake"))
|
||||||
|
SoundEffectPad("Swipe", SoundEffect("swipe"))
|
||||||
|
SoundEffectPad("Swish", SoundEffect("swish"))
|
||||||
|
}
|
||||||
|
|
||||||
|
HStack {
|
||||||
|
SoundEffectPad("Wip", SoundEffect("wip"))
|
||||||
|
SoundEffectPad("Whooop", SoundEffect("whop"))
|
||||||
|
SoundEffectPad("Detach", SoundEffect("detach"))
|
||||||
|
SoundEffectPad("Detach", SoundEffect("detach")).hidden()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
.buttonStyle(SoundEffectButtonStyle())
|
||||||
|
.buttonStyle(.bordered)
|
||||||
|
}
|
||||||
|
|
||||||
|
static var description: some View {
|
||||||
|
Text("""
|
||||||
|
Triggers the playback of a sound.
|
||||||
|
|
||||||
|
- Parameters:
|
||||||
|
- `effect`: The `SoundEffect` to play back.
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "speaker.wave.2")
|
||||||
|
}
|
||||||
|
|
||||||
|
static let newIn0_2_0: Bool = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct SoundEffectPad: View {
|
||||||
|
var name: String
|
||||||
|
|
||||||
|
var effect: SoundEffect
|
||||||
|
|
||||||
|
init(_ name: String, _ effect: SoundEffect) {
|
||||||
|
self.name = name
|
||||||
|
self.effect = effect
|
||||||
|
}
|
||||||
|
|
||||||
|
@State
|
||||||
|
private var triggers = 0
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Button(name) {
|
||||||
|
triggers += 1
|
||||||
|
}
|
||||||
|
.changeEffect(.feedback(effect), value: triggers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct SoundEffectButtonStyle: ButtonStyle {
|
||||||
|
func makeBody(configuration: Configuration) -> some View {
|
||||||
|
configuration.label
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
|
||||||
|
.font(.caption2)
|
||||||
|
.padding(4)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
.background(.tertiary, in: RoundedRectangle(cornerRadius: 3, style: .continuous))
|
||||||
|
.overlay {
|
||||||
|
if configuration.isPressed {
|
||||||
|
Circle()
|
||||||
|
.fill(RadialGradient(colors: [.white, .white.opacity(0.0)], center: .center, startRadius: 0, endRadius: 30))
|
||||||
|
.opacity(0.5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(height: 64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SoundEffectExample_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
SoundEffectExample()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct SpinExample: View, Example {
|
||||||
|
@State
|
||||||
|
var changes: Int = 0
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
Label {
|
||||||
|
Text(changes.formatted())
|
||||||
|
.contentTransition(.identity)
|
||||||
|
.monospacedDigit()
|
||||||
|
} icon: {
|
||||||
|
Image(systemName: "hand.thumbsup.fill")
|
||||||
|
.foregroundStyle(.blue.gradient)
|
||||||
|
.changeEffect(.spin(axis: (0, 1, -0.05), anchor: UnitPoint(x: 0.5, y: 0.5), perspective: 0.6, rate: .fast), value: changes)
|
||||||
|
}
|
||||||
|
.padding(.vertical, 8)
|
||||||
|
.padding(.leading, 16)
|
||||||
|
.padding(.trailing, 24)
|
||||||
|
.background(.thinMaterial, in: Capsule(style: .continuous))
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
.font(.system(.title, design: .rounded, weight: .bold))
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation {
|
||||||
|
changes += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static var description: some View {
|
||||||
|
Text("""
|
||||||
|
Spins the view around the given axis when a change happens.
|
||||||
|
|
||||||
|
- Parameters:
|
||||||
|
- `axis`: The x, y and z elements that specify the axis of rotation.
|
||||||
|
- `anchor`: The location with a default of center that defines a point in 3D space about which the rotation is anchored.
|
||||||
|
- `anchorZ`: The location with a default of 0 that defines a point in 3D space about which the rotation is anchored.
|
||||||
|
- `perspective`: The relative vanishing point with a default of 1 / 6 for this rotation.
|
||||||
|
- `rate`: How fast the the view spins.
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "arrow.clockwise")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct SprayExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isFavorited: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
Label {
|
||||||
|
let favoriteCount = isFavorited ? 143 : 142
|
||||||
|
|
||||||
|
Text(favoriteCount.formatted())
|
||||||
|
.contentTransition(.numericText())
|
||||||
|
.monospacedDigit()
|
||||||
|
} icon: {
|
||||||
|
ZStack {
|
||||||
|
Image(systemName: "heart")
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
.fontWeight(.light)
|
||||||
|
.opacity(isFavorited ? 0 : 1)
|
||||||
|
|
||||||
|
Image(systemName: "heart.fill")
|
||||||
|
.foregroundStyle(.pink.gradient)
|
||||||
|
.scaleEffect(isFavorited ? 1 : 0.1, anchor: .center)
|
||||||
|
.opacity(isFavorited ? 1 : 0)
|
||||||
|
}
|
||||||
|
.changeEffect(.spray {
|
||||||
|
Group {
|
||||||
|
Image(systemName: "heart.fill")
|
||||||
|
Image(systemName: "sparkles")
|
||||||
|
}
|
||||||
|
.font(.title)
|
||||||
|
.foregroundStyle(.pink.gradient)
|
||||||
|
}, value: isFavorited, isEnabled: isFavorited)
|
||||||
|
}
|
||||||
|
.padding(.vertical, 8)
|
||||||
|
.padding(.leading, 16)
|
||||||
|
.padding(.trailing, 24)
|
||||||
|
.background {
|
||||||
|
RoundedRectangle(cornerRadius: 12, style: .continuous)
|
||||||
|
.fill(.foreground)
|
||||||
|
.opacity(0.3)
|
||||||
|
}
|
||||||
|
.foregroundStyle(isFavorited ? .pink : .secondary)
|
||||||
|
.font(.system(.title, design: .rounded, weight: .semibold))
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation(.movingParts.overshoot(duration: 0.4)) {
|
||||||
|
isFavorited.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static var description: some View {
|
||||||
|
Text("""
|
||||||
|
An effect that emits multiple particles in different shades and sizes moving up from the origin point.
|
||||||
|
|
||||||
|
- Parameters:
|
||||||
|
- `origin`: The origin of the particles.
|
||||||
|
- `particles`: The particles to emit.
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "party.popper")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct PushDownExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isPressed: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
Text("Push me")
|
||||||
|
.font(.system(.title, design: .rounded, weight: .semibold))
|
||||||
|
.blendMode(.destinationOut)
|
||||||
|
.padding()
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.background(Color.accentColor.gradient, in: Capsule(style: .continuous))
|
||||||
|
._onButtonGesture {
|
||||||
|
isPressed = $0
|
||||||
|
} perform: {
|
||||||
|
|
||||||
|
}
|
||||||
|
.conditionalEffect(.pushDown, condition: isPressed)
|
||||||
|
.compositingGroup()
|
||||||
|
.padding()
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
}
|
||||||
|
|
||||||
|
static var description: some View {
|
||||||
|
Text("""
|
||||||
|
Scales the view down as if pushed wile a condition is met.
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "arrow.down.to.line.compact")
|
||||||
|
}
|
||||||
|
|
||||||
|
static var newIn0_3_0: Bool { true }
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct RepeatExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isEnabled: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
GroupBox {
|
||||||
|
Toggle("Enable Effect", isOn: $isEnabled.animation())
|
||||||
|
}
|
||||||
|
.padding(.horizontal)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
Button {
|
||||||
|
|
||||||
|
} label: {
|
||||||
|
Label("Accept", systemImage: "phone.fill")
|
||||||
|
}
|
||||||
|
.tint(.green)
|
||||||
|
.disabled(!isEnabled)
|
||||||
|
.conditionalEffect(.repeat(.wiggle(rate: .fast), every: .seconds(2)), condition: isEnabled)
|
||||||
|
|
||||||
|
Button {
|
||||||
|
|
||||||
|
} label: {
|
||||||
|
Label("Update", systemImage: "sparkles")
|
||||||
|
}
|
||||||
|
.disabled(!isEnabled)
|
||||||
|
.conditionalEffect(.repeat(.shine, every: .seconds(2)), condition: isEnabled)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.controlSize(.large)
|
||||||
|
.buttonStyle(.borderedProminent)
|
||||||
|
.defaultBackground()
|
||||||
|
.autotoggle($isEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
static var description: some View {
|
||||||
|
Text("""
|
||||||
|
Repeats an `AnyChangeEffect` at regular intervals.
|
||||||
|
|
||||||
|
- `effect`: The effect to repeat.
|
||||||
|
- `interval` The candence at which the effect is repeated.
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "arrow.counterclockwise")
|
||||||
|
}
|
||||||
|
|
||||||
|
static var newIn0_3_0: Bool { true }
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct SmokeExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isEnabled: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
GroupBox {
|
||||||
|
Toggle("Enable Effect", isOn: $isEnabled.animation())
|
||||||
|
}
|
||||||
|
.padding(.horizontal)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
ZStack {
|
||||||
|
Circle()
|
||||||
|
.fill(.orange.gradient)
|
||||||
|
.brightness(-0.1)
|
||||||
|
|
||||||
|
Rectangle()
|
||||||
|
.fill(.white.gradient)
|
||||||
|
.mask {
|
||||||
|
ZStack {
|
||||||
|
Circle()
|
||||||
|
.strokeBorder(.white.opacity(0.8).gradient, lineWidth: 4)
|
||||||
|
.padding(6)
|
||||||
|
|
||||||
|
Image(systemName: "opticaldiscdrive.fill")
|
||||||
|
.imageScale(.large)
|
||||||
|
.font(.system(size: 40, weight: .black))
|
||||||
|
.offset(y: -2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.blendMode(.lighten)
|
||||||
|
}
|
||||||
|
.compositingGroup()
|
||||||
|
.drawingGroup()
|
||||||
|
.frame(width: 120, height: 120)
|
||||||
|
.grayscale(isEnabled ? 0 : 1)
|
||||||
|
.conditionalEffect(.smoke(layer: .named("root")), condition: isEnabled)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.autotoggle($isEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
static var description: some View {
|
||||||
|
Text("""
|
||||||
|
Emmits smoke from behind the view.
|
||||||
|
|
||||||
|
- `layer` The particle layer to use. Prevents the smoke from being clipped by the parent view. (Optional)
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "flame")
|
||||||
|
}
|
||||||
|
|
||||||
|
static var newIn0_3_0: Bool { true }
|
||||||
|
}
|
||||||
217
Example/Pow Example/Examples/Example.swift
Normal file
|
|
@ -0,0 +1,217 @@
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
protocol Example: View {
|
||||||
|
associatedtype Description: View
|
||||||
|
|
||||||
|
init()
|
||||||
|
|
||||||
|
static var title: String { get }
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
static var description: Description { get }
|
||||||
|
|
||||||
|
static var icon: Image? { get }
|
||||||
|
|
||||||
|
static var localPath: LocalPath { get }
|
||||||
|
|
||||||
|
static var newIn0_2_0: Bool { get }
|
||||||
|
|
||||||
|
static var newIn0_3_0: Bool { get }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Example {
|
||||||
|
static var title: String {
|
||||||
|
String(describing: type(of: self))
|
||||||
|
.replacingOccurrences(of: "Example.Type", with: "")
|
||||||
|
.reduce(into: "") { string, character in
|
||||||
|
if string.last?.isUppercase == false && character.isUppercase {
|
||||||
|
string.append(" ")
|
||||||
|
}
|
||||||
|
|
||||||
|
string.append(character)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
static var navigationLink: NavigationLink<some View, some View> {
|
||||||
|
NavigationLink {
|
||||||
|
ZStack {
|
||||||
|
Self()
|
||||||
|
.background()
|
||||||
|
.toolbar {
|
||||||
|
GithubButton(Self.localPath)
|
||||||
|
|
||||||
|
if type(of: Self.description) != EmptyView.self {
|
||||||
|
InfoButton(type: Self.self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.navigationTitle(title)
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
let colors = [Color.red, .orange, .yellow, .green, .blue, .indigo, .purple, .mint]
|
||||||
|
|
||||||
|
var rng = MinimalPCG(string: title)
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Text(title)
|
||||||
|
.layoutPriority(1)
|
||||||
|
|
||||||
|
if newIn0_2_0 {
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
NewBadge("0.2.0")
|
||||||
|
}
|
||||||
|
|
||||||
|
if newIn0_3_0 {
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
NewBadge("0.3.0")
|
||||||
|
}
|
||||||
|
} icon: {
|
||||||
|
IconView {
|
||||||
|
icon ?? Image(systemName: "wand.and.stars.inverse")
|
||||||
|
}
|
||||||
|
.foregroundStyle(colors[Int(rng.next()) % colors.count].gradient)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static var icon: Image? { nil }
|
||||||
|
|
||||||
|
static var newIn0_2_0: Bool { false }
|
||||||
|
|
||||||
|
static var newIn0_3_0: Bool { false }
|
||||||
|
|
||||||
|
static var description: some View {
|
||||||
|
EmptyView()
|
||||||
|
}
|
||||||
|
|
||||||
|
static var erasedDescription: AnyView {
|
||||||
|
AnyView(description)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension View {
|
||||||
|
func defaultBackground() -> some View {
|
||||||
|
self
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
|
.background(Rectangle().fill(.background).ignoresSafeArea())
|
||||||
|
.contentShape(Rectangle())
|
||||||
|
}
|
||||||
|
|
||||||
|
func autotoggle(_ binding: Binding<Bool>, with animation: Animation = .default) -> some View {
|
||||||
|
self
|
||||||
|
.onAppear {
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||||
|
withAnimation(animation) {
|
||||||
|
binding.wrappedValue = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NewBadge: View {
|
||||||
|
var version: String
|
||||||
|
|
||||||
|
init(_ version: String) {
|
||||||
|
self.version = version
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ViewThatFits {
|
||||||
|
Text("New in \(version)").fixedSize()
|
||||||
|
Text("\(version)").fixedSize()
|
||||||
|
}
|
||||||
|
.dynamicTypeSize(...DynamicTypeSize.accessibility1)
|
||||||
|
.font(.caption2.monospacedDigit())
|
||||||
|
.textCase(.uppercase)
|
||||||
|
.bold()
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
.padding(.horizontal, 8)
|
||||||
|
.padding(.vertical, 4)
|
||||||
|
.background(.thinMaterial, in: Capsule())
|
||||||
|
.overlay {
|
||||||
|
Capsule()
|
||||||
|
.stroke(.quaternary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct IconView<Content: View>: View {
|
||||||
|
var content: Content
|
||||||
|
|
||||||
|
init(@ViewBuilder content: () -> Content) {
|
||||||
|
self.content = content()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(\.colorScheme)
|
||||||
|
var colorScheme
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
Rectangle()
|
||||||
|
.fill(.primary)
|
||||||
|
.aspectRatio(1, contentMode: .fill)
|
||||||
|
.frame(width: 28, height: 28)
|
||||||
|
.brightness(colorScheme == .dark ? -0.2 : -0.03)
|
||||||
|
|
||||||
|
content
|
||||||
|
.foregroundStyle(.white)
|
||||||
|
}
|
||||||
|
.font(.system(size: 18))
|
||||||
|
.imageScale(.small)
|
||||||
|
.symbolRenderingMode(.monochrome)
|
||||||
|
.symbolVariant(.fill)
|
||||||
|
.clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous))
|
||||||
|
.overlay {
|
||||||
|
RoundedRectangle(cornerRadius: 8, style: .continuous)
|
||||||
|
.strokeBorder(.white.opacity(0.1), lineWidth: 0.5)
|
||||||
|
.blendMode(.plusLighter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LocalPath {
|
||||||
|
var path: String
|
||||||
|
|
||||||
|
init(path: String = #file) {
|
||||||
|
self.path = path
|
||||||
|
}
|
||||||
|
|
||||||
|
var url: URL {
|
||||||
|
URL(fileURLWithPath: path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// *Really* minimal PCG32 code / (c) 2014 M.E. O'Neill / pcg-random.org
|
||||||
|
// Licensed under Apache License 2.0 (NO WARRANTY, etc. see website)
|
||||||
|
//
|
||||||
|
// Ported from https://www.pcg-random.org/download.html
|
||||||
|
private struct MinimalPCG {
|
||||||
|
var state: UInt64
|
||||||
|
|
||||||
|
var inc: UInt64
|
||||||
|
|
||||||
|
init(string: String) {
|
||||||
|
self.state = string.utf8.reduce(0.0) { a, b in a + (Double(b) * .pi) }.bitPattern
|
||||||
|
self.inc = (Double(string.count) * .pi).bitPattern
|
||||||
|
}
|
||||||
|
|
||||||
|
init(state: UInt64, inc: UInt64) {
|
||||||
|
self.state = state
|
||||||
|
self.inc = inc
|
||||||
|
}
|
||||||
|
|
||||||
|
mutating func next() -> UInt32 {
|
||||||
|
let oldstate = state
|
||||||
|
|
||||||
|
// Advance internal state
|
||||||
|
state = oldstate &* 6364136223846793005 &+ (inc | 1)
|
||||||
|
// Calculate output function (XSH RR), uses old state for max ILP
|
||||||
|
let xorshifted = ((oldstate >> 18) ^ oldstate) >> 27
|
||||||
|
let rot = Int(truncatingIfNeeded: oldstate >> 59)
|
||||||
|
|
||||||
|
return UInt32(truncatingIfNeeded: (xorshifted >> rot) | (xorshifted << ((-rot) & 31)))
|
||||||
|
}
|
||||||
|
}
|
||||||
275
Example/Pow Example/Examples/Screens/CheckoutExample.swift
Normal file
|
|
@ -0,0 +1,275 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct CheckoutExample: View, Example {
|
||||||
|
enum PaymentError: Error {
|
||||||
|
case unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
@State
|
||||||
|
var result: Result<Void, Error>?
|
||||||
|
|
||||||
|
@State
|
||||||
|
var quantity = 1
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
List {
|
||||||
|
if case .success = result {
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
Text("Thank You For Your Order")
|
||||||
|
.font(.title2)
|
||||||
|
.bold()
|
||||||
|
Text("We'll notify you when your order has been sent.")
|
||||||
|
.font(.title3)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
}
|
||||||
|
.listRowSeparator(.hidden)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
LabeledContent("Purchase Number", value: "P023121114")
|
||||||
|
} else {
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
Text("Checkout")
|
||||||
|
.font(.largeTitle)
|
||||||
|
.bold()
|
||||||
|
.accessibility(addTraits: .isHeader)
|
||||||
|
Text(quantity > 0 ? "1 Item" : "No Items")
|
||||||
|
.font(.title2)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
}
|
||||||
|
.listRowSeparator(.hidden)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
Section {
|
||||||
|
if quantity > 0 {
|
||||||
|
CartItem(quantity: $quantity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
Section {
|
||||||
|
LabeledContent("Address", value: "jane.doe@example.com")
|
||||||
|
|
||||||
|
LabeledContent("Payment", value: "VISA")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.listStyle(.plain)
|
||||||
|
.navigationTitle("")
|
||||||
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
|
.animation(.default, value: quantity != 0)
|
||||||
|
.toolbar {
|
||||||
|
if quantity == 0 {
|
||||||
|
ToolbarItem(placement: .navigationBarTrailing) {
|
||||||
|
Button("Undo") {
|
||||||
|
quantity = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.changeEffect(.feedback(SoundEffect("whop")), value: quantity == 0, isEnabled: quantity == 0)
|
||||||
|
.changeEffect(.feedback(SoundEffect("wip")), value: quantity != 0, isEnabled: quantity != 0)
|
||||||
|
.safeAreaInset(edge: .bottom, spacing: 0) {
|
||||||
|
VStack(spacing: 16) {
|
||||||
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
|
LabeledContent("Subtotal", value: 99 * quantity, format: .currency(code: "USD"))
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
LabeledContent("Shipping", value: 0, format: .currency(code: "USD"))
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
LabeledContent("Total", value: 99 * quantity, format: .currency(code: "USD"))
|
||||||
|
.fontWeight(.heavy)
|
||||||
|
}
|
||||||
|
|
||||||
|
PayButton {
|
||||||
|
let isFirstPayAttempt = result == nil
|
||||||
|
|
||||||
|
try? await Task.sleep(nanoseconds: 1_000_000_000)
|
||||||
|
|
||||||
|
if isFirstPayAttempt {
|
||||||
|
throw PaymentError.unknown
|
||||||
|
}
|
||||||
|
} completion: { payResult in
|
||||||
|
withAnimation {
|
||||||
|
result = payResult
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.disabled(quantity == 0)
|
||||||
|
.changeEffect(.shine.delay(1), value: quantity != 0, isEnabled: quantity != 0)
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.background(.bar)
|
||||||
|
}
|
||||||
|
.labeledContentStyle(CheckoutLabeledContentStyle())
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "cart")
|
||||||
|
}
|
||||||
|
|
||||||
|
static let newIn0_2_0: Bool = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct CartItem: View {
|
||||||
|
@Binding
|
||||||
|
var quantity: Int
|
||||||
|
|
||||||
|
@State
|
||||||
|
var lastQuantity: Int = 0
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
HStack {
|
||||||
|
Stepper("Quantity", value: $quantity, in: 0...99)
|
||||||
|
.labelsHidden()
|
||||||
|
.alignmentGuide(.listRowSeparatorLeading) { dimensions in
|
||||||
|
dimensions[.leading]
|
||||||
|
}
|
||||||
|
.changeEffect(.feedback(SoundEffect("beep")), value: quantity, isEnabled: quantity > lastQuantity && quantity > 1)
|
||||||
|
.changeEffect(.feedback(SoundEffect("boop")), value: quantity, isEnabled: quantity < lastQuantity && quantity > 0)
|
||||||
|
.onChange(of: quantity) { newValue in
|
||||||
|
lastQuantity = quantity
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(quantity, format: .number).monospacedDigit() + Text("×")
|
||||||
|
|
||||||
|
LabeledContent("Pow License", value: 99, format: .currency(code: "USD"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PayButton: View {
|
||||||
|
var action: () async throws -> Void
|
||||||
|
|
||||||
|
var completion: (Result<Void, Error>) -> Void
|
||||||
|
|
||||||
|
enum Status {
|
||||||
|
case initial
|
||||||
|
case inProgress
|
||||||
|
case succeeded
|
||||||
|
case failed
|
||||||
|
}
|
||||||
|
|
||||||
|
@State
|
||||||
|
var status: Status = .initial
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Button {
|
||||||
|
status = .inProgress
|
||||||
|
Task {
|
||||||
|
do {
|
||||||
|
try await action()
|
||||||
|
status = .succeeded
|
||||||
|
completion(.success(()))
|
||||||
|
} catch {
|
||||||
|
status = .failed
|
||||||
|
try? await Task.sleep(nanoseconds: 1_500_000_000)
|
||||||
|
status = .initial
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
HStack(spacing: 12) {
|
||||||
|
ZStack {
|
||||||
|
ProgressView()
|
||||||
|
.controlSize(.regular)
|
||||||
|
.tint(.white)
|
||||||
|
.opacity(status == .inProgress ? 1 : 0)
|
||||||
|
.animation(.spring(), value: status == .inProgress)
|
||||||
|
|
||||||
|
Image(systemName: "exclamationmark.triangle")
|
||||||
|
.opacity(status == .failed ? 1 : 0)
|
||||||
|
.animation(.spring(), value: status == .failed)
|
||||||
|
|
||||||
|
Checkmark()
|
||||||
|
.trim(from: 0, to: status == .succeeded ? 1 : 0)
|
||||||
|
.stroke(style: .init(lineWidth: 3, lineCap: .round, lineJoin: .round))
|
||||||
|
.padding(4)
|
||||||
|
.animation(.spring(response: 0.3), value: status == .succeeded)
|
||||||
|
}
|
||||||
|
.frame(width: 20, height: 20)
|
||||||
|
.imageScale(.large)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
switch status {
|
||||||
|
case .initial:
|
||||||
|
Text("Pay")
|
||||||
|
case .inProgress:
|
||||||
|
Text("Paying…")
|
||||||
|
case .succeeded:
|
||||||
|
Text("Paid")
|
||||||
|
case .failed:
|
||||||
|
Text("Try Again")
|
||||||
|
}
|
||||||
|
|
||||||
|
Color.clear
|
||||||
|
.frame(width: 20, height: 20)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.font(.headline)
|
||||||
|
.buttonStyle(.borderedProminent)
|
||||||
|
.transformEnvironment(\.backgroundMaterial, transform: { material in
|
||||||
|
material = nil
|
||||||
|
})
|
||||||
|
.controlSize(.large)
|
||||||
|
.animation(.spring(response: 0.3), value: status == .inProgress)
|
||||||
|
.tint(status == .failed ? .red : status == .succeeded ? .green : nil)
|
||||||
|
.allowsHitTesting(status == .initial)
|
||||||
|
.changeEffect(.shake(rate: .fast), value: status == .failed, isEnabled: status == .failed)
|
||||||
|
.changeEffect(.feedback(SoundEffect("plop")), value: status == .inProgress, isEnabled: status == .inProgress)
|
||||||
|
.changeEffect(.feedback(SoundEffect("sparkle")), value: status == .succeeded, isEnabled: status == .succeeded)
|
||||||
|
.changeEffect(.feedback(SoundEffect("notfound")), value: status == .failed, isEnabled: status == .failed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct Checkmark: Shape {
|
||||||
|
func path(in rect: CGRect) -> Path {
|
||||||
|
let insetFrame = rect
|
||||||
|
|
||||||
|
let referenceSize = CGSize(width: 67, height: 68)
|
||||||
|
let referencePoint1: CGPoint
|
||||||
|
let referencePoint2: CGPoint
|
||||||
|
let referencePoint3: CGPoint
|
||||||
|
|
||||||
|
referencePoint1 = CGPoint(x: 3.5, y: 36.5)
|
||||||
|
referencePoint2 = CGPoint(x: 25.5, y: 63.5)
|
||||||
|
referencePoint3 = CGPoint(x: 63, y: 5.5)
|
||||||
|
|
||||||
|
return Path { path in
|
||||||
|
path.move(to: CGPoint(x: insetFrame.width * referencePoint1.x / referenceSize.width, y: insetFrame.height * referencePoint1.y / referenceSize.height))
|
||||||
|
path.addLine(to: CGPoint(x: insetFrame.width * referencePoint2.x / referenceSize.width, y: insetFrame.width * referencePoint2.y / referenceSize.height))
|
||||||
|
path.addLine(to: CGPoint(x: insetFrame.width * referencePoint3.x / referenceSize.width, y: insetFrame.width * referencePoint3.y / referenceSize.height))
|
||||||
|
}
|
||||||
|
.offsetBy(dx: insetFrame.origin.x, dy: insetFrame.origin.y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct CheckoutLabeledContentStyle: LabeledContentStyle {
|
||||||
|
func makeBody(configuration: Configuration) -> some View {
|
||||||
|
HStack(alignment: .firstTextBaseline) {
|
||||||
|
configuration.label
|
||||||
|
.font(.headline)
|
||||||
|
Spacer()
|
||||||
|
configuration.content
|
||||||
|
.font(.body)
|
||||||
|
.multilineTextAlignment(.trailing)
|
||||||
|
}
|
||||||
|
.padding(.vertical, 8)
|
||||||
|
.contentShape(Rectangle())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CheckoutExample_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
NavigationStack {
|
||||||
|
CheckoutExample()
|
||||||
|
.toolbar(.visible, for: .navigationBar)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
261
Example/Pow Example/Examples/Screens/SocialFeedExample.swift
Normal file
|
|
@ -0,0 +1,261 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct SocialFeedExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isLiked = false
|
||||||
|
|
||||||
|
@State
|
||||||
|
var isBoosted = false
|
||||||
|
|
||||||
|
@State
|
||||||
|
var clapCount = 202
|
||||||
|
|
||||||
|
@State
|
||||||
|
var isBookmarked = false
|
||||||
|
|
||||||
|
@State
|
||||||
|
var notificationCount: Int = 0
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ScrollView {
|
||||||
|
VStack(alignment: .trailing, spacing: 24) {
|
||||||
|
HStack(alignment: .top, spacing: 12) {
|
||||||
|
Image("mvp")
|
||||||
|
.resizable()
|
||||||
|
.aspectRatio(contentMode: .fill)
|
||||||
|
.clipShape(Circle())
|
||||||
|
.frame(width: 52, height: 52)
|
||||||
|
|
||||||
|
VStack(alignment: .leading, spacing: 6) {
|
||||||
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
|
HStack(alignment: .firstTextBaseline) {
|
||||||
|
Text("Moving Parts").font(.headline.bold())
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
Text("12 min")
|
||||||
|
.font(.footnote)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
}
|
||||||
|
Text("@movingpartsio").foregroundColor(.secondary)
|
||||||
|
}
|
||||||
|
.padding(.top, 3)
|
||||||
|
|
||||||
|
Text("Use Pow's Change Effects to give your buttons a little extra flair.")
|
||||||
|
|
||||||
|
Text("Try it on these buttons here:")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewThatFits {
|
||||||
|
buttonBar
|
||||||
|
.labelStyle(CustomButtonLabelStyle())
|
||||||
|
|
||||||
|
buttonBar
|
||||||
|
.labelStyle(.iconOnly)
|
||||||
|
}
|
||||||
|
.buttonStyle(.bordered)
|
||||||
|
.controlSize(.mini)
|
||||||
|
.tint(.gray)
|
||||||
|
.font(.footnote.weight(.medium).monospacedDigit())
|
||||||
|
}
|
||||||
|
.padding(12)
|
||||||
|
.background(.regularMaterial, in: RoundedRectangle(cornerRadius: 12, style: .continuous))
|
||||||
|
.padding(12)
|
||||||
|
}
|
||||||
|
.task {
|
||||||
|
try? await Task.sleep(for: .seconds(3))
|
||||||
|
|
||||||
|
withAnimation {
|
||||||
|
notificationCount += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.safeAreaInset(edge: .bottom, spacing: 0) {
|
||||||
|
tabBar
|
||||||
|
}
|
||||||
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
|
}
|
||||||
|
|
||||||
|
var buttonBar: some View {
|
||||||
|
HStack(alignment: .firstTextBaseline, spacing: 12) {
|
||||||
|
let pop = SoundEffect("pop1", "pop2", "pop3", "pop4", "pop5")
|
||||||
|
|
||||||
|
Button {
|
||||||
|
isLiked.toggle()
|
||||||
|
} label: {
|
||||||
|
let likeCount = isLiked ? 144: 143
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Text(likeCount.formatted())
|
||||||
|
} icon: {
|
||||||
|
Image(systemName: "heart.fill")
|
||||||
|
.changeEffect(
|
||||||
|
.spray {
|
||||||
|
Image(systemName: "heart.fill").foregroundStyle(.red)
|
||||||
|
},
|
||||||
|
value: likeCount,
|
||||||
|
isEnabled: isLiked
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tint(isLiked ? .red : .gray)
|
||||||
|
.changeEffect(.feedback(pop), value: isLiked, isEnabled: isLiked)
|
||||||
|
|
||||||
|
let sparkle = SoundEffect(isBoosted ? "sparkle.rising" : "sparkle.falling")
|
||||||
|
|
||||||
|
Button {
|
||||||
|
isBoosted.toggle()
|
||||||
|
} label: {
|
||||||
|
let boostCount = isBoosted ? 55 : 54
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Text(boostCount.formatted())
|
||||||
|
} icon: {
|
||||||
|
Image(systemName: "arrow.3.trianglepath")
|
||||||
|
.changeEffect(
|
||||||
|
.rise {
|
||||||
|
Text("+1")
|
||||||
|
.font(.footnote.weight(.heavy))
|
||||||
|
.shadow(color: .green.opacity(0.5), radius: 1)
|
||||||
|
.foregroundStyle(.green.gradient)
|
||||||
|
},
|
||||||
|
value: boostCount,
|
||||||
|
isEnabled: isBoosted
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tint(isBoosted ? .green : .gray)
|
||||||
|
.changeEffect(.feedback(sparkle), value: isBoosted)
|
||||||
|
|
||||||
|
Button {
|
||||||
|
clapCount += 1
|
||||||
|
} label: {
|
||||||
|
Label {
|
||||||
|
Text(clapCount.formatted())
|
||||||
|
} icon: {
|
||||||
|
Image(systemName: "hands.clap.fill")
|
||||||
|
.changeEffect(
|
||||||
|
.spray {
|
||||||
|
Group {
|
||||||
|
Image(systemName: "circle.fill").foregroundColor(.red)
|
||||||
|
Image(systemName: "square.fill").foregroundColor(.green)
|
||||||
|
Image(systemName: "circle.fill").foregroundColor(.blue)
|
||||||
|
Image(systemName: "diamond.fill").foregroundColor(.orange)
|
||||||
|
Image(systemName: "triangle.fill").foregroundColor(.indigo)
|
||||||
|
}
|
||||||
|
.shadow(radius: 1)
|
||||||
|
.font(.caption.weight(.black))
|
||||||
|
},
|
||||||
|
value: clapCount
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.changeEffect(.feedback(pop), value: clapCount)
|
||||||
|
.tint(clapCount > 202 ? .blue : .gray)
|
||||||
|
|
||||||
|
let pick = SoundEffect(isBookmarked ? "pick.rising" : "pick.falling")
|
||||||
|
|
||||||
|
Button {
|
||||||
|
isBookmarked.toggle()
|
||||||
|
} label: {
|
||||||
|
Label {
|
||||||
|
ZStack {
|
||||||
|
Text("Saved").hidden()
|
||||||
|
Text(isBookmarked ? "Saved" : "Save")
|
||||||
|
}
|
||||||
|
} icon: {
|
||||||
|
Image(systemName: "bookmark.fill")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tint(isBookmarked ? .orange : .gray)
|
||||||
|
.animation(.spring(response: 0.4, dampingFraction: 1), value: isBookmarked)
|
||||||
|
.changeEffect(.feedback(pick), value: isBookmarked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var tabBar: some View {
|
||||||
|
HStack {
|
||||||
|
Label("Home", systemImage: "house")
|
||||||
|
.labelStyle(SocialFeedTabBarLabelStyle(isSelected: true))
|
||||||
|
|
||||||
|
Label("Search", systemImage: "magnifyingglass")
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Text("Notifications")
|
||||||
|
} icon: {
|
||||||
|
Image(systemName: "bell")
|
||||||
|
.overlay(alignment: .topTrailing) {
|
||||||
|
Text(notificationCount.formatted())
|
||||||
|
.fixedSize()
|
||||||
|
.font(.caption.monospacedDigit())
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.padding(.vertical, 2)
|
||||||
|
.padding(.horizontal, 7)
|
||||||
|
.background(.red, in: Capsule())
|
||||||
|
.changeEffect(.pulse(shape: Capsule(), style: .red, count: 3), value: notificationCount)
|
||||||
|
.alignmentGuide(.top) { dimensions in
|
||||||
|
dimensions[VerticalAlignment.center] - 2
|
||||||
|
}
|
||||||
|
.alignmentGuide(.trailing) { dimensions in
|
||||||
|
dimensions[HorizontalAlignment.center]
|
||||||
|
}
|
||||||
|
.scaleEffect(notificationCount > 0 ? 1 : 0.1)
|
||||||
|
.opacity(notificationCount > 0 ? 1 : 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation {
|
||||||
|
notificationCount += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Text("Archive")
|
||||||
|
} icon: {
|
||||||
|
Image(systemName: "archivebox")
|
||||||
|
.changeEffect(.jump(height: 50), value: isBookmarked, isEnabled: isBookmarked)
|
||||||
|
}
|
||||||
|
|
||||||
|
Label("Profile", systemImage: "person")
|
||||||
|
}
|
||||||
|
.labelStyle(SocialFeedTabBarLabelStyle(isSelected: false))
|
||||||
|
.padding(12)
|
||||||
|
.padding(.bottom, 2)
|
||||||
|
.background(.regularMaterial, in: Capsule(style: .continuous))
|
||||||
|
.padding(.horizontal)
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "heart")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct SocialFeedTabBarLabelStyle: LabelStyle {
|
||||||
|
var isSelected: Bool
|
||||||
|
|
||||||
|
func makeBody(configuration: Configuration) -> some View {
|
||||||
|
VStack(spacing: 6) {
|
||||||
|
configuration.icon
|
||||||
|
.imageScale(.medium)
|
||||||
|
.symbolVariant(isSelected ? .fill : .none)
|
||||||
|
.font(.system(size: 22))
|
||||||
|
}
|
||||||
|
.foregroundStyle(isSelected ? AnyShapeStyle(.tint) : AnyShapeStyle(Color.primary))
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct CustomButtonLabelStyle: LabelStyle {
|
||||||
|
func makeBody(configuration: Configuration) -> some View {
|
||||||
|
HStack(spacing: 4) {
|
||||||
|
configuration.icon
|
||||||
|
|
||||||
|
configuration.title
|
||||||
|
.lineLimit(1)
|
||||||
|
.fixedSize(horizontal: true, vertical: false)
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
}
|
||||||
|
}
|
||||||
29
Example/Pow Example/Examples/Transitions/AnvilExample.swift
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct AnvilExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isVisible: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
if isVisible {
|
||||||
|
PlaceholderView()
|
||||||
|
.transition(.movingParts.anvil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.autotoggle($isVisible)
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "scalemass")
|
||||||
|
}
|
||||||
|
}
|
||||||
29
Example/Pow Example/Examples/Transitions/BlindsExample.swift
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct BlindsExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isVisible: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
if isVisible {
|
||||||
|
PlaceholderView()
|
||||||
|
.transition(.movingParts.blinds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.autotoggle($isVisible)
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "blinds.horizontal.open")
|
||||||
|
}
|
||||||
|
}
|
||||||
29
Example/Pow Example/Examples/Transitions/BlurExample.swift
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct BlurExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isVisible: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
if isVisible {
|
||||||
|
PlaceholderView()
|
||||||
|
.transition(.movingParts.blur.combined(with: .opacity))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.autotoggle($isVisible)
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "drop")
|
||||||
|
}
|
||||||
|
}
|
||||||
59
Example/Pow Example/Examples/Transitions/BoingExample.swift
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct BoingExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isVisible: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
HStack {
|
||||||
|
if isVisible {
|
||||||
|
let defaultSpring = Animation.spring()
|
||||||
|
|
||||||
|
PlaceholderView()
|
||||||
|
.frame(maxWidth: 120, maxHeight: 120)
|
||||||
|
.transition(
|
||||||
|
.asymmetric(
|
||||||
|
insertion: .movingParts.boing(edge: .top).animation(defaultSpring),
|
||||||
|
removal: .movingParts.boing(edge: .top).animation(defaultSpring).combined(with: .opacity.animation(.easeInOut(duration: 0.2)))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
let mediumSpring = Animation.interactiveSpring(dampingFraction: 0.5)
|
||||||
|
|
||||||
|
PlaceholderView()
|
||||||
|
.frame(maxWidth: 120, maxHeight: 120)
|
||||||
|
.transition(
|
||||||
|
.asymmetric(
|
||||||
|
insertion: .movingParts.boing(edge: .top).animation(mediumSpring),
|
||||||
|
removal: .movingParts.boing(edge: .top).animation(mediumSpring).combined(with: .opacity.animation(.easeInOut(duration: 0.2)))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
let looseSpring = Animation.interpolatingSpring(stiffness: 100, damping: 8)
|
||||||
|
|
||||||
|
PlaceholderView()
|
||||||
|
.frame(maxWidth: 120, maxHeight: 120)
|
||||||
|
.transition(
|
||||||
|
.asymmetric(
|
||||||
|
insertion: .movingParts.boing(edge: .top).animation(looseSpring),
|
||||||
|
removal: .movingParts.boing(edge: .top).animation(looseSpring).combined(with: .opacity.animation(.easeInOut(duration: 0.2)))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.autotoggle($isVisible)
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "figure.jumprope")
|
||||||
|
}
|
||||||
|
}
|
||||||
29
Example/Pow Example/Examples/Transitions/ClockExample.swift
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct ClockExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isVisible: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
if isVisible {
|
||||||
|
PlaceholderView()
|
||||||
|
.transition(.movingParts.clock(blurRadius: 10))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation(.spring(dampingFraction: 1)) {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.autotoggle($isVisible, with: .spring(dampingFraction: 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "clock")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct FilmExposureExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isVisible: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
ZStack {
|
||||||
|
// Placeholder
|
||||||
|
Rectangle().fill(.black)
|
||||||
|
|
||||||
|
if isVisible {
|
||||||
|
Image("disco")
|
||||||
|
.resizable()
|
||||||
|
.zIndex(1)
|
||||||
|
.transition(.movingParts.filmExposure)
|
||||||
|
} else {
|
||||||
|
ProgressView()
|
||||||
|
.tint(.white)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(width: 350, height: 525)
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation(.easeInOut(duration: 1.8)) {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.autotoggle($isVisible, with: .easeInOut(duration: 1.8))
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "film")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct FlickerExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isVisible: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
if isVisible {
|
||||||
|
PlaceholderView()
|
||||||
|
.transition(.movingParts.flicker)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.autotoggle($isVisible)
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "lightbulb")
|
||||||
|
}
|
||||||
|
}
|
||||||
79
Example/Pow Example/Examples/Transitions/FlipExample.swift
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct FlipExample: View, Example {
|
||||||
|
enum Variant: Hashable {
|
||||||
|
case flip
|
||||||
|
case standUp
|
||||||
|
case sideways
|
||||||
|
|
||||||
|
var transition: AnyTransition {
|
||||||
|
switch self {
|
||||||
|
case .flip: return .movingParts.flip
|
||||||
|
case .standUp: return .movingParts.rotate3D(.degrees(90), axis: (1, 0, 0), anchor: .bottom, perspective: 1 / 6)
|
||||||
|
case .sideways: return .movingParts.rotate3D(.degrees(90), axis: (0, 1, 0), perspective: 1 / 6)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@State
|
||||||
|
var variant: Variant = .flip
|
||||||
|
|
||||||
|
@State
|
||||||
|
var isVisible: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
GroupBox {
|
||||||
|
LabeledContent("Configuration") {
|
||||||
|
Picker("Configuration", selection: $variant) {
|
||||||
|
Text("Flip").tag(Variant.flip)
|
||||||
|
Text("Sideways").tag(Variant.sideways)
|
||||||
|
Text("Stand Up").tag(Variant.standUp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.horizontal)
|
||||||
|
|
||||||
|
VStack {
|
||||||
|
if isVisible {
|
||||||
|
PlaceholderView()
|
||||||
|
.id(variant)
|
||||||
|
.transition(variant.transition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(maxHeight: .infinity)
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation(animation) {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onChange(of: variant) { _ in
|
||||||
|
withAnimation(animation) {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.autotoggle($isVisible, with: animation)
|
||||||
|
}
|
||||||
|
|
||||||
|
var animation: Animation {
|
||||||
|
if isVisible {
|
||||||
|
return .easeIn
|
||||||
|
} else {
|
||||||
|
return .interactiveSpring(response: 0.4, dampingFraction: 0.4, blendDuration: 2.45)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static var title: String {
|
||||||
|
"Flip & Rotate3D"
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "rotate.3d")
|
||||||
|
}
|
||||||
|
}
|
||||||
39
Example/Pow Example/Examples/Transitions/GlareExample.swift
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct GlareExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isVisible: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
if isVisible {
|
||||||
|
PlaceholderView()
|
||||||
|
.transition(
|
||||||
|
.asymmetric(
|
||||||
|
insertion: .movingParts.glare(angle: .degrees(225), color: .white),
|
||||||
|
removal: .movingParts.glare(angle: .degrees(45), color: .white)
|
||||||
|
.animation(.movingParts.easeInExponential(duration: 0.9))
|
||||||
|
.combined(with:
|
||||||
|
.scale(scale: 1.4)
|
||||||
|
.animation(.movingParts.anticipate(duration: 0.9).delay(0.1))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.autotoggle($isVisible)
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "sun.max")
|
||||||
|
}
|
||||||
|
}
|
||||||
30
Example/Pow Example/Examples/Transitions/IrisExample.swift
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct IrisExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isVisible: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
if isVisible {
|
||||||
|
PlaceholderView()
|
||||||
|
.compositingGroup()
|
||||||
|
.transition(.movingParts.iris(blurRadius: 10))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation(.spring(dampingFraction: 1)) {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.autotoggle($isVisible, with: .spring(dampingFraction: 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "camera.aperture")
|
||||||
|
}
|
||||||
|
}
|
||||||
62
Example/Pow Example/Examples/Transitions/MoveExample.swift
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct MoveExample: View, Example {
|
||||||
|
@State
|
||||||
|
var angle: Angle = .degrees(225)
|
||||||
|
|
||||||
|
@State
|
||||||
|
var isVisible: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
GroupBox {
|
||||||
|
LabeledContent {
|
||||||
|
Slider(value: $angle.degrees, in: 0 ... 360, step: 5)
|
||||||
|
} label: {
|
||||||
|
Text("Angle")
|
||||||
|
Spacer()
|
||||||
|
Text(Measurement(value: angle.degrees, unit: UnitAngle.degrees).formatted(.measurement(width: .narrow, numberFormatStyle: .number.precision(.fractionLength(0)))))
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.font(.subheadline.monospacedDigit())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.horizontal)
|
||||||
|
|
||||||
|
VStack {
|
||||||
|
if isVisible {
|
||||||
|
PlaceholderView()
|
||||||
|
.compositingGroup()
|
||||||
|
.transition(.movingParts.move(angle: angle).combined(with: .opacity))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation(.spring(dampingFraction: 1)) {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.labeledContentStyle(VerticalLabeledContentStyle())
|
||||||
|
.defaultBackground()
|
||||||
|
.autotoggle($isVisible, with: .spring(dampingFraction: 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "arrow.up.left.and.down.right.and.arrow.up.right.and.down.left")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct VerticalLabeledContentStyle: LabeledContentStyle {
|
||||||
|
func makeBody(configuration: Configuration) -> some View {
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
HStack(alignment: .firstTextBaseline) {
|
||||||
|
configuration.label
|
||||||
|
}
|
||||||
|
|
||||||
|
configuration.content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
Example/Pow Example/Examples/Transitions/PoofExample.swift
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct PoofExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isVisible: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
if isVisible {
|
||||||
|
PlaceholderView()
|
||||||
|
.compositingGroup()
|
||||||
|
// Assign a random ID so that quick re-insertion will not
|
||||||
|
// play the poof transition backwards.
|
||||||
|
.id(UUID())
|
||||||
|
.transition(
|
||||||
|
.asymmetric(insertion: .opacity, removal: .movingParts.poof)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.autotoggle($isVisible)
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "trash")
|
||||||
|
}
|
||||||
|
}
|
||||||
44
Example/Pow Example/Examples/Transitions/PopExample.swift
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct PopExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isFavorited: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
HStack {
|
||||||
|
if isFavorited {
|
||||||
|
Image(systemName: "heart.fill")
|
||||||
|
.foregroundColor(.red)
|
||||||
|
.transition(
|
||||||
|
.movingParts.pop(.red)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Image(systemName: "heart")
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
.transition(.identity)
|
||||||
|
}
|
||||||
|
|
||||||
|
let favoriteCount = isFavorited ? 143 : 142
|
||||||
|
|
||||||
|
Text(favoriteCount.formatted())
|
||||||
|
.foregroundColor(isFavorited ? .red : .gray)
|
||||||
|
.animation(isFavorited ? .default.delay(0.4) : nil, value: isFavorited)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation(.spring(dampingFraction: 1)) {
|
||||||
|
isFavorited.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.autotoggle($isFavorited, with: .spring(dampingFraction: 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "rays")
|
||||||
|
}
|
||||||
|
}
|
||||||
44
Example/Pow Example/Examples/Transitions/SkidExample.swift
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct SkidExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isVisible: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
if isVisible {
|
||||||
|
let overshoot = Animation.movingParts.overshoot(duration: 0.8)
|
||||||
|
|
||||||
|
PlaceholderView()
|
||||||
|
.frame(maxWidth: 120, maxHeight: 120)
|
||||||
|
.transition(.movingParts.skid(direction: .leading).animation(overshoot))
|
||||||
|
|
||||||
|
let mediumSpring = Animation.interactiveSpring(dampingFraction: 0.5)
|
||||||
|
|
||||||
|
PlaceholderView()
|
||||||
|
.frame(maxWidth: 120, maxHeight: 120)
|
||||||
|
.transition(.movingParts.skid.animation(mediumSpring))
|
||||||
|
|
||||||
|
let looseSpring = Animation.interpolatingSpring(stiffness: 100, damping: 8)
|
||||||
|
|
||||||
|
PlaceholderView()
|
||||||
|
.frame(maxWidth: 120, maxHeight: 120)
|
||||||
|
.transition(.movingParts.skid.animation(looseSpring))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.autotoggle($isVisible)
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "arrow.left.and.right.square")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct SnapshotExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isVisible: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
ZStack {
|
||||||
|
// Placeholder
|
||||||
|
Rectangle()
|
||||||
|
.fill(.white)
|
||||||
|
|
||||||
|
if isVisible {
|
||||||
|
Image("disco")
|
||||||
|
.resizable()
|
||||||
|
.zIndex(1)
|
||||||
|
.transition(.movingParts.snapshot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(width: 350, height: 525)
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation(.easeInOut(duration: 1.8)) {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.autotoggle($isVisible, with: .easeInOut(duration: 1.8))
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "camera")
|
||||||
|
}
|
||||||
|
}
|
||||||
37
Example/Pow Example/Examples/Transitions/SwooshExample.swift
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct SwooshExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isVisible: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
if isVisible {
|
||||||
|
PlaceholderView()
|
||||||
|
.transition(.movingParts.swoosh.combined(with: .opacity))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
let animation: Animation
|
||||||
|
|
||||||
|
if isVisible {
|
||||||
|
animation = .easeIn
|
||||||
|
} else {
|
||||||
|
animation = .spring()
|
||||||
|
}
|
||||||
|
|
||||||
|
withAnimation(animation) {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.autotoggle($isVisible, with: .spring())
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "skew")
|
||||||
|
}
|
||||||
|
}
|
||||||
38
Example/Pow Example/Examples/Transitions/VanishExample.swift
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct VanishExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isVisible: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
if isVisible {
|
||||||
|
Circle()
|
||||||
|
.frame(width: 250, height: 250)
|
||||||
|
// Assign a random ID so that quick re-insertion will not
|
||||||
|
// play the vanish transition backwards.
|
||||||
|
.id(UUID())
|
||||||
|
.transition(
|
||||||
|
.asymmetric(
|
||||||
|
insertion: .opacity,
|
||||||
|
removal: .movingParts.vanish(Color(white: 0.8), mask: Circle())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.autotoggle($isVisible)
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "circle.dotted")
|
||||||
|
}
|
||||||
|
}
|
||||||
37
Example/Pow Example/Examples/Transitions/WipeExample.swift
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
import Pow
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct WipeExample: View, Example {
|
||||||
|
@State
|
||||||
|
var isVisible: Bool = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
if isVisible {
|
||||||
|
PlaceholderView()
|
||||||
|
// Assign a random ID so that quick re-insertion will not
|
||||||
|
// play the wipe transition backwards.
|
||||||
|
.id(UUID())
|
||||||
|
.transition(
|
||||||
|
.asymmetric(
|
||||||
|
insertion: .movingParts.wipe(angle: .degrees(235), blurRadius: 30),
|
||||||
|
removal: .movingParts.wipe(angle: .degrees(55), blurRadius: 30)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.defaultBackground()
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation(.spring(dampingFraction: 1)) {
|
||||||
|
isVisible.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.autotoggle($isVisible, with: .spring(dampingFraction: 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
static let localPath = LocalPath()
|
||||||
|
|
||||||
|
static var icon: Image? {
|
||||||
|
Image(systemName: "windshield.rear.and.wiper")
|
||||||
|
}
|
||||||
|
}
|
||||||
43
Example/Pow Example/GithubButton.swift
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct GithubButton: View {
|
||||||
|
var localPath: LocalPath
|
||||||
|
|
||||||
|
let baseURL = URL(string: "https://github.com/movingparts-io/Pow-Examples/blob/main/")!
|
||||||
|
|
||||||
|
init(_ localPath: LocalPath) {
|
||||||
|
self.localPath = localPath
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
let srcroot = Bundle.main.object(forInfoDictionaryKey: "MVP_SRCROOT") as? String
|
||||||
|
|
||||||
|
if let srcURL = srcroot.map(URL.init(fileURLWithPath:)) {
|
||||||
|
let relative = localPath.url.relativePath(to: srcURL)
|
||||||
|
|
||||||
|
let url = baseURL.appendingPathComponent(relative)
|
||||||
|
|
||||||
|
Link(destination: url) {
|
||||||
|
ViewThatFits {
|
||||||
|
Label("Show Example on GitHub", systemImage: "terminal")
|
||||||
|
Label("Show on GitHub", systemImage: "terminal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension URL {
|
||||||
|
func relativePath(to base: URL) -> String {
|
||||||
|
let pathComponents = self.pathComponents
|
||||||
|
let baseComponents = base.pathComponents
|
||||||
|
|
||||||
|
guard pathComponents.starts(with: baseComponents) else {
|
||||||
|
fatalError("\(self) is not contained inside \(base).")
|
||||||
|
}
|
||||||
|
|
||||||
|
return pathComponents
|
||||||
|
.dropFirst(baseComponents.count)
|
||||||
|
.joined(separator: "/")
|
||||||
|
}
|
||||||
|
}
|
||||||
94
Example/Pow Example/PlaceholderView.swift
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct PlaceholderView: View {
|
||||||
|
var hiddenContent: Bool
|
||||||
|
|
||||||
|
init(hiddenContent: Bool = false) {
|
||||||
|
self.hiddenContent = hiddenContent
|
||||||
|
}
|
||||||
|
|
||||||
|
var gridLines: some View {
|
||||||
|
ZStack {
|
||||||
|
Circle()
|
||||||
|
.stroke(lineWidth: 1)
|
||||||
|
.padding()
|
||||||
|
Circle()
|
||||||
|
.stroke(lineWidth: 1)
|
||||||
|
.padding()
|
||||||
|
.padding()
|
||||||
|
.padding()
|
||||||
|
.padding()
|
||||||
|
HStack {
|
||||||
|
ForEach(0..<5) { _ in
|
||||||
|
Spacer()
|
||||||
|
Rectangle().frame(width: 1)
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
VStack {
|
||||||
|
Spacer()
|
||||||
|
Rectangle().frame(height: 1)
|
||||||
|
Spacer()
|
||||||
|
Rectangle().frame(height: 1)
|
||||||
|
Spacer()
|
||||||
|
Rectangle().frame(height: 1)
|
||||||
|
Spacer()
|
||||||
|
Rectangle().frame(height: 1)
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.overlay {
|
||||||
|
Rectangle().frame(width: 1, height: 500)
|
||||||
|
.rotationEffect(.degrees(45))
|
||||||
|
Rectangle().frame(width: 1, height: 500)
|
||||||
|
.rotationEffect(.degrees(-45))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var fillColors: [Color] {
|
||||||
|
if !hiddenContent {
|
||||||
|
return [
|
||||||
|
Color(.displayP3, red: 0.32, green: 0.61, blue: 0.97),
|
||||||
|
Color(.displayP3, red: 0.20, green: 0.47, blue: 0.96)
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
return [
|
||||||
|
Color(.displayP3, white: 0.25),
|
||||||
|
Color(.displayP3, white: 0.3)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
var fill: some View {
|
||||||
|
RoundedRectangle(cornerRadius: 32, style: .continuous)
|
||||||
|
.fill(LinearGradient(colors: fillColors, startPoint: .top, endPoint: .bottom))
|
||||||
|
.overlay {
|
||||||
|
RoundedRectangle(cornerRadius: 32, style: .continuous)
|
||||||
|
.strokeBorder(.black.opacity(0.3), lineWidth: 4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
fill
|
||||||
|
.overlay {
|
||||||
|
gridLines
|
||||||
|
.opacity(0.25)
|
||||||
|
.scaledToFill()
|
||||||
|
}
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.font(
|
||||||
|
Font
|
||||||
|
.system(.largeTitle)
|
||||||
|
.bold()
|
||||||
|
.leading(.tight)
|
||||||
|
)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.environment(\.dynamicTypeSize, .xxLarge)
|
||||||
|
.aspectRatio(1, contentMode: .fit)
|
||||||
|
.clipShape(RoundedRectangle(cornerRadius: 32, style: .continuous))
|
||||||
|
.compositingGroup()
|
||||||
|
.frame(maxWidth: 250, maxHeight: 250)
|
||||||
|
}
|
||||||
|
}
|
||||||
40
Example/Pow Example/PowExampleApp.swift
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
@main
|
||||||
|
struct PowExampleApp: App {
|
||||||
|
struct Presentation: Identifiable {
|
||||||
|
var type: any Example.Type
|
||||||
|
|
||||||
|
var id: UUID = UUID()
|
||||||
|
}
|
||||||
|
|
||||||
|
@State
|
||||||
|
var presentedType: Presentation? = nil
|
||||||
|
|
||||||
|
var body: some Scene {
|
||||||
|
WindowGroup {
|
||||||
|
NavigationStack {
|
||||||
|
ExampleList()
|
||||||
|
}
|
||||||
|
.environment(\.presentInfoAction, PresentInfoAction {
|
||||||
|
presentedType = Presentation(type: $0)
|
||||||
|
})
|
||||||
|
.sheet(item: $presentedType) { t in
|
||||||
|
ScrollView {
|
||||||
|
VStack(alignment: .leading, spacing: 12) {
|
||||||
|
Text(t.type.title).font(.title.bold())
|
||||||
|
|
||||||
|
GithubButton(t.type.localPath)
|
||||||
|
.controlSize(.small)
|
||||||
|
.buttonStyle(.bordered)
|
||||||
|
|
||||||
|
t.type.erasedDescription
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
.presentationDetents([.medium])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||