├── .gitattributes
├── KiClipperImageDemo
├── KiClipperImageDemo.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcuserdata
│ │ │ └── mbapple.xcuserdatad
│ │ │ │ └── UserInterfaceState.xcuserstate
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── xcuserdata
│ │ └── mbapple.xcuserdatad
│ │ │ ├── xcschemes
│ │ │ └── xcschememanagement.plist
│ │ │ └── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ └── project.pbxproj
├── KiClipperImageDemoTests
│ ├── Info.plist
│ └── KiClipperImageDemoTests.swift
├── KiClipperImageDemoUITests
│ ├── Info.plist
│ └── KiClipperImageDemoUITests.swift
├── KiClipperImageDemo
│ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ ├── Info.plist
│ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── AppDelegate.swift
│ └── ViewController.swift
└── KiClipperHelper
│ ├── KiClipperHelper.swift
│ ├── KiImageClipperViewController.swift
│ └── KiClipperView.swift
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperImageDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperImageDemo.xcodeproj/project.xcworkspace/xcuserdata/mbapple.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kingzhijie/KiClipperImageDemo/HEAD/KiClipperImageDemo/KiClipperImageDemo.xcodeproj/project.xcworkspace/xcuserdata/mbapple.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperImageDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperImageDemo.xcodeproj/xcuserdata/mbapple.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | KiClipperImageDemo.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperImageDemoTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
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 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperImageDemoUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
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 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperImageDemo.xcodeproj/xcuserdata/mbapple.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperImageDemoTests/KiClipperImageDemoTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // KiClipperImageDemoTests.swift
3 | // KiClipperImageDemoTests
4 | //
5 | // Created by mbApple on 2017/11/15.
6 | // Copyright © 2017年 panda誌. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import KiClipperImageDemo
11 |
12 | class KiClipperImageDemoTests: 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 | // Use XCTAssert and related functions to verify your tests produce the correct results.
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measure {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # KiClipperImageDemo
2 | ######图片裁剪工具类
3 | ###工具提供四种方式: 获取图片##
4 | 1. 直接获取图片
5 | 2. 直接获取图片, 并使用系统的编辑功能
6 | 3. 自定义裁剪图片, 设置好裁剪框的尺寸, 图片可以自由拖动和缩放
7 | 4. 自定义裁剪图片, 图片不移动, 自由拖动或者缩放裁剪框
8 |
9 | ###使用方法 : 使用单例工具类 KiClipperHelper
10 |
11 | KiClipperHelper.sharedInstance.nav = navigationController //获取当前导航
12 | KiClipperHelper.sharedInstance.clippedImgSize = size // 传入, 自定义的裁剪尺寸 (不需要裁剪, 可以不传)
13 | //获取图片成功的回调 img 即为目标图片
14 | KiClipperHelper.sharedInstance.clippedImageHandler = {[weak self]img in
15 | self?.clippedImageView?.image = img
16 | }
17 |
18 | ###参数说明:
19 | public var clippedImageHandler:clippedImageHandlerBlock? //裁剪结束回调
20 | public var systemEditing = false // 系统方式获取图片时, 是否允许系统编辑裁剪
21 | public var isSystemType = false //是否系统方式获取图片
22 | public var clippedImgSize:CGSize? //自定义裁剪的尺寸
23 | public weak var nav:UINavigationController? //当前导航
24 | public var clipperType:ClipperType = .Move //裁剪框移动类型 (move图片移动, stay裁剪框移动)
25 | ###方法说明
26 | //制定获取图片的方式, 相册或者相机
27 | public func photoWithSourceType(type:UIImagePickerControllerSourceType)
28 | //代理方法 , 获取图片后的回调方法
29 | func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
30 |
31 | 
32 |
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperImageDemoUITests/KiClipperImageDemoUITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // KiClipperImageDemoUITests.swift
3 | // KiClipperImageDemoUITests
4 | //
5 | // Created by mbApple on 2017/11/15.
6 | // Copyright © 2017年 panda誌. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class KiClipperImageDemoUITests: XCTestCase {
12 |
13 | override func setUp() {
14 | super.setUp()
15 |
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 |
18 | // In UI tests it is usually best to stop immediately when a failure occurs.
19 | continueAfterFailure = false
20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
21 | XCUIApplication().launch()
22 |
23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
24 | }
25 |
26 | override func tearDown() {
27 | // Put teardown code here. This method is called after the invocation of each test method in the class.
28 | super.tearDown()
29 | }
30 |
31 | func testExample() {
32 | // Use recording to get started writing UI tests.
33 | // Use XCTAssert and related functions to verify your tests produce the correct results.
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperImageDemo/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 |
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperImageDemo/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 |
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperImageDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
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 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | NSCameraUsageDescription
24 | 访问相机
25 | NSPhotoLibraryUsageDescription
26 | 访问相册
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
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 |
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperImageDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | }
88 | ],
89 | "info" : {
90 | "version" : 1,
91 | "author" : "xcode"
92 | }
93 | }
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperImageDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // KiClipperImageDemo
4 | //
5 | // Created by mbApple on 2017/11/15.
6 | // Copyright © 2017年 panda誌. 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: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | let VC = ViewController()
20 | let nav = UINavigationController(rootViewController: VC)
21 | self.window?.rootViewController = nav
22 |
23 | return true
24 | }
25 |
26 | func applicationWillResignActive(_ application: UIApplication) {
27 | // 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.
28 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
29 | }
30 |
31 | func applicationDidEnterBackground(_ application: UIApplication) {
32 | // 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.
33 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
34 | }
35 |
36 | func applicationWillEnterForeground(_ application: UIApplication) {
37 | // 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.
38 | }
39 |
40 | func applicationDidBecomeActive(_ application: UIApplication) {
41 | // 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.
42 | }
43 |
44 | func applicationWillTerminate(_ application: UIApplication) {
45 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
46 | }
47 |
48 |
49 | }
50 |
51 |
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperHelper/KiClipperHelper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // KiClipperHelper.swift
3 | // KiClipperImageDemo
4 | //
5 | // Created by mbApple on 2017/11/15.
6 | // Copyright © 2017年 panda誌. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | private let shareManager = KiClipperHelper()
12 | typealias clippedImageHandlerBlock = (_ img:UIImage)->Void
13 | class KiClipperHelper: NSObject,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
14 |
15 | class var sharedInstance : KiClipperHelper { //单例---工具类
16 | return shareManager
17 | }
18 |
19 | public var clippedImageHandler:clippedImageHandlerBlock? //裁剪结束回调
20 | public var systemEditing = false // 系统方式获取图片时, 是否允许系统编辑裁剪
21 | public var isSystemType = false //是否系统方式获取图片
22 | public var clippedImgSize:CGSize? //自定义裁剪的尺寸
23 | public weak var nav:UINavigationController? //当前导航
24 | public var clipperType:ClipperType = .Move //裁剪框移动类型 (move图片移动, stay裁剪框移动)
25 |
26 | public func photoWithSourceType(type:UIImagePickerControllerSourceType) {
27 | let imagePicker = UIImagePickerController()
28 | imagePicker.delegate = self
29 | imagePicker.sourceType = type
30 | imagePicker.allowsEditing = systemEditing
31 | // imagePicker.modalTransitionStyle = .crossDissolve
32 | nav?.present(imagePicker, animated: true, completion: nil)
33 | }
34 |
35 | //MARK UIImagePickerControllerDelegate
36 | func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]){
37 | if !isSystemType { //自定义裁剪
38 | let image = self.turnImageWithInfo(info: info)
39 | let clipperVC = KiImageClipperViewController()
40 | clipperVC.setBaseImg(image, resultImgSize: clippedImgSize!, type: clipperType)
41 | clipperVC.cancelClippedHandler = {
42 | picker.dismiss(animated: true, completion: nil)
43 | }
44 | clipperVC.successClippedHandler = {[weak self]img in
45 | if self?.clippedImageHandler != nil{
46 | self?.clippedImageHandler!(img)
47 | }
48 | picker.dismiss(animated: true, completion: nil)
49 | }
50 | picker.pushViewController(clipperVC, animated: true)
51 | }else{ //系统获取
52 | if !self.systemEditing{
53 | image = self.turnImageWithInfo(info: info)
54 | }else{
55 | image = info[UIImagePickerControllerEditedImage] as? UIImage
56 | }
57 | if clippedImageHandler != nil{
58 | clippedImageHandler!(image ?? UIImage())
59 | }
60 | picker.dismiss(animated: true, completion: nil)
61 | }
62 | }
63 |
64 | private var image:UIImage?
65 |
66 | private func turnImageWithInfo(info:[String:Any]) -> UIImage {
67 | var image = info[UIImagePickerControllerOriginalImage] as? UIImage
68 | //类型为 UIImagePickerControllerOriginalImage 时调整图片角度
69 | let type = info[UIImagePickerControllerMediaType] as? String
70 |
71 | if type == "public.image" {
72 | let imageOrientation = image?.imageOrientation
73 | if imageOrientation != UIImageOrientation.up{
74 | // 原始图片可以根据照相时的角度来显示,但 UIImage无法判定,于是出现获取的图片会向左转90度的现象。
75 | UIGraphicsBeginImageContext((image?.size)!)
76 | image?.draw(in: CGRect(x: 0, y: 0, width: (image?.size.width)!, height: (image?.size.height)!))
77 | image = UIGraphicsGetImageFromCurrentImageContext()
78 | UIGraphicsEndImageContext()
79 | }
80 | }
81 | return image!
82 | }
83 |
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperHelper/KiImageClipperViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // KiImageClipperViewController.swift
3 | // KiClipperImageDemo
4 | //
5 | // Created by mbApple on 2017/11/15.
6 | // Copyright © 2017年 panda誌. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | // iPhone X
11 | let iphoneX = (UIScreen.main.bounds.size.width == 375.0 && UIScreen.main.bounds.size.height == 812.0 ? true : false) as Bool
12 |
13 | typealias cancelClippedHandlerBlock = ()->Void
14 | typealias successClippedHandlerBlock = (_ clippedImage:UIImage)->Void
15 | class KiImageClipperViewController: UIViewController {
16 | //MARK Public
17 | public var cancelClippedHandler:cancelClippedHandlerBlock?
18 | public var successClippedHandler:successClippedHandlerBlock?
19 | public func setBaseImg(_ baseImg:UIImage,resultImgSize:CGSize,type:ClipperType) {
20 | clipperView = KiClipperView(frame: CGRect(x: 0, y: (iphoneX ? 88:64), width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height - (iphoneX ? 88:64)))
21 | clipperView?.resultImgSize = resultImgSize
22 | clipperView?.baseImg = baseImg
23 | clipperView?.type = type
24 | self.view.addSubview(clipperView!)
25 | }
26 |
27 | //MARK Private
28 | private var clipperView:KiClipperView?
29 | private let TITLE_BAR_HEIGHT:Int = 44
30 | private var rightBtn:UIButton?
31 | private var leftBtn:UIButton?
32 |
33 | override func viewDidLoad() {
34 | super.viewDidLoad()
35 | self.title = "选择图片"
36 | view.backgroundColor = .black
37 |
38 | self.hidesBottomBarWhenPushed = true
39 | if #available(iOS 11.0, *) {
40 | }else{
41 | self.automaticallyAdjustsScrollViewInsets = false
42 | }
43 |
44 | self.creatLeftBtnWithTitle(title: "取消")
45 | self.creaRightBtnWithTitle(title: "确认")
46 | // Do any additional setup after loading the view.
47 | }
48 |
49 | @objc private func leftBtnTUI(btn: UIButton) {
50 | if cancelClippedHandler != nil {
51 | cancelClippedHandler!()
52 | }
53 | }
54 |
55 | @objc private func rightBtnTUI(btn: UIButton) {
56 | let clippedImg = self.clipperView?.clipImg()
57 | if successClippedHandler != nil {
58 | successClippedHandler!(clippedImg ?? UIImage())
59 | }
60 | }
61 |
62 | //MARK
63 | private func creatLeftBtnWithTitle(title:String) {
64 | if leftBtn == nil {
65 | leftBtn = UIButton(type: .custom)
66 | leftBtn?.frame = CGRect(x: 20, y: 20, width: TITLE_BAR_HEIGHT, height: TITLE_BAR_HEIGHT)
67 | leftBtn?.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
68 | leftBtn?.contentHorizontalAlignment = .left
69 | leftBtn?.setTitle(title, for: .normal)
70 | leftBtn?.setTitleColor(UIColor.init(red: 0.118, green: 0.133, blue: 0.153, alpha: 1.0), for: .normal)
71 | leftBtn?.titleLabel?.font = UIFont.systemFont(ofSize: 16)
72 | leftBtn?.addTarget(self, action: #selector(leftBtnTUI(btn:)), for: .touchUpInside)
73 | navigationItem.leftBarButtonItem = UIBarButtonItem(customView: leftBtn!)
74 | }
75 | }
76 |
77 | private func creaRightBtnWithTitle(title:String) {
78 | if rightBtn == nil {
79 | rightBtn = UIButton(type: .custom)
80 | rightBtn?.setTitleColor(UIColor.init(red: 0.118, green: 0.133, blue: 0.153, alpha: 1.0), for: .normal)
81 | rightBtn?.titleLabel?.font = UIFont.systemFont(ofSize: 16)
82 | rightBtn?.addTarget(self, action: #selector(rightBtnTUI(btn:)), for: .touchUpInside)
83 | rightBtn?.layer.cornerRadius = 8
84 | }
85 | rightBtn?.sizeToFit()
86 | rightBtn?.setTitle(title, for: .normal)
87 | navigationItem.rightBarButtonItem = UIBarButtonItem(customView: rightBtn!)
88 | }
89 |
90 | override func viewWillAppear(_ animated: Bool) {
91 | super.viewWillAppear(animated)
92 | navigationController?.isNavigationBarHidden = false
93 | }
94 |
95 | override func didReceiveMemoryWarning() {
96 | super.didReceiveMemoryWarning()
97 | // Dispose of any resources that can be recreated.
98 | }
99 |
100 |
101 | /*
102 | // MARK: - Navigation
103 |
104 | // In a storyboard-based application, you will often want to do a little preparation before navigation
105 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
106 | // Get the new view controller using segue.destinationViewController.
107 | // Pass the selected object to the new view controller.
108 | }
109 | */
110 |
111 | }
112 |
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperImageDemo/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // KiClipperImageDemo
4 | //
5 | // Created by mbApple on 2017/11/15.
6 | // Copyright © 2017年 panda誌. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController,UIActionSheetDelegate {
12 |
13 | lazy var clippedImageView: UIImageView? = {
14 | let clippedImageView = UIImageView(frame: CGRect(x: 20, y: 300, width: 300, height: 300))
15 | clippedImageView.backgroundColor = .red
16 | return clippedImageView
17 | }()
18 |
19 | override func viewDidLoad() {
20 | super.viewDidLoad()
21 | view.backgroundColor = .white
22 | // Do any additional setup after loading the view, typically from a nib.
23 | self.view.addSubview(self.clippedImageView!)
24 | let button = UIButton(type: .custom)
25 | button.backgroundColor = .red
26 | button.setTitle("不裁剪", for: .normal)
27 | button.frame = CGRect(x: 10, y: 100, width: 60, height: 60)
28 | button.addTarget(self, action:#selector(action1), for: .touchUpInside)
29 | button.sizeToFit()
30 | self.view.addSubview(button)
31 |
32 | let button2 = UIButton(type: .custom)
33 | button2.backgroundColor = .red
34 | button2.setTitle("系统裁剪", for: .normal)
35 | button2.frame = CGRect(x: 200, y: 100, width: 60, height: 60)
36 | button2.addTarget(self, action:#selector(action2), for: .touchUpInside)
37 | button2.sizeToFit()
38 | self.view.addSubview(button2)
39 |
40 | let button3 = UIButton(type: .custom)
41 | button3.backgroundColor = .red
42 | button3.setTitle("图片移动,裁剪框不移动", for: .normal)
43 | button3.frame = CGRect(x: 10, y: 200, width: 60, height: 60)
44 | button3.addTarget(self, action:#selector(action3), for: .touchUpInside)
45 | button3.sizeToFit()
46 | self.view.addSubview(button3)
47 |
48 | let button4 = UIButton(type: .custom)
49 | button4.backgroundColor = .red
50 | button4.setTitle("裁剪框移动,图片不动", for: .normal)
51 | button4.frame = CGRect(x: 250, y: 200, width: 60, height: 60)
52 | button4.addTarget(self, action:#selector(action4), for: .touchUpInside)
53 | button4.sizeToFit()
54 | self.view.addSubview(button4)
55 |
56 | KiClipperHelper.sharedInstance.nav = navigationController
57 | KiClipperHelper.sharedInstance.clippedImgSize = self.clippedImageView?.frame.size
58 | KiClipperHelper.sharedInstance.clippedImageHandler = {[weak self]img in
59 | self?.clippedImageView?.image = img
60 | }
61 |
62 | }
63 |
64 | @objc func action1() { //直接系统方法获取图片, 不裁剪, 获取原图
65 | KiClipperHelper.sharedInstance.systemEditing = false
66 | KiClipperHelper.sharedInstance.isSystemType = true
67 | takePhoto()
68 | }
69 | @objc func action2() { //直接系统方法获取图片, 默认系统尺寸, 裁剪图片
70 | KiClipperHelper.sharedInstance.systemEditing = true
71 | KiClipperHelper.sharedInstance.isSystemType = true
72 | takePhoto()
73 | }
74 | @objc func action3() { //自定义裁剪图片, 图片移动, 裁剪框不移动
75 | KiClipperHelper.sharedInstance.clipperType = .Move
76 | KiClipperHelper.sharedInstance.systemEditing = false
77 | KiClipperHelper.sharedInstance.isSystemType = false
78 | takePhoto()
79 | }
80 | @objc func action4() { //自定义裁剪图片, 图片不移动, 裁剪框移动, 及自定义等比缩放大小
81 | KiClipperHelper.sharedInstance.clipperType = .Stay
82 | KiClipperHelper.sharedInstance.systemEditing = false
83 | KiClipperHelper.sharedInstance.isSystemType = false
84 | takePhoto()
85 | }
86 |
87 | func takePhoto() {
88 |
89 | KiClipperHelper.sharedInstance.photoWithSourceType(type: .photoLibrary) //直接打开相册选取图片
90 |
91 | // KiClipperHelper.sharedInstance.photoWithSourceType(type: .camera) //打开相机拍摄照片
92 |
93 | // let sheet = UIActionSheet(title: nil, delegate: self, cancelButtonTitle: "取消", destructiveButtonTitle: nil, otherButtonTitles: "相册", "拍照")
94 | // sheet.show(in: UIApplication.shared.keyWindow!)
95 | }
96 |
97 | func actionSheet(_ actionSheet: UIActionSheet, clickedButtonAt buttonIndex: Int){
98 | DispatchQueue.main.async {
99 | if buttonIndex == 0 {
100 | //取消
101 | }else if buttonIndex == 1 {
102 | KiClipperHelper.sharedInstance.photoWithSourceType(type: .photoLibrary)
103 | }else if buttonIndex == 2 {
104 | // KiClipperHelper.sharedInstance.photoWithSourceType(type: .camera) //模拟机不支持相机
105 | }
106 | }
107 | }
108 |
109 | override func didReceiveMemoryWarning() {
110 | super.didReceiveMemoryWarning()
111 | // Dispose of any resources that can be recreated.
112 | }
113 |
114 |
115 | }
116 |
117 |
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperHelper/KiClipperView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // KiClipperView.swift
3 | // KiClipperImageDemo
4 | //
5 | // Created by mbApple on 2017/11/15.
6 | // Copyright © 2017年 panda誌. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | enum ClipperType {
12 | case Move
13 | case Stay
14 | }
15 |
16 | class KiClipperView: UIView {
17 |
18 | public var resultImgSize:CGSize?{
19 | didSet{
20 | self.setClipperView()
21 | }
22 | }
23 | public var type:ClipperType = .Move
24 | public var baseImg:UIImage?{
25 | didSet{
26 | var width = baseImg?.size.width ?? 0
27 | var height = baseImg?.size.height ?? 0
28 | if width != self.frame.size.width {
29 | width = self.frame.size.width
30 | }
31 | height = (baseImg?.size.height ?? 0)! / (baseImg?.size.width ?? 0)! * width
32 | if height < (self.clipperView?.frame.size.height ?? 0)! {
33 | height = (self.clipperView?.frame.size.height ?? 0)!
34 | }
35 | width = (baseImg?.size.width ?? 0)! / (baseImg?.size.height ?? 0)! * height
36 | let img = baseImg?.scaledToSize(newSize: CGSize(width: width, height: height), withScale: false)
37 | self.baseImgView?.image = img
38 | self.baseImgView?.frame = CGRect(x: 0, y: 0, width: (img?.size.width)!, height: (img?.size.height)!)
39 |
40 | correctBackImgView()
41 | }
42 | }
43 | private let minWidth:CGFloat = 60
44 | private var clipperView: UIImageView?
45 |
46 | private lazy var baseImgView: UIImageView? = {
47 | let baseImgView = UIImageView()
48 | self.addSubview(baseImgView)
49 | self.sendSubview(toBack: baseImgView)
50 | return baseImgView
51 | }()
52 | private lazy var fillLayer: CAShapeLayer? = {
53 | let fillLayer = CAShapeLayer()
54 | fillLayer.fillRule = kCAFillRuleEvenOdd
55 | fillLayer.fillColor = UIColor.black.cgColor
56 | fillLayer.opacity = 0.5
57 | self.layer.addSublayer(fillLayer)
58 | return fillLayer
59 | }()
60 | private var panTouch:CGPoint?
61 | private var scaleDistance:CGFloat = 0 //缩放距离
62 |
63 | override init(frame: CGRect) {
64 | super.init(frame: frame)
65 | loadSubViews()
66 | }
67 | //MARK Public
68 | public func clipImg() -> UIImage {
69 | let scale = UIScreen.main.scale * (self.baseImgView?.image?.size.width)!/(self.baseImgView?.frame.size.width)!
70 | let rect = self.convert((self.clipperView?.frame)!, to: self.baseImgView)
71 | let rect2 = CGRect(x: rect.origin.x * scale, y: rect.origin.y * scale, width: rect.size.width * scale, height: rect.size.height * scale)
72 | let cgImg = self.baseImgView?.image?.cgImage?.cropping(to: rect2)
73 | let clippedImg = UIImage.init(cgImage: cgImg!)
74 | return clippedImg
75 | }
76 |
77 | private func loadSubViews() {
78 | self.layer.contentsGravity = kCAGravityResizeAspect
79 | }
80 |
81 | private func setClipperView() {
82 | let kscWidth = UIScreen.main.bounds.size.width
83 | let kscHeight = UIScreen.main.bounds.size.height - 64
84 | var width = kscWidth
85 | var height = kscHeight
86 | if (self.resultImgSize?.width)! > ((self.resultImgSize?.height ?? 0)! / height * width) {
87 | height = kscWidth / (self.resultImgSize?.width ?? 0)! * (self.resultImgSize?.height ?? 0)!
88 | }else{
89 | width = kscHeight / (self.resultImgSize?.height ?? 0)! * (self.resultImgSize?.width ?? 0)!
90 | }
91 | let y = (kscHeight - height)/2
92 | let x = (kscWidth - width)/2
93 | clipperView = UIImageView(frame: CGRect(x: x, y: y, width: width, height: height))
94 | clipperView?.layer.borderColor = UIColor.white.cgColor
95 | clipperView?.layer.borderWidth = 2
96 | self.addSubview(clipperView!)
97 |
98 | correctFillLayer()
99 | }
100 |
101 | //MARK Touches (注意问题::::)
102 | override func touchesBegan(_ touches: Set, with event: UIEvent?) {
103 | let allTouches = event?.allTouches
104 | switch allTouches?.count {
105 | case 1?:
106 | panTouch = allTouches?.first?.location(in: self)
107 | break
108 | default:
109 | break
110 | }
111 | }
112 |
113 | override func touchesMoved(_ touches: Set, with event: UIEvent?) {
114 | self.willChangeValue(forKey: "crop")
115 | let allTouches = event?.allTouches
116 | switch allTouches?.count {
117 | case 1?:
118 | let touchCurrent = allTouches?.first?.location(in: self)
119 | let x = (touchCurrent?.x ?? 0)! - (panTouch?.x ?? 0)!
120 | let y = (touchCurrent?.y ?? 0)! - (panTouch?.y ?? 0)!
121 | switch type {
122 | case .Move:
123 | self.baseImgView?.center = CGPoint(x: (self.baseImgView?.center.x ?? 0)! + x, y: (self.baseImgView?.center.y ?? 0)! + y)
124 | break
125 | case .Stay:
126 | self.clipperView?.center = CGPoint(x: (self.clipperView?.center.x ?? 0)! + x, y: (self.clipperView?.center.y ?? 0)! + y)
127 | break
128 | }
129 | panTouch = touchCurrent
130 | break
131 | case 2?:
132 | switch type {
133 | case .Move:
134 | self.scaleView(self.baseImgView!, touches: (allTouches! as NSSet).allObjects)
135 | break
136 | case .Stay:
137 | self.scaleView(self.clipperView!, touches: (allTouches! as NSSet).allObjects)
138 | break
139 | }
140 | break
141 | default:
142 | break
143 | }
144 | correctFillLayer()
145 | }
146 |
147 | override func touchesEnded(_ touches: Set, with event: UIEvent?) {
148 | switch type {
149 | case .Move:
150 | correctBackImgView()
151 | break
152 | case .Stay:
153 | correctClipperView()
154 | break
155 | }
156 | }
157 |
158 | //MARK Correct
159 | private func correctBackImgView(){
160 | var x = self.baseImgView?.frame.origin.x ?? 0
161 | var y = self.baseImgView?.frame.origin.y ?? 0
162 | var height = self.baseImgView?.frame.size.height ?? 0
163 | var width = self.baseImgView?.frame.size.width ?? 0
164 |
165 | if width < (self.clipperView?.frame.size.width ?? 0)! {
166 | width = (self.clipperView?.frame.size.width ?? 0)!
167 | height = width / (self.baseImgView?.frame.size.width ?? 0)! * height
168 | }
169 | if height < (self.clipperView?.frame.size.height ?? 0)! {
170 | height = (self.clipperView?.frame.size.height ?? 0)!
171 | width = height / (self.baseImgView?.frame.size.height ?? 0)! * width
172 | }
173 |
174 | if x > (self.clipperView?.frame.origin.x ?? 0)! {
175 | x = (self.clipperView?.frame.origin.x ?? 0)!
176 | } else if x < ((self.clipperView?.frame.origin.x ?? 0)! + (self.clipperView?.frame.size.width ?? 0)! - width){
177 | x = (self.clipperView?.frame.origin.x ?? 0)! + (self.clipperView?.frame.size.width ?? 0)! - width
178 | }
179 |
180 | if y > (self.clipperView?.frame.origin.y ?? 0)! {
181 | y = (self.clipperView?.frame.origin.y ?? 0)!
182 | } else if y < (self.clipperView?.frame.origin.y ?? 0)! + (self.clipperView?.frame.size.height ?? 0)! - height {
183 | y = (self.clipperView?.frame.origin.y ?? 0)! + (self.clipperView?.frame.size.height ?? 0)! - height
184 | }
185 |
186 | self.baseImgView?.frame = CGRect(x: x, y: y, width: width, height: height)
187 | }
188 |
189 | private func correctClipperView(){
190 | var width = self.clipperView?.frame.size.width ?? 0
191 | var height:CGFloat = 0.0
192 | if width < minWidth {
193 | width = minWidth
194 | }
195 | if width > UIScreen.main.bounds.size.width {
196 | width = UIScreen.main.bounds.size.width
197 | }
198 | height = width / (self.resultImgSize?.width ?? 0)! * (self.resultImgSize?.height ?? 0)!
199 | var x = self.clipperView?.frame.origin.x ?? 0
200 | var y = self.clipperView?.frame.origin.y ?? 0
201 | if x < (self.baseImgView?.frame.origin.x ?? 0)! {
202 | x = (self.baseImgView?.frame.origin.x ?? 0)!
203 | }
204 | if x > UIScreen.main.bounds.size.width - width {
205 | x = UIScreen.main.bounds.size.width - width
206 | }
207 | if y < (self.baseImgView?.frame.origin.y ?? 0)! {
208 | y = (self.baseImgView?.frame.origin.y ?? 0)!
209 | }
210 | let tempy = (self.baseImgView?.frame.origin.y ?? 0)! + (self.baseImgView?.frame.size.height ?? 0)! - (self.clipperView?.frame.size.height ?? 0)!
211 | if y > tempy{
212 | y = (self.baseImgView?.frame.origin.y ?? 0)! + (self.baseImgView?.frame.size.height ?? 0)! - (self.clipperView?.frame.size.height ?? 0)!
213 | }
214 | self.clipperView?.frame = CGRect(x: x, y: y, width: width, height: height)
215 | correctFillLayer()
216 | }
217 |
218 | private func correctFillLayer() {
219 | let path = UIBezierPath.init(roundedRect: self.bounds, cornerRadius: 0)
220 | let circlePath = UIBezierPath.init(roundedRect: (clipperView?.frame)!, cornerRadius: 0)
221 | path.append(circlePath)
222 | path.usesEvenOddFillRule = true
223 | self.fillLayer?.path = path.cgPath
224 | }
225 |
226 | //MARK Correct
227 | private func scaleView(_ view:UIView,touches:Array){
228 | let touch1 = (touches[0] as AnyObject).location(in: self)
229 | let touch2 = (touches[1] as AnyObject).location(in: self)
230 | let distance = self.distanceBetweenTwoPoints(touch1, toPoint: touch2)
231 | if scaleDistance > 0 {
232 | var imgFrame = view.frame
233 | if distance > scaleDistance + 2{
234 | imgFrame.size.width += 10
235 | scaleDistance = distance
236 | }
237 | if distance < scaleDistance - 2 {
238 | imgFrame.size.width -= 10
239 | scaleDistance = distance
240 | }
241 | if type == .Stay{ //图片不动
242 | imgFrame.size.height = view.frame.size.height * imgFrame.size.width / view.frame.size.width
243 | let mainWidth = UIScreen.main.bounds.size.width
244 | let imgWidth = imgFrame.size.width > mainWidth ? mainWidth : imgFrame.size.width
245 | let imgHeight = imgWidth * (resultImgSize?.height ?? 0) / (resultImgSize?.width == 0 ? 1 : (resultImgSize?.width ?? 1)!)
246 | let addwidth = imgWidth - view.frame.size.width
247 | let addheight = imgHeight - view.frame.size.height
248 | if imgHeight != 0 && imgWidth != 0{
249 | view.frame = CGRect(x:imgFrame.origin.x - addwidth/2.0, y: imgFrame.origin.y - addheight/2.0, width: imgWidth, height: imgHeight)
250 | }
251 | }else{ //图片移动
252 | imgFrame.size.height = view.frame.size.height * imgFrame.size.width / view.frame.size.width
253 | let addwidth = imgFrame.size.width - view.frame.size.width
254 | let addheight = imgFrame.size.height - view.frame.size.height
255 | let cripWidth = imgFrame.size.width - (clipperView?.frame.width ?? 0)
256 | let cripHeight = imgFrame.size.height - (clipperView?.frame.height ?? 0)
257 |
258 | if imgFrame.size.width != 0 && imgFrame.size.height != 0 && cripWidth > -5 && cripHeight > -5 {
259 | view.frame = CGRect(x:imgFrame.origin.x - addwidth/2.0, y: imgFrame.origin.y - addheight/2.0, width: imgFrame.width, height: imgFrame.height)
260 | }
261 | }
262 | }else{
263 | scaleDistance = distance
264 | }
265 | }
266 |
267 | private func distanceBetweenTwoPoints(_ fromPoint:CGPoint,toPoint:CGPoint) -> CGFloat {
268 | let x = toPoint.x - fromPoint.x
269 | let y = toPoint.y - fromPoint.y
270 | return CGFloat(sqrtf(Float(x * x + y * y)))
271 | }
272 |
273 |
274 | required init?(coder aDecoder: NSCoder) {
275 | fatalError("init(coder:) has not been implemented")
276 | }
277 | /*
278 | // Only override draw() if you perform custom drawing.
279 | // An empty implementation adversely affects performance during animation.
280 | override func draw(_ rect: CGRect) {
281 | // Drawing code
282 | }
283 | */
284 | }
285 |
286 | extension UIImage{
287 | func scaledToSize(newSize:CGSize,withScale:Bool) -> UIImage {
288 | var scale:CGFloat = 1
289 | if withScale {
290 | scale = UIScreen.main.scale
291 | }
292 | let mynewSize = CGSize(width: newSize.width * scale, height: newSize.height * scale)
293 | UIGraphicsBeginImageContextWithOptions(mynewSize, false, 0)
294 | self.draw(in: CGRect(origin: CGPoint.zero, size: mynewSize))
295 | let newImage = UIGraphicsGetImageFromCurrentImageContext()
296 | UIGraphicsEndImageContext()
297 | return newImage ?? UIImage()
298 | }
299 | }
300 |
--------------------------------------------------------------------------------
/KiClipperImageDemo/KiClipperImageDemo.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 48;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 4C1D7FF71FBBE88800B86C89 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1D7FF61FBBE88800B86C89 /* AppDelegate.swift */; };
11 | 4C1D7FF91FBBE88800B86C89 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1D7FF81FBBE88800B86C89 /* ViewController.swift */; };
12 | 4C1D7FFC1FBBE88800B86C89 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4C1D7FFA1FBBE88800B86C89 /* Main.storyboard */; };
13 | 4C1D7FFE1FBBE88800B86C89 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4C1D7FFD1FBBE88800B86C89 /* Assets.xcassets */; };
14 | 4C1D80011FBBE88800B86C89 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4C1D7FFF1FBBE88800B86C89 /* LaunchScreen.storyboard */; };
15 | 4C1D800C1FBBE88800B86C89 /* KiClipperImageDemoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1D800B1FBBE88800B86C89 /* KiClipperImageDemoTests.swift */; };
16 | 4C1D80171FBBE88800B86C89 /* KiClipperImageDemoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1D80161FBBE88800B86C89 /* KiClipperImageDemoUITests.swift */; };
17 | 4C1D80331FBBE9EE00B86C89 /* KiClipperView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1D80321FBBE9EE00B86C89 /* KiClipperView.swift */; };
18 | 4C1D80351FBC247B00B86C89 /* KiClipperHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1D80341FBC247B00B86C89 /* KiClipperHelper.swift */; };
19 | 4C1D80391FBC2F6C00B86C89 /* KiImageClipperViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1D80381FBC2F6C00B86C89 /* KiImageClipperViewController.swift */; };
20 | /* End PBXBuildFile section */
21 |
22 | /* Begin PBXContainerItemProxy section */
23 | 4C1D80081FBBE88800B86C89 /* PBXContainerItemProxy */ = {
24 | isa = PBXContainerItemProxy;
25 | containerPortal = 4C1D7FEB1FBBE88700B86C89 /* Project object */;
26 | proxyType = 1;
27 | remoteGlobalIDString = 4C1D7FF21FBBE88800B86C89;
28 | remoteInfo = KiClipperImageDemo;
29 | };
30 | 4C1D80131FBBE88800B86C89 /* PBXContainerItemProxy */ = {
31 | isa = PBXContainerItemProxy;
32 | containerPortal = 4C1D7FEB1FBBE88700B86C89 /* Project object */;
33 | proxyType = 1;
34 | remoteGlobalIDString = 4C1D7FF21FBBE88800B86C89;
35 | remoteInfo = KiClipperImageDemo;
36 | };
37 | /* End PBXContainerItemProxy section */
38 |
39 | /* Begin PBXFileReference section */
40 | 4C1D7FF31FBBE88800B86C89 /* KiClipperImageDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KiClipperImageDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
41 | 4C1D7FF61FBBE88800B86C89 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
42 | 4C1D7FF81FBBE88800B86C89 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
43 | 4C1D7FFB1FBBE88800B86C89 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
44 | 4C1D7FFD1FBBE88800B86C89 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
45 | 4C1D80001FBBE88800B86C89 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
46 | 4C1D80021FBBE88800B86C89 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
47 | 4C1D80071FBBE88800B86C89 /* KiClipperImageDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KiClipperImageDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
48 | 4C1D800B1FBBE88800B86C89 /* KiClipperImageDemoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KiClipperImageDemoTests.swift; sourceTree = ""; };
49 | 4C1D800D1FBBE88800B86C89 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
50 | 4C1D80121FBBE88800B86C89 /* KiClipperImageDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KiClipperImageDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
51 | 4C1D80161FBBE88800B86C89 /* KiClipperImageDemoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KiClipperImageDemoUITests.swift; sourceTree = ""; };
52 | 4C1D80181FBBE88800B86C89 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
53 | 4C1D80321FBBE9EE00B86C89 /* KiClipperView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KiClipperView.swift; sourceTree = ""; };
54 | 4C1D80341FBC247B00B86C89 /* KiClipperHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KiClipperHelper.swift; sourceTree = ""; };
55 | 4C1D80381FBC2F6C00B86C89 /* KiImageClipperViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KiImageClipperViewController.swift; sourceTree = ""; };
56 | /* End PBXFileReference section */
57 |
58 | /* Begin PBXFrameworksBuildPhase section */
59 | 4C1D7FF01FBBE88800B86C89 /* Frameworks */ = {
60 | isa = PBXFrameworksBuildPhase;
61 | buildActionMask = 2147483647;
62 | files = (
63 | );
64 | runOnlyForDeploymentPostprocessing = 0;
65 | };
66 | 4C1D80041FBBE88800B86C89 /* Frameworks */ = {
67 | isa = PBXFrameworksBuildPhase;
68 | buildActionMask = 2147483647;
69 | files = (
70 | );
71 | runOnlyForDeploymentPostprocessing = 0;
72 | };
73 | 4C1D800F1FBBE88800B86C89 /* Frameworks */ = {
74 | isa = PBXFrameworksBuildPhase;
75 | buildActionMask = 2147483647;
76 | files = (
77 | );
78 | runOnlyForDeploymentPostprocessing = 0;
79 | };
80 | /* End PBXFrameworksBuildPhase section */
81 |
82 | /* Begin PBXGroup section */
83 | 4C1D7FEA1FBBE88700B86C89 = {
84 | isa = PBXGroup;
85 | children = (
86 | 4C1D80311FBBE9D800B86C89 /* KiClipperHelper */,
87 | 4C1D7FF51FBBE88800B86C89 /* KiClipperImageDemo */,
88 | 4C1D800A1FBBE88800B86C89 /* KiClipperImageDemoTests */,
89 | 4C1D80151FBBE88800B86C89 /* KiClipperImageDemoUITests */,
90 | 4C1D7FF41FBBE88800B86C89 /* Products */,
91 | );
92 | sourceTree = "";
93 | };
94 | 4C1D7FF41FBBE88800B86C89 /* Products */ = {
95 | isa = PBXGroup;
96 | children = (
97 | 4C1D7FF31FBBE88800B86C89 /* KiClipperImageDemo.app */,
98 | 4C1D80071FBBE88800B86C89 /* KiClipperImageDemoTests.xctest */,
99 | 4C1D80121FBBE88800B86C89 /* KiClipperImageDemoUITests.xctest */,
100 | );
101 | name = Products;
102 | sourceTree = "";
103 | };
104 | 4C1D7FF51FBBE88800B86C89 /* KiClipperImageDemo */ = {
105 | isa = PBXGroup;
106 | children = (
107 | 4C1D7FF61FBBE88800B86C89 /* AppDelegate.swift */,
108 | 4C1D7FF81FBBE88800B86C89 /* ViewController.swift */,
109 | 4C1D7FFA1FBBE88800B86C89 /* Main.storyboard */,
110 | 4C1D7FFD1FBBE88800B86C89 /* Assets.xcassets */,
111 | 4C1D7FFF1FBBE88800B86C89 /* LaunchScreen.storyboard */,
112 | 4C1D80021FBBE88800B86C89 /* Info.plist */,
113 | );
114 | path = KiClipperImageDemo;
115 | sourceTree = "";
116 | };
117 | 4C1D800A1FBBE88800B86C89 /* KiClipperImageDemoTests */ = {
118 | isa = PBXGroup;
119 | children = (
120 | 4C1D800B1FBBE88800B86C89 /* KiClipperImageDemoTests.swift */,
121 | 4C1D800D1FBBE88800B86C89 /* Info.plist */,
122 | );
123 | path = KiClipperImageDemoTests;
124 | sourceTree = "";
125 | };
126 | 4C1D80151FBBE88800B86C89 /* KiClipperImageDemoUITests */ = {
127 | isa = PBXGroup;
128 | children = (
129 | 4C1D80161FBBE88800B86C89 /* KiClipperImageDemoUITests.swift */,
130 | 4C1D80181FBBE88800B86C89 /* Info.plist */,
131 | );
132 | path = KiClipperImageDemoUITests;
133 | sourceTree = "";
134 | };
135 | 4C1D80311FBBE9D800B86C89 /* KiClipperHelper */ = {
136 | isa = PBXGroup;
137 | children = (
138 | 4C1D80321FBBE9EE00B86C89 /* KiClipperView.swift */,
139 | 4C1D80341FBC247B00B86C89 /* KiClipperHelper.swift */,
140 | 4C1D80381FBC2F6C00B86C89 /* KiImageClipperViewController.swift */,
141 | );
142 | path = KiClipperHelper;
143 | sourceTree = "";
144 | };
145 | /* End PBXGroup section */
146 |
147 | /* Begin PBXNativeTarget section */
148 | 4C1D7FF21FBBE88800B86C89 /* KiClipperImageDemo */ = {
149 | isa = PBXNativeTarget;
150 | buildConfigurationList = 4C1D801B1FBBE88800B86C89 /* Build configuration list for PBXNativeTarget "KiClipperImageDemo" */;
151 | buildPhases = (
152 | 4C1D7FEF1FBBE88800B86C89 /* Sources */,
153 | 4C1D7FF01FBBE88800B86C89 /* Frameworks */,
154 | 4C1D7FF11FBBE88800B86C89 /* Resources */,
155 | );
156 | buildRules = (
157 | );
158 | dependencies = (
159 | );
160 | name = KiClipperImageDemo;
161 | productName = KiClipperImageDemo;
162 | productReference = 4C1D7FF31FBBE88800B86C89 /* KiClipperImageDemo.app */;
163 | productType = "com.apple.product-type.application";
164 | };
165 | 4C1D80061FBBE88800B86C89 /* KiClipperImageDemoTests */ = {
166 | isa = PBXNativeTarget;
167 | buildConfigurationList = 4C1D801E1FBBE88800B86C89 /* Build configuration list for PBXNativeTarget "KiClipperImageDemoTests" */;
168 | buildPhases = (
169 | 4C1D80031FBBE88800B86C89 /* Sources */,
170 | 4C1D80041FBBE88800B86C89 /* Frameworks */,
171 | 4C1D80051FBBE88800B86C89 /* Resources */,
172 | );
173 | buildRules = (
174 | );
175 | dependencies = (
176 | 4C1D80091FBBE88800B86C89 /* PBXTargetDependency */,
177 | );
178 | name = KiClipperImageDemoTests;
179 | productName = KiClipperImageDemoTests;
180 | productReference = 4C1D80071FBBE88800B86C89 /* KiClipperImageDemoTests.xctest */;
181 | productType = "com.apple.product-type.bundle.unit-test";
182 | };
183 | 4C1D80111FBBE88800B86C89 /* KiClipperImageDemoUITests */ = {
184 | isa = PBXNativeTarget;
185 | buildConfigurationList = 4C1D80211FBBE88800B86C89 /* Build configuration list for PBXNativeTarget "KiClipperImageDemoUITests" */;
186 | buildPhases = (
187 | 4C1D800E1FBBE88800B86C89 /* Sources */,
188 | 4C1D800F1FBBE88800B86C89 /* Frameworks */,
189 | 4C1D80101FBBE88800B86C89 /* Resources */,
190 | );
191 | buildRules = (
192 | );
193 | dependencies = (
194 | 4C1D80141FBBE88800B86C89 /* PBXTargetDependency */,
195 | );
196 | name = KiClipperImageDemoUITests;
197 | productName = KiClipperImageDemoUITests;
198 | productReference = 4C1D80121FBBE88800B86C89 /* KiClipperImageDemoUITests.xctest */;
199 | productType = "com.apple.product-type.bundle.ui-testing";
200 | };
201 | /* End PBXNativeTarget section */
202 |
203 | /* Begin PBXProject section */
204 | 4C1D7FEB1FBBE88700B86C89 /* Project object */ = {
205 | isa = PBXProject;
206 | attributes = {
207 | LastSwiftUpdateCheck = 0900;
208 | LastUpgradeCheck = 0900;
209 | ORGANIZATIONNAME = "panda誌";
210 | TargetAttributes = {
211 | 4C1D7FF21FBBE88800B86C89 = {
212 | CreatedOnToolsVersion = 9.0;
213 | ProvisioningStyle = Automatic;
214 | };
215 | 4C1D80061FBBE88800B86C89 = {
216 | CreatedOnToolsVersion = 9.0;
217 | ProvisioningStyle = Automatic;
218 | TestTargetID = 4C1D7FF21FBBE88800B86C89;
219 | };
220 | 4C1D80111FBBE88800B86C89 = {
221 | CreatedOnToolsVersion = 9.0;
222 | ProvisioningStyle = Automatic;
223 | TestTargetID = 4C1D7FF21FBBE88800B86C89;
224 | };
225 | };
226 | };
227 | buildConfigurationList = 4C1D7FEE1FBBE88700B86C89 /* Build configuration list for PBXProject "KiClipperImageDemo" */;
228 | compatibilityVersion = "Xcode 8.0";
229 | developmentRegion = en;
230 | hasScannedForEncodings = 0;
231 | knownRegions = (
232 | en,
233 | Base,
234 | );
235 | mainGroup = 4C1D7FEA1FBBE88700B86C89;
236 | productRefGroup = 4C1D7FF41FBBE88800B86C89 /* Products */;
237 | projectDirPath = "";
238 | projectRoot = "";
239 | targets = (
240 | 4C1D7FF21FBBE88800B86C89 /* KiClipperImageDemo */,
241 | 4C1D80061FBBE88800B86C89 /* KiClipperImageDemoTests */,
242 | 4C1D80111FBBE88800B86C89 /* KiClipperImageDemoUITests */,
243 | );
244 | };
245 | /* End PBXProject section */
246 |
247 | /* Begin PBXResourcesBuildPhase section */
248 | 4C1D7FF11FBBE88800B86C89 /* Resources */ = {
249 | isa = PBXResourcesBuildPhase;
250 | buildActionMask = 2147483647;
251 | files = (
252 | 4C1D80011FBBE88800B86C89 /* LaunchScreen.storyboard in Resources */,
253 | 4C1D7FFE1FBBE88800B86C89 /* Assets.xcassets in Resources */,
254 | 4C1D7FFC1FBBE88800B86C89 /* Main.storyboard in Resources */,
255 | );
256 | runOnlyForDeploymentPostprocessing = 0;
257 | };
258 | 4C1D80051FBBE88800B86C89 /* Resources */ = {
259 | isa = PBXResourcesBuildPhase;
260 | buildActionMask = 2147483647;
261 | files = (
262 | );
263 | runOnlyForDeploymentPostprocessing = 0;
264 | };
265 | 4C1D80101FBBE88800B86C89 /* Resources */ = {
266 | isa = PBXResourcesBuildPhase;
267 | buildActionMask = 2147483647;
268 | files = (
269 | );
270 | runOnlyForDeploymentPostprocessing = 0;
271 | };
272 | /* End PBXResourcesBuildPhase section */
273 |
274 | /* Begin PBXSourcesBuildPhase section */
275 | 4C1D7FEF1FBBE88800B86C89 /* Sources */ = {
276 | isa = PBXSourcesBuildPhase;
277 | buildActionMask = 2147483647;
278 | files = (
279 | 4C1D7FF91FBBE88800B86C89 /* ViewController.swift in Sources */,
280 | 4C1D7FF71FBBE88800B86C89 /* AppDelegate.swift in Sources */,
281 | 4C1D80391FBC2F6C00B86C89 /* KiImageClipperViewController.swift in Sources */,
282 | 4C1D80331FBBE9EE00B86C89 /* KiClipperView.swift in Sources */,
283 | 4C1D80351FBC247B00B86C89 /* KiClipperHelper.swift in Sources */,
284 | );
285 | runOnlyForDeploymentPostprocessing = 0;
286 | };
287 | 4C1D80031FBBE88800B86C89 /* Sources */ = {
288 | isa = PBXSourcesBuildPhase;
289 | buildActionMask = 2147483647;
290 | files = (
291 | 4C1D800C1FBBE88800B86C89 /* KiClipperImageDemoTests.swift in Sources */,
292 | );
293 | runOnlyForDeploymentPostprocessing = 0;
294 | };
295 | 4C1D800E1FBBE88800B86C89 /* Sources */ = {
296 | isa = PBXSourcesBuildPhase;
297 | buildActionMask = 2147483647;
298 | files = (
299 | 4C1D80171FBBE88800B86C89 /* KiClipperImageDemoUITests.swift in Sources */,
300 | );
301 | runOnlyForDeploymentPostprocessing = 0;
302 | };
303 | /* End PBXSourcesBuildPhase section */
304 |
305 | /* Begin PBXTargetDependency section */
306 | 4C1D80091FBBE88800B86C89 /* PBXTargetDependency */ = {
307 | isa = PBXTargetDependency;
308 | target = 4C1D7FF21FBBE88800B86C89 /* KiClipperImageDemo */;
309 | targetProxy = 4C1D80081FBBE88800B86C89 /* PBXContainerItemProxy */;
310 | };
311 | 4C1D80141FBBE88800B86C89 /* PBXTargetDependency */ = {
312 | isa = PBXTargetDependency;
313 | target = 4C1D7FF21FBBE88800B86C89 /* KiClipperImageDemo */;
314 | targetProxy = 4C1D80131FBBE88800B86C89 /* PBXContainerItemProxy */;
315 | };
316 | /* End PBXTargetDependency section */
317 |
318 | /* Begin PBXVariantGroup section */
319 | 4C1D7FFA1FBBE88800B86C89 /* Main.storyboard */ = {
320 | isa = PBXVariantGroup;
321 | children = (
322 | 4C1D7FFB1FBBE88800B86C89 /* Base */,
323 | );
324 | name = Main.storyboard;
325 | sourceTree = "";
326 | };
327 | 4C1D7FFF1FBBE88800B86C89 /* LaunchScreen.storyboard */ = {
328 | isa = PBXVariantGroup;
329 | children = (
330 | 4C1D80001FBBE88800B86C89 /* Base */,
331 | );
332 | name = LaunchScreen.storyboard;
333 | sourceTree = "";
334 | };
335 | /* End PBXVariantGroup section */
336 |
337 | /* Begin XCBuildConfiguration section */
338 | 4C1D80191FBBE88800B86C89 /* Debug */ = {
339 | isa = XCBuildConfiguration;
340 | buildSettings = {
341 | ALWAYS_SEARCH_USER_PATHS = NO;
342 | CLANG_ANALYZER_NONNULL = YES;
343 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
344 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
345 | CLANG_CXX_LIBRARY = "libc++";
346 | CLANG_ENABLE_MODULES = YES;
347 | CLANG_ENABLE_OBJC_ARC = YES;
348 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
349 | CLANG_WARN_BOOL_CONVERSION = YES;
350 | CLANG_WARN_COMMA = YES;
351 | CLANG_WARN_CONSTANT_CONVERSION = YES;
352 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
353 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
354 | CLANG_WARN_EMPTY_BODY = YES;
355 | CLANG_WARN_ENUM_CONVERSION = YES;
356 | CLANG_WARN_INFINITE_RECURSION = YES;
357 | CLANG_WARN_INT_CONVERSION = YES;
358 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
359 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
360 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
361 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
362 | CLANG_WARN_STRICT_PROTOTYPES = YES;
363 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
364 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
365 | CLANG_WARN_UNREACHABLE_CODE = YES;
366 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
367 | CODE_SIGN_IDENTITY = "iPhone Developer";
368 | COPY_PHASE_STRIP = NO;
369 | DEBUG_INFORMATION_FORMAT = dwarf;
370 | ENABLE_STRICT_OBJC_MSGSEND = YES;
371 | ENABLE_TESTABILITY = YES;
372 | GCC_C_LANGUAGE_STANDARD = gnu11;
373 | GCC_DYNAMIC_NO_PIC = NO;
374 | GCC_NO_COMMON_BLOCKS = YES;
375 | GCC_OPTIMIZATION_LEVEL = 0;
376 | GCC_PREPROCESSOR_DEFINITIONS = (
377 | "DEBUG=1",
378 | "$(inherited)",
379 | );
380 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
381 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
382 | GCC_WARN_UNDECLARED_SELECTOR = YES;
383 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
384 | GCC_WARN_UNUSED_FUNCTION = YES;
385 | GCC_WARN_UNUSED_VARIABLE = YES;
386 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
387 | MTL_ENABLE_DEBUG_INFO = YES;
388 | ONLY_ACTIVE_ARCH = YES;
389 | SDKROOT = iphoneos;
390 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
391 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
392 | };
393 | name = Debug;
394 | };
395 | 4C1D801A1FBBE88800B86C89 /* Release */ = {
396 | isa = XCBuildConfiguration;
397 | buildSettings = {
398 | ALWAYS_SEARCH_USER_PATHS = NO;
399 | CLANG_ANALYZER_NONNULL = YES;
400 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
401 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
402 | CLANG_CXX_LIBRARY = "libc++";
403 | CLANG_ENABLE_MODULES = YES;
404 | CLANG_ENABLE_OBJC_ARC = YES;
405 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
406 | CLANG_WARN_BOOL_CONVERSION = YES;
407 | CLANG_WARN_COMMA = YES;
408 | CLANG_WARN_CONSTANT_CONVERSION = YES;
409 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
410 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
411 | CLANG_WARN_EMPTY_BODY = YES;
412 | CLANG_WARN_ENUM_CONVERSION = YES;
413 | CLANG_WARN_INFINITE_RECURSION = YES;
414 | CLANG_WARN_INT_CONVERSION = YES;
415 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
416 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
417 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
418 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
419 | CLANG_WARN_STRICT_PROTOTYPES = YES;
420 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
421 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
422 | CLANG_WARN_UNREACHABLE_CODE = YES;
423 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
424 | CODE_SIGN_IDENTITY = "iPhone Developer";
425 | COPY_PHASE_STRIP = NO;
426 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
427 | ENABLE_NS_ASSERTIONS = NO;
428 | ENABLE_STRICT_OBJC_MSGSEND = YES;
429 | GCC_C_LANGUAGE_STANDARD = gnu11;
430 | GCC_NO_COMMON_BLOCKS = YES;
431 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
432 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
433 | GCC_WARN_UNDECLARED_SELECTOR = YES;
434 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
435 | GCC_WARN_UNUSED_FUNCTION = YES;
436 | GCC_WARN_UNUSED_VARIABLE = YES;
437 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
438 | MTL_ENABLE_DEBUG_INFO = NO;
439 | SDKROOT = iphoneos;
440 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
441 | VALIDATE_PRODUCT = YES;
442 | };
443 | name = Release;
444 | };
445 | 4C1D801C1FBBE88800B86C89 /* Debug */ = {
446 | isa = XCBuildConfiguration;
447 | buildSettings = {
448 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
449 | CODE_SIGN_STYLE = Automatic;
450 | DEVELOPMENT_TEAM = ZXV6VE2UUN;
451 | INFOPLIST_FILE = KiClipperImageDemo/Info.plist;
452 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
453 | PRODUCT_BUNDLE_IDENTIFIER = XXXXXX.KiClipperImageDemo;
454 | PRODUCT_NAME = "$(TARGET_NAME)";
455 | SWIFT_VERSION = 4.0;
456 | TARGETED_DEVICE_FAMILY = "1,2";
457 | };
458 | name = Debug;
459 | };
460 | 4C1D801D1FBBE88800B86C89 /* Release */ = {
461 | isa = XCBuildConfiguration;
462 | buildSettings = {
463 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
464 | CODE_SIGN_STYLE = Automatic;
465 | DEVELOPMENT_TEAM = ZXV6VE2UUN;
466 | INFOPLIST_FILE = KiClipperImageDemo/Info.plist;
467 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
468 | PRODUCT_BUNDLE_IDENTIFIER = XXXXXX.KiClipperImageDemo;
469 | PRODUCT_NAME = "$(TARGET_NAME)";
470 | SWIFT_VERSION = 4.0;
471 | TARGETED_DEVICE_FAMILY = "1,2";
472 | };
473 | name = Release;
474 | };
475 | 4C1D801F1FBBE88800B86C89 /* Debug */ = {
476 | isa = XCBuildConfiguration;
477 | buildSettings = {
478 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
479 | BUNDLE_LOADER = "$(TEST_HOST)";
480 | CODE_SIGN_STYLE = Automatic;
481 | DEVELOPMENT_TEAM = 7R27LC3TJ9;
482 | INFOPLIST_FILE = KiClipperImageDemoTests/Info.plist;
483 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
484 | PRODUCT_BUNDLE_IDENTIFIER = XXXXXX.KiClipperImageDemoTests;
485 | PRODUCT_NAME = "$(TARGET_NAME)";
486 | SWIFT_VERSION = 4.0;
487 | TARGETED_DEVICE_FAMILY = "1,2";
488 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/KiClipperImageDemo.app/KiClipperImageDemo";
489 | };
490 | name = Debug;
491 | };
492 | 4C1D80201FBBE88800B86C89 /* Release */ = {
493 | isa = XCBuildConfiguration;
494 | buildSettings = {
495 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
496 | BUNDLE_LOADER = "$(TEST_HOST)";
497 | CODE_SIGN_STYLE = Automatic;
498 | DEVELOPMENT_TEAM = 7R27LC3TJ9;
499 | INFOPLIST_FILE = KiClipperImageDemoTests/Info.plist;
500 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
501 | PRODUCT_BUNDLE_IDENTIFIER = XXXXXX.KiClipperImageDemoTests;
502 | PRODUCT_NAME = "$(TARGET_NAME)";
503 | SWIFT_VERSION = 4.0;
504 | TARGETED_DEVICE_FAMILY = "1,2";
505 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/KiClipperImageDemo.app/KiClipperImageDemo";
506 | };
507 | name = Release;
508 | };
509 | 4C1D80221FBBE88800B86C89 /* Debug */ = {
510 | isa = XCBuildConfiguration;
511 | buildSettings = {
512 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
513 | CODE_SIGN_STYLE = Automatic;
514 | DEVELOPMENT_TEAM = 7R27LC3TJ9;
515 | INFOPLIST_FILE = KiClipperImageDemoUITests/Info.plist;
516 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
517 | PRODUCT_BUNDLE_IDENTIFIER = XXXXXX.KiClipperImageDemoUITests;
518 | PRODUCT_NAME = "$(TARGET_NAME)";
519 | SWIFT_VERSION = 4.0;
520 | TARGETED_DEVICE_FAMILY = "1,2";
521 | TEST_TARGET_NAME = KiClipperImageDemo;
522 | };
523 | name = Debug;
524 | };
525 | 4C1D80231FBBE88800B86C89 /* Release */ = {
526 | isa = XCBuildConfiguration;
527 | buildSettings = {
528 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
529 | CODE_SIGN_STYLE = Automatic;
530 | DEVELOPMENT_TEAM = 7R27LC3TJ9;
531 | INFOPLIST_FILE = KiClipperImageDemoUITests/Info.plist;
532 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
533 | PRODUCT_BUNDLE_IDENTIFIER = XXXXXX.KiClipperImageDemoUITests;
534 | PRODUCT_NAME = "$(TARGET_NAME)";
535 | SWIFT_VERSION = 4.0;
536 | TARGETED_DEVICE_FAMILY = "1,2";
537 | TEST_TARGET_NAME = KiClipperImageDemo;
538 | };
539 | name = Release;
540 | };
541 | /* End XCBuildConfiguration section */
542 |
543 | /* Begin XCConfigurationList section */
544 | 4C1D7FEE1FBBE88700B86C89 /* Build configuration list for PBXProject "KiClipperImageDemo" */ = {
545 | isa = XCConfigurationList;
546 | buildConfigurations = (
547 | 4C1D80191FBBE88800B86C89 /* Debug */,
548 | 4C1D801A1FBBE88800B86C89 /* Release */,
549 | );
550 | defaultConfigurationIsVisible = 0;
551 | defaultConfigurationName = Release;
552 | };
553 | 4C1D801B1FBBE88800B86C89 /* Build configuration list for PBXNativeTarget "KiClipperImageDemo" */ = {
554 | isa = XCConfigurationList;
555 | buildConfigurations = (
556 | 4C1D801C1FBBE88800B86C89 /* Debug */,
557 | 4C1D801D1FBBE88800B86C89 /* Release */,
558 | );
559 | defaultConfigurationIsVisible = 0;
560 | defaultConfigurationName = Release;
561 | };
562 | 4C1D801E1FBBE88800B86C89 /* Build configuration list for PBXNativeTarget "KiClipperImageDemoTests" */ = {
563 | isa = XCConfigurationList;
564 | buildConfigurations = (
565 | 4C1D801F1FBBE88800B86C89 /* Debug */,
566 | 4C1D80201FBBE88800B86C89 /* Release */,
567 | );
568 | defaultConfigurationIsVisible = 0;
569 | defaultConfigurationName = Release;
570 | };
571 | 4C1D80211FBBE88800B86C89 /* Build configuration list for PBXNativeTarget "KiClipperImageDemoUITests" */ = {
572 | isa = XCConfigurationList;
573 | buildConfigurations = (
574 | 4C1D80221FBBE88800B86C89 /* Debug */,
575 | 4C1D80231FBBE88800B86C89 /* Release */,
576 | );
577 | defaultConfigurationIsVisible = 0;
578 | defaultConfigurationName = Release;
579 | };
580 | /* End XCConfigurationList section */
581 | };
582 | rootObject = 4C1D7FEB1FBBE88700B86C89 /* Project object */;
583 | }
584 |
--------------------------------------------------------------------------------