Full Code of rakaramos/StarButton for AI

master 644bac546603 cached
16 files
52.3 KB
15.6k tokens
1 requests
Download .txt
Repository: rakaramos/StarButton
Branch: master
Commit: 644bac546603
Files: 16
Total size: 52.3 KB

Directory structure:
gitextract_8i_7yswl/

├── .gitignore
├── LICENSE
├── README.md
├── StarBounce/
│   ├── AppDelegate.swift
│   ├── Base.lproj/
│   │   ├── LaunchScreen.xib
│   │   └── Main.storyboard
│   ├── Extensions.swift
│   ├── Images.xcassets/
│   │   └── AppIcon.appiconset/
│   │       └── Contents.json
│   ├── Info.plist
│   ├── Paths.swift
│   ├── StarButton.swift
│   └── ViewController.swift
├── StarBounce.xcodeproj/
│   ├── project.pbxproj
│   └── project.xcworkspace/
│       └── contents.xcworkspacedata
└── StarBounceTests/
    ├── Info.plist
    └── StarBounceTests.swift

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
#
# Pods/
.DS_Store

================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2015 Rafael Machado

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.



================================================
FILE: README.md
================================================
# Star Button
## Article
[Creating Custom Animated Buttons](https://swift.unicorn.tv/articles/creating-custom-animated-buttons)

## Demo
Source of inspiration
![alt tag](https://d13yacurqjgara.cloudfront.net/users/100791/screenshots/1555501/driblle_star.gif)

## Code result
![alt tag](http://ramosmachado.net/wp-content/uploads/2015/02/starbounce.gif)

## A Swift bounce animation :)
![alt tag](http://ramosmachado.net/wp-content/uploads/2015/02/swift.gif)


## License
Released under the MIT license. See the LICENSE file for more info.


================================================
FILE: StarBounce/AppDelegate.swift
================================================
//
//  AppDelegate.swift
//  StarBounce
//
//  Created by Rafael Machado on 2/10/15.
//  Copyright (c) 2015 Rafael Machado. All rights reserved.
//

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        return true
    }
}


================================================
FILE: StarBounce/Base.lproj/LaunchScreen.xib
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6214" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6207"/>
        <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <view contentMode="scaleToFill" id="iN0-l3-epB">
            <rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
            <subviews>
                <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="  Copyright (c) 2015 Rafael Machado. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
                    <rect key="frame" x="20" y="439" width="441" height="21"/>
                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
                    <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
                    <nil key="highlightedColor"/>
                </label>
                <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="StarBounce" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
                    <rect key="frame" x="20" y="140" width="441" height="43"/>
                    <fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
                    <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
                    <nil key="highlightedColor"/>
                </label>
            </subviews>
            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
            <constraints>
                <constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
                <constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
                <constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
                <constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
                <constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
                <constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
            </constraints>
            <nil key="simulatedStatusBarMetrics"/>
            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
            <point key="canvasLocation" x="548" y="455"/>
        </view>
    </objects>
</document>


================================================
FILE: StarBounce/Base.lproj/Main.storyboard
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6254" systemVersion="14C109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
    </dependencies>
    <scenes>
        <!--View Controller-->
        <scene sceneID="tne-QT-ifu">
            <objects>
                <viewController id="BYZ-38-t0r" customClass="ViewController" customModule="StarBounce" customModuleProvider="target" sceneMemberID="viewController">
                    <layoutGuides>
                        <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
                        <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
                    </layoutGuides>
                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                        <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Ois-ef-f1f" customClass="StarButton" customModule="StarBounce" customModuleProvider="target">
                                <rect key="frame" x="250" y="250" width="100" height="100"/>
                                <constraints>
                                    <constraint firstAttribute="height" constant="100" id="CoI-Xk-aOa"/>
                                    <constraint firstAttribute="width" constant="100" id="apZ-gS-R0k"/>
                                </constraints>
                                <state key="normal">
                                    <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
                                </state>
                                <userDefinedRuntimeAttributes>
                                    <userDefinedRuntimeAttribute type="number" keyPath="lineWidth">
                                        <real key="value" value="3"/>
                                    </userDefinedRuntimeAttribute>
                                    <userDefinedRuntimeAttribute type="color" keyPath="favoriteColor">
                                        <color key="value" red="0.94509803920000002" green="0.76862745099999996" blue="0.058823529409999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                    </userDefinedRuntimeAttribute>
                                    <userDefinedRuntimeAttribute type="color" keyPath="notFavoriteColor">
                                        <color key="value" red="0.58431372550000005" green="0.64705882349999999" blue="0.65098039220000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                    </userDefinedRuntimeAttribute>
                                    <userDefinedRuntimeAttribute type="color" keyPath="starFavoriteColor">
                                        <color key="value" white="1" alpha="1" colorSpace="calibratedWhite"/>
                                    </userDefinedRuntimeAttribute>
                                </userDefinedRuntimeAttributes>
                                <connections>
                                    <action selector="favorite:" destination="BYZ-38-t0r" eventType="touchUpInside" id="fct-j6-UcT"/>
                                </connections>
                            </button>
                        </subviews>
                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
                        <constraints>
                            <constraint firstAttribute="centerY" secondItem="Ois-ef-f1f" secondAttribute="centerY" id="LT6-y1-wrH"/>
                            <constraint firstAttribute="centerX" secondItem="Ois-ef-f1f" secondAttribute="centerX" id="bAT-8T-uJt"/>
                        </constraints>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
            </objects>
        </scene>
    </scenes>
</document>


================================================
FILE: StarBounce/Extensions.swift
================================================
//
//  Extensions.swift
//  FavoriteStart
//
//  Created by Rafael Machado on 2/9/15.
//  Copyright (c) 2015 Rafael Machado. All rights reserved.
//

import UIKit

extension UIColor {
    convenience init (hex: String) {
        var cString = hex.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).uppercased()

        if cString.hasPrefix("#") {
            cString = (cString as NSString).substring(from: 1)
        }

        if cString.characters.count != 6 {
            self.init()
            return
        }

        let rString = (cString as NSString).substring(to: 2)
        let gString = ((cString as NSString).substring(from: 2) as NSString).substring(to: 2)
        let bString = ((cString as NSString).substring(from: 4) as NSString).substring(to: 2)

        var r: CUnsignedInt = 0, g: CUnsignedInt = 0, b: CUnsignedInt = 0
        Scanner(string: rString).scanHexInt32(&r)
        Scanner(string: gString).scanHexInt32(&g)
        Scanner(string: bString).scanHexInt32(&b)

        self.init(red: CGFloat(r) / 255.0, green: CGFloat(g) / 255.0, blue: CGFloat(b) / 255.0, alpha: CGFloat(1))
    }
}

extension CALayer {
    func applyAnimation(_ animation: CABasicAnimation) {
        guard let copy = animation.copy() as? CABasicAnimation,
        let presentationLayer = self.presentation(),
        let keyPath = copy.keyPath else {
                return
        }

        if copy.fromValue == nil {
            copy.fromValue = presentationLayer.value(forKeyPath: keyPath)
        }
        self.add(copy, forKey: copy.keyPath)
        CATransaction.begin()
        CATransaction.setDisableActions(true)
        self.setValue(copy.toValue, forKeyPath:keyPath)
        CATransaction.commit()
    }
}

extension CGPath {
    class func rescaleForFrame(path: CGPath, frame: CGRect) -> CGPath {
        let boundingBox = path.boundingBoxOfPath
        let boundingBoxAspectRatio = boundingBox.width/boundingBox.height
        let viewAspectRatio = frame.width/frame.height

        var scaleFactor: CGFloat = 1
        if boundingBoxAspectRatio > viewAspectRatio {
            scaleFactor = frame.width/boundingBox.width
        } else {
            scaleFactor = frame.height/boundingBox.height
        }

        var scaleTransform = CGAffineTransform.identity
        scaleTransform = scaleTransform.scaledBy(x: scaleFactor, y: scaleFactor)
        scaleTransform = scaleTransform.translatedBy(x: -boundingBox.minX, y: -boundingBox.minY)
        let scaledSize = boundingBox.size.applying(CGAffineTransform(scaleX: scaleFactor, y: scaleFactor))
        let centerOffset = CGSize(width: (frame.width - scaledSize.width) / (scaleFactor * 2.0),
                                  height: (frame.height - scaledSize.height) / (scaleFactor * 2.0))
        scaleTransform = scaleTransform.translatedBy(x: centerOffset.width, y: centerOffset.height)

        if let scaleTransform = path.copy(using: &scaleTransform) {
            return scaleTransform
        } else {
            return path
        }
    }
}


================================================
FILE: StarBounce/Images.xcassets/AppIcon.appiconset/Contents.json
================================================
{
  "images" : [
    {
      "idiom" : "iphone",
      "size" : "29x29",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "29x29",
      "scale" : "3x"
    },
    {
      "idiom" : "iphone",
      "size" : "40x40",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "40x40",
      "scale" : "3x"
    },
    {
      "idiom" : "iphone",
      "size" : "60x60",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "60x60",
      "scale" : "3x"
    },
    {
      "idiom" : "ipad",
      "size" : "29x29",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "29x29",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "40x40",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "40x40",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "76x76",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "76x76",
      "scale" : "2x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: StarBounce/Info.plist
================================================
<?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>CFBundleDevelopmentRegion</key>
	<string>en</string>
	<key>CFBundleExecutable</key>
	<string>$(EXECUTABLE_NAME)</string>
	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>$(PRODUCT_NAME)</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
	<key>CFBundleSignature</key>
	<string>????</string>
	<key>CFBundleVersion</key>
	<string>1</string>
	<key>LSRequiresIPhoneOS</key>
	<true/>
	<key>UILaunchStoryboardName</key>
	<string>LaunchScreen</string>
	<key>UIMainStoryboardFile</key>
	<string>Main</string>
	<key>UIRequiredDeviceCapabilities</key>
	<array>
		<string>armv7</string>
	</array>
	<key>UISupportedInterfaceOrientations</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
	<key>UISupportedInterfaceOrientations~ipad</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationPortraitUpsideDown</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
</dict>
</plist>


================================================
FILE: StarBounce/Paths.swift
================================================
//
//  Paths.swift
//  FavoriteStart
//
//  Created by Rafael Machado on 2/9/15.
//  Copyright (c) 2015 Rafael Machado. All rights reserved.
//

import UIKit

struct Paths {

    static var star: CGPath {
        let star = UIBezierPath()
        star.move(to: CGPoint(x: 112.79, y: 119))
        star.addCurve(to: CGPoint(x: 107.75, y: 122.6),
                      controlPoint1: CGPoint(x: 113.41, y: 122.8),
                      controlPoint2: CGPoint(x: 111.14, y: 124.42))
        star.addLine(to: CGPoint(x: 96.53, y: 116.58))
        star.addCurve(to: CGPoint(x: 84.14, y: 116.47),
                      controlPoint1: CGPoint(x: 93.14, y: 114.76),
                      controlPoint2: CGPoint(x: 87.56, y: 114.71))
        star.addLine(to: CGPoint(x: 72.82, y: 122.3))
        star.addCurve(to: CGPoint(x: 67.84, y: 118.62),
                      controlPoint1: CGPoint(x: 69.4, y: 124.06),
                      controlPoint2: CGPoint(x: 67.15, y: 122.41))
        star.addLine(to: CGPoint(x: 70.1, y: 106.09))
        star.addCurve(to: CGPoint(x: 66.37, y: 94.27),
                      controlPoint1: CGPoint(x: 70.78, y: 102.3),
                      controlPoint2: CGPoint(x: 69.1, y: 96.98))
        star.addLine(to: CGPoint(x: 57.33, y: 85.31))
        star.addCurve(to: CGPoint(x: 59.29, y: 79.43),
                      controlPoint1: CGPoint(x: 54.6, y: 82.6),
                      controlPoint2: CGPoint(x: 55.48, y: 79.95))
        star.addLine(to: CGPoint(x: 71.91, y: 77.71))
        star.addCurve(to: CGPoint(x: 81.99, y: 70.51),
                      controlPoint1: CGPoint(x: 75.72, y: 77.19),
                      controlPoint2: CGPoint(x: 80.26, y: 73.95))
        star.addLine(to: CGPoint(x: 87.72, y: 59.14))
        star.addCurve(to: CGPoint(x: 93.92, y: 59.2),
                      controlPoint1: CGPoint(x: 89.46, y: 55.71),
                      controlPoint2: CGPoint(x: 92.25, y: 55.73))
        star.addLine(to: CGPoint(x: 99.46, y: 70.66))
        star.addCurve(to: CGPoint(x: 109.42, y: 78.03),
                      controlPoint1: CGPoint(x: 101.13, y: 74.13),
                      controlPoint2: CGPoint(x: 105.62, y: 77.44))
        star.addLine(to: CGPoint(x: 122, y: 79.96))
        star.addCurve(to: CGPoint(x: 123.87, y: 85.87),
                      controlPoint1: CGPoint(x: 125.81, y: 80.55),
                      controlPoint2: CGPoint(x: 126.64, y: 83.21))
        star.addLine(to: CGPoint(x: 114.67, y: 94.68))
        star.addCurve(to: CGPoint(x: 110.75, y: 106.43),
                      controlPoint1: CGPoint(x: 111.89, y: 97.34),
                      controlPoint2: CGPoint(x: 110.13, y: 102.63))
        star.addLine(to: CGPoint(x: 112.79, y: 119))
        return star.cgPath
    }

    static var swift: CGPath {
        let swiftPath = UIBezierPath()
        swiftPath.move(to: CGPoint(x: 376.2, y: 283.2))
        swiftPath.addCurve(to: CGPoint(x: 349.8, y: 238.4),
                           controlPoint1: CGPoint(x: 367.4, y: 258.4),
                           controlPoint2: CGPoint(x: 349.8, y: 238.4))
        swiftPath.addCurve(to: CGPoint(x: 236.5, y: 0),
                           controlPoint1: CGPoint(x: 349.8, y: 238.4),
                           controlPoint2: CGPoint(x: 399.7, y: 105.6))
        swiftPath.addCurve(to: CGPoint(x: 269, y: 180.8),
                           controlPoint1: CGPoint(x: 303.7, y: 101.6),
                           controlPoint2: CGPoint(x: 269, y: 180.8))
        swiftPath.addCurve(to: CGPoint(x: 181.29, y: 117.07),
                           controlPoint1: CGPoint(x: 269, y: 180.8),
                           controlPoint2: CGPoint(x: 211.4, y: 140.8))
        swiftPath.addCurve(to: CGPoint(x: 85, y: 33.6),
                           controlPoint1: CGPoint(x: 151.18, y: 93.35),
                           controlPoint2: CGPoint(x: 85, y: 33.6))
        swiftPath.addCurve(to: CGPoint(x: 145, y: 117.07),
                           controlPoint1: CGPoint(x: 85, y: 33.6),
                           controlPoint2: CGPoint(x: 128.15, y: 96.31))
        swiftPath.addCurve(to: CGPoint(x: 185.78, y: 163.66),
                           controlPoint1: CGPoint(x: 161.85, y: 137.84),
                           controlPoint2: CGPoint(x: 185.78, y: 163.66))
        swiftPath.addCurve(to: CGPoint(x: 136.36, y: 129.42),
                           controlPoint1: CGPoint(x: 185.78, y: 163.66),
                           controlPoint2: CGPoint(x: 161.07, y: 147.39))
        swiftPath.addCurve(to: CGPoint(x: 34.6, y: 50.4),
                           controlPoint1: CGPoint(x: 111.65, y: 111.46),
                           controlPoint2: CGPoint(x: 34.6, y: 50.4))
        swiftPath.addCurve(to: CGPoint(x: 133.8, y: 169.2),
                           controlPoint1: CGPoint(x: 34.6, y: 50.4),
                           controlPoint2: CGPoint(x: 82.69, y: 119.24))
        swiftPath.addCurve(to: CGPoint(x: 214.6, y: 244),
                           controlPoint1: CGPoint(x: 184.91, y: 219.16),
                           controlPoint2: CGPoint(x: 214.6, y: 244))
        swiftPath.addCurve(to: CGPoint(x: 129.8, y: 264.8),
                           controlPoint1: CGPoint(x: 214.6, y: 244),
                           controlPoint2: CGPoint(x: 196.2, y: 263.2))
        swiftPath.addCurve(to: CGPoint(x: 0, y: 221),
                           controlPoint1: CGPoint(x: 63.4, y: 266.4),
                           controlPoint2: CGPoint(x: 0, y: 221))
        swiftPath.addCurve(to: CGPoint(x: 206.6, y: 339.2),
                           controlPoint1: CGPoint(x: 0, y: 221),
                           controlPoint2: CGPoint(x: 62.5, y: 339.2))
        swiftPath.addCurve(to: CGPoint(x: 325, y: 304.8),
                           controlPoint1: CGPoint(x: 270.6, y: 339.2),
                           controlPoint2: CGPoint(x: 288.93, y: 304.8))
        swiftPath.addCurve(to: CGPoint(x: 383.3, y: 339.2),
                           controlPoint1: CGPoint(x: 361.07, y: 304.8),
                           controlPoint2: CGPoint(x: 381.7, y: 340))
        swiftPath.addCurve(to: CGPoint(x: 376.2, y: 283.2),
                           controlPoint1: CGPoint(x: 384.9, y: 338.4),
                           controlPoint2: CGPoint(x: 385, y: 308))
        return swiftPath.cgPath
    }

    static func circle(_ inFrame: CGRect) -> CGPath {
        let circle = UIBezierPath(ovalIn: inFrame)
        return circle.cgPath
    }
}


================================================
FILE: StarBounce/StarButton.swift
================================================
//
//  StatButton.swift
//  FavoriteStar
//
//  Created by Rafael Machado on 14/11/14.
//  Copyright (c) 2014 Rafael Machado. All rights reserved.
//

import UIKit
import QuartzCore

@IBDesignable
class StarButton: UIButton, CAAnimationDelegate {

    fileprivate var starShape: CAShapeLayer!
    fileprivate var outerRingShape: CAShapeLayer!
    fileprivate var fillRingShape: CAShapeLayer!

    fileprivate let starKey = "FAVANIMKEY"
    fileprivate let favoriteKey = "FAVORITE"
    fileprivate let notFavoriteKey = "NOTFAVORITE"

    @IBInspectable
    var lineWidth: CGFloat = 1 {
        didSet {
            updateLayerProperties()
        }
    }

    @IBInspectable
    var favoriteColor: UIColor = UIColor(hex:"eecd34") {
        didSet {
            updateLayerProperties()
        }
    }

    @IBInspectable
    var notFavoriteColor: UIColor = UIColor(hex:"9e9b9b") {
        didSet {
            updateLayerProperties()
        }
    }

    @IBInspectable
    var starFavoriteColor: UIColor = UIColor(hex:"9e9b9b") {
        didSet {
            updateLayerProperties()
        }
    }

    var isFavorite: Bool = false {
        didSet {
            if self.isFavorite {
                favorite()
            } else {
                notFavorite()
            }
        }
    }

    fileprivate func updateLayerProperties() {
        if fillRingShape != nil {
            fillRingShape.fillColor = favoriteColor.cgColor
        }

        if outerRingShape != nil {
            outerRingShape.lineWidth = lineWidth
            outerRingShape.strokeColor = notFavoriteColor.cgColor
        }

        if starShape != nil {
            if isFavorite {
                starShape.fillColor = starFavoriteColor.cgColor
            } else {
                starShape.fillColor = notFavoriteColor.cgColor
            }
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        createLayersIfNeeded()
        updateLayerProperties()
    }

    fileprivate func createLayersIfNeeded() {
        if fillRingShape == nil {
            fillRingShape = CAShapeLayer()
            fillRingShape.path = Paths.circle(frameWithInset())
            fillRingShape.bounds = (fillRingShape.path?.boundingBox)!
            fillRingShape.fillColor = favoriteColor.cgColor
            fillRingShape.lineWidth = lineWidth
            fillRingShape.position = CGPoint(x: fillRingShape.bounds.width/2, y: fillRingShape.bounds.height/2)
            fillRingShape.transform = CATransform3DMakeScale(0.2, 0.2, 0.2)
            fillRingShape.opacity = 0
            self.layer.addSublayer(fillRingShape)
        }
        if outerRingShape == nil {
            outerRingShape = CAShapeLayer()
            outerRingShape.path = Paths.circle(frameWithInset())
            outerRingShape.bounds = frameWithInset()
            outerRingShape.lineWidth = lineWidth
            outerRingShape.strokeColor = notFavoriteColor.cgColor
            outerRingShape.fillColor = UIColor.clear.cgColor
            outerRingShape.position = CGPoint(x: self.bounds.width/2, y: self.bounds.height/2)
            outerRingShape.transform = CATransform3DIdentity
            outerRingShape.opacity = 0.5
            self.layer.addSublayer(outerRingShape)
        }
        if starShape == nil {
            var starFrame = self.bounds
            starFrame.size.width = starFrame.width/2.5
            starFrame.size.height = starFrame.height/2.5

            starShape = CAShapeLayer()
            starShape.path = CGPath.rescaleForFrame(path: Paths.star, frame: starFrame)
            starShape.bounds = (starShape.path?.boundingBoxOfPath)!
            starShape.fillColor = notFavoriteColor.cgColor
            starShape.position = CGPoint(x: (outerRingShape.path?.boundingBox.width)!/2,
                                         y: (outerRingShape.path?.boundingBox.height)!/2)
            starShape.transform = CATransform3DIdentity
            starShape.opacity = 0.5
            self.layer.addSublayer(starShape)
        }
    }

    fileprivate func frameWithInset() -> CGRect {
        return self.bounds.insetBy(dx: lineWidth/2, dy: lineWidth/2)
    }

    fileprivate func notFavorite() {
        let starFillColor = CABasicAnimation(keyPath: "fillColor")
        starFillColor.toValue = notFavoriteColor.cgColor
        starFillColor.duration = 0.3

        let starOpacity = CABasicAnimation(keyPath: "opacity")
        starOpacity.toValue = 0.5
        starOpacity.duration = 0.3

        let starGroup = CAAnimationGroup()
        starGroup.animations = [starFillColor, starOpacity]

        starShape.add(starGroup, forKey: nil)
        starShape.fillColor = notFavoriteColor.cgColor
        starShape.opacity = 0.5

        let fillCircle = CABasicAnimation(keyPath: "opacity")
        fillCircle.toValue = 0
        fillCircle.duration = 0.3
        fillCircle.setValue(notFavoriteKey, forKey: starKey)
        fillCircle.delegate = self

        fillRingShape.add(fillCircle, forKey: nil)
        fillRingShape.opacity = 0

        let outerCircle = CABasicAnimation(keyPath: "opacity")
        outerCircle.toValue = 0.5
        outerCircle.duration = 0.3

        outerRingShape.add(outerCircle, forKey: nil)
        outerRingShape.opacity = 0.5

    }

    fileprivate func favorite() {
        var starGoUp = CATransform3DIdentity
        starGoUp = CATransform3DScale(starGoUp, 1.5, 1.5, 1.5)
        var starGoDown = CATransform3DIdentity
        starGoDown = CATransform3DScale(starGoDown, 0.01, 0.01, 0.01)

        let starKeyFrames = CAKeyframeAnimation(keyPath: "transform")
        starKeyFrames.values = [NSValue(caTransform3D:CATransform3DIdentity),
                                NSValue(caTransform3D:starGoUp),
                                NSValue(caTransform3D:starGoDown)]
        starKeyFrames.keyTimes = [0.0, 0.4, 0.6]
        starKeyFrames.duration = 0.4
        starKeyFrames.beginTime = CACurrentMediaTime() + 0.05
        starKeyFrames.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
        starKeyFrames.fillMode =  kCAFillModeBackwards
        starKeyFrames.setValue(favoriteKey, forKey: starKey)
        starKeyFrames.delegate = self

        starShape.add(starKeyFrames, forKey: favoriteKey)
        starShape.transform = starGoDown

        var grayGoUp = CATransform3DIdentity
        grayGoUp = CATransform3DScale(grayGoUp, 1.5, 1.5, 1.5)
        var grayGoDown = CATransform3DIdentity
        grayGoDown = CATransform3DScale(grayGoDown, 0.01, 0.01, 0.01)

        let outerCircleAnimation = CAKeyframeAnimation(keyPath: "transform")
        outerCircleAnimation.values = [NSValue(caTransform3D:CATransform3DIdentity),
                                       NSValue(caTransform3D:grayGoUp),
                                       NSValue(caTransform3D:grayGoDown)]
        outerCircleAnimation.keyTimes = [0.0, 0.4, 0.6]
        outerCircleAnimation.duration = 0.4
        outerCircleAnimation.beginTime = CACurrentMediaTime() + 0.01
        outerCircleAnimation.fillMode =  kCAFillModeBackwards
        outerCircleAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)

        outerRingShape.add(outerCircleAnimation, forKey: "Gray circle Animation")
        outerRingShape.transform = grayGoDown

        var favoriteFillGrow = CATransform3DIdentity
        favoriteFillGrow = CATransform3DScale(favoriteFillGrow, 1.5, 1.5, 1.5)
        let fillCircleAnimation = CAKeyframeAnimation(keyPath: "transform")
        fillCircleAnimation.values = [NSValue(caTransform3D:fillRingShape.transform),
                                      NSValue(caTransform3D:favoriteFillGrow),
                                      NSValue(caTransform3D:CATransform3DIdentity)]
        fillCircleAnimation.keyTimes = [0.0, 0.4, 0.6]
        fillCircleAnimation.duration = 0.4
        fillCircleAnimation.beginTime = CACurrentMediaTime() + 0.22
        fillCircleAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
        fillCircleAnimation.fillMode =  kCAFillModeBackwards

        let favoriteFillOpacity = CABasicAnimation(keyPath: "opacity")
        favoriteFillOpacity.toValue = 1
        favoriteFillOpacity.duration = 1
        favoriteFillOpacity.beginTime = CACurrentMediaTime()
        favoriteFillOpacity.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
        favoriteFillOpacity.fillMode =  kCAFillModeBackwards

        fillRingShape.add(favoriteFillOpacity, forKey: "Show fill circle")
        fillRingShape.add(fillCircleAnimation, forKey: "fill circle Animation")
        fillRingShape.transform = CATransform3DIdentity
    }

    func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
        if let key = anim.value(forKey: starKey) as? String {
            switch key  {
            case favoriteKey:
                endFavorite()
            case notFavoriteKey:
                prepareForFavorite()
            default:
                break
            }
        }
        enableTouch()
    }

    fileprivate func endFavorite() {

        executeWithoutActions {
            self.starShape.fillColor = self.starFavoriteColor.cgColor
            self.starShape.opacity = 1
            self.fillRingShape.opacity = 1
            self.outerRingShape.transform = CATransform3DIdentity
            self.outerRingShape.opacity = 0
        }

        var starGoUp = CATransform3DIdentity
        starGoUp = CATransform3DScale(starGoUp, 2, 2, 2)

        let starKeyFrames = CAKeyframeAnimation(keyPath: "transform")
        starKeyFrames.values = [NSValue(caTransform3D: starShape.transform),
                                NSValue(caTransform3D:starGoUp),
                                NSValue(caTransform3D:CATransform3DIdentity)]
        starKeyFrames.keyTimes = [0.0, 0.4, 0.6]
        starKeyFrames.duration = 0.2
        starKeyFrames.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)

        starShape.add(starKeyFrames, forKey: nil)
        starShape.transform = CATransform3DIdentity
    }

    fileprivate func prepareForFavorite() {
        executeWithoutActions {
            self.fillRingShape.opacity = 0
            self.fillRingShape.transform = CATransform3DMakeScale(0.2, 0.2, 0.2)
        }
    }

    fileprivate func executeWithoutActions(_ closure: () -> Void) {
        CATransaction.begin()
        CATransaction.setDisableActions(true)
        closure()
        CATransaction.commit()
    }

    func animationDidStart(_ anim: CAAnimation) {
        disableTouch()
    }

    fileprivate func disableTouch() {
        self.isUserInteractionEnabled = false
    }

    fileprivate func enableTouch() {
        self.isUserInteractionEnabled = true
    }
}


================================================
FILE: StarBounce/ViewController.swift
================================================
//
//  ViewController.swift
//  FavoriteStart
//
//  Created by Rafael Machado on 14/11/14.
//  Copyright (c) 2014 Rafael Machado. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    @IBAction func favorite(_ sender: StarButton!) {
        sender.isFavorite = !sender.isFavorite
    }
}


================================================
FILE: StarBounce.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 46;
	objects = {

/* Begin PBXBuildFile section */
		01D15DC41A8A60240046F649 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01D15DC31A8A60240046F649 /* AppDelegate.swift */; };
		01D15DC91A8A60240046F649 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 01D15DC71A8A60240046F649 /* Main.storyboard */; };
		01D15DCB1A8A60240046F649 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 01D15DCA1A8A60240046F649 /* Images.xcassets */; };
		01D15DCE1A8A60240046F649 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 01D15DCC1A8A60240046F649 /* LaunchScreen.xib */; };
		01D15DDA1A8A60240046F649 /* StarBounceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01D15DD91A8A60240046F649 /* StarBounceTests.swift */; };
		01D15DE71A8A60620046F649 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01D15DE31A8A60620046F649 /* ViewController.swift */; };
		01D15DE81A8A60620046F649 /* StarButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01D15DE41A8A60620046F649 /* StarButton.swift */; };
		01D15DE91A8A60620046F649 /* Paths.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01D15DE51A8A60620046F649 /* Paths.swift */; };
		01D15DEA1A8A60620046F649 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01D15DE61A8A60620046F649 /* Extensions.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
		01D15DD41A8A60240046F649 /* PBXContainerItemProxy */ = {
			isa = PBXContainerItemProxy;
			containerPortal = 01D15DB61A8A60240046F649 /* Project object */;
			proxyType = 1;
			remoteGlobalIDString = 01D15DBD1A8A60240046F649;
			remoteInfo = StarBounce;
		};
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
		01D15DBE1A8A60240046F649 /* StarBounce.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = StarBounce.app; sourceTree = BUILT_PRODUCTS_DIR; };
		01D15DC21A8A60240046F649 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
		01D15DC31A8A60240046F649 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
		01D15DC81A8A60240046F649 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
		01D15DCA1A8A60240046F649 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
		01D15DCD1A8A60240046F649 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
		01D15DD31A8A60240046F649 /* StarBounceTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StarBounceTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
		01D15DD81A8A60240046F649 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
		01D15DD91A8A60240046F649 /* StarBounceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StarBounceTests.swift; sourceTree = "<group>"; };
		01D15DE31A8A60620046F649 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
		01D15DE41A8A60620046F649 /* StarButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StarButton.swift; sourceTree = "<group>"; };
		01D15DE51A8A60620046F649 /* Paths.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Paths.swift; sourceTree = "<group>"; };
		01D15DE61A8A60620046F649 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
		01D15DBB1A8A60240046F649 /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		01D15DD01A8A60240046F649 /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
		01D15DB51A8A60240046F649 = {
			isa = PBXGroup;
			children = (
				01D15DC01A8A60240046F649 /* StarBounce */,
				01D15DD61A8A60240046F649 /* StarBounceTests */,
				01D15DBF1A8A60240046F649 /* Products */,
			);
			sourceTree = "<group>";
		};
		01D15DBF1A8A60240046F649 /* Products */ = {
			isa = PBXGroup;
			children = (
				01D15DBE1A8A60240046F649 /* StarBounce.app */,
				01D15DD31A8A60240046F649 /* StarBounceTests.xctest */,
			);
			name = Products;
			sourceTree = "<group>";
		};
		01D15DC01A8A60240046F649 /* StarBounce */ = {
			isa = PBXGroup;
			children = (
				01D15DC31A8A60240046F649 /* AppDelegate.swift */,
				01D15DE31A8A60620046F649 /* ViewController.swift */,
				01D15DE41A8A60620046F649 /* StarButton.swift */,
				01D15DE51A8A60620046F649 /* Paths.swift */,
				01D15DE61A8A60620046F649 /* Extensions.swift */,
				01D15DC71A8A60240046F649 /* Main.storyboard */,
				01D15DCA1A8A60240046F649 /* Images.xcassets */,
				01D15DCC1A8A60240046F649 /* LaunchScreen.xib */,
				01D15DC11A8A60240046F649 /* Supporting Files */,
			);
			path = StarBounce;
			sourceTree = "<group>";
		};
		01D15DC11A8A60240046F649 /* Supporting Files */ = {
			isa = PBXGroup;
			children = (
				01D15DC21A8A60240046F649 /* Info.plist */,
			);
			name = "Supporting Files";
			sourceTree = "<group>";
		};
		01D15DD61A8A60240046F649 /* StarBounceTests */ = {
			isa = PBXGroup;
			children = (
				01D15DD91A8A60240046F649 /* StarBounceTests.swift */,
				01D15DD71A8A60240046F649 /* Supporting Files */,
			);
			path = StarBounceTests;
			sourceTree = "<group>";
		};
		01D15DD71A8A60240046F649 /* Supporting Files */ = {
			isa = PBXGroup;
			children = (
				01D15DD81A8A60240046F649 /* Info.plist */,
			);
			name = "Supporting Files";
			sourceTree = "<group>";
		};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
		01D15DBD1A8A60240046F649 /* StarBounce */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = 01D15DDD1A8A60240046F649 /* Build configuration list for PBXNativeTarget "StarBounce" */;
			buildPhases = (
				01D15DBA1A8A60240046F649 /* Sources */,
				01D15DBB1A8A60240046F649 /* Frameworks */,
				01D15DBC1A8A60240046F649 /* Resources */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = StarBounce;
			productName = StarBounce;
			productReference = 01D15DBE1A8A60240046F649 /* StarBounce.app */;
			productType = "com.apple.product-type.application";
		};
		01D15DD21A8A60240046F649 /* StarBounceTests */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = 01D15DE01A8A60240046F649 /* Build configuration list for PBXNativeTarget "StarBounceTests" */;
			buildPhases = (
				01D15DCF1A8A60240046F649 /* Sources */,
				01D15DD01A8A60240046F649 /* Frameworks */,
				01D15DD11A8A60240046F649 /* Resources */,
			);
			buildRules = (
			);
			dependencies = (
				01D15DD51A8A60240046F649 /* PBXTargetDependency */,
			);
			name = StarBounceTests;
			productName = StarBounceTests;
			productReference = 01D15DD31A8A60240046F649 /* StarBounceTests.xctest */;
			productType = "com.apple.product-type.bundle.unit-test";
		};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
		01D15DB61A8A60240046F649 /* Project object */ = {
			isa = PBXProject;
			attributes = {
				LastSwiftMigration = 0710;
				LastSwiftUpdateCheck = 0710;
				LastUpgradeCheck = 0820;
				ORGANIZATIONNAME = "Rafael Machado";
				TargetAttributes = {
					01D15DBD1A8A60240046F649 = {
						CreatedOnToolsVersion = 6.1.1;
						LastSwiftMigration = 0820;
					};
					01D15DD21A8A60240046F649 = {
						CreatedOnToolsVersion = 6.1.1;
						LastSwiftMigration = 0820;
						TestTargetID = 01D15DBD1A8A60240046F649;
					};
				};
			};
			buildConfigurationList = 01D15DB91A8A60240046F649 /* Build configuration list for PBXProject "StarBounce" */;
			compatibilityVersion = "Xcode 3.2";
			developmentRegion = English;
			hasScannedForEncodings = 0;
			knownRegions = (
				en,
				Base,
			);
			mainGroup = 01D15DB51A8A60240046F649;
			productRefGroup = 01D15DBF1A8A60240046F649 /* Products */;
			projectDirPath = "";
			projectRoot = "";
			targets = (
				01D15DBD1A8A60240046F649 /* StarBounce */,
				01D15DD21A8A60240046F649 /* StarBounceTests */,
			);
		};
/* End PBXProject section */

/* Begin PBXResourcesBuildPhase section */
		01D15DBC1A8A60240046F649 /* Resources */ = {
			isa = PBXResourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				01D15DC91A8A60240046F649 /* Main.storyboard in Resources */,
				01D15DCE1A8A60240046F649 /* LaunchScreen.xib in Resources */,
				01D15DCB1A8A60240046F649 /* Images.xcassets in Resources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		01D15DD11A8A60240046F649 /* Resources */ = {
			isa = PBXResourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXResourcesBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
		01D15DBA1A8A60240046F649 /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				01D15DEA1A8A60620046F649 /* Extensions.swift in Sources */,
				01D15DE81A8A60620046F649 /* StarButton.swift in Sources */,
				01D15DE71A8A60620046F649 /* ViewController.swift in Sources */,
				01D15DE91A8A60620046F649 /* Paths.swift in Sources */,
				01D15DC41A8A60240046F649 /* AppDelegate.swift in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		01D15DCF1A8A60240046F649 /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				01D15DDA1A8A60240046F649 /* StarBounceTests.swift in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXSourcesBuildPhase section */

/* Begin PBXTargetDependency section */
		01D15DD51A8A60240046F649 /* PBXTargetDependency */ = {
			isa = PBXTargetDependency;
			target = 01D15DBD1A8A60240046F649 /* StarBounce */;
			targetProxy = 01D15DD41A8A60240046F649 /* PBXContainerItemProxy */;
		};
/* End PBXTargetDependency section */

/* Begin PBXVariantGroup section */
		01D15DC71A8A60240046F649 /* Main.storyboard */ = {
			isa = PBXVariantGroup;
			children = (
				01D15DC81A8A60240046F649 /* Base */,
			);
			name = Main.storyboard;
			sourceTree = "<group>";
		};
		01D15DCC1A8A60240046F649 /* LaunchScreen.xib */ = {
			isa = PBXVariantGroup;
			children = (
				01D15DCD1A8A60240046F649 /* Base */,
			);
			name = LaunchScreen.xib;
			sourceTree = "<group>";
		};
/* End PBXVariantGroup section */

/* Begin XCBuildConfiguration section */
		01D15DDB1A8A60240046F649 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
				CLANG_WARN_EMPTY_BODY = YES;
				CLANG_WARN_ENUM_CONVERSION = YES;
				CLANG_WARN_INFINITE_RECURSION = YES;
				CLANG_WARN_INT_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN_SUSPICIOUS_MOVE = YES;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
				COPY_PHASE_STRIP = NO;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				ENABLE_TESTABILITY = YES;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_OPTIMIZATION_LEVEL = 0;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"DEBUG=1",
					"$(inherited)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				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 = 8.1;
				MTL_ENABLE_DEBUG_INFO = YES;
				ONLY_ACTIVE_ARCH = YES;
				SDKROOT = iphoneos;
				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
				SWIFT_VERSION = 3.0;
				TARGETED_DEVICE_FAMILY = "1,2";
			};
			name = Debug;
		};
		01D15DDC1A8A60240046F649 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
				CLANG_WARN_EMPTY_BODY = YES;
				CLANG_WARN_ENUM_CONVERSION = YES;
				CLANG_WARN_INFINITE_RECURSION = YES;
				CLANG_WARN_INT_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN_SUSPICIOUS_MOVE = YES;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
				COPY_PHASE_STRIP = YES;
				ENABLE_NS_ASSERTIONS = NO;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				IPHONEOS_DEPLOYMENT_TARGET = 8.1;
				MTL_ENABLE_DEBUG_INFO = NO;
				SDKROOT = iphoneos;
				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
				SWIFT_VERSION = 3.0;
				TARGETED_DEVICE_FAMILY = "1,2";
				VALIDATE_PRODUCT = YES;
			};
			name = Release;
		};
		01D15DDE1A8A60240046F649 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				INFOPLIST_FILE = StarBounce/Info.plist;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
				PRODUCT_BUNDLE_IDENTIFIER = "com.machado.$(PRODUCT_NAME:rfc1034identifier)";
				PRODUCT_NAME = "$(TARGET_NAME)";
				SWIFT_VERSION = 3.0;
			};
			name = Debug;
		};
		01D15DDF1A8A60240046F649 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				INFOPLIST_FILE = StarBounce/Info.plist;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
				PRODUCT_BUNDLE_IDENTIFIER = "com.machado.$(PRODUCT_NAME:rfc1034identifier)";
				PRODUCT_NAME = "$(TARGET_NAME)";
				SWIFT_VERSION = 3.0;
			};
			name = Release;
		};
		01D15DE11A8A60240046F649 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				BUNDLE_LOADER = "$(TEST_HOST)";
				FRAMEWORK_SEARCH_PATHS = (
					"$(SDKROOT)/Developer/Library/Frameworks",
					"$(inherited)",
				);
				GCC_PREPROCESSOR_DEFINITIONS = (
					"DEBUG=1",
					"$(inherited)",
				);
				INFOPLIST_FILE = StarBounceTests/Info.plist;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
				PRODUCT_BUNDLE_IDENTIFIER = "com.machado.$(PRODUCT_NAME:rfc1034identifier)";
				PRODUCT_NAME = "$(TARGET_NAME)";
				SWIFT_VERSION = 3.0;
				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StarBounce.app/StarBounce";
			};
			name = Debug;
		};
		01D15DE21A8A60240046F649 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				BUNDLE_LOADER = "$(TEST_HOST)";
				FRAMEWORK_SEARCH_PATHS = (
					"$(SDKROOT)/Developer/Library/Frameworks",
					"$(inherited)",
				);
				INFOPLIST_FILE = StarBounceTests/Info.plist;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
				PRODUCT_BUNDLE_IDENTIFIER = "com.machado.$(PRODUCT_NAME:rfc1034identifier)";
				PRODUCT_NAME = "$(TARGET_NAME)";
				SWIFT_VERSION = 3.0;
				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StarBounce.app/StarBounce";
			};
			name = Release;
		};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
		01D15DB91A8A60240046F649 /* Build configuration list for PBXProject "StarBounce" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				01D15DDB1A8A60240046F649 /* Debug */,
				01D15DDC1A8A60240046F649 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
		01D15DDD1A8A60240046F649 /* Build configuration list for PBXNativeTarget "StarBounce" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				01D15DDE1A8A60240046F649 /* Debug */,
				01D15DDF1A8A60240046F649 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
		01D15DE01A8A60240046F649 /* Build configuration list for PBXNativeTarget "StarBounceTests" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				01D15DE11A8A60240046F649 /* Debug */,
				01D15DE21A8A60240046F649 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
/* End XCConfigurationList section */
	};
	rootObject = 01D15DB61A8A60240046F649 /* Project object */;
}


================================================
FILE: StarBounce.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
   version = "1.0">
   <FileRef
      location = "self:StarBounce.xcodeproj">
   </FileRef>
</Workspace>


================================================
FILE: StarBounceTests/Info.plist
================================================
<?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>CFBundleDevelopmentRegion</key>
	<string>en</string>
	<key>CFBundleExecutable</key>
	<string>$(EXECUTABLE_NAME)</string>
	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>$(PRODUCT_NAME)</string>
	<key>CFBundlePackageType</key>
	<string>BNDL</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
	<key>CFBundleSignature</key>
	<string>????</string>
	<key>CFBundleVersion</key>
	<string>1</string>
</dict>
</plist>


================================================
FILE: StarBounceTests/StarBounceTests.swift
================================================
//
//  StarBounceTests.swift
//  StarBounceTests
//
//  Created by Rafael Machado on 2/10/15.
//  Copyright (c) 2015 Rafael Machado. All rights reserved.
//

import UIKit
import XCTest

class StarBounceTests: XCTestCase {

    override func setUp() {
        super.setUp()
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }

    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }

    func testExample() {
        // This is an example of a functional test case.
        XCTAssert(true, "Pass")
    }

    func testPerformanceExample() {
        // This is an example of a performance test case.
        self.measure {
            // Put the code you want to measure the time of here.
        }
    }

}
Download .txt
gitextract_8i_7yswl/

├── .gitignore
├── LICENSE
├── README.md
├── StarBounce/
│   ├── AppDelegate.swift
│   ├── Base.lproj/
│   │   ├── LaunchScreen.xib
│   │   └── Main.storyboard
│   ├── Extensions.swift
│   ├── Images.xcassets/
│   │   └── AppIcon.appiconset/
│   │       └── Contents.json
│   ├── Info.plist
│   ├── Paths.swift
│   ├── StarButton.swift
│   └── ViewController.swift
├── StarBounce.xcodeproj/
│   ├── project.pbxproj
│   └── project.xcworkspace/
│       └── contents.xcworkspacedata
└── StarBounceTests/
    ├── Info.plist
    └── StarBounceTests.swift
Condensed preview — 16 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (58K chars).
[
  {
    "path": ".gitignore",
    "chars": 503,
    "preview": "# Xcode\n#\nbuild/\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev3\n!defau"
  },
  {
    "path": "LICENSE",
    "chars": 1082,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2015 Rafael Machado\n\nPermission is hereby granted, free of charge, to any person ob"
  },
  {
    "path": "README.md",
    "chars": 539,
    "preview": "# Star Button\n## Article\n[Creating Custom Animated Buttons](https://swift.unicorn.tv/articles/creating-custom-animated-b"
  },
  {
    "path": "StarBounce/AppDelegate.swift",
    "chars": 461,
    "preview": "//\n//  AppDelegate.swift\n//  StarBounce\n//\n//  Created by Rafael Machado on 2/10/15.\n//  Copyright (c) 2015 Rafael Macha"
  },
  {
    "path": "StarBounce/Base.lproj/LaunchScreen.xib",
    "chars": 3709,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" versi"
  },
  {
    "path": "StarBounce/Base.lproj/Main.storyboard",
    "chars": 4599,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
  },
  {
    "path": "StarBounce/Extensions.swift",
    "chars": 3036,
    "preview": "//\n//  Extensions.swift\n//  FavoriteStart\n//\n//  Created by Rafael Machado on 2/9/15.\n//  Copyright (c) 2015 Rafael Mach"
  },
  {
    "path": "StarBounce/Images.xcassets/AppIcon.appiconset/Contents.json",
    "chars": 1077,
    "preview": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\""
  },
  {
    "path": "StarBounce/Info.plist",
    "chars": 1495,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "StarBounce/Paths.swift",
    "chars": 6449,
    "preview": "//\n//  Paths.swift\n//  FavoriteStart\n//\n//  Created by Rafael Machado on 2/9/15.\n//  Copyright (c) 2015 Rafael Machado. "
  },
  {
    "path": "StarBounce/StarButton.swift",
    "chars": 10786,
    "preview": "//\n//  StatButton.swift\n//  FavoriteStar\n//\n//  Created by Rafael Machado on 14/11/14.\n//  Copyright (c) 2014 Rafael Mac"
  },
  {
    "path": "StarBounce/ViewController.swift",
    "chars": 320,
    "preview": "//\n//  ViewController.swift\n//  FavoriteStart\n//\n//  Created by Rafael Machado on 14/11/14.\n//  Copyright (c) 2014 Rafae"
  },
  {
    "path": "StarBounce.xcodeproj/project.pbxproj",
    "chars": 17688,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "StarBounce.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "chars": 155,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:StarBounce.xcod"
  },
  {
    "path": "StarBounceTests/Info.plist",
    "chars": 733,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "StarBounceTests/StarBounceTests.swift",
    "chars": 888,
    "preview": "//\n//  StarBounceTests.swift\n//  StarBounceTests\n//\n//  Created by Rafael Machado on 2/10/15.\n//  Copyright (c) 2015 Raf"
  }
]

About this extraction

This page contains the full source code of the rakaramos/StarButton GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 16 files (52.3 KB), approximately 15.6k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!