├── .DS_Store
├── etc
└── image1.png
├── BtnResources
├── buy.png
├── back@2x.png
├── bkbtn.png
├── bkbtn_d.png
├── buy_d.png
├── click.wav
├── back_d@2x.png
├── back_x@2x.png
├── buttons.atlasc
│ ├── buttons.1.png
│ ├── buttons.1@2x.png
│ ├── buttons.1@3x.png
│ └── buttons.plist
└── Buttons.swift
├── SgButtonDemoIOS
├── .DS_Store
├── SgButtonDemoIOS.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcuserdata
│ │ │ ├── TonyPham.xcuserdatad
│ │ │ │ └── UserInterfaceState.xcuserstate
│ │ │ └── nguyenpham.xcuserdatad
│ │ │ │ └── UserInterfaceState.xcuserstate
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── xcuserdata
│ │ ├── TonyPham.xcuserdatad
│ │ │ └── xcschemes
│ │ │ │ ├── xcschememanagement.plist
│ │ │ │ └── SgButtonDemoIOS.xcscheme
│ │ └── nguyenpham.xcuserdatad
│ │ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ └── SgButtonDemoIOS.xcscheme
│ └── project.pbxproj
├── SgButtonDemoIOSTests
│ ├── Info.plist
│ └── SgButtonDemoIOSTests.swift
└── SgButtonDemoIOS
│ ├── GameViewController.swift
│ ├── Info.plist
│ ├── Base.lproj
│ ├── Main.storyboard
│ └── LaunchScreen.xib
│ ├── AppDelegate.swift
│ └── GameScene.swift
├── SgButtonDemo
├── SgButtonDemo
│ ├── Actions.sks
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── GameViewController.swift
│ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ ├── AppDelegate.swift
│ └── GameScene.swift
└── SgButtonDemo.xcodeproj
│ ├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ └── nguyenpham.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ ├── xcuserdata
│ └── nguyenpham.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
│ └── project.pbxproj
├── sgbutton.podspec
├── LICENSE
├── README.md
└── SgButton
└── SgButton.swift
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/.DS_Store
--------------------------------------------------------------------------------
/etc/image1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/etc/image1.png
--------------------------------------------------------------------------------
/BtnResources/buy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/BtnResources/buy.png
--------------------------------------------------------------------------------
/BtnResources/back@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/BtnResources/back@2x.png
--------------------------------------------------------------------------------
/BtnResources/bkbtn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/BtnResources/bkbtn.png
--------------------------------------------------------------------------------
/BtnResources/bkbtn_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/BtnResources/bkbtn_d.png
--------------------------------------------------------------------------------
/BtnResources/buy_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/BtnResources/buy_d.png
--------------------------------------------------------------------------------
/BtnResources/click.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/BtnResources/click.wav
--------------------------------------------------------------------------------
/BtnResources/back_d@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/BtnResources/back_d@2x.png
--------------------------------------------------------------------------------
/BtnResources/back_x@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/BtnResources/back_x@2x.png
--------------------------------------------------------------------------------
/SgButtonDemoIOS/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/SgButtonDemoIOS/.DS_Store
--------------------------------------------------------------------------------
/SgButtonDemo/SgButtonDemo/Actions.sks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/SgButtonDemo/SgButtonDemo/Actions.sks
--------------------------------------------------------------------------------
/BtnResources/buttons.atlasc/buttons.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/BtnResources/buttons.atlasc/buttons.1.png
--------------------------------------------------------------------------------
/BtnResources/buttons.atlasc/buttons.1@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/BtnResources/buttons.atlasc/buttons.1@2x.png
--------------------------------------------------------------------------------
/BtnResources/buttons.atlasc/buttons.1@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/BtnResources/buttons.atlasc/buttons.1@3x.png
--------------------------------------------------------------------------------
/SgButtonDemo/SgButtonDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/SgButtonDemo/SgButtonDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SgButtonDemo/SgButtonDemo/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/SgButtonDemoIOS/SgButtonDemoIOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SgButtonDemo/SgButtonDemo.xcodeproj/project.xcworkspace/xcuserdata/nguyenpham.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/SgButtonDemo/SgButtonDemo.xcodeproj/project.xcworkspace/xcuserdata/nguyenpham.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/SgButtonDemoIOS/SgButtonDemoIOS.xcodeproj/project.xcworkspace/xcuserdata/TonyPham.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/SgButtonDemoIOS/SgButtonDemoIOS.xcodeproj/project.xcworkspace/xcuserdata/TonyPham.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/SgButtonDemoIOS/SgButtonDemoIOS.xcodeproj/project.xcworkspace/xcuserdata/nguyenpham.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nguyenpham/sgbutton/HEAD/SgButtonDemoIOS/SgButtonDemoIOS.xcodeproj/project.xcworkspace/xcuserdata/nguyenpham.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/SgButtonDemo/SgButtonDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/SgButtonDemo/SgButtonDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SgButtonDemoIOS/SgButtonDemoIOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SgButtonDemo/SgButtonDemo.xcodeproj/xcuserdata/nguyenpham.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SgButtonDemo.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/sgbutton.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "sgbutton"
3 | s.version = "0.0.2"
4 | s.summary = "Button library for SpriteKit in Swift"
5 | s.homepage = "https://github.com/nguyenpham/sgbutton"
6 | s.license = "MIT"
7 | s.author = { "nguyenpham" => "axchess@yahoo.com" }
8 |
9 | s.ios.deployment_target = "8.0"
10 | s.source = { :git => "https://github.com/nguyenpham/sgbutton.git", :tag => s.version }
11 |
12 | s.source_files = "SgButton/*.swift"
13 | end
14 |
--------------------------------------------------------------------------------
/SgButtonDemoIOS/SgButtonDemoIOS.xcodeproj/xcuserdata/TonyPham.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SgButtonDemoIOS.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | B153314E1A9FE49A0026FE28
16 |
17 | primary
18 |
19 |
20 | B15331671A9FE49A0026FE28
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/SgButtonDemoIOS/SgButtonDemoIOS.xcodeproj/xcuserdata/nguyenpham.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SgButtonDemoIOS.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | B153314E1A9FE49A0026FE28
16 |
17 | primary
18 |
19 |
20 | B15331671A9FE49A0026FE28
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/SgButtonDemoIOS/SgButtonDemoIOSTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/SgButtonDemoIOS/SgButtonDemoIOSTests/SgButtonDemoIOSTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SgButtonDemoIOSTests.swift
3 | // SgButtonDemoIOSTests
4 | //
5 | // Created by Nguyen Pham on 27/02/2015.
6 | // Copyright (c) 2015 Softgaroo. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import XCTest
11 |
12 | class SgButtonDemoIOSTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | XCTAssert(true, "Pass")
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measureBlock() {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/SgButtonDemo/SgButtonDemo/GameViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GameViewController.swift
3 | // SgButtonDemo
4 | //
5 | // Created by Nguyen Pham on 22/3/2023.
6 | //
7 |
8 | import UIKit
9 | import SpriteKit
10 | import GameplayKit
11 |
12 | class GameViewController: UIViewController {
13 |
14 | override func viewDidLoad() {
15 | super.viewDidLoad()
16 |
17 | if let view = self.view as! SKView? {
18 | let scene = GameScene(size: view.bounds.size)
19 |
20 | // Set the scale mode to scale to fit the window
21 | scene.scaleMode = .aspectFill
22 |
23 | // Present the scene
24 | view.presentScene(scene)
25 |
26 | view.ignoresSiblingOrder = true
27 |
28 | view.showsFPS = true
29 | view.showsNodeCount = true
30 | }
31 | }
32 |
33 | override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
34 | if UIDevice.current.userInterfaceIdiom == .phone {
35 | return .allButUpsideDown
36 | } else {
37 | return .all
38 | }
39 | }
40 |
41 | override var prefersStatusBarHidden: Bool {
42 | return true
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/BtnResources/Buttons.swift:
--------------------------------------------------------------------------------
1 | // ---------------------------------------
2 | // Sprite definitions for 'buttons'
3 | // Generated with TexturePacker 3.6.0
4 | //
5 | // http://www.codeandweb.com/texturepacker
6 | // ---------------------------------------
7 |
8 | import SpriteKit
9 |
10 |
11 | class Buttons {
12 |
13 | // sprite names
14 | let BACK = "back"
15 | let BACK_D = "back_d"
16 | let BACK_X = "back_x"
17 | let BUY = "buy"
18 | let BUY_D = "buy_d"
19 | let GREENBUTTON = "greenbutton"
20 | let YELLOWBUTTON = "yellowbutton"
21 |
22 |
23 | // load texture atlas
24 | let textureAtlas = SKTextureAtlas(named: "buttons")
25 |
26 |
27 | // individual texture objects
28 | func back() -> SKTexture { return textureAtlas.textureNamed(BACK) }
29 | func back_d() -> SKTexture { return textureAtlas.textureNamed(BACK_D) }
30 | func back_x() -> SKTexture { return textureAtlas.textureNamed(BACK_X) }
31 | func buy() -> SKTexture { return textureAtlas.textureNamed(BUY) }
32 | func buy_d() -> SKTexture { return textureAtlas.textureNamed(BUY_D) }
33 | func greenbutton() -> SKTexture { return textureAtlas.textureNamed(GREENBUTTON) }
34 | func yellowbutton() -> SKTexture { return textureAtlas.textureNamed(YELLOWBUTTON) }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012, SmartFish Software Ltd.
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 | * Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | * Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | * Neither the name of the nor the
12 | names of its contributors may be used to endorse or promote products
13 | derived from this software without specific prior written permission.
14 |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 |
--------------------------------------------------------------------------------
/SgButtonDemoIOS/SgButtonDemoIOS/GameViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GameViewController.swift
3 | // SgButtonDemoIOS
4 | //
5 | // Created by Nguyen Pham on 27/02/2015.
6 | // Copyright (c) 2015 Softgaroo. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SpriteKit
11 |
12 | class GameViewController: UIViewController {
13 |
14 | override func viewDidLoad() {
15 | super.viewDidLoad()
16 |
17 | let skView = self.view as! SKView
18 | let scene = GameScene(size: skView.bounds.size)
19 |
20 | // Configure the view.
21 | skView.showsFPS = true
22 | skView.showsNodeCount = true
23 |
24 | /* Sprite Kit applies additional optimizations to improve rendering performance */
25 | skView.ignoresSiblingOrder = true
26 |
27 | /* Set the scale mode to scale to fit the window */
28 | scene.scaleMode = .AspectFill
29 |
30 | skView.presentScene(scene)
31 |
32 | }
33 |
34 | override func shouldAutorotate() -> Bool {
35 | return true
36 | }
37 |
38 | override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
39 | if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
40 | return UIInterfaceOrientationMask.AllButUpsideDown
41 | } else {
42 | return UIInterfaceOrientationMask.All
43 | }
44 | }
45 |
46 | override func didReceiveMemoryWarning() {
47 | super.didReceiveMemoryWarning()
48 | // Release any cached data, images, etc that aren't in use.
49 | }
50 |
51 | override func prefersStatusBarHidden() -> Bool {
52 | return true
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/SgButtonDemoIOS/SgButtonDemoIOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UIStatusBarHidden
34 |
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationLandscapeLeft
39 | UIInterfaceOrientationLandscapeRight
40 |
41 | UISupportedInterfaceOrientations~ipad
42 |
43 | UIInterfaceOrientationPortrait
44 | UIInterfaceOrientationPortraitUpsideDown
45 | UIInterfaceOrientationLandscapeLeft
46 | UIInterfaceOrientationLandscapeRight
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/SgButtonDemo/SgButtonDemo/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/SgButtonDemo/SgButtonDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/SgButtonDemoIOS/SgButtonDemoIOS/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/SgButtonDemo/SgButtonDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SgButtonDemo
4 | //
5 | // Created by Nguyen Pham on 22/3/2023.
6 | //
7 |
8 | import UIKit
9 |
10 | @main
11 | class AppDelegate: UIResponder, UIApplicationDelegate {
12 |
13 | var window: UIWindow?
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | func applicationWillResignActive(_ application: UIApplication) {
22 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
23 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
24 | }
25 |
26 | func applicationDidEnterBackground(_ application: UIApplication) {
27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
28 | }
29 |
30 | func applicationWillEnterForeground(_ application: UIApplication) {
31 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
32 | }
33 |
34 | func applicationDidBecomeActive(_ application: UIApplication) {
35 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
36 | }
37 |
38 |
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/SgButtonDemoIOS/SgButtonDemoIOS/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SgButtonDemoIOS
4 | //
5 | // Created by Nguyen Pham on 27/02/2015.
6 | // Copyright (c) 2015 Softgaroo. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | SgButton in Swift for SpriteKit
2 | ===============================
3 | Update March 2023
4 | -----------------
5 | - Support Swift 5
6 | - Support sounds, new button type
7 |
8 |
9 | Background
10 | ----------
11 |
12 | When starting working with SpriteKit, we have found that that framework has not supported buttons yet. Some current open-source is not good enough for me. Thus I have created this component to fill my needs. The code is written in Swift. We share it in hope it may be usefull to others as well as having more contributes / improvements from other programmers.
13 |
14 | Screenshots
15 | -------
16 | 
17 |
18 |
19 | Features
20 | -------
21 | * Create buttons from image files or texture (sprite sheet)
22 | * Create rectangle / round corner rectangle buttons
23 | * Create buttons with string (text)
24 | * Sound click
25 | * Work well with defferent screen (rentina)
26 | * Work well after being rotated, changed anchorPoint
27 |
28 | Installation
29 | -------
30 |
31 | ### Add files directly
32 |
33 | Copy the file SgButton.swift (in the SgButton folder) into your project.
34 |
35 |
36 | Usage
37 | -----
38 | Use image files to create buttons:
39 |
40 | var btn1 = SgButton(normalImageNamed: "back.png")
41 | var btn2 = SgButton(normalImageNamed: "back.png", highlightedImageNamed: "back_d.png", disabledImageNamed: "back_x.png", buttonFunc: tappedButton)
42 |
43 | Use textures (from spritesheet) to create buttons:
44 |
45 | var btn3 = SgButton(normalTexture: buttonSheet.buy(), highlightedTexture: buttonSheet.buy_d(), buttonFunc: tappedButton)
46 |
47 | Create text buttons (round corner button):
48 |
49 | var btn4 = SgButton(normalString: "Tap me", normalStringColor: UIColor.blue, size: CGSizeMake(200, 40), cornerRadius: 10.0, buttonFunc: tappedButton)
50 |
51 | Users can setup for highlighed and disabled state too. Just any of parametters will be fine:
52 |
53 | var btn44 = SgButton(normalString: "Tap me", normalStringColor: UIColor.blue, highlightedStringColor: UIColor.yellow, size: CGSizeMake(200, 40), cornerRadius: 10.0, buttonFunc: tappedButton)
54 |
55 | Create text buttons with image as background
56 |
57 | var btn5 = SgButton(normalTexture: buttonSheet.greenbutton(), highlightedTexture: buttonSheet.yellowbutton(), buttonFunc: tappedButton)
58 | btn5.setString(.Normal, string: "Are you sure?", fontSize: 24, stringColor: UIColor.white)
59 |
60 | License
61 | -------
62 | [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0.html)
63 | Almost total free, just fair use!
64 |
--------------------------------------------------------------------------------
/SgButtonDemoIOS/SgButtonDemoIOS/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
21 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/SgButtonDemoIOS/SgButtonDemoIOS.xcodeproj/xcuserdata/TonyPham.xcuserdatad/xcschemes/SgButtonDemoIOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
66 |
72 |
73 |
74 |
75 |
76 |
77 |
83 |
85 |
91 |
92 |
93 |
94 |
96 |
97 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/SgButtonDemoIOS/SgButtonDemoIOS.xcodeproj/xcuserdata/nguyenpham.xcuserdatad/xcschemes/SgButtonDemoIOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
94 |
100 |
101 |
102 |
103 |
105 |
106 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/SgButtonDemoIOS/SgButtonDemoIOS/GameScene.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GameScene.swift
3 | // SgButtonDemoIOS
4 | //
5 | // Created by Nguyen Pham on 27/02/2015.
6 | // Copyright (c) 2015 Softgaroo. All rights reserved.
7 | //
8 |
9 | import SpriteKit
10 |
11 | class GameScene: SKScene {
12 | var buttonSheet = Buttons()
13 | override func didMoveToView(view: SKView) {
14 | self.backgroundColor = UIColor.grayColor()
15 |
16 | let x: CGFloat = 100
17 | var y: CGFloat = self.frame.height - 80
18 |
19 | /*
20 | * Using image file
21 | */
22 | // Simplest
23 | let btn00 = SgButton(normalImageNamed: "back.png", buttonFunc: tappedButton)
24 | btn00.position = CGPointMake(x, y)
25 | btn00.tag = 0
26 | self.addChild(btn00)
27 |
28 |
29 | // 3 images for 3 states, rotate
30 | let btn01 = SgButton(normalImageNamed: "back.png", highlightedImageNamed: "back_d.png", disabledImageNamed: "back_x.png", buttonFunc: tappedButton)
31 | btn01.position = CGPointMake(x + 100, y)
32 | btn01.tag = 1
33 | btn01.zRotation = CGFloat(M_PI_2)
34 | self.addChild(btn01)
35 |
36 |
37 | // 3 images for 3 states
38 | y -= 80
39 | let btn10 = SgButton(normalImageNamed: "back.png", highlightedImageNamed: "back_d.png", disabledImageNamed: "back_x.png", buttonFunc: tappedButton)
40 | btn10.position = CGPointMake(x, y)
41 | btn10.tag = 10
42 | self.addChild(btn10)
43 |
44 | // 3 images for 3 states, start by highlighted state
45 | let btn11 = SgButton(normalImageNamed: "back.png", highlightedImageNamed: "back_d.png", disabledImageNamed: "back_x.png", buttonFunc: tappedButton)
46 | btn11.position = CGPointMake(x + 100, y)
47 | btn11.buttonState = .Highlighted
48 | btn11.tag = 11
49 | self.addChild(btn11)
50 |
51 | // 3 images for 3 states, disabled
52 | let btn12 = SgButton(normalImageNamed: "back.png", highlightedImageNamed: "back_d.png", disabledImageNamed: "back_x.png", buttonFunc: tappedButton)
53 | btn12.position = CGPointMake(x + 200, y)
54 | btn12.disabled = true
55 | btn12.tag = 13
56 | self.addChild(btn12)
57 |
58 | /*
59 | * Using texture from sprite sheet
60 | */
61 |
62 | y -= 80
63 | let btn20 = SgButton(normalTexture: buttonSheet.buy(), highlightedTexture: buttonSheet.buy_d(), buttonFunc: tappedButton)
64 | btn20.position = CGPointMake(x, y)
65 | btn20.tag = 20
66 | self.addChild(btn20)
67 |
68 | // the second texture for highlighted is bigger than the first one, but button is still same size
69 | let btn21 = SgButton(normalTexture: buttonSheet.buy(), highlightedTexture: buttonSheet.back(), buttonFunc: tappedButton)
70 | btn21.position = CGPointMake(x + 100, y)
71 | btn21.tag = 21
72 | self.addChild(btn21)
73 |
74 | // using closure as the button func, change texture randomly after tapping
75 | let btn22 = SgButton(normalTexture: buttonSheet.buy(), highlightedTexture: buttonSheet.back(), buttonFunc: { (button: SgButton) -> Void in
76 | let names: [ String ] = [ self.buttonSheet.BUY, self.buttonSheet.BUY_D, self.buttonSheet.BACK, self.buttonSheet.BACK_D, self.buttonSheet.BACK_X ]
77 | let k = Int(arc4random() % UInt32(names.count))
78 | let str = names[k]
79 | let newTex = self.buttonSheet.textureAtlas.textureNamed(str)
80 | button.setTexture(.Normal, texture: newTex)
81 | })
82 | btn22.position = CGPointMake(x + 200, y)
83 | btn22.tag = 22
84 | self.addChild(btn22)
85 |
86 | /*
87 | * Using text and background as plan color
88 | */
89 |
90 | // Simplest case. The button created with black text, white background, size is just fit to the text
91 | y -= 80
92 | let btn30 = SgButton(normalString: "Hello World!!!", buttonFunc: tappedButton)
93 | btn30.position = CGPointMake(x, y)
94 | btn30.tag = 30
95 | self.addChild(btn30)
96 |
97 | // Round corner button
98 | let btn31 = SgButton(normalString: "Tap me", normalStringColor: UIColor.blueColor(), normalFontName: "Arial", normalFontSize: 25, backgroundNormalColor: UIColor.yellowColor(), size: CGSizeMake(200, 40), cornerRadius: 10.0, buttonFunc: tappedButton)
99 | btn31.setString(.Highlighted, string: "Being tapped", stringColor: UIColor.redColor(), backgroundColor: UIColor.greenColor())
100 | btn31.position = CGPointMake(x + 200, y)
101 | btn31.tag = 31
102 | self.addChild(btn31)
103 |
104 | /*
105 | * Using text & image as background
106 | */
107 | y -= 90
108 | let btn40 = SgButton(normalImageNamed: "bkbtn.png", buttonFunc: tappedButton)
109 | btn40.setString(.Normal, string: "REGISTER", stringColor: UIColor.blueColor())
110 | btn40.setString(.Highlighted, string: "REGISTER", stringColor: UIColor.redColor())
111 | btn40.position = CGPointMake(x, y)
112 | btn40.tag = 40
113 | self.addChild(btn40)
114 |
115 | let btn41 = SgButton(normalImageNamed: "bkbtn.png", buttonFunc: tappedButton)
116 | btn41.setString(.Normal, string: "Fun", stringColor: UIColor.blueColor())
117 | btn41.setString(.Highlighted, string: "Funiest", stringColor: UIColor.redColor())
118 | btn41.position = CGPointMake(x + 200, y)
119 | btn41.zRotation = CGFloat(M_PI_4)
120 | btn41.tag = 40
121 | self.addChild(btn41)
122 |
123 |
124 | /*
125 | * Using text & texture as background
126 | * WARRNING: in the case of combining text and texture, due to the current limit of the technique (convert texture to image),
127 | * all black point of the texture will be converted into transparent. Avoid to use black details in the texture if you don not
128 | * want that effect
129 | */
130 | y -= 90
131 | let btn50 = SgButton(normalTexture: buttonSheet.greenbutton(), highlightedTexture: buttonSheet.yellowbutton(), buttonFunc: tappedButton)
132 | btn50.setString(.Normal, string: "Are you sure?", fontSize: 24, stringColor: UIColor.whiteColor())
133 | btn50.setString(.Highlighted, string: "LOL!!!", stringColor: UIColor.blueColor())
134 | btn50.position = CGPointMake(x, y)
135 | btn50.tag = 50
136 | self.addChild(btn50)
137 | }
138 |
139 | func tappedButton(button: SgButton) {
140 | print("tappedButton tappedButton tag=\(button.tag)")
141 | }
142 |
143 | }
144 |
--------------------------------------------------------------------------------
/SgButtonDemo/SgButtonDemo/GameScene.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GameScene.swift
3 | // SgButtonDemo
4 | //
5 | // Created by Nguyen Pham on 22/3/2023.
6 | //
7 |
8 | import SpriteKit
9 | import GameplayKit
10 |
11 | class GameScene: SKScene {
12 |
13 | var buttonSheet = Buttons()
14 |
15 | override func didMove(to view: SKView) {
16 | self.backgroundColor = UIColor.gray
17 |
18 | let x: CGFloat = 100
19 | var y: CGFloat = self.frame.height - 160
20 |
21 | /*
22 | * Using image file
23 | */
24 | // Simplest
25 | let btn00 = SgButton(normalImageNamed: "back.png", buttonFunc: tappedButton)
26 | btn00.position = CGPointMake(x, y)
27 | btn00.tag = 0
28 | self.addChild(btn00)
29 |
30 |
31 | // 3 images for 3 states, rotate
32 | let btn01 = SgButton(normalImageNamed: "back.png", highlightedImageNamed: "back_d.png", disabledImageNamed: "back_x.png",
33 | clickSoundName: "click", buttonFunc: tappedButton)
34 | btn01.position = CGPointMake(x + 100, y)
35 | btn01.tag = 1
36 | btn01.zRotation = CGFloat(Float.pi / 2)
37 | self.addChild(btn01)
38 |
39 |
40 | // 3 images for 3 states
41 | y -= 80
42 | let btn10 = SgButton(normalImageNamed: "back.png", highlightedImageNamed: "back_d.png", disabledImageNamed: "back_x.png", buttonFunc: tappedButton)
43 | btn10.position = CGPointMake(x, y)
44 | btn10.tag = 10
45 | self.addChild(btn10)
46 |
47 | // 3 images for 3 states, start by highlighted state
48 | let btn11 = SgButton(normalImageNamed: "back.png", highlightedImageNamed: "back_d.png", disabledImageNamed: "back_x.png", buttonFunc: tappedButton)
49 | btn11.position = CGPointMake(x + 100, y)
50 | btn11.state = .highlighted
51 | btn11.tag = 11
52 | self.addChild(btn11)
53 |
54 | // 3 images for 3 states, disabled
55 | let btn12 = SgButton(normalImageNamed: "back.png", highlightedImageNamed: "back_d.png", disabledImageNamed: "back_x.png", buttonFunc: tappedButton)
56 | btn12.position = CGPointMake(x + 200, y)
57 | btn12.disabled = true
58 | btn12.tag = 13
59 | self.addChild(btn12)
60 |
61 | /*
62 | * Using texture from sprite sheet
63 | */
64 |
65 | y -= 80
66 | let btn20 = SgButton(normalTexture: buttonSheet.buy(), highlightedTexture: buttonSheet.buy_d(), clickSoundName: "click", buttonFunc: tappedButton)
67 | btn20.position = CGPointMake(x, y)
68 | btn20.tag = 20
69 | self.addChild(btn20)
70 |
71 | // the second texture for highlighted is bigger than the first one, but button is still same size
72 | let btn21 = SgButton(normalTexture: buttonSheet.buy(), highlightedTexture: buttonSheet.back(), clickSoundName: "click", buttonFunc: tappedButton)
73 | btn21.position = CGPointMake(x + 100, y)
74 | btn21.tag = 21
75 | self.addChild(btn21)
76 |
77 | // using closure as the button func, change texture randomly after tapping
78 | let btn22 = SgButton(normalTexture: buttonSheet.buy(), highlightedTexture: buttonSheet.back(), clickSoundName: "click", buttonFunc: { (button: SgButton) -> Void in
79 | let names: [ String ] = [ self.buttonSheet.BUY, self.buttonSheet.BUY_D, self.buttonSheet.BACK, self.buttonSheet.BACK_D, self.buttonSheet.BACK_X ]
80 | let k = Int(arc4random() % UInt32(names.count))
81 | let str = names[k]
82 | let newTex = self.buttonSheet.textureAtlas.textureNamed(str)
83 | button.setTexture(state: .normal, texture: newTex)
84 | })
85 | btn22.position = CGPointMake(x + 200, y)
86 | btn22.tag = 22
87 | self.addChild(btn22)
88 |
89 | /*
90 | * Using text and background as plan color
91 | */
92 |
93 | // Simplest case. The button created with black text, white background, size is just fit to the text
94 | y -= 80
95 | let btn30 = SgButton(normalString: "Hello World!!!", clickSoundName: "click", buttonFunc: tappedButton)
96 | btn30.position = CGPointMake(x, y)
97 | btn30.tag = 30
98 | self.addChild(btn30)
99 |
100 | // Round corner button
101 | let btn31 = SgButton(normalString: "Tap me",
102 | normalStringColor: UIColor.blue,
103 | normalBackgroundColor: UIColor.yellow, fontName: "Arial", fontSize: 25,
104 | size: CGSizeMake(200, 40),
105 | cornerRadius: 10.0,
106 | buttonFunc: tappedButton)
107 |
108 | btn31.setString(state: .highlighted, string: "Being tapped", stringColor: UIColor.red, backgroundColor: UIColor.green)
109 | btn31.position = CGPointMake(x + 200, y)
110 | btn31.tag = 31
111 | self.addChild(btn31)
112 |
113 | /*
114 | * Using text & image as background
115 | */
116 | y -= 90
117 | let btn40 = SgButton(normalImageNamed: "bkbtn.png", buttonFunc: tappedButton)
118 | btn40.setString(state: .normal, string: "REGISTER", stringColor: UIColor.blue)
119 | btn40.setString(state: .highlighted, string: "REGISTER", stringColor: UIColor.red)
120 | btn40.position = CGPointMake(x, y)
121 | btn40.tag = 40
122 | self.addChild(btn40)
123 |
124 | let btn41 = SgButton(normalImageNamed: "bkbtn.png", buttonFunc: tappedButton)
125 | btn41.setString(state: .normal, string: "Fun", stringColor: UIColor.blue)
126 | btn41.setString(state: .highlighted, string: "Funiest", stringColor: UIColor.red)
127 | btn41.position = CGPointMake(x + 200, y)
128 | btn41.zRotation = CGFloat(Float.pi / 4)
129 | btn41.tag = 40
130 | self.addChild(btn41)
131 |
132 |
133 | /*
134 | * Using text & texture as background
135 | * WARRNING: in the case of combining text and texture, due to the current limit of the technique (convert texture to image),
136 | * all black point of the texture will be converted into transparent. Avoid to use black details in the texture if you don not
137 | * want that effect
138 | */
139 | y -= 90
140 | let btn50 = SgButton(normalTexture: buttonSheet.greenbutton(), highlightedTexture: buttonSheet.yellowbutton(), buttonFunc: tappedButton)
141 | btn50.setString(state: .normal, string: "Are you sure?", fontSize: 24, stringColor: UIColor.white)
142 | btn50.setString(state: .highlighted, string: "LOL!!!", stringColor: UIColor.blue)
143 | btn50.position = CGPointMake(x, y)
144 | btn50.tag = 50
145 | self.addChild(btn50)
146 | }
147 |
148 | func tappedButton(button: SgButton) {
149 | print("tappedButton tappedButton tag=\(button.tag)")
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/BtnResources/buttons.atlasc/buttons.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | codeandweb
6 |
7 | generator
8 | TexturePacker 3.6.0 - http://www.codeandweb.com/texturepacker
9 | smartupdate
10 | $TexturePacker:SmartUpdate:2867a5dd42654d7ff9c511add55c3a36:4874254ddeaf41ed3da6e3a36e3fc0a4:1e86c9befc434447f48cd1c6a2a01fb2$
11 |
12 | format
13 | APPL
14 | images
15 |
16 |
17 | path
18 | buttons.1@3x.png
19 | size
20 | {233,1732}
21 | subimages
22 |
23 |
24 | aliases
25 |
26 | isFullyOpaque
27 |
28 | name
29 | greenbutton@3x.png
30 | spriteOffset
31 | {0,8}
32 | spriteSourceSize
33 | {600,200}
34 | textureRect
35 | {{1,1},{192,591}}
36 | textureRotated
37 |
38 |
39 |
40 | aliases
41 |
42 | isFullyOpaque
43 |
44 | name
45 | yellowbutton@3x.png
46 | spriteOffset
47 | {9,0}
48 | spriteSourceSize
49 | {600,200}
50 | textureRect
51 | {{1,594},{192,591}}
52 | textureRotated
53 |
54 |
55 |
56 | aliases
57 |
58 | isFullyOpaque
59 |
60 | name
61 | back@3x.png
62 | spriteOffset
63 | {4,0}
64 | spriteSourceSize
65 | {220,125}
66 | textureRect
67 | {{1,1187},{115,212}}
68 | textureRotated
69 |
70 |
71 |
72 | aliases
73 |
74 | isFullyOpaque
75 |
76 | name
77 | buy@3x.png
78 | spriteOffset
79 | {7,1}
80 | spriteSourceSize
81 | {220,125}
82 | textureRect
83 | {{118,1187},{114,210}}
84 | textureRotated
85 |
86 |
87 |
88 | aliases
89 |
90 | isFullyOpaque
91 |
92 | name
93 | back_d@3x.png
94 | spriteOffset
95 | {4,0}
96 | spriteSourceSize
97 | {220,125}
98 | textureRect
99 | {{1,1401},{115,212}}
100 | textureRotated
101 |
102 |
103 |
104 | aliases
105 |
106 | isFullyOpaque
107 |
108 | name
109 | buy_d@3x.png
110 | spriteOffset
111 | {7,1}
112 | spriteSourceSize
113 | {220,125}
114 | textureRect
115 | {{118,1399},{114,210}}
116 | textureRotated
117 |
118 |
119 |
120 | aliases
121 |
122 | isFullyOpaque
123 |
124 | name
125 | back_x@3x.png
126 | spriteOffset
127 | {0,0}
128 | spriteSourceSize
129 | {200,120}
130 | textureRect
131 | {{1,1615},{200,116}}
132 | textureRotated
133 |
134 |
135 |
136 |
137 |
138 | path
139 | buttons.1@2x.png
140 | size
141 | {792,209}
142 | subimages
143 |
144 |
145 | aliases
146 |
147 | isFullyOpaque
148 |
149 | name
150 | greenbutton@2x.png
151 | spriteOffset
152 | {0,5}
153 | spriteSourceSize
154 | {400,133}
155 | textureRect
156 | {{1,1},{394,128}}
157 | textureRotated
158 |
159 |
160 |
161 | aliases
162 |
163 | isFullyOpaque
164 |
165 | name
166 | yellowbutton@2x.png
167 | spriteOffset
168 | {6,0}
169 | spriteSourceSize
170 | {400,133}
171 | textureRect
172 | {{397,1},{394,128}}
173 | textureRotated
174 |
175 |
176 |
177 | aliases
178 |
179 | isFullyOpaque
180 |
181 | name
182 | back@2x.png
183 | spriteOffset
184 | {2,0}
185 | spriteSourceSize
186 | {147,83}
187 | textureRect
188 | {{1,131},{143,77}}
189 | textureRotated
190 |
191 |
192 |
193 | aliases
194 |
195 | isFullyOpaque
196 |
197 | name
198 | back_d@2x.png
199 | spriteOffset
200 | {2,0}
201 | spriteSourceSize
202 | {147,83}
203 | textureRect
204 | {{146,131},{143,77}}
205 | textureRotated
206 |
207 |
208 |
209 | aliases
210 |
211 | isFullyOpaque
212 |
213 | name
214 | buy@2x.png
215 | spriteOffset
216 | {4,0}
217 | spriteSourceSize
218 | {147,83}
219 | textureRect
220 | {{291,131},{141,77}}
221 | textureRotated
222 |
223 |
224 |
225 | aliases
226 |
227 | isFullyOpaque
228 |
229 | name
230 | buy_d@2x.png
231 | spriteOffset
232 | {4,0}
233 | spriteSourceSize
234 | {147,83}
235 | textureRect
236 | {{434,131},{141,77}}
237 | textureRotated
238 |
239 |
240 |
241 | aliases
242 |
243 | isFullyOpaque
244 |
245 | name
246 | back_x@2x.png
247 | spriteOffset
248 | {0,0}
249 | spriteSourceSize
250 | {133,80}
251 | textureRect
252 | {{577,131},{133,77}}
253 | textureRotated
254 |
255 |
256 |
257 |
258 |
259 | path
260 | buttons.1.png
261 | size
262 | {398,108}
263 | subimages
264 |
265 |
266 | aliases
267 |
268 | isFullyOpaque
269 |
270 | name
271 | greenbutton.png
272 | spriteOffset
273 | {0,2}
274 | spriteSourceSize
275 | {200,67}
276 | textureRect
277 | {{1,1},{197,65}}
278 | textureRotated
279 |
280 |
281 |
282 | aliases
283 |
284 | isFullyOpaque
285 |
286 | name
287 | yellowbutton.png
288 | spriteOffset
289 | {3,0}
290 | spriteSourceSize
291 | {200,67}
292 | textureRect
293 | {{200,1},{197,65}}
294 | textureRotated
295 |
296 |
297 |
298 | aliases
299 |
300 | isFullyOpaque
301 |
302 | name
303 | back.png
304 | spriteOffset
305 | {1,0}
306 | spriteSourceSize
307 | {73,42}
308 | textureRect
309 | {{1,68},{71,39}}
310 | textureRotated
311 |
312 |
313 |
314 | aliases
315 |
316 | isFullyOpaque
317 |
318 | name
319 | back_d.png
320 | spriteOffset
321 | {1,0}
322 | spriteSourceSize
323 | {73,42}
324 | textureRect
325 | {{74,68},{71,39}}
326 | textureRotated
327 |
328 |
329 |
330 | aliases
331 |
332 | isFullyOpaque
333 |
334 | name
335 | buy.png
336 | spriteOffset
337 | {2,0}
338 | spriteSourceSize
339 | {73,42}
340 | textureRect
341 | {{147,68},{70,39}}
342 | textureRotated
343 |
344 |
345 |
346 | aliases
347 |
348 | isFullyOpaque
349 |
350 | name
351 | buy_d.png
352 | spriteOffset
353 | {2,0}
354 | spriteSourceSize
355 | {73,42}
356 | textureRect
357 | {{219,68},{70,39}}
358 | textureRotated
359 |
360 |
361 |
362 | aliases
363 |
364 | isFullyOpaque
365 |
366 | name
367 | back_x.png
368 | spriteOffset
369 | {0,0}
370 | spriteSourceSize
371 | {67,40}
372 | textureRect
373 | {{291,68},{67,39}}
374 | textureRotated
375 |
376 |
377 |
378 |
379 |
380 | version
381 | 1
382 |
383 |
384 |
--------------------------------------------------------------------------------
/SgButton/SgButton.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SgButton.swift
3 | //
4 | /*
5 | * Copyright (c) 2016 Nguyen Pham, February 10 2015, code revised on 22 March 2023
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | import SpriteKit
27 |
28 | class SgButton: SKSpriteNode {
29 | enum ButtonType {
30 | case normal, flip
31 | }
32 |
33 | enum State {
34 | case normal, highlighted, disabled
35 | }
36 |
37 | class Record {
38 | /* Input image */
39 | var imageFileName: String?
40 | var imageTexture: SKTexture?
41 |
42 | /* text */
43 | var string: String?
44 | var fontName: String?
45 | var fontSize: CGFloat?
46 | var stringColor: UIColor?
47 |
48 | /* Background color */
49 | var backgroundColor: UIColor?
50 | var cornerRadius: CGFloat?
51 |
52 | /* Size */
53 | var buttonSize: CGSize?
54 |
55 | var generatedImageTexture: SKTexture?
56 |
57 | init() {}
58 |
59 | init(imageFileName: String) {
60 | self.imageFileName = imageFileName
61 | generateTexture()
62 | }
63 |
64 | init(texture: SKTexture) {
65 | self.imageTexture = texture
66 | generateTexture()
67 | }
68 |
69 | private func getFont() -> UIFont {
70 | let fSz: CGFloat = fontSize == nil ? 18 : fontSize!
71 | var font: UIFont
72 | if fontName != nil {
73 | let f = UIFont(name: fontName!, size: fSz)
74 | assert(f != nil, "Error: Cannot create font \(String(describing: fontName)) / \(String(describing: fontSize))")
75 | font = f!
76 | } else {
77 | font = UIFont.systemFont(ofSize: fSz)
78 | }
79 | return font
80 | }
81 |
82 | func createBkImage(color: UIColor, size: CGSize, cornerRadius: CGFloat?) -> UIImage? {
83 | let rect = CGRectMake(0, 0, size.width, size.height)
84 | UIGraphicsBeginImageContextWithOptions(size, false, 0)
85 | color.setFill()
86 |
87 | if cornerRadius != nil {
88 | UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius!).addClip()
89 | }
90 |
91 | UIRectFill(rect)
92 | let image = UIGraphicsGetImageFromCurrentImageContext()
93 | UIGraphicsEndImageContext()
94 | return image
95 | }
96 |
97 | private func getImage(tex: SKTexture) -> UIImage? {
98 | let sz = tex.size()
99 |
100 | UIGraphicsBeginImageContextWithOptions(sz, false, 0.0);
101 | _ = UIGraphicsGetCurrentContext();
102 |
103 | let rect = CGRectMake(0, 0, sz.width, sz.height)
104 | let view = SKView(frame:rect)
105 | let scene = SKScene(size: sz)
106 | view.backgroundColor = UIColor.clear
107 |
108 | /*
109 | * WARNING: Limited technique. When converting a texture into image, all transparent points will be lost
110 | * My currrent solution: fill all transparent points by black ones, those black points will be converted
111 | * back into transparent later. Thus texture for background button (only in case using with string) should
112 | * not have black points to avoid that limit
113 | */
114 | scene.backgroundColor = UIColor.black // -> color will be converted into transparent
115 | let sprite = SKSpriteNode(texture: tex)
116 | sprite.position = CGPoint(x: CGRectGetMidX(view.frame), y: CGRectGetMidY(view.frame))
117 |
118 | scene.addChild(sprite)
119 | view.presentScene(scene)
120 | view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
121 |
122 | //Create the image from the context
123 | let image = UIGraphicsGetImageFromCurrentImageContext();
124 |
125 | //Close the context
126 | UIGraphicsEndImageContext();
127 |
128 | return image
129 | }
130 |
131 | /*
132 | * WARNING: to avoid blending effect, we convert all black points with value from 0 to 50 into transprent
133 | */
134 | //RGB color range to mask (make transparent) R-Low, R-High, G-Low, G-High, B-Low, B-High
135 | private let colorMasking:[CGFloat] = [0, 50, 0, 50, 0, 50]
136 |
137 | private func makeTransparent(image: UIImage?) -> UIImage? {
138 | guard
139 | let theimage = image,
140 | let img = UIImage(data: theimage.jpegData(compressionQuality: 1.0)! ),
141 | let imageRef = img.cgImage?.copy(maskingColorComponents: colorMasking) else {
142 | return nil
143 | }
144 | return UIImage(cgImage: imageRef, scale: theimage.scale, orientation: UIImage.Orientation.up)
145 | }
146 |
147 | private var textAttributes: [NSAttributedString.Key: Any]?
148 | private var stringSz: CGSize?
149 |
150 | fileprivate func generateTexture() {
151 |
152 | if string != nil {
153 | let color = stringColor == nil ? UIColor.black : stringColor!
154 | textAttributes = [
155 | .foregroundColor: color,
156 | .font: getFont()
157 | ]
158 | stringSz = string!.size(withAttributes: textAttributes)
159 | }
160 |
161 |
162 | if imageFileName != nil || (imageTexture == nil && string != nil) {
163 | var image: UIImage?
164 |
165 | if imageFileName != nil {
166 | image = UIImage(named: imageFileName!)
167 | } else {
168 | let sz: CGSize = buttonSize != nil ? buttonSize! : stringSz!
169 | let color: UIColor = backgroundColor ?? UIColor.white
170 | image = createBkImage(color: color, size: sz, cornerRadius: cornerRadius)
171 | }
172 |
173 | assert(image != nil, "Image is nil")
174 |
175 | if let str = string {
176 | generatedImageTexture = generatedStringTexture(image: image, string: str)
177 | } else {
178 | generatedImageTexture = SKTexture(image: image!)
179 | }
180 | return
181 | }
182 |
183 | if imageTexture != nil {
184 | if string == nil {
185 | generatedImageTexture = imageTexture
186 | } else {
187 | /*
188 | * Due to the limit of current technique to convert a texture into image (cannot keep transparence)
189 | * we have to convert later all back points into transparent ones. Don not use black in the background
190 | * button images if you dont want them to be transparent in case of having string
191 | */
192 | if let image = makeTransparent(image: getImage(tex: imageTexture!)) {
193 | generatedImageTexture = generatedStringTexture(image: image, string: string!)
194 | }
195 | }
196 | }
197 | }
198 |
199 | private func generatedStringTexture(image: UIImage?, string: String) -> SKTexture {
200 | var sz: CGSize
201 |
202 | if buttonSize != nil {
203 | sz = buttonSize!
204 | } else if image != nil {
205 | sz = image!.size
206 | } else {
207 | sz = stringSz!
208 | }
209 |
210 | UIGraphicsBeginImageContextWithOptions(sz, false, 0.0);
211 | guard let ctx = UIGraphicsGetCurrentContext() else { return SKTexture() };
212 |
213 | if image != nil {
214 | image!.draw(at: CGPointZero)
215 | } else {
216 | let color = backgroundColor ?? UIColor.white
217 | color.setFill()
218 | ctx.fill(CGRectMake(0, 0, sz.width, sz.height));
219 | }
220 |
221 | let rect = sz==stringSz! ? CGRectMake(0, 0, sz.width, sz.height) : CGRectMake((sz.width - stringSz!.width) * 0.5, (sz.height - stringSz!.height) * 0.5, stringSz!.width, stringSz!.height)
222 | (string as NSString).draw(in: rect, withAttributes: textAttributes)
223 |
224 | //Create the image from the context
225 | let image = UIGraphicsGetImageFromCurrentImageContext();
226 |
227 | //Close the context
228 | UIGraphicsEndImageContext();
229 |
230 | return SKTexture(image: image!)
231 | }
232 | } // class Record
233 |
234 | /*
235 | * Assign to name for convernient debug / work
236 | */
237 | let buttonName = "SgButton"
238 |
239 | /*
240 | * Convernient tag
241 | */
242 | var tag: Int = 0
243 |
244 |
245 | /*
246 | * Function to be called after being tapped
247 | */
248 | var buttonFunc: ((_ button: SgButton) -> Void)?
249 |
250 | /*
251 | * ButtonType
252 | */
253 | var buttonType = ButtonType.normal
254 |
255 | /*
256 | * Sound
257 | */
258 | var soundOn = true
259 | var clickSoundName: String? = nil
260 | var disableSoundName: String? = nil
261 |
262 |
263 | /*
264 | * Internal data, should not be accessed from outside
265 | */
266 |
267 | private var records = [ State : Record]()
268 |
269 | private var isDisabled: Bool = false
270 | private var _state = State.normal
271 | private var _size: CGSize?
272 |
273 |
274 | func playSound(clickSound: Bool) {
275 | guard soundOn,
276 | let soundName = clickSound ? clickSoundName : disableSoundName else {
277 | return
278 | }
279 |
280 | let soundAct = SKAction.playSoundFileNamed(soundName, waitForCompletion: false)
281 | self.run(soundAct)
282 | }
283 |
284 |
285 | /*
286 | * Init
287 | */
288 |
289 | // Button with images
290 | init(buttonType: ButtonType = .normal,
291 | normalImageNamed: String,
292 | highlightedImageNamed: String? = nil,
293 | disabledImageNamed: String? = nil,
294 | size: CGSize? = nil,
295 | clickSoundName: String? = nil,
296 | disableSoundName: String? = nil,
297 | buttonFunc: ((_ button: SgButton) -> Void)? = nil) {
298 |
299 | let record = Record(imageFileName: normalImageNamed)
300 | self.buttonFunc = buttonFunc
301 |
302 | super.init(texture: record.generatedImageTexture,
303 | color: UIColor.clear,
304 | size: record.generatedImageTexture!.size())
305 |
306 | records[ .normal ] = record
307 |
308 | self.buttonType = buttonType
309 | self.clickSoundName = clickSoundName
310 | self.disableSoundName = disableSoundName
311 |
312 | if highlightedImageNamed != nil {
313 | records[ .highlighted ] = Record(imageFileName: highlightedImageNamed!)
314 | }
315 |
316 | if disabledImageNamed != nil {
317 | records[ .disabled ] = Record(imageFileName: disabledImageNamed!)
318 | }
319 |
320 | completeInit()
321 | }
322 |
323 | // Button with textures
324 | init(buttonType: ButtonType = .normal,
325 | normalTexture: SKTexture,
326 | highlightedTexture: SKTexture? = nil,
327 | disabledTexture: SKTexture? = nil,
328 | clickSoundName: String? = nil,
329 | disableSoundName: String? = nil,
330 | buttonFunc: ((_ button: SgButton) -> Void)? = nil) {
331 |
332 | let record = Record(texture: normalTexture)
333 |
334 | self.buttonFunc = buttonFunc
335 |
336 | super.init(texture: record.generatedImageTexture,
337 | color: UIColor.clear,
338 | size: record.generatedImageTexture!.size())
339 |
340 | records[ .normal ] = record
341 |
342 | self.buttonType = buttonType
343 | self.clickSoundName = clickSoundName
344 | self.disableSoundName = disableSoundName
345 |
346 | if highlightedTexture != nil {
347 | records[ .highlighted ] = Record(texture: highlightedTexture!)
348 | }
349 |
350 | if disabledTexture != nil {
351 | records[ .disabled ] = Record(texture: disabledTexture!)
352 | }
353 |
354 | completeInit()
355 | }
356 |
357 | // Button with string
358 | init(buttonType: ButtonType = .normal,
359 | normalString: String,
360 | normalStringColor: UIColor = UIColor.white,
361 | normalBackgroundColor: UIColor = UIColor.blue,
362 |
363 | highlightedString: String? = nil,
364 | highlightedStringColor: UIColor? = UIColor.yellow,
365 | highlightedBackgroundColor: UIColor? = UIColor.green,
366 |
367 | disabledString: String? = nil,
368 | disabledStringColor: UIColor? = UIColor.black,
369 | disabledBackgroundColor: UIColor? = UIColor.gray,
370 |
371 | fontName: String? = nil,
372 | fontSize: CGFloat? = nil,
373 | size: CGSize? = nil,
374 | cornerRadius: CGFloat? = nil,
375 |
376 | clickSoundName: String? = nil,
377 | disableSoundName: String? = nil,
378 | buttonFunc: ((_ button: SgButton) -> Void)? = nil) {
379 |
380 | let record = Record()
381 | record.string = normalString
382 | record.stringColor = normalStringColor
383 | record.fontName = fontName
384 | record.fontSize = fontSize
385 | record.backgroundColor = normalBackgroundColor
386 | record.buttonSize = size
387 | record.cornerRadius = cornerRadius
388 | record.generateTexture()
389 |
390 | self.buttonFunc = buttonFunc
391 |
392 | super.init(texture: record.generatedImageTexture,
393 | color: UIColor.clear,
394 | size: record.generatedImageTexture!.size())
395 |
396 | records[ .normal ] = record
397 |
398 | self.buttonType = buttonType
399 | self.clickSoundName = clickSoundName
400 | self.disableSoundName = disableSoundName
401 |
402 | _size = size
403 |
404 | if highlightedString?.isEmpty == true
405 | || highlightedStringColor != nil
406 | || highlightedBackgroundColor != nil {
407 | let record = Record()
408 | record.string = highlightedString ?? normalString
409 | record.stringColor = highlightedStringColor ?? normalStringColor
410 | record.fontName = fontName
411 | record.fontSize = fontSize
412 | record.backgroundColor = highlightedBackgroundColor ?? normalStringColor
413 | record.buttonSize = size
414 | record.cornerRadius = cornerRadius
415 | record.generateTexture()
416 | records[ .highlighted ] = record
417 | }
418 |
419 | if disabledString?.isEmpty == true
420 | || disabledStringColor != nil
421 | || disabledBackgroundColor != nil {
422 | let record = Record()
423 | record.string = disabledString ?? normalString
424 | record.stringColor = disabledStringColor ?? normalStringColor
425 | record.fontName = fontName
426 | record.fontSize = fontSize
427 | record.backgroundColor = disabledBackgroundColor ?? normalStringColor
428 | record.buttonSize = size
429 | record.cornerRadius = cornerRadius
430 | record.generateTexture()
431 | records[ .disabled ] = record
432 | }
433 |
434 | completeInit()
435 | }
436 |
437 | /*
438 | * Methods
439 | */
440 | var disabled: Bool {
441 | set {
442 | isDisabled = newValue
443 | state = isDisabled ? .disabled : .normal
444 |
445 | if newValue {
446 | playSound(clickSound: false)
447 | }
448 | }
449 |
450 | get {
451 | return self.isDisabled
452 | }
453 | }
454 |
455 | var state: State {
456 | get {
457 | return self._state
458 | }
459 |
460 | set {
461 | _state = newValue
462 | if let tex = records[newValue]?.generatedImageTexture {
463 | self.texture = tex
464 | }
465 | }
466 | }
467 |
468 |
469 | func setString(state: State, string: String, fontName: String? = nil, fontSize: CGFloat? = nil, stringColor: UIColor? = nil, backgroundColor: UIColor? = nil, size: CGSize? = nil, cornerRadius: CGFloat? = nil) {
470 | var record = records[ state ]
471 | if record == nil {
472 | record = Record()
473 | records[ state ] = record
474 | }
475 | record?.string = string
476 |
477 | /*
478 | * copy data from normal state if current is nil
479 | */
480 | record!.fontName = fontName != nil ? fontName : records[ .normal ]?.fontName
481 | record!.fontSize = fontSize != nil ? fontSize : records[ .normal ]?.fontSize
482 | record!.stringColor = stringColor != nil ? stringColor : records[ .normal ]?.stringColor
483 | record!.backgroundColor = backgroundColor != nil ? backgroundColor : records[ .normal ]?.backgroundColor
484 | record!.buttonSize = size != nil ? size : records[ .normal ]?.buttonSize
485 | record!.cornerRadius = cornerRadius != nil ? cornerRadius : records[ .normal ]?.cornerRadius
486 |
487 | /*
488 | * copy background from normal state if current one is not enough info
489 | */
490 | if backgroundColor == nil && state != .normal && record!.imageFileName == nil && record!.imageTexture == nil {
491 | record!.imageFileName = records[ .normal ]?.imageFileName
492 | record!.imageTexture = records[ .normal ]?.imageTexture
493 | }
494 |
495 | record!.generateTexture()
496 |
497 | // update current texture
498 | if self.state == state {
499 | self.state = state
500 | }
501 | }
502 |
503 | func setImage(state: State, imageFileName: String) {
504 | var record = records[ state ]
505 | if record == nil {
506 | record = Record()
507 | records[ state ] = record
508 | }
509 |
510 | record!.imageFileName = imageFileName
511 |
512 | record!.generateTexture()
513 |
514 | // update current texture
515 | self.state = state
516 | }
517 |
518 | func setTexture(state: State, texture: SKTexture) {
519 | var record = records[ state ]
520 | if record == nil {
521 | record = Record()
522 | records[ state ] = record
523 | }
524 |
525 | record!.imageTexture = texture
526 |
527 | record!.generateTexture()
528 |
529 | // update current texture
530 | self.state = state
531 | }
532 |
533 | private func completeInit() {
534 | self.isUserInteractionEnabled = true
535 | self.name = buttonName
536 | }
537 |
538 | /*
539 | * Needed to stop XCode warnings
540 | */
541 | required init?(coder aDecoder: NSCoder) {
542 | fatalError("init(coder:) has not been implemented")
543 | }
544 |
545 | override func touchesBegan(_ touches: Set, with event: UIEvent?) {
546 | if !isDisabled {
547 | if buttonType == .flip {
548 | state = state == .normal ? .highlighted : .normal
549 | } else {
550 | state = .highlighted
551 | }
552 | }
553 | }
554 |
555 | override func touchesEnded(_ touches: Set, with event: UIEvent?) {
556 | if !isDisabled {
557 | if buttonType != .flip {
558 | state = .normal
559 | }
560 |
561 | if buttonFunc != nil {
562 | if let touch = touches.first {
563 | let location = touch.location(in: parent!)
564 | if self.contains(location) {
565 | playSound(clickSound: true)
566 | buttonFunc!(self)
567 | }
568 | }
569 | }
570 | }
571 | }
572 |
573 | override func touchesCancelled(_ touches: Set?, with event: UIEvent?) {
574 | if !isDisabled && buttonType != .flip {
575 | state = .normal
576 | }
577 | }
578 |
579 | }
580 |
--------------------------------------------------------------------------------
/SgButtonDemo/SgButtonDemo.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 56;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | B1D0224929CB137F00B9E20E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D0224829CB137F00B9E20E /* AppDelegate.swift */; };
11 | B1D0224D29CB137F00B9E20E /* Actions.sks in Resources */ = {isa = PBXBuildFile; fileRef = B1D0224C29CB137F00B9E20E /* Actions.sks */; };
12 | B1D0224F29CB137F00B9E20E /* GameScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D0224E29CB137F00B9E20E /* GameScene.swift */; };
13 | B1D0225129CB137F00B9E20E /* GameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D0225029CB137F00B9E20E /* GameViewController.swift */; };
14 | B1D0225429CB137F00B9E20E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B1D0225229CB137F00B9E20E /* Main.storyboard */; };
15 | B1D0225629CB138400B9E20E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B1D0225529CB138400B9E20E /* Assets.xcassets */; };
16 | B1D0225929CB138400B9E20E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B1D0225729CB138400B9E20E /* LaunchScreen.storyboard */; };
17 | B1D0227129CB13BE00B9E20E /* buy_d.png in Resources */ = {isa = PBXBuildFile; fileRef = B1D0226029CB13BC00B9E20E /* buy_d.png */; };
18 | B1D0227229CB13BE00B9E20E /* buy.png in Resources */ = {isa = PBXBuildFile; fileRef = B1D0226129CB13BC00B9E20E /* buy.png */; };
19 | B1D0227329CB13BE00B9E20E /* back@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1D0226229CB13BC00B9E20E /* back@2x.png */; };
20 | B1D0227429CB13BE00B9E20E /* bkbtn.png in Resources */ = {isa = PBXBuildFile; fileRef = B1D0226329CB13BC00B9E20E /* bkbtn.png */; };
21 | B1D0227529CB13BE00B9E20E /* Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D0226429CB13BC00B9E20E /* Buttons.swift */; };
22 | B1D0227629CB13BE00B9E20E /* back_x@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1D0226529CB13BC00B9E20E /* back_x@2x.png */; };
23 | B1D0227729CB13BE00B9E20E /* back_d@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1D0226629CB13BC00B9E20E /* back_d@2x.png */; };
24 | B1D0227829CB13BE00B9E20E /* buttons.1.png in Resources */ = {isa = PBXBuildFile; fileRef = B1D0226829CB13BC00B9E20E /* buttons.1.png */; };
25 | B1D0227929CB13BE00B9E20E /* buttons.plist in Resources */ = {isa = PBXBuildFile; fileRef = B1D0226929CB13BC00B9E20E /* buttons.plist */; };
26 | B1D0227A29CB13BE00B9E20E /* buttons.1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1D0226A29CB13BC00B9E20E /* buttons.1@2x.png */; };
27 | B1D0227B29CB13BE00B9E20E /* buttons.1@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1D0226B29CB13BC00B9E20E /* buttons.1@3x.png */; };
28 | B1D0227C29CB13BE00B9E20E /* click.wav in Resources */ = {isa = PBXBuildFile; fileRef = B1D0226C29CB13BC00B9E20E /* click.wav */; };
29 | B1D0227D29CB13BE00B9E20E /* bkbtn_d.png in Resources */ = {isa = PBXBuildFile; fileRef = B1D0226D29CB13BC00B9E20E /* bkbtn_d.png */; };
30 | B1D0227E29CB13BE00B9E20E /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = B1D0226E29CB13BD00B9E20E /* README.md */; };
31 | B1D0227F29CB13BE00B9E20E /* SgButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D0227029CB13BD00B9E20E /* SgButton.swift */; };
32 | /* End PBXBuildFile section */
33 |
34 | /* Begin PBXFileReference section */
35 | B1D0224529CB137F00B9E20E /* SgButtonDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SgButtonDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
36 | B1D0224829CB137F00B9E20E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
37 | B1D0224C29CB137F00B9E20E /* Actions.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = Actions.sks; sourceTree = ""; };
38 | B1D0224E29CB137F00B9E20E /* GameScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameScene.swift; sourceTree = ""; };
39 | B1D0225029CB137F00B9E20E /* GameViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameViewController.swift; sourceTree = ""; };
40 | B1D0225329CB137F00B9E20E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
41 | B1D0225529CB138400B9E20E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
42 | B1D0225829CB138400B9E20E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
43 | B1D0226029CB13BC00B9E20E /* buy_d.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = buy_d.png; sourceTree = ""; };
44 | B1D0226129CB13BC00B9E20E /* buy.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = buy.png; sourceTree = ""; };
45 | B1D0226229CB13BC00B9E20E /* back@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back@2x.png"; sourceTree = ""; };
46 | B1D0226329CB13BC00B9E20E /* bkbtn.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = bkbtn.png; sourceTree = ""; };
47 | B1D0226429CB13BC00B9E20E /* Buttons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Buttons.swift; sourceTree = ""; };
48 | B1D0226529CB13BC00B9E20E /* back_x@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back_x@2x.png"; sourceTree = ""; };
49 | B1D0226629CB13BC00B9E20E /* back_d@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back_d@2x.png"; sourceTree = ""; };
50 | B1D0226829CB13BC00B9E20E /* buttons.1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = buttons.1.png; sourceTree = ""; };
51 | B1D0226929CB13BC00B9E20E /* buttons.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = buttons.plist; sourceTree = ""; };
52 | B1D0226A29CB13BC00B9E20E /* buttons.1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "buttons.1@2x.png"; sourceTree = ""; };
53 | B1D0226B29CB13BC00B9E20E /* buttons.1@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "buttons.1@3x.png"; sourceTree = ""; };
54 | B1D0226C29CB13BC00B9E20E /* click.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = click.wav; sourceTree = ""; };
55 | B1D0226D29CB13BC00B9E20E /* bkbtn_d.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = bkbtn_d.png; sourceTree = ""; };
56 | B1D0226E29CB13BD00B9E20E /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../../README.md; sourceTree = ""; };
57 | B1D0227029CB13BD00B9E20E /* SgButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SgButton.swift; sourceTree = ""; };
58 | /* End PBXFileReference section */
59 |
60 | /* Begin PBXFrameworksBuildPhase section */
61 | B1D0224229CB137F00B9E20E /* Frameworks */ = {
62 | isa = PBXFrameworksBuildPhase;
63 | buildActionMask = 2147483647;
64 | files = (
65 | );
66 | runOnlyForDeploymentPostprocessing = 0;
67 | };
68 | /* End PBXFrameworksBuildPhase section */
69 |
70 | /* Begin PBXGroup section */
71 | B1D0223C29CB137E00B9E20E = {
72 | isa = PBXGroup;
73 | children = (
74 | B1D0224729CB137F00B9E20E /* SgButtonDemo */,
75 | B1D0224629CB137F00B9E20E /* Products */,
76 | );
77 | sourceTree = "";
78 | };
79 | B1D0224629CB137F00B9E20E /* Products */ = {
80 | isa = PBXGroup;
81 | children = (
82 | B1D0224529CB137F00B9E20E /* SgButtonDemo.app */,
83 | );
84 | name = Products;
85 | sourceTree = "";
86 | };
87 | B1D0224729CB137F00B9E20E /* SgButtonDemo */ = {
88 | isa = PBXGroup;
89 | children = (
90 | B1D0225F29CB13BC00B9E20E /* BtnResources */,
91 | B1D0226E29CB13BD00B9E20E /* README.md */,
92 | B1D0226F29CB13BD00B9E20E /* SgButton */,
93 | B1D0224829CB137F00B9E20E /* AppDelegate.swift */,
94 | B1D0224C29CB137F00B9E20E /* Actions.sks */,
95 | B1D0224E29CB137F00B9E20E /* GameScene.swift */,
96 | B1D0225029CB137F00B9E20E /* GameViewController.swift */,
97 | B1D0225229CB137F00B9E20E /* Main.storyboard */,
98 | B1D0225529CB138400B9E20E /* Assets.xcassets */,
99 | B1D0225729CB138400B9E20E /* LaunchScreen.storyboard */,
100 | );
101 | path = SgButtonDemo;
102 | sourceTree = "";
103 | };
104 | B1D0225F29CB13BC00B9E20E /* BtnResources */ = {
105 | isa = PBXGroup;
106 | children = (
107 | B1D0226029CB13BC00B9E20E /* buy_d.png */,
108 | B1D0226129CB13BC00B9E20E /* buy.png */,
109 | B1D0226229CB13BC00B9E20E /* back@2x.png */,
110 | B1D0226329CB13BC00B9E20E /* bkbtn.png */,
111 | B1D0226429CB13BC00B9E20E /* Buttons.swift */,
112 | B1D0226529CB13BC00B9E20E /* back_x@2x.png */,
113 | B1D0226629CB13BC00B9E20E /* back_d@2x.png */,
114 | B1D0226729CB13BC00B9E20E /* buttons.atlasc */,
115 | B1D0226C29CB13BC00B9E20E /* click.wav */,
116 | B1D0226D29CB13BC00B9E20E /* bkbtn_d.png */,
117 | );
118 | name = BtnResources;
119 | path = ../../BtnResources;
120 | sourceTree = "";
121 | };
122 | B1D0226729CB13BC00B9E20E /* buttons.atlasc */ = {
123 | isa = PBXGroup;
124 | children = (
125 | B1D0226829CB13BC00B9E20E /* buttons.1.png */,
126 | B1D0226929CB13BC00B9E20E /* buttons.plist */,
127 | B1D0226A29CB13BC00B9E20E /* buttons.1@2x.png */,
128 | B1D0226B29CB13BC00B9E20E /* buttons.1@3x.png */,
129 | );
130 | path = buttons.atlasc;
131 | sourceTree = "";
132 | };
133 | B1D0226F29CB13BD00B9E20E /* SgButton */ = {
134 | isa = PBXGroup;
135 | children = (
136 | B1D0227029CB13BD00B9E20E /* SgButton.swift */,
137 | );
138 | name = SgButton;
139 | path = ../../SgButton;
140 | sourceTree = "";
141 | };
142 | /* End PBXGroup section */
143 |
144 | /* Begin PBXNativeTarget section */
145 | B1D0224429CB137F00B9E20E /* SgButtonDemo */ = {
146 | isa = PBXNativeTarget;
147 | buildConfigurationList = B1D0225C29CB138400B9E20E /* Build configuration list for PBXNativeTarget "SgButtonDemo" */;
148 | buildPhases = (
149 | B1D0224129CB137F00B9E20E /* Sources */,
150 | B1D0224229CB137F00B9E20E /* Frameworks */,
151 | B1D0224329CB137F00B9E20E /* Resources */,
152 | );
153 | buildRules = (
154 | );
155 | dependencies = (
156 | );
157 | name = SgButtonDemo;
158 | productName = SgButtonDemo;
159 | productReference = B1D0224529CB137F00B9E20E /* SgButtonDemo.app */;
160 | productType = "com.apple.product-type.application";
161 | };
162 | /* End PBXNativeTarget section */
163 |
164 | /* Begin PBXProject section */
165 | B1D0223D29CB137E00B9E20E /* Project object */ = {
166 | isa = PBXProject;
167 | attributes = {
168 | BuildIndependentTargetsInParallel = 1;
169 | LastSwiftUpdateCheck = 1420;
170 | LastUpgradeCheck = 1420;
171 | TargetAttributes = {
172 | B1D0224429CB137F00B9E20E = {
173 | CreatedOnToolsVersion = 14.2;
174 | };
175 | };
176 | };
177 | buildConfigurationList = B1D0224029CB137E00B9E20E /* Build configuration list for PBXProject "SgButtonDemo" */;
178 | compatibilityVersion = "Xcode 14.0";
179 | developmentRegion = en;
180 | hasScannedForEncodings = 0;
181 | knownRegions = (
182 | en,
183 | Base,
184 | );
185 | mainGroup = B1D0223C29CB137E00B9E20E;
186 | productRefGroup = B1D0224629CB137F00B9E20E /* Products */;
187 | projectDirPath = "";
188 | projectRoot = "";
189 | targets = (
190 | B1D0224429CB137F00B9E20E /* SgButtonDemo */,
191 | );
192 | };
193 | /* End PBXProject section */
194 |
195 | /* Begin PBXResourcesBuildPhase section */
196 | B1D0224329CB137F00B9E20E /* Resources */ = {
197 | isa = PBXResourcesBuildPhase;
198 | buildActionMask = 2147483647;
199 | files = (
200 | B1D0225429CB137F00B9E20E /* Main.storyboard in Resources */,
201 | B1D0227A29CB13BE00B9E20E /* buttons.1@2x.png in Resources */,
202 | B1D0227729CB13BE00B9E20E /* back_d@2x.png in Resources */,
203 | B1D0227329CB13BE00B9E20E /* back@2x.png in Resources */,
204 | B1D0227B29CB13BE00B9E20E /* buttons.1@3x.png in Resources */,
205 | B1D0227429CB13BE00B9E20E /* bkbtn.png in Resources */,
206 | B1D0227E29CB13BE00B9E20E /* README.md in Resources */,
207 | B1D0227D29CB13BE00B9E20E /* bkbtn_d.png in Resources */,
208 | B1D0227229CB13BE00B9E20E /* buy.png in Resources */,
209 | B1D0225629CB138400B9E20E /* Assets.xcassets in Resources */,
210 | B1D0227629CB13BE00B9E20E /* back_x@2x.png in Resources */,
211 | B1D0225929CB138400B9E20E /* LaunchScreen.storyboard in Resources */,
212 | B1D0227C29CB13BE00B9E20E /* click.wav in Resources */,
213 | B1D0224D29CB137F00B9E20E /* Actions.sks in Resources */,
214 | B1D0227829CB13BE00B9E20E /* buttons.1.png in Resources */,
215 | B1D0227129CB13BE00B9E20E /* buy_d.png in Resources */,
216 | B1D0227929CB13BE00B9E20E /* buttons.plist in Resources */,
217 | );
218 | runOnlyForDeploymentPostprocessing = 0;
219 | };
220 | /* End PBXResourcesBuildPhase section */
221 |
222 | /* Begin PBXSourcesBuildPhase section */
223 | B1D0224129CB137F00B9E20E /* Sources */ = {
224 | isa = PBXSourcesBuildPhase;
225 | buildActionMask = 2147483647;
226 | files = (
227 | B1D0224F29CB137F00B9E20E /* GameScene.swift in Sources */,
228 | B1D0225129CB137F00B9E20E /* GameViewController.swift in Sources */,
229 | B1D0224929CB137F00B9E20E /* AppDelegate.swift in Sources */,
230 | B1D0227F29CB13BE00B9E20E /* SgButton.swift in Sources */,
231 | B1D0227529CB13BE00B9E20E /* Buttons.swift in Sources */,
232 | );
233 | runOnlyForDeploymentPostprocessing = 0;
234 | };
235 | /* End PBXSourcesBuildPhase section */
236 |
237 | /* Begin PBXVariantGroup section */
238 | B1D0225229CB137F00B9E20E /* Main.storyboard */ = {
239 | isa = PBXVariantGroup;
240 | children = (
241 | B1D0225329CB137F00B9E20E /* Base */,
242 | );
243 | name = Main.storyboard;
244 | sourceTree = "";
245 | };
246 | B1D0225729CB138400B9E20E /* LaunchScreen.storyboard */ = {
247 | isa = PBXVariantGroup;
248 | children = (
249 | B1D0225829CB138400B9E20E /* Base */,
250 | );
251 | name = LaunchScreen.storyboard;
252 | sourceTree = "";
253 | };
254 | /* End PBXVariantGroup section */
255 |
256 | /* Begin XCBuildConfiguration section */
257 | B1D0225A29CB138400B9E20E /* Debug */ = {
258 | isa = XCBuildConfiguration;
259 | buildSettings = {
260 | ALWAYS_SEARCH_USER_PATHS = NO;
261 | CLANG_ANALYZER_NONNULL = YES;
262 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
263 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
264 | CLANG_ENABLE_MODULES = YES;
265 | CLANG_ENABLE_OBJC_ARC = YES;
266 | CLANG_ENABLE_OBJC_WEAK = YES;
267 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
268 | CLANG_WARN_BOOL_CONVERSION = YES;
269 | CLANG_WARN_COMMA = YES;
270 | CLANG_WARN_CONSTANT_CONVERSION = YES;
271 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
272 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
273 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
274 | CLANG_WARN_EMPTY_BODY = YES;
275 | CLANG_WARN_ENUM_CONVERSION = YES;
276 | CLANG_WARN_INFINITE_RECURSION = YES;
277 | CLANG_WARN_INT_CONVERSION = YES;
278 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
279 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
280 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
281 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
282 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
283 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
284 | CLANG_WARN_STRICT_PROTOTYPES = YES;
285 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
286 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
287 | CLANG_WARN_UNREACHABLE_CODE = YES;
288 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
289 | COPY_PHASE_STRIP = NO;
290 | DEBUG_INFORMATION_FORMAT = dwarf;
291 | ENABLE_STRICT_OBJC_MSGSEND = YES;
292 | ENABLE_TESTABILITY = YES;
293 | GCC_C_LANGUAGE_STANDARD = gnu11;
294 | GCC_DYNAMIC_NO_PIC = NO;
295 | GCC_NO_COMMON_BLOCKS = YES;
296 | GCC_OPTIMIZATION_LEVEL = 0;
297 | GCC_PREPROCESSOR_DEFINITIONS = (
298 | "DEBUG=1",
299 | "$(inherited)",
300 | );
301 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
302 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
303 | GCC_WARN_UNDECLARED_SELECTOR = YES;
304 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
305 | GCC_WARN_UNUSED_FUNCTION = YES;
306 | GCC_WARN_UNUSED_VARIABLE = YES;
307 | IPHONEOS_DEPLOYMENT_TARGET = 16.2;
308 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
309 | MTL_FAST_MATH = YES;
310 | ONLY_ACTIVE_ARCH = YES;
311 | SDKROOT = iphoneos;
312 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
313 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
314 | };
315 | name = Debug;
316 | };
317 | B1D0225B29CB138400B9E20E /* Release */ = {
318 | isa = XCBuildConfiguration;
319 | buildSettings = {
320 | ALWAYS_SEARCH_USER_PATHS = NO;
321 | CLANG_ANALYZER_NONNULL = YES;
322 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
323 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
324 | CLANG_ENABLE_MODULES = YES;
325 | CLANG_ENABLE_OBJC_ARC = YES;
326 | CLANG_ENABLE_OBJC_WEAK = YES;
327 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
328 | CLANG_WARN_BOOL_CONVERSION = YES;
329 | CLANG_WARN_COMMA = YES;
330 | CLANG_WARN_CONSTANT_CONVERSION = YES;
331 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
332 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
333 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
334 | CLANG_WARN_EMPTY_BODY = YES;
335 | CLANG_WARN_ENUM_CONVERSION = YES;
336 | CLANG_WARN_INFINITE_RECURSION = YES;
337 | CLANG_WARN_INT_CONVERSION = YES;
338 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
339 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
340 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
341 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
342 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
343 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
344 | CLANG_WARN_STRICT_PROTOTYPES = YES;
345 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
346 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
347 | CLANG_WARN_UNREACHABLE_CODE = YES;
348 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
349 | COPY_PHASE_STRIP = NO;
350 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
351 | ENABLE_NS_ASSERTIONS = NO;
352 | ENABLE_STRICT_OBJC_MSGSEND = YES;
353 | GCC_C_LANGUAGE_STANDARD = gnu11;
354 | GCC_NO_COMMON_BLOCKS = YES;
355 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
356 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
357 | GCC_WARN_UNDECLARED_SELECTOR = YES;
358 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
359 | GCC_WARN_UNUSED_FUNCTION = YES;
360 | GCC_WARN_UNUSED_VARIABLE = YES;
361 | IPHONEOS_DEPLOYMENT_TARGET = 16.2;
362 | MTL_ENABLE_DEBUG_INFO = NO;
363 | MTL_FAST_MATH = YES;
364 | SDKROOT = iphoneos;
365 | SWIFT_COMPILATION_MODE = wholemodule;
366 | SWIFT_OPTIMIZATION_LEVEL = "-O";
367 | VALIDATE_PRODUCT = YES;
368 | };
369 | name = Release;
370 | };
371 | B1D0225D29CB138400B9E20E /* Debug */ = {
372 | isa = XCBuildConfiguration;
373 | buildSettings = {
374 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
375 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
376 | CODE_SIGN_STYLE = Automatic;
377 | CURRENT_PROJECT_VERSION = 1;
378 | DEVELOPMENT_TEAM = 3FHDXJ5CB2;
379 | GENERATE_INFOPLIST_FILE = YES;
380 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
381 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
382 | INFOPLIST_KEY_UIMainStoryboardFile = Main;
383 | INFOPLIST_KEY_UIStatusBarHidden = YES;
384 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
385 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
386 | IPHONEOS_DEPLOYMENT_TARGET = 16.0;
387 | LD_RUNPATH_SEARCH_PATHS = (
388 | "$(inherited)",
389 | "@executable_path/Frameworks",
390 | );
391 | MARKETING_VERSION = 1.0;
392 | PRODUCT_BUNDLE_IDENTIFIER = com.xqfan.SgButtonDemo;
393 | PRODUCT_NAME = "$(TARGET_NAME)";
394 | SWIFT_EMIT_LOC_STRINGS = YES;
395 | SWIFT_VERSION = 5.0;
396 | TARGETED_DEVICE_FAMILY = "1,2";
397 | };
398 | name = Debug;
399 | };
400 | B1D0225E29CB138400B9E20E /* Release */ = {
401 | isa = XCBuildConfiguration;
402 | buildSettings = {
403 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
404 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
405 | CODE_SIGN_STYLE = Automatic;
406 | CURRENT_PROJECT_VERSION = 1;
407 | DEVELOPMENT_TEAM = 3FHDXJ5CB2;
408 | GENERATE_INFOPLIST_FILE = YES;
409 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
410 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
411 | INFOPLIST_KEY_UIMainStoryboardFile = Main;
412 | INFOPLIST_KEY_UIStatusBarHidden = YES;
413 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
414 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
415 | IPHONEOS_DEPLOYMENT_TARGET = 16.0;
416 | LD_RUNPATH_SEARCH_PATHS = (
417 | "$(inherited)",
418 | "@executable_path/Frameworks",
419 | );
420 | MARKETING_VERSION = 1.0;
421 | PRODUCT_BUNDLE_IDENTIFIER = com.xqfan.SgButtonDemo;
422 | PRODUCT_NAME = "$(TARGET_NAME)";
423 | SWIFT_EMIT_LOC_STRINGS = YES;
424 | SWIFT_VERSION = 5.0;
425 | TARGETED_DEVICE_FAMILY = "1,2";
426 | };
427 | name = Release;
428 | };
429 | /* End XCBuildConfiguration section */
430 |
431 | /* Begin XCConfigurationList section */
432 | B1D0224029CB137E00B9E20E /* Build configuration list for PBXProject "SgButtonDemo" */ = {
433 | isa = XCConfigurationList;
434 | buildConfigurations = (
435 | B1D0225A29CB138400B9E20E /* Debug */,
436 | B1D0225B29CB138400B9E20E /* Release */,
437 | );
438 | defaultConfigurationIsVisible = 0;
439 | defaultConfigurationName = Release;
440 | };
441 | B1D0225C29CB138400B9E20E /* Build configuration list for PBXNativeTarget "SgButtonDemo" */ = {
442 | isa = XCConfigurationList;
443 | buildConfigurations = (
444 | B1D0225D29CB138400B9E20E /* Debug */,
445 | B1D0225E29CB138400B9E20E /* Release */,
446 | );
447 | defaultConfigurationIsVisible = 0;
448 | defaultConfigurationName = Release;
449 | };
450 | /* End XCConfigurationList section */
451 | };
452 | rootObject = B1D0223D29CB137E00B9E20E /* Project object */;
453 | }
454 |
--------------------------------------------------------------------------------
/SgButtonDemoIOS/SgButtonDemoIOS.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | B129DF6C1AA2E7AE0013334E /* back@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF5F1AA2E7AE0013334E /* back@2x.png */; };
11 | B129DF6D1AA2E7AE0013334E /* back@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF5F1AA2E7AE0013334E /* back@2x.png */; };
12 | B129DF6E1AA2E7AE0013334E /* back_d@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF601AA2E7AE0013334E /* back_d@2x.png */; };
13 | B129DF6F1AA2E7AE0013334E /* back_d@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF601AA2E7AE0013334E /* back_d@2x.png */; };
14 | B129DF701AA2E7AE0013334E /* back_x@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF611AA2E7AE0013334E /* back_x@2x.png */; };
15 | B129DF711AA2E7AE0013334E /* back_x@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF611AA2E7AE0013334E /* back_x@2x.png */; };
16 | B129DF721AA2E7AE0013334E /* bkbtn.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF621AA2E7AE0013334E /* bkbtn.png */; };
17 | B129DF731AA2E7AE0013334E /* bkbtn.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF621AA2E7AE0013334E /* bkbtn.png */; };
18 | B129DF741AA2E7AE0013334E /* bkbtn_d.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF631AA2E7AE0013334E /* bkbtn_d.png */; };
19 | B129DF751AA2E7AE0013334E /* bkbtn_d.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF631AA2E7AE0013334E /* bkbtn_d.png */; };
20 | B129DF761AA2E7AE0013334E /* buttons.1.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF651AA2E7AE0013334E /* buttons.1.png */; };
21 | B129DF771AA2E7AE0013334E /* buttons.1.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF651AA2E7AE0013334E /* buttons.1.png */; };
22 | B129DF781AA2E7AE0013334E /* buttons.1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF661AA2E7AE0013334E /* buttons.1@2x.png */; };
23 | B129DF791AA2E7AE0013334E /* buttons.1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF661AA2E7AE0013334E /* buttons.1@2x.png */; };
24 | B129DF7A1AA2E7AE0013334E /* buttons.1@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF671AA2E7AE0013334E /* buttons.1@3x.png */; };
25 | B129DF7B1AA2E7AE0013334E /* buttons.1@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF671AA2E7AE0013334E /* buttons.1@3x.png */; };
26 | B129DF7C1AA2E7AE0013334E /* buttons.plist in Resources */ = {isa = PBXBuildFile; fileRef = B129DF681AA2E7AE0013334E /* buttons.plist */; };
27 | B129DF7D1AA2E7AE0013334E /* buttons.plist in Resources */ = {isa = PBXBuildFile; fileRef = B129DF681AA2E7AE0013334E /* buttons.plist */; };
28 | B129DF7E1AA2E7AE0013334E /* Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = B129DF691AA2E7AE0013334E /* Buttons.swift */; };
29 | B129DF7F1AA2E7AE0013334E /* Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = B129DF691AA2E7AE0013334E /* Buttons.swift */; };
30 | B129DF801AA2E7AE0013334E /* buy.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF6A1AA2E7AE0013334E /* buy.png */; };
31 | B129DF811AA2E7AE0013334E /* buy.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF6A1AA2E7AE0013334E /* buy.png */; };
32 | B129DF821AA2E7AE0013334E /* buy_d.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF6B1AA2E7AE0013334E /* buy_d.png */; };
33 | B129DF831AA2E7AE0013334E /* buy_d.png in Resources */ = {isa = PBXBuildFile; fileRef = B129DF6B1AA2E7AE0013334E /* buy_d.png */; };
34 | B15331551A9FE49A0026FE28 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B15331541A9FE49A0026FE28 /* AppDelegate.swift */; };
35 | B15331591A9FE49A0026FE28 /* GameScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = B15331581A9FE49A0026FE28 /* GameScene.swift */; };
36 | B153315B1A9FE49A0026FE28 /* GameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B153315A1A9FE49A0026FE28 /* GameViewController.swift */; };
37 | B153315E1A9FE49A0026FE28 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B153315C1A9FE49A0026FE28 /* Main.storyboard */; };
38 | B15331631A9FE49A0026FE28 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = B15331611A9FE49A0026FE28 /* LaunchScreen.xib */; };
39 | B153316F1A9FE49A0026FE28 /* SgButtonDemoIOSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B153316E1A9FE49A0026FE28 /* SgButtonDemoIOSTests.swift */; };
40 | B15331A41A9FEAEA0026FE28 /* SgButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B153318B1A9FEAEA0026FE28 /* SgButton.swift */; };
41 | B15331A51A9FEAEA0026FE28 /* SgButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B153318B1A9FEAEA0026FE28 /* SgButton.swift */; };
42 | /* End PBXBuildFile section */
43 |
44 | /* Begin PBXContainerItemProxy section */
45 | B15331691A9FE49A0026FE28 /* PBXContainerItemProxy */ = {
46 | isa = PBXContainerItemProxy;
47 | containerPortal = B15331471A9FE49A0026FE28 /* Project object */;
48 | proxyType = 1;
49 | remoteGlobalIDString = B153314E1A9FE49A0026FE28;
50 | remoteInfo = SgButtonDemoIOS;
51 | };
52 | /* End PBXContainerItemProxy section */
53 |
54 | /* Begin PBXFileReference section */
55 | B129DF5F1AA2E7AE0013334E /* back@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back@2x.png"; sourceTree = ""; };
56 | B129DF601AA2E7AE0013334E /* back_d@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back_d@2x.png"; sourceTree = ""; };
57 | B129DF611AA2E7AE0013334E /* back_x@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back_x@2x.png"; sourceTree = ""; };
58 | B129DF621AA2E7AE0013334E /* bkbtn.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = bkbtn.png; sourceTree = ""; };
59 | B129DF631AA2E7AE0013334E /* bkbtn_d.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = bkbtn_d.png; sourceTree = ""; };
60 | B129DF651AA2E7AE0013334E /* buttons.1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = buttons.1.png; sourceTree = ""; };
61 | B129DF661AA2E7AE0013334E /* buttons.1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "buttons.1@2x.png"; sourceTree = ""; };
62 | B129DF671AA2E7AE0013334E /* buttons.1@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "buttons.1@3x.png"; sourceTree = ""; };
63 | B129DF681AA2E7AE0013334E /* buttons.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = buttons.plist; sourceTree = ""; };
64 | B129DF691AA2E7AE0013334E /* Buttons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Buttons.swift; sourceTree = ""; };
65 | B129DF6A1AA2E7AE0013334E /* buy.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = buy.png; sourceTree = ""; };
66 | B129DF6B1AA2E7AE0013334E /* buy_d.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = buy_d.png; sourceTree = ""; };
67 | B153314F1A9FE49A0026FE28 /* SgButtonDemoIOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SgButtonDemoIOS.app; sourceTree = BUILT_PRODUCTS_DIR; };
68 | B15331531A9FE49A0026FE28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
69 | B15331541A9FE49A0026FE28 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
70 | B15331581A9FE49A0026FE28 /* GameScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameScene.swift; sourceTree = ""; };
71 | B153315A1A9FE49A0026FE28 /* GameViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameViewController.swift; sourceTree = ""; };
72 | B153315D1A9FE49A0026FE28 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
73 | B15331621A9FE49A0026FE28 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
74 | B15331681A9FE49A0026FE28 /* SgButtonDemoIOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SgButtonDemoIOSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
75 | B153316D1A9FE49A0026FE28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
76 | B153316E1A9FE49A0026FE28 /* SgButtonDemoIOSTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SgButtonDemoIOSTests.swift; sourceTree = ""; };
77 | B153318B1A9FEAEA0026FE28 /* SgButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SgButton.swift; sourceTree = ""; };
78 | /* End PBXFileReference section */
79 |
80 | /* Begin PBXFrameworksBuildPhase section */
81 | B153314C1A9FE49A0026FE28 /* Frameworks */ = {
82 | isa = PBXFrameworksBuildPhase;
83 | buildActionMask = 2147483647;
84 | files = (
85 | );
86 | runOnlyForDeploymentPostprocessing = 0;
87 | };
88 | B15331651A9FE49A0026FE28 /* Frameworks */ = {
89 | isa = PBXFrameworksBuildPhase;
90 | buildActionMask = 2147483647;
91 | files = (
92 | );
93 | runOnlyForDeploymentPostprocessing = 0;
94 | };
95 | /* End PBXFrameworksBuildPhase section */
96 |
97 | /* Begin PBXGroup section */
98 | B129DF5E1AA2E7AE0013334E /* BtnResources */ = {
99 | isa = PBXGroup;
100 | children = (
101 | B129DF5F1AA2E7AE0013334E /* back@2x.png */,
102 | B129DF601AA2E7AE0013334E /* back_d@2x.png */,
103 | B129DF611AA2E7AE0013334E /* back_x@2x.png */,
104 | B129DF621AA2E7AE0013334E /* bkbtn.png */,
105 | B129DF631AA2E7AE0013334E /* bkbtn_d.png */,
106 | B129DF641AA2E7AE0013334E /* buttons.atlasc */,
107 | B129DF691AA2E7AE0013334E /* Buttons.swift */,
108 | B129DF6A1AA2E7AE0013334E /* buy.png */,
109 | B129DF6B1AA2E7AE0013334E /* buy_d.png */,
110 | );
111 | name = BtnResources;
112 | path = ../../BtnResources;
113 | sourceTree = "";
114 | };
115 | B129DF641AA2E7AE0013334E /* buttons.atlasc */ = {
116 | isa = PBXGroup;
117 | children = (
118 | B129DF651AA2E7AE0013334E /* buttons.1.png */,
119 | B129DF661AA2E7AE0013334E /* buttons.1@2x.png */,
120 | B129DF671AA2E7AE0013334E /* buttons.1@3x.png */,
121 | B129DF681AA2E7AE0013334E /* buttons.plist */,
122 | );
123 | path = buttons.atlasc;
124 | sourceTree = "";
125 | };
126 | B15331461A9FE49A0026FE28 = {
127 | isa = PBXGroup;
128 | children = (
129 | B15331511A9FE49A0026FE28 /* SgButtonDemoIOS */,
130 | B153316B1A9FE49A0026FE28 /* SgButtonDemoIOSTests */,
131 | B15331501A9FE49A0026FE28 /* Products */,
132 | );
133 | sourceTree = "";
134 | };
135 | B15331501A9FE49A0026FE28 /* Products */ = {
136 | isa = PBXGroup;
137 | children = (
138 | B153314F1A9FE49A0026FE28 /* SgButtonDemoIOS.app */,
139 | B15331681A9FE49A0026FE28 /* SgButtonDemoIOSTests.xctest */,
140 | );
141 | name = Products;
142 | sourceTree = "";
143 | };
144 | B15331511A9FE49A0026FE28 /* SgButtonDemoIOS */ = {
145 | isa = PBXGroup;
146 | children = (
147 | B153318A1A9FEAEA0026FE28 /* SgButton */,
148 | B129DF5E1AA2E7AE0013334E /* BtnResources */,
149 | B15331541A9FE49A0026FE28 /* AppDelegate.swift */,
150 | B15331581A9FE49A0026FE28 /* GameScene.swift */,
151 | B153315A1A9FE49A0026FE28 /* GameViewController.swift */,
152 | B153315C1A9FE49A0026FE28 /* Main.storyboard */,
153 | B15331611A9FE49A0026FE28 /* LaunchScreen.xib */,
154 | B15331521A9FE49A0026FE28 /* Supporting Files */,
155 | );
156 | path = SgButtonDemoIOS;
157 | sourceTree = "";
158 | };
159 | B15331521A9FE49A0026FE28 /* Supporting Files */ = {
160 | isa = PBXGroup;
161 | children = (
162 | B15331531A9FE49A0026FE28 /* Info.plist */,
163 | );
164 | name = "Supporting Files";
165 | sourceTree = "";
166 | };
167 | B153316B1A9FE49A0026FE28 /* SgButtonDemoIOSTests */ = {
168 | isa = PBXGroup;
169 | children = (
170 | B153316E1A9FE49A0026FE28 /* SgButtonDemoIOSTests.swift */,
171 | B153316C1A9FE49A0026FE28 /* Supporting Files */,
172 | );
173 | path = SgButtonDemoIOSTests;
174 | sourceTree = "";
175 | };
176 | B153316C1A9FE49A0026FE28 /* Supporting Files */ = {
177 | isa = PBXGroup;
178 | children = (
179 | B153316D1A9FE49A0026FE28 /* Info.plist */,
180 | );
181 | name = "Supporting Files";
182 | sourceTree = "";
183 | };
184 | B153318A1A9FEAEA0026FE28 /* SgButton */ = {
185 | isa = PBXGroup;
186 | children = (
187 | B153318B1A9FEAEA0026FE28 /* SgButton.swift */,
188 | );
189 | name = SgButton;
190 | path = ../../SgButton;
191 | sourceTree = "";
192 | };
193 | /* End PBXGroup section */
194 |
195 | /* Begin PBXNativeTarget section */
196 | B153314E1A9FE49A0026FE28 /* SgButtonDemoIOS */ = {
197 | isa = PBXNativeTarget;
198 | buildConfigurationList = B15331721A9FE49A0026FE28 /* Build configuration list for PBXNativeTarget "SgButtonDemoIOS" */;
199 | buildPhases = (
200 | B153314B1A9FE49A0026FE28 /* Sources */,
201 | B153314C1A9FE49A0026FE28 /* Frameworks */,
202 | B153314D1A9FE49A0026FE28 /* Resources */,
203 | );
204 | buildRules = (
205 | );
206 | dependencies = (
207 | );
208 | name = SgButtonDemoIOS;
209 | productName = SgButtonDemoIOS;
210 | productReference = B153314F1A9FE49A0026FE28 /* SgButtonDemoIOS.app */;
211 | productType = "com.apple.product-type.application";
212 | };
213 | B15331671A9FE49A0026FE28 /* SgButtonDemoIOSTests */ = {
214 | isa = PBXNativeTarget;
215 | buildConfigurationList = B15331751A9FE49A0026FE28 /* Build configuration list for PBXNativeTarget "SgButtonDemoIOSTests" */;
216 | buildPhases = (
217 | B15331641A9FE49A0026FE28 /* Sources */,
218 | B15331651A9FE49A0026FE28 /* Frameworks */,
219 | B15331661A9FE49A0026FE28 /* Resources */,
220 | );
221 | buildRules = (
222 | );
223 | dependencies = (
224 | B153316A1A9FE49A0026FE28 /* PBXTargetDependency */,
225 | );
226 | name = SgButtonDemoIOSTests;
227 | productName = SgButtonDemoIOSTests;
228 | productReference = B15331681A9FE49A0026FE28 /* SgButtonDemoIOSTests.xctest */;
229 | productType = "com.apple.product-type.bundle.unit-test";
230 | };
231 | /* End PBXNativeTarget section */
232 |
233 | /* Begin PBXProject section */
234 | B15331471A9FE49A0026FE28 /* Project object */ = {
235 | isa = PBXProject;
236 | attributes = {
237 | LastSwiftMigration = 0730;
238 | LastSwiftUpdateCheck = 0730;
239 | LastUpgradeCheck = 0730;
240 | ORGANIZATIONNAME = Softgaroo;
241 | TargetAttributes = {
242 | B153314E1A9FE49A0026FE28 = {
243 | CreatedOnToolsVersion = 6.1.1;
244 | };
245 | B15331671A9FE49A0026FE28 = {
246 | CreatedOnToolsVersion = 6.1.1;
247 | TestTargetID = B153314E1A9FE49A0026FE28;
248 | };
249 | };
250 | };
251 | buildConfigurationList = B153314A1A9FE49A0026FE28 /* Build configuration list for PBXProject "SgButtonDemoIOS" */;
252 | compatibilityVersion = "Xcode 3.2";
253 | developmentRegion = English;
254 | hasScannedForEncodings = 0;
255 | knownRegions = (
256 | en,
257 | Base,
258 | );
259 | mainGroup = B15331461A9FE49A0026FE28;
260 | productRefGroup = B15331501A9FE49A0026FE28 /* Products */;
261 | projectDirPath = "";
262 | projectRoot = "";
263 | targets = (
264 | B153314E1A9FE49A0026FE28 /* SgButtonDemoIOS */,
265 | B15331671A9FE49A0026FE28 /* SgButtonDemoIOSTests */,
266 | );
267 | };
268 | /* End PBXProject section */
269 |
270 | /* Begin PBXResourcesBuildPhase section */
271 | B153314D1A9FE49A0026FE28 /* Resources */ = {
272 | isa = PBXResourcesBuildPhase;
273 | buildActionMask = 2147483647;
274 | files = (
275 | B15331631A9FE49A0026FE28 /* LaunchScreen.xib in Resources */,
276 | B129DF741AA2E7AE0013334E /* bkbtn_d.png in Resources */,
277 | B129DF801AA2E7AE0013334E /* buy.png in Resources */,
278 | B129DF6E1AA2E7AE0013334E /* back_d@2x.png in Resources */,
279 | B129DF7A1AA2E7AE0013334E /* buttons.1@3x.png in Resources */,
280 | B129DF761AA2E7AE0013334E /* buttons.1.png in Resources */,
281 | B129DF6C1AA2E7AE0013334E /* back@2x.png in Resources */,
282 | B129DF821AA2E7AE0013334E /* buy_d.png in Resources */,
283 | B129DF721AA2E7AE0013334E /* bkbtn.png in Resources */,
284 | B129DF781AA2E7AE0013334E /* buttons.1@2x.png in Resources */,
285 | B129DF701AA2E7AE0013334E /* back_x@2x.png in Resources */,
286 | B153315E1A9FE49A0026FE28 /* Main.storyboard in Resources */,
287 | B129DF7C1AA2E7AE0013334E /* buttons.plist in Resources */,
288 | );
289 | runOnlyForDeploymentPostprocessing = 0;
290 | };
291 | B15331661A9FE49A0026FE28 /* Resources */ = {
292 | isa = PBXResourcesBuildPhase;
293 | buildActionMask = 2147483647;
294 | files = (
295 | B129DF711AA2E7AE0013334E /* back_x@2x.png in Resources */,
296 | B129DF791AA2E7AE0013334E /* buttons.1@2x.png in Resources */,
297 | B129DF731AA2E7AE0013334E /* bkbtn.png in Resources */,
298 | B129DF6F1AA2E7AE0013334E /* back_d@2x.png in Resources */,
299 | B129DF811AA2E7AE0013334E /* buy.png in Resources */,
300 | B129DF7B1AA2E7AE0013334E /* buttons.1@3x.png in Resources */,
301 | B129DF6D1AA2E7AE0013334E /* back@2x.png in Resources */,
302 | B129DF831AA2E7AE0013334E /* buy_d.png in Resources */,
303 | B129DF771AA2E7AE0013334E /* buttons.1.png in Resources */,
304 | B129DF7D1AA2E7AE0013334E /* buttons.plist in Resources */,
305 | B129DF751AA2E7AE0013334E /* bkbtn_d.png in Resources */,
306 | );
307 | runOnlyForDeploymentPostprocessing = 0;
308 | };
309 | /* End PBXResourcesBuildPhase section */
310 |
311 | /* Begin PBXSourcesBuildPhase section */
312 | B153314B1A9FE49A0026FE28 /* Sources */ = {
313 | isa = PBXSourcesBuildPhase;
314 | buildActionMask = 2147483647;
315 | files = (
316 | B129DF7E1AA2E7AE0013334E /* Buttons.swift in Sources */,
317 | B15331591A9FE49A0026FE28 /* GameScene.swift in Sources */,
318 | B153315B1A9FE49A0026FE28 /* GameViewController.swift in Sources */,
319 | B15331551A9FE49A0026FE28 /* AppDelegate.swift in Sources */,
320 | B15331A41A9FEAEA0026FE28 /* SgButton.swift in Sources */,
321 | );
322 | runOnlyForDeploymentPostprocessing = 0;
323 | };
324 | B15331641A9FE49A0026FE28 /* Sources */ = {
325 | isa = PBXSourcesBuildPhase;
326 | buildActionMask = 2147483647;
327 | files = (
328 | B129DF7F1AA2E7AE0013334E /* Buttons.swift in Sources */,
329 | B153316F1A9FE49A0026FE28 /* SgButtonDemoIOSTests.swift in Sources */,
330 | B15331A51A9FEAEA0026FE28 /* SgButton.swift in Sources */,
331 | );
332 | runOnlyForDeploymentPostprocessing = 0;
333 | };
334 | /* End PBXSourcesBuildPhase section */
335 |
336 | /* Begin PBXTargetDependency section */
337 | B153316A1A9FE49A0026FE28 /* PBXTargetDependency */ = {
338 | isa = PBXTargetDependency;
339 | target = B153314E1A9FE49A0026FE28 /* SgButtonDemoIOS */;
340 | targetProxy = B15331691A9FE49A0026FE28 /* PBXContainerItemProxy */;
341 | };
342 | /* End PBXTargetDependency section */
343 |
344 | /* Begin PBXVariantGroup section */
345 | B153315C1A9FE49A0026FE28 /* Main.storyboard */ = {
346 | isa = PBXVariantGroup;
347 | children = (
348 | B153315D1A9FE49A0026FE28 /* Base */,
349 | );
350 | name = Main.storyboard;
351 | sourceTree = "";
352 | };
353 | B15331611A9FE49A0026FE28 /* LaunchScreen.xib */ = {
354 | isa = PBXVariantGroup;
355 | children = (
356 | B15331621A9FE49A0026FE28 /* Base */,
357 | );
358 | name = LaunchScreen.xib;
359 | sourceTree = "";
360 | };
361 | /* End PBXVariantGroup section */
362 |
363 | /* Begin XCBuildConfiguration section */
364 | B15331701A9FE49A0026FE28 /* Debug */ = {
365 | isa = XCBuildConfiguration;
366 | buildSettings = {
367 | ALWAYS_SEARCH_USER_PATHS = NO;
368 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
369 | CLANG_CXX_LIBRARY = "libc++";
370 | CLANG_ENABLE_MODULES = YES;
371 | CLANG_ENABLE_OBJC_ARC = YES;
372 | CLANG_WARN_BOOL_CONVERSION = YES;
373 | CLANG_WARN_CONSTANT_CONVERSION = YES;
374 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
375 | CLANG_WARN_EMPTY_BODY = YES;
376 | CLANG_WARN_ENUM_CONVERSION = YES;
377 | CLANG_WARN_INT_CONVERSION = YES;
378 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
379 | CLANG_WARN_UNREACHABLE_CODE = YES;
380 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
381 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
382 | COPY_PHASE_STRIP = NO;
383 | ENABLE_STRICT_OBJC_MSGSEND = YES;
384 | ENABLE_TESTABILITY = YES;
385 | GCC_C_LANGUAGE_STANDARD = gnu99;
386 | GCC_DYNAMIC_NO_PIC = NO;
387 | GCC_OPTIMIZATION_LEVEL = 0;
388 | GCC_PREPROCESSOR_DEFINITIONS = (
389 | "DEBUG=1",
390 | "$(inherited)",
391 | );
392 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
393 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
394 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
395 | GCC_WARN_UNDECLARED_SELECTOR = YES;
396 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
397 | GCC_WARN_UNUSED_FUNCTION = YES;
398 | GCC_WARN_UNUSED_VARIABLE = YES;
399 | IPHONEOS_DEPLOYMENT_TARGET = 8.1;
400 | MTL_ENABLE_DEBUG_INFO = YES;
401 | ONLY_ACTIVE_ARCH = YES;
402 | SDKROOT = iphoneos;
403 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
404 | TARGETED_DEVICE_FAMILY = "1,2";
405 | };
406 | name = Debug;
407 | };
408 | B15331711A9FE49A0026FE28 /* Release */ = {
409 | isa = XCBuildConfiguration;
410 | buildSettings = {
411 | ALWAYS_SEARCH_USER_PATHS = NO;
412 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
413 | CLANG_CXX_LIBRARY = "libc++";
414 | CLANG_ENABLE_MODULES = YES;
415 | CLANG_ENABLE_OBJC_ARC = YES;
416 | CLANG_WARN_BOOL_CONVERSION = YES;
417 | CLANG_WARN_CONSTANT_CONVERSION = YES;
418 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
419 | CLANG_WARN_EMPTY_BODY = YES;
420 | CLANG_WARN_ENUM_CONVERSION = YES;
421 | CLANG_WARN_INT_CONVERSION = YES;
422 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
423 | CLANG_WARN_UNREACHABLE_CODE = YES;
424 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
425 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
426 | COPY_PHASE_STRIP = YES;
427 | ENABLE_NS_ASSERTIONS = NO;
428 | ENABLE_STRICT_OBJC_MSGSEND = YES;
429 | GCC_C_LANGUAGE_STANDARD = gnu99;
430 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
431 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
432 | GCC_WARN_UNDECLARED_SELECTOR = YES;
433 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
434 | GCC_WARN_UNUSED_FUNCTION = YES;
435 | GCC_WARN_UNUSED_VARIABLE = YES;
436 | IPHONEOS_DEPLOYMENT_TARGET = 8.1;
437 | MTL_ENABLE_DEBUG_INFO = NO;
438 | SDKROOT = iphoneos;
439 | TARGETED_DEVICE_FAMILY = "1,2";
440 | VALIDATE_PRODUCT = YES;
441 | };
442 | name = Release;
443 | };
444 | B15331731A9FE49A0026FE28 /* Debug */ = {
445 | isa = XCBuildConfiguration;
446 | buildSettings = {
447 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
448 | INFOPLIST_FILE = SgButtonDemoIOS/Info.plist;
449 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
450 | PRODUCT_BUNDLE_IDENTIFIER = "com.softgaroo.$(PRODUCT_NAME:rfc1034identifier)";
451 | PRODUCT_NAME = "$(TARGET_NAME)";
452 | };
453 | name = Debug;
454 | };
455 | B15331741A9FE49A0026FE28 /* Release */ = {
456 | isa = XCBuildConfiguration;
457 | buildSettings = {
458 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
459 | INFOPLIST_FILE = SgButtonDemoIOS/Info.plist;
460 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
461 | PRODUCT_BUNDLE_IDENTIFIER = "com.softgaroo.$(PRODUCT_NAME:rfc1034identifier)";
462 | PRODUCT_NAME = "$(TARGET_NAME)";
463 | };
464 | name = Release;
465 | };
466 | B15331761A9FE49A0026FE28 /* Debug */ = {
467 | isa = XCBuildConfiguration;
468 | buildSettings = {
469 | BUNDLE_LOADER = "$(TEST_HOST)";
470 | FRAMEWORK_SEARCH_PATHS = (
471 | "$(SDKROOT)/Developer/Library/Frameworks",
472 | "$(inherited)",
473 | );
474 | GCC_PREPROCESSOR_DEFINITIONS = (
475 | "DEBUG=1",
476 | "$(inherited)",
477 | );
478 | INFOPLIST_FILE = SgButtonDemoIOSTests/Info.plist;
479 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
480 | PRODUCT_BUNDLE_IDENTIFIER = "com.softgaroo.$(PRODUCT_NAME:rfc1034identifier)";
481 | PRODUCT_NAME = "$(TARGET_NAME)";
482 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SgButtonDemoIOS.app/SgButtonDemoIOS";
483 | };
484 | name = Debug;
485 | };
486 | B15331771A9FE49A0026FE28 /* Release */ = {
487 | isa = XCBuildConfiguration;
488 | buildSettings = {
489 | BUNDLE_LOADER = "$(TEST_HOST)";
490 | FRAMEWORK_SEARCH_PATHS = (
491 | "$(SDKROOT)/Developer/Library/Frameworks",
492 | "$(inherited)",
493 | );
494 | INFOPLIST_FILE = SgButtonDemoIOSTests/Info.plist;
495 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
496 | PRODUCT_BUNDLE_IDENTIFIER = "com.softgaroo.$(PRODUCT_NAME:rfc1034identifier)";
497 | PRODUCT_NAME = "$(TARGET_NAME)";
498 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SgButtonDemoIOS.app/SgButtonDemoIOS";
499 | };
500 | name = Release;
501 | };
502 | /* End XCBuildConfiguration section */
503 |
504 | /* Begin XCConfigurationList section */
505 | B153314A1A9FE49A0026FE28 /* Build configuration list for PBXProject "SgButtonDemoIOS" */ = {
506 | isa = XCConfigurationList;
507 | buildConfigurations = (
508 | B15331701A9FE49A0026FE28 /* Debug */,
509 | B15331711A9FE49A0026FE28 /* Release */,
510 | );
511 | defaultConfigurationIsVisible = 0;
512 | defaultConfigurationName = Release;
513 | };
514 | B15331721A9FE49A0026FE28 /* Build configuration list for PBXNativeTarget "SgButtonDemoIOS" */ = {
515 | isa = XCConfigurationList;
516 | buildConfigurations = (
517 | B15331731A9FE49A0026FE28 /* Debug */,
518 | B15331741A9FE49A0026FE28 /* Release */,
519 | );
520 | defaultConfigurationIsVisible = 0;
521 | defaultConfigurationName = Release;
522 | };
523 | B15331751A9FE49A0026FE28 /* Build configuration list for PBXNativeTarget "SgButtonDemoIOSTests" */ = {
524 | isa = XCConfigurationList;
525 | buildConfigurations = (
526 | B15331761A9FE49A0026FE28 /* Debug */,
527 | B15331771A9FE49A0026FE28 /* Release */,
528 | );
529 | defaultConfigurationIsVisible = 0;
530 | defaultConfigurationName = Release;
531 | };
532 | /* End XCConfigurationList section */
533 | };
534 | rootObject = B15331471A9FE49A0026FE28 /* Project object */;
535 | }
536 |
--------------------------------------------------------------------------------