├── WXProgressWindow
├── Demo
│ ├── demo.gif
│ ├── progressWindow.png
│ ├── ViewController.swift
│ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Info.plist
│ ├── TestNoNavViewController.swift
│ ├── TestViewController.swift
│ ├── AppDelegate.swift
│ ├── LaunchScreen.storyboard
│ └── Base.lproj
│ │ └── Main.storyboard
└── WXProgressWindow
│ ├── Extensions.swift
│ ├── WXProgressCircleTransition.swift
│ ├── WXProgressWindowManager.swift
│ └── WXProgressViewController.swift
├── WXProgressWindow.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
├── xcuserdata
│ └── luo.xcuserdatad
│ │ ├── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── WXProgressWindow.xcscheme
│ │ └── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
└── project.pbxproj
└── README.md
/WXProgressWindow/Demo/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luowenxing/WXProgressWindow/HEAD/WXProgressWindow/Demo/demo.gif
--------------------------------------------------------------------------------
/WXProgressWindow/Demo/progressWindow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luowenxing/WXProgressWindow/HEAD/WXProgressWindow/Demo/progressWindow.png
--------------------------------------------------------------------------------
/WXProgressWindow.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/WXProgressWindow.xcodeproj/xcuserdata/luo.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | WXProgressWindow.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | B175CDD81D3795CA009B5D52
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/WXProgressWindow/Demo/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // WXProgressWindow
4 | //
5 | // Created by Luo on 7/14/16.
6 | // Copyright © 2016 Luo. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | self.view.backgroundColor = UIColor.lightGrayColor()
15 | super.viewDidLoad()
16 | // Do any additional setup after loading the view, typically from a nib.
17 | }
18 |
19 | override func didReceiveMemoryWarning() {
20 | super.didReceiveMemoryWarning()
21 | // Dispose of any resources that can be recreated.
22 | }
23 |
24 | @IBAction func btnPresentTouch(sender: AnyObject) {
25 | let sb = UIStoryboard(name: "Main", bundle: nil)
26 | let vc = sb.instantiateViewControllerWithIdentifier("TestViewController")
27 | let nc = UINavigationController(rootViewController: vc)
28 | self.presentViewController(nc, animated: true, completion: nil)
29 |
30 | }
31 | @IBAction func btnPresentNoNavTouch(sender: AnyObject) {
32 |
33 | let sb = UIStoryboard(name: "Main", bundle: nil)
34 | let vc = sb.instantiateViewControllerWithIdentifier("TestNoNavViewController")
35 | self.presentViewController(vc, animated: true, completion: nil)
36 | }
37 |
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/WXProgressWindow/Demo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/WXProgressWindow/WXProgressWindow/Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // extensions.swift
3 | // WXProgressWindow
4 | //
5 | // Created by Luo on 7/14/16.
6 | // Copyright © 2016 Luo. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIScreen {
12 | var compatibleBounds:CGRect{//iOS7 mainScreen bounds 不随设备旋转
13 | var rect = self.bounds
14 | if NSFoundationVersionNumber < NSFoundationVersionNumber_iOS_8_0 {
15 | let orientation = UIApplication.sharedApplication().statusBarOrientation
16 | if orientation.isLandscape{
17 | rect.size.width = self.bounds.height
18 | rect.size.height = self.bounds.width
19 | }
20 | }
21 | return rect
22 | }
23 | }
24 |
25 | extension UIColor {
26 | class func hexColor(hex:String) -> UIColor {
27 | var cString:String = hex.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet() as NSCharacterSet).uppercaseString
28 |
29 | if (cString.hasPrefix("#")) {
30 | cString = cString.substringFromIndex(cString.startIndex.advancedBy(1))
31 | }
32 |
33 | if ((cString.characters.count) != 6) {
34 | return UIColor.grayColor()
35 | }
36 |
37 | var rgbValue:UInt32 = 0
38 | NSScanner(string: cString).scanHexInt(&rgbValue)
39 |
40 | return UIColor(
41 | red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
42 | green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
43 | blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
44 | alpha: CGFloat(1.0)
45 | )
46 | }
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/WXProgressWindow/Demo/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 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WXProgressWindow
2 | A progress window hide presented view controller of background work with progress(e.g. download),and return to view controller by tap.The progress window also can be dragged to place in somewhere else.
3 |
4 | # Demo
5 | 
6 |
7 | 
8 |
9 | # Installation
10 | There is no other dependecy in it.Just add WXProgressWindow folder to your project.
11 |
12 | # Usage
13 | * Implement delegate method.
14 | ```
15 | @objc protocol WXProgressWindowManagerDelegate:NSObjectProtocol {
16 | func currentProgress() -> Float
17 | optional func currentProgressText() -> String?
18 | }
19 | ```
20 | * Init `WXProgressWindowManager` in view controller to present.
21 | ```
22 | private lazy var progressManager:WXProgressWindowManager = {
23 | //Pass self.navigationController! to rootViewController if your view controller is wrapped in a navigationController.
24 | let manager = WXProgressWindowManager(rootViewController: self, delegate: self)
25 | //manager.arcColor = UIColor.redColor()
26 | //manager.cycleColor = UIColor.grayColor()
27 | //manager.fontSize = 13
28 | //manager.progressRect = CGRect(x: UIScreen.mainScreen().compatibleBounds.width - 50 - 100, y: 20, width: 50, height: 50)
29 | return manager
30 | }()
31 | ```
32 | * Call instance function `showProgressWindow()` to hide your view controller and show the progress window.
33 | * Call instance function `dismissProgressWindow()` to dismiss your view controller and destory progress window.
34 |
35 | # Detail
36 | http://www.jianshu.com/p/34701b334ed7
37 |
38 |
--------------------------------------------------------------------------------
/WXProgressWindow/Demo/TestNoNavViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestNoNavViewController.swift
3 | // WXProgressWindow
4 | //
5 | // Created by Luo on 7/14/16.
6 | // Copyright © 2016 Luo. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class TestNoNavViewController:UIViewController,WXProgressWindowManagerDelegate {
12 |
13 | private var timer:NSTimer!
14 | @IBOutlet weak var labelProgress: UILabel!
15 | @IBOutlet weak var progress: UIProgressView!
16 |
17 | override func viewDidLoad() {
18 | self.progress.progress = 0
19 | }
20 |
21 | func updateProgress() {
22 | if self.progress.progress < 1 {
23 | self.progress.progress += 0.01
24 | self.labelProgress.text = "\(Int(self.progress.progress * 100))%"
25 | } else {
26 | self.timer.invalidate()
27 | }
28 | }
29 |
30 | @IBAction func btnStartTouch(sender: AnyObject) {
31 | self.timer = NSTimer(timeInterval: 0.1, target: self, selector: #selector(TestViewController.updateProgress), userInfo: nil, repeats: true)
32 | NSRunLoop.currentRunLoop().addTimer(self.timer, forMode: NSDefaultRunLoopMode)
33 | }
34 |
35 |
36 |
37 | //MARK:ProgressWindowManager
38 | private lazy var progressManager:WXProgressWindowManager! = WXProgressWindowManager(rootViewController: self, delegate:self)
39 |
40 | func currentProgress() -> Float {
41 | return progress.progress
42 | }
43 |
44 | @IBAction func btnHideTouch(sender: AnyObject) {
45 | self.progressManager.showProgressView()
46 | }
47 |
48 | @IBAction func btnCancelTouch(sender: AnyObject) {
49 | self.progressManager.dismissProgressView()
50 | }
51 |
52 | }
--------------------------------------------------------------------------------
/WXProgressWindow/Demo/TestViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestViewController.swift
3 | // WXProgressWindow
4 | //
5 | // Created by Luo on 7/14/16.
6 | // Copyright © 2016 Luo. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class TestViewController:UIViewController,WXProgressWindowManagerDelegate {
12 |
13 | private var timer:NSTimer!
14 | @IBOutlet weak var labelProgress: UILabel!
15 | @IBOutlet weak var progress: UIProgressView!
16 |
17 | override func viewDidLoad() {
18 | self.progress.progress = 0
19 | }
20 |
21 | func updateProgress() {
22 | if self.progress.progress < 1 {
23 | self.progress.progress += 0.01
24 | self.labelProgress.text = "\(Int(self.progress.progress * 100))%"
25 | } else {
26 | self.timer.invalidate()
27 | }
28 | }
29 |
30 | @IBAction func btnStartTouch(sender: AnyObject) {
31 | self.timer = NSTimer(timeInterval: 0.1, target: self, selector: #selector(TestViewController.updateProgress), userInfo: nil, repeats: true)
32 | NSRunLoop.currentRunLoop().addTimer(self.timer, forMode: NSDefaultRunLoopMode)
33 | }
34 |
35 |
36 |
37 | //MARK:ProgressWindowManager
38 |
39 | private lazy var progressManager:WXProgressWindowManager = WXProgressWindowManager(rootViewController: self.navigationController!, delegate: self)
40 |
41 | @IBAction func btnHideTouch(sender: AnyObject) {
42 | self.progressManager.showProgressView()
43 | }
44 |
45 | @IBAction func btnCancelTouch(sender: AnyObject) {
46 | self.progressManager.dismissProgressView()
47 | }
48 |
49 | func currentProgress() -> Float {
50 | return progress.progress
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/WXProgressWindow/Demo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // WXProgressWindow
4 | //
5 | // Created by Luo on 7/14/16.
6 | // Copyright © 2016 Luo. 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 |
--------------------------------------------------------------------------------
/WXProgressWindow.xcodeproj/xcuserdata/luo.xcuserdatad/xcschemes/WXProgressWindow.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/WXProgressWindow/Demo/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
27 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/WXProgressWindow/WXProgressWindow/WXProgressCircleTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProgressWindowTransition.swift
3 | // WXProgressWindow
4 | //
5 | // Created by Luo on 7/14/16.
6 | // Copyright © 2016 Luo. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 |
12 | enum WXProgressCircleTransitionType {
13 | case Present
14 | case Dismiss
15 | }
16 |
17 | class WXProgressCircleTransition:NSObject,UIViewControllerAnimatedTransitioning {
18 |
19 | var type:WXProgressCircleTransitionType
20 |
21 | init(type:WXProgressCircleTransitionType) {
22 | self.type = type
23 | }
24 |
25 | func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
26 | if self.type == .Present {
27 | self.animateTransitionPresent(transitionContext)
28 | } else {
29 | self.animateTransitionDismiss(transitionContext)
30 | }
31 | }
32 |
33 | func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
34 | return 0.35
35 | }
36 |
37 | func animationEnded(transitionCompleted: Bool) {
38 |
39 | }
40 |
41 | private func animateTransitionPresent(transitionContext: UIViewControllerContextTransitioning) {
42 | guard let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey),toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) as? WXProgressViewController else {
43 | return
44 | }
45 | if let containerView = transitionContext.containerView() {
46 | containerView.addSubview(fromVC.view)
47 | let x = max(toVC.progressRect.origin.x,containerView.frame.size.width - toVC.progressRect.origin.x)
48 | let y = max(toVC.progressRect.origin.y,containerView.frame.size.height - toVC.progressRect.origin.y)
49 | let radius = sqrt(x*x + y*y)
50 | let startCycle = UIBezierPath(arcCenter: containerView.center, radius: radius, startAngle: 0, endAngle: CGFloat(M_PI * 2), clockwise:true)
51 | let endCycle = UIBezierPath(ovalInRect: toVC.progressRect)
52 |
53 | let maskLayer = CAShapeLayer()
54 | maskLayer.path = startCycle.CGPath
55 | fromVC.view.layer.mask = maskLayer
56 |
57 | let maskAnimation = CABasicAnimation(keyPath: "path")
58 | maskAnimation.delegate = self
59 | maskAnimation.fromValue = startCycle.CGPath
60 | maskAnimation.toValue = endCycle.CGPath
61 | maskAnimation.duration = self.transitionDuration(transitionContext)
62 | maskAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
63 | maskAnimation.setValue(transitionContext, forKey: "transitionContext")
64 | maskAnimation.setValue(fromVC.view, forKey: "maskedView")
65 | maskAnimation.fillMode = kCAFillModeForwards
66 | maskAnimation.removedOnCompletion = false
67 | maskLayer.addAnimation(maskAnimation, forKey: "path")
68 |
69 | }
70 | }
71 |
72 | private func animateTransitionDismiss(transitionContext: UIViewControllerContextTransitioning) {
73 | guard let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) as? WXProgressViewController,toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) else {
74 | return
75 | }
76 | if let containerView = transitionContext.containerView() {
77 | fromVC.view.removeFromSuperview()
78 | containerView.addSubview(toVC.view)
79 | let x = max(fromVC.progressRect.origin.x,containerView.frame.size.width - fromVC.progressRect.origin.x)
80 | let y = max(fromVC.progressRect.origin.y,containerView.frame.size.height - fromVC.progressRect.origin.y)
81 | let radius = sqrt(x*x + y*y)
82 | let endCycle = UIBezierPath(arcCenter: containerView.center, radius: radius, startAngle: 0, endAngle: CGFloat(M_PI * 2), clockwise:true)
83 | let startCycle = UIBezierPath(ovalInRect: fromVC.progressRect)
84 |
85 | let maskLayer = CAShapeLayer()
86 | maskLayer.path = startCycle.CGPath
87 | toVC.view.layer.mask = maskLayer
88 |
89 | let maskAnimation = CABasicAnimation(keyPath: "path")
90 | maskAnimation.delegate = self
91 | maskAnimation.fromValue = startCycle.CGPath
92 | maskAnimation.toValue = endCycle.CGPath
93 | maskAnimation.duration = self.transitionDuration(transitionContext)
94 | maskAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
95 | maskAnimation.setValue(transitionContext, forKey: "transitionContext")
96 | maskAnimation.setValue(toVC.view, forKey: "maskedView")
97 | maskAnimation.fillMode = kCAFillModeForwards
98 | maskAnimation.removedOnCompletion = false
99 | maskLayer.addAnimation(maskAnimation, forKey: "path")
100 |
101 | }
102 |
103 | }
104 |
105 | override func animationDidStop(anim: CAAnimation, finished flag: Bool) {
106 | if let context = anim.valueForKey("transitionContext") as? UIViewControllerContextTransitioning,maskedView = anim.valueForKey("maskedView") as? UIView {
107 | context.completeTransition(true)
108 | maskedView.layer.mask = nil
109 | }
110 | }
111 | }
112 |
113 |
--------------------------------------------------------------------------------
/WXProgressWindow/WXProgressWindow/WXProgressWindowManager.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProgressWindow.swift
3 | // WXProgressWindow
4 | //
5 | // Created by Luo on 7/14/16.
6 | // Copyright © 2016 Luo. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | enum WXProgressWindowStatus {
12 | case InitialView
13 | case RootView
14 | case ProgressView
15 |
16 | }
17 |
18 | class WXProgressWindow:UIWindow {
19 | weak var manager:WXProgressWindowManager!
20 | override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
21 | let hitView = super.hitTest(point, withEvent: event)
22 | //显示悬浮窗时,只响应悬浮窗区域的手势事件
23 | if let m = self.manager where m.status == .ProgressView {
24 | if let _ = hitView as? WXProgressView {
25 | return hitView
26 | } else {
27 | return nil
28 | }
29 | }
30 | return hitView
31 | }
32 | }
33 |
34 | @objc protocol WXProgressWindowManagerDelegate:NSObjectProtocol {
35 | func currentProgress() -> Float
36 | optional func currentProgressText() -> String?
37 | }
38 |
39 | class WXProgressWindowManager:NSObject,UIViewControllerTransitioningDelegate,WXProgressViewControllerDelegate {
40 |
41 | deinit {
42 | NSLog("deinit ProgressWindowManager")
43 | }
44 |
45 | var progressRect:CGRect {
46 | get {
47 | return self.progressVC.progressRect
48 | }
49 | set {
50 | self.progressVC.progressRect = newValue
51 | }
52 | }
53 | var cycleColor:UIColor {
54 | get {
55 | return self.progressVC.cycleColor
56 | }
57 | set {
58 | self.progressVC.cycleColor = newValue
59 | }
60 | }
61 | var arcColor:UIColor {
62 | get {
63 | return self.progressVC.arcColor
64 | }
65 | set {
66 | self.progressVC.arcColor = newValue
67 | }
68 | }
69 | var fontSize:CGFloat {
70 | get {
71 | return self.progressVC.fontSize
72 | }
73 | set {
74 | self.progressVC.fontSize = newValue
75 | }
76 | }
77 |
78 | var status:WXProgressWindowStatus = .InitialView
79 | private var prevWindow:UIWindow!
80 | private weak var rootViewController:UIViewController!
81 | private weak var delegate:WXProgressWindowManagerDelegate?
82 | private lazy var progressVC:WXProgressViewController! = WXProgressViewController(delegate: self)
83 | private lazy var snapView:UIView = self.rootViewController.view.snapshotViewAfterScreenUpdates(false)
84 | private lazy var window:WXProgressWindow! = {
85 | let window = WXProgressWindow(frame: UIScreen.mainScreen().bounds)
86 | window.backgroundColor = UIColor.clearColor()
87 | window.layer.masksToBounds = true
88 | window.manager = self
89 | return window
90 | }()
91 |
92 | init(rootViewController:UIViewController,delegate:WXProgressWindowManagerDelegate) {
93 | super.init()
94 | self.rootViewController = rootViewController
95 | self.delegate = delegate
96 | }
97 |
98 | //MARK:界面切换
99 | func showProgressView() {
100 | if self.status == .InitialView {
101 | if self.window.hidden {
102 | // 在window设置rootVC为snapViewVC,防止闪屏
103 | // 使用vc包裹snapView为了使旋转正确。只有vc会处理旋转,view不会。此处也可自行处理旋转后直接window.addSubview
104 | let vc = UIViewController()
105 | vc.view.addSubview(self.snapView)
106 | vc.view.layoutIfNeeded()
107 | self.window.hidden = false
108 | self.window.rootViewController = vc
109 | self.performSelector(#selector(WXProgressWindowManager.showProgressView), withObject: nil, afterDelay: 0)
110 | return
111 | }
112 | self.status = .RootView
113 | self.rootViewController.dismissViewControllerAnimated(false) {
114 | self.window.rootViewController = self.rootViewController
115 | // 防止闪屏
116 | self.performSelector(#selector(WXProgressWindowManager.showProgressView), withObject: nil, afterDelay: 0)
117 | }
118 | }
119 | else if self.status == .RootView{
120 | self.status = .ProgressView
121 | self.progressVC.transitioningDelegate = self
122 | self.rootViewController.transitioningDelegate = self
123 | //设置transitionDelegate后present就有自定义动画效果
124 | self.rootViewController.presentViewController(self.progressVC, animated: true) {
125 | // iOS8以上的bug,present之后又present一个view,这个view不会被加到window上,需要手动添加
126 | self.window.addSubview(self.progressVC.view)
127 | self.progressVC.startCADisplayLink()
128 | }
129 | }
130 | }
131 |
132 | func showRootView() {
133 | progressVC.stopCADisplayLink()
134 | self.status = .RootView
135 | progressVC.dismissViewControllerAnimated(true, completion: nil)
136 | }
137 |
138 | func dismissProgressView(complete:(()->Void)? = nil) {
139 | if self.status == .InitialView {
140 | self.rootViewController.dismissViewControllerAnimated(true, completion: nil)
141 | }
142 | else if self.status == .RootView {
143 | UIView.animateWithDuration(0.35, delay: 0, options: .CurveEaseInOut , animations: {
144 | // 处理iOS7的的window消失动画,因为iOS7的bounds不随系统旋转而改变
145 | if NSFoundationVersionNumber < NSFoundationVersionNumber_iOS_8_0 {
146 | if self.rootViewController.interfaceOrientation.isPortrait {
147 | self.window.frame.origin.y = UIScreen.mainScreen().bounds.height
148 | } else {
149 | self.window.frame.origin.x = -UIScreen.mainScreen().bounds.width
150 | }
151 | } else {
152 | self.window.frame.origin.y = UIScreen.mainScreen().bounds.height
153 | }
154 | }) {
155 | _ in
156 | self.window.hidden = true
157 | self.window.rootViewController = nil
158 | }
159 | } else {
160 | self.window.hidden = true
161 | self.progressVC.stopCADisplayLink()
162 | self.progressVC.dismissViewControllerAnimated(false) {
163 | self.window.rootViewController = nil
164 | self.window = nil
165 | }
166 | }
167 | }
168 |
169 | //MARK:ProgressViewControllerDelegate
170 | func getProgress() -> Float {
171 | if let delegate = self.delegate {
172 | return delegate.currentProgress()
173 | }
174 | return 0
175 | }
176 |
177 | func getProgressText() -> String? {
178 | if let delegate = self.delegate {
179 | return delegate.currentProgressText?()
180 | }
181 | return nil
182 | }
183 |
184 | //MARK:UIViewControllerTransitioningDelegate
185 | func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
186 | return WXProgressCircleTransition(type: .Dismiss)
187 | }
188 |
189 | func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
190 | return WXProgressCircleTransition(type: .Present)
191 | }
192 |
193 | }
194 |
--------------------------------------------------------------------------------
/WXProgressWindow/WXProgressWindow/WXProgressViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProgressWindowController.swift
3 | // CMBMobile
4 | //
5 | // Created by Luo on 7/11/16.
6 | // Copyright © 2016 Yst-WHB. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class WXProgressView:UIView {
13 |
14 | }
15 |
16 | protocol WXProgressViewControllerDelegate:NSObjectProtocol {
17 | func getProgress() -> Float
18 | func getProgressText() -> String?
19 | func showRootView()
20 | }
21 |
22 | class WXProgressViewController:UIViewController {
23 |
24 | weak var delegate: WXProgressViewControllerDelegate?
25 | init(delegate:WXProgressViewControllerDelegate) {
26 | self.delegate = delegate
27 | super.init(nibName: nil, bundle: nil)
28 | }
29 |
30 | required init?(coder aDecoder: NSCoder) {
31 | super.init(coder: aDecoder)
32 | }
33 |
34 | var progressRect:CGRect = CGRect(x: UIScreen.mainScreen().compatibleBounds.width - 50 - 100, y: 20, width: 50, height: 50)
35 | var cycleColor:UIColor = UIColor.hexColor("#AFD8FB")
36 | var arcColor:UIColor = UIColor.hexColor("#1F7FEC")
37 | lazy var fontSize:CGFloat = self.progressRect.size.width / 8.0 * 3.0
38 |
39 | private lazy var progressView:WXProgressView = WXProgressView()
40 | private lazy var progressLabel = UILabel()
41 | private lazy var circleLayer:CAShapeLayer! = self.getCycleLayer(self.cycleColor, startAngle: 0, endAngle: CGFloat(M_PI * 2))
42 | private lazy var arcLayer:CAShapeLayer! = self.getCycleLayer(self.arcColor, startAngle: -CGFloat(M_PI_2), endAngle: -CGFloat(M_PI_2))
43 | private var displayLink:CADisplayLink!
44 |
45 | override func viewDidLayoutSubviews() {
46 | super.viewDidLayoutSubviews()
47 | self.circleLayer.frame = self.progressView.bounds
48 | }
49 |
50 |
51 | override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
52 | if self.interfaceOrientation.isPortrait != toInterfaceOrientation.isPortrait {
53 | let size = self.view.frame.size
54 | self.resetProgressViewFrameOnRotate(size.height, toHeight: size.width)
55 | }
56 | }
57 |
58 | // 处理iOS7旋转bug
59 | override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
60 | let size = self.view.frame.size
61 | self.resetProgressViewFrameOnRotate(size.width, toHeight: size.height)
62 | }
63 |
64 |
65 | override func viewDidLoad() {
66 | super.viewDidLoad()
67 | self.view.backgroundColor = UIColor.clearColor()
68 |
69 | self.progressView.frame = self.progressRect
70 | self.progressView.backgroundColor = UIColor.whiteColor()
71 | self.progressView.layer.cornerRadius = self.progressRect.width / 2.0
72 | self.view.addSubview(progressView)
73 |
74 | let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(WXProgressViewController.onTap))
75 | let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(WXProgressViewController.onPan))
76 | self.progressView.addGestureRecognizer(tapRecognizer)
77 | self.progressView.addGestureRecognizer(panRecognizer)
78 |
79 | self.progressLabel.translatesAutoresizingMaskIntoConstraints = false
80 | self.progressLabel.text = "0"
81 | self.progressLabel.textColor = arcColor
82 | self.progressLabel.font = UIFont.boldSystemFontOfSize(fontSize)
83 | self.progressView.addSubview(self.progressLabel)
84 | let constraintX = NSLayoutConstraint(item: progressLabel, attribute: .CenterX, relatedBy: .Equal, toItem: self.progressView, attribute: .CenterX, multiplier: 1, constant: 0)
85 | let constraintY = NSLayoutConstraint(item: progressLabel, attribute: .CenterY, relatedBy: .Equal, toItem: self.progressView, attribute: .CenterY, multiplier: 1, constant: 0)
86 | self.progressView.addConstraints([constraintX,constraintY])
87 |
88 | self.progressView.layer.addSublayer(self.circleLayer)
89 | self.progressView.layer.addSublayer(self.arcLayer)
90 |
91 | }
92 |
93 | func startCADisplayLink() {
94 | self.displayLink = CADisplayLink(target: self, selector: #selector(WXProgressViewController.updateProgressView))
95 | self.displayLink.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)
96 | }
97 |
98 | func stopCADisplayLink() {
99 | self.displayLink?.invalidate()
100 | self.displayLink = nil
101 | }
102 |
103 | func updateProgressView() {
104 | if let delegate = self.delegate {
105 | let progress = CGFloat(delegate.getProgress())
106 | self.arcLayer.path = self.getLayerPath(-CGFloat(M_PI_2), endAngle: CGFloat(M_PI) * 2 * progress - CGFloat(M_PI_2) )
107 | self.arcLayer.setNeedsDisplay()
108 | if let text = delegate.getProgressText() {
109 | self.progressLabel.text = text
110 | } else {
111 | self.progressLabel.text = String(Int(progress * 100))
112 | }
113 | }
114 | }
115 |
116 | func onTap() {
117 | self.delegate?.showRootView()
118 | }
119 |
120 | func onPan(sender:UIPanGestureRecognizer) {
121 | let point = sender.locationInView(self.view)
122 | // 保证悬浮框在边框范围内
123 | let prevCenter = self.progressView.center
124 | var frame = UIScreen.mainScreen().compatibleBounds
125 | frame.origin.y = 20
126 | frame.size.height -= 20
127 | self.progressView.center = point
128 | if !frame.contains(self.progressView.frame) {
129 | let unionFrame = frame.union(self.progressView.frame)
130 | if unionFrame.width > frame.width {
131 | self.progressView.center.x = prevCenter.x
132 | }
133 | if unionFrame.height > frame.height {
134 | self.progressView.center.y = prevCenter.y
135 | }
136 | }
137 | self.progressRect = self.progressView.frame
138 | }
139 |
140 | private func getLayerPath(startAngle:CGFloat,endAngle:CGFloat) -> CGPath {
141 | let width = self.progressRect.size.width
142 | let lineWidth:CGFloat = width / 8.0
143 | let radius = (width - lineWidth ) / 2.0
144 | let center = CGPoint(x: width / 2.0, y: width / 2.0)
145 | return UIBezierPath(arcCenter:center , radius: radius, startAngle: startAngle, endAngle:endAngle , clockwise:true).CGPath
146 | }
147 |
148 | private func getCycleLayer(color:UIColor,startAngle:CGFloat,endAngle:CGFloat) -> CAShapeLayer {
149 | let width = self.progressRect.size.width
150 | let lineWidth:CGFloat = width / 8.0
151 | let layer = CAShapeLayer()
152 | layer.strokeColor = color.CGColor
153 | layer.lineCap = "round"
154 | layer.lineWidth = lineWidth
155 | layer.path = self.getLayerPath(startAngle, endAngle: endAngle)
156 | layer.fillColor = UIColor.clearColor().CGColor
157 | return layer
158 | }
159 |
160 | // 处理旋转
161 | private func resetProgressViewFrameOnRotate(toWidth:CGFloat,toHeight:CGFloat) {
162 | let origin = self.progressView.frame.origin
163 | let size = self.progressView.frame.size
164 | if origin.x + size.width > toWidth {
165 | self.progressView.frame.origin.x = toWidth - size.width
166 | }
167 | if origin.y + size.height > toHeight {
168 | self.progressView.frame.origin.y = toHeight - size.height
169 | }
170 | self.progressRect = self.progressView.frame
171 | }
172 | }
173 |
174 |
175 |
176 |
177 |
178 |
--------------------------------------------------------------------------------
/WXProgressWindow.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | B175CDF81D37961D009B5D52 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B175CDEF1D37961D009B5D52 /* AppDelegate.swift */; };
11 | B175CDF91D37961D009B5D52 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B175CDF01D37961D009B5D52 /* Assets.xcassets */; };
12 | B175CDFB1D37961D009B5D52 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B175CDF31D37961D009B5D52 /* Main.storyboard */; };
13 | B175CDFC1D37961D009B5D52 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B175CDF51D37961D009B5D52 /* Info.plist */; };
14 | B175CDFD1D37961D009B5D52 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B175CDF61D37961D009B5D52 /* ViewController.swift */; };
15 | B175CDFF1D379651009B5D52 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B175CDFE1D379651009B5D52 /* LaunchScreen.storyboard */; };
16 | B175CE011D3796F3009B5D52 /* WXProgressViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B175CE001D3796F3009B5D52 /* WXProgressViewController.swift */; };
17 | B175CE031D379735009B5D52 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B175CE021D379735009B5D52 /* Extensions.swift */; };
18 | B175CE051D37A654009B5D52 /* WXProgressWindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B175CE041D37A654009B5D52 /* WXProgressWindowManager.swift */; };
19 | B175CE071D37A6DC009B5D52 /* WXProgressCircleTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = B175CE061D37A6DC009B5D52 /* WXProgressCircleTransition.swift */; };
20 | B175CE091D37A904009B5D52 /* TestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B175CE081D37A904009B5D52 /* TestViewController.swift */; };
21 | B175CE0B1D37BB27009B5D52 /* TestNoNavViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B175CE0A1D37BB27009B5D52 /* TestNoNavViewController.swift */; };
22 | /* End PBXBuildFile section */
23 |
24 | /* Begin PBXFileReference section */
25 | B175CDD91D3795CA009B5D52 /* WXProgressWindow.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WXProgressWindow.app; sourceTree = BUILT_PRODUCTS_DIR; };
26 | B175CDEF1D37961D009B5D52 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
27 | B175CDF01D37961D009B5D52 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
28 | B175CDF41D37961D009B5D52 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
29 | B175CDF51D37961D009B5D52 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
30 | B175CDF61D37961D009B5D52 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
31 | B175CDFE1D379651009B5D52 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; };
32 | B175CE001D3796F3009B5D52 /* WXProgressViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WXProgressViewController.swift; sourceTree = ""; };
33 | B175CE021D379735009B5D52 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; };
34 | B175CE041D37A654009B5D52 /* WXProgressWindowManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WXProgressWindowManager.swift; sourceTree = ""; };
35 | B175CE061D37A6DC009B5D52 /* WXProgressCircleTransition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WXProgressCircleTransition.swift; sourceTree = ""; };
36 | B175CE081D37A904009B5D52 /* TestViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestViewController.swift; sourceTree = ""; };
37 | B175CE0A1D37BB27009B5D52 /* TestNoNavViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNoNavViewController.swift; sourceTree = ""; };
38 | /* End PBXFileReference section */
39 |
40 | /* Begin PBXFrameworksBuildPhase section */
41 | B175CDD61D3795CA009B5D52 /* Frameworks */ = {
42 | isa = PBXFrameworksBuildPhase;
43 | buildActionMask = 2147483647;
44 | files = (
45 | );
46 | runOnlyForDeploymentPostprocessing = 0;
47 | };
48 | /* End PBXFrameworksBuildPhase section */
49 |
50 | /* Begin PBXGroup section */
51 | B175CDD01D3795CA009B5D52 = {
52 | isa = PBXGroup;
53 | children = (
54 | B175CDDB1D3795CB009B5D52 /* WXProgressWindow */,
55 | B175CDDA1D3795CA009B5D52 /* Products */,
56 | );
57 | sourceTree = "";
58 | };
59 | B175CDDA1D3795CA009B5D52 /* Products */ = {
60 | isa = PBXGroup;
61 | children = (
62 | B175CDD91D3795CA009B5D52 /* WXProgressWindow.app */,
63 | );
64 | name = Products;
65 | sourceTree = "";
66 | };
67 | B175CDDB1D3795CB009B5D52 /* WXProgressWindow */ = {
68 | isa = PBXGroup;
69 | children = (
70 | B175CDEE1D37961D009B5D52 /* Demo */,
71 | B175CDF71D37961D009B5D52 /* WXProgressWindow */,
72 | );
73 | path = WXProgressWindow;
74 | sourceTree = "";
75 | };
76 | B175CDEE1D37961D009B5D52 /* Demo */ = {
77 | isa = PBXGroup;
78 | children = (
79 | B175CDEF1D37961D009B5D52 /* AppDelegate.swift */,
80 | B175CDF01D37961D009B5D52 /* Assets.xcassets */,
81 | B175CDF31D37961D009B5D52 /* Main.storyboard */,
82 | B175CDF51D37961D009B5D52 /* Info.plist */,
83 | B175CDF61D37961D009B5D52 /* ViewController.swift */,
84 | B175CDFE1D379651009B5D52 /* LaunchScreen.storyboard */,
85 | B175CE081D37A904009B5D52 /* TestViewController.swift */,
86 | B175CE0A1D37BB27009B5D52 /* TestNoNavViewController.swift */,
87 | );
88 | path = Demo;
89 | sourceTree = "";
90 | };
91 | B175CDF71D37961D009B5D52 /* WXProgressWindow */ = {
92 | isa = PBXGroup;
93 | children = (
94 | B175CE041D37A654009B5D52 /* WXProgressWindowManager.swift */,
95 | B175CE001D3796F3009B5D52 /* WXProgressViewController.swift */,
96 | B175CE061D37A6DC009B5D52 /* WXProgressCircleTransition.swift */,
97 | B175CE021D379735009B5D52 /* Extensions.swift */,
98 | );
99 | path = WXProgressWindow;
100 | sourceTree = "";
101 | };
102 | /* End PBXGroup section */
103 |
104 | /* Begin PBXNativeTarget section */
105 | B175CDD81D3795CA009B5D52 /* WXProgressWindow */ = {
106 | isa = PBXNativeTarget;
107 | buildConfigurationList = B175CDEB1D3795CB009B5D52 /* Build configuration list for PBXNativeTarget "WXProgressWindow" */;
108 | buildPhases = (
109 | B175CDD51D3795CA009B5D52 /* Sources */,
110 | B175CDD61D3795CA009B5D52 /* Frameworks */,
111 | B175CDD71D3795CA009B5D52 /* Resources */,
112 | );
113 | buildRules = (
114 | );
115 | dependencies = (
116 | );
117 | name = WXProgressWindow;
118 | productName = WXProgressWindow;
119 | productReference = B175CDD91D3795CA009B5D52 /* WXProgressWindow.app */;
120 | productType = "com.apple.product-type.application";
121 | };
122 | /* End PBXNativeTarget section */
123 |
124 | /* Begin PBXProject section */
125 | B175CDD11D3795CA009B5D52 /* Project object */ = {
126 | isa = PBXProject;
127 | attributes = {
128 | LastSwiftUpdateCheck = 0730;
129 | LastUpgradeCheck = 0730;
130 | ORGANIZATIONNAME = Luo;
131 | TargetAttributes = {
132 | B175CDD81D3795CA009B5D52 = {
133 | CreatedOnToolsVersion = 7.3;
134 | };
135 | };
136 | };
137 | buildConfigurationList = B175CDD41D3795CA009B5D52 /* Build configuration list for PBXProject "WXProgressWindow" */;
138 | compatibilityVersion = "Xcode 3.2";
139 | developmentRegion = English;
140 | hasScannedForEncodings = 0;
141 | knownRegions = (
142 | en,
143 | Base,
144 | );
145 | mainGroup = B175CDD01D3795CA009B5D52;
146 | productRefGroup = B175CDDA1D3795CA009B5D52 /* Products */;
147 | projectDirPath = "";
148 | projectRoot = "";
149 | targets = (
150 | B175CDD81D3795CA009B5D52 /* WXProgressWindow */,
151 | );
152 | };
153 | /* End PBXProject section */
154 |
155 | /* Begin PBXResourcesBuildPhase section */
156 | B175CDD71D3795CA009B5D52 /* Resources */ = {
157 | isa = PBXResourcesBuildPhase;
158 | buildActionMask = 2147483647;
159 | files = (
160 | B175CDFC1D37961D009B5D52 /* Info.plist in Resources */,
161 | B175CDFB1D37961D009B5D52 /* Main.storyboard in Resources */,
162 | B175CDF91D37961D009B5D52 /* Assets.xcassets in Resources */,
163 | B175CDFF1D379651009B5D52 /* LaunchScreen.storyboard in Resources */,
164 | );
165 | runOnlyForDeploymentPostprocessing = 0;
166 | };
167 | /* End PBXResourcesBuildPhase section */
168 |
169 | /* Begin PBXSourcesBuildPhase section */
170 | B175CDD51D3795CA009B5D52 /* Sources */ = {
171 | isa = PBXSourcesBuildPhase;
172 | buildActionMask = 2147483647;
173 | files = (
174 | B175CE091D37A904009B5D52 /* TestViewController.swift in Sources */,
175 | B175CE0B1D37BB27009B5D52 /* TestNoNavViewController.swift in Sources */,
176 | B175CDFD1D37961D009B5D52 /* ViewController.swift in Sources */,
177 | B175CE071D37A6DC009B5D52 /* WXProgressCircleTransition.swift in Sources */,
178 | B175CE011D3796F3009B5D52 /* WXProgressViewController.swift in Sources */,
179 | B175CDF81D37961D009B5D52 /* AppDelegate.swift in Sources */,
180 | B175CE051D37A654009B5D52 /* WXProgressWindowManager.swift in Sources */,
181 | B175CE031D379735009B5D52 /* Extensions.swift in Sources */,
182 | );
183 | runOnlyForDeploymentPostprocessing = 0;
184 | };
185 | /* End PBXSourcesBuildPhase section */
186 |
187 | /* Begin PBXVariantGroup section */
188 | B175CDF31D37961D009B5D52 /* Main.storyboard */ = {
189 | isa = PBXVariantGroup;
190 | children = (
191 | B175CDF41D37961D009B5D52 /* Base */,
192 | );
193 | name = Main.storyboard;
194 | sourceTree = "";
195 | };
196 | /* End PBXVariantGroup section */
197 |
198 | /* Begin XCBuildConfiguration section */
199 | B175CDE91D3795CB009B5D52 /* Debug */ = {
200 | isa = XCBuildConfiguration;
201 | buildSettings = {
202 | ALWAYS_SEARCH_USER_PATHS = NO;
203 | CLANG_ANALYZER_NONNULL = YES;
204 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
205 | CLANG_CXX_LIBRARY = "libc++";
206 | CLANG_ENABLE_MODULES = YES;
207 | CLANG_ENABLE_OBJC_ARC = YES;
208 | CLANG_WARN_BOOL_CONVERSION = YES;
209 | CLANG_WARN_CONSTANT_CONVERSION = YES;
210 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
211 | CLANG_WARN_EMPTY_BODY = YES;
212 | CLANG_WARN_ENUM_CONVERSION = YES;
213 | CLANG_WARN_INT_CONVERSION = YES;
214 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
215 | CLANG_WARN_UNREACHABLE_CODE = YES;
216 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
217 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
218 | COPY_PHASE_STRIP = NO;
219 | DEBUG_INFORMATION_FORMAT = dwarf;
220 | ENABLE_STRICT_OBJC_MSGSEND = YES;
221 | ENABLE_TESTABILITY = YES;
222 | GCC_C_LANGUAGE_STANDARD = gnu99;
223 | GCC_DYNAMIC_NO_PIC = NO;
224 | GCC_NO_COMMON_BLOCKS = YES;
225 | GCC_OPTIMIZATION_LEVEL = 0;
226 | GCC_PREPROCESSOR_DEFINITIONS = (
227 | "DEBUG=1",
228 | "$(inherited)",
229 | );
230 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
231 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
232 | GCC_WARN_UNDECLARED_SELECTOR = YES;
233 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
234 | GCC_WARN_UNUSED_FUNCTION = YES;
235 | GCC_WARN_UNUSED_VARIABLE = YES;
236 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
237 | MTL_ENABLE_DEBUG_INFO = YES;
238 | ONLY_ACTIVE_ARCH = YES;
239 | SDKROOT = iphoneos;
240 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
241 | TARGETED_DEVICE_FAMILY = "1,2";
242 | };
243 | name = Debug;
244 | };
245 | B175CDEA1D3795CB009B5D52 /* Release */ = {
246 | isa = XCBuildConfiguration;
247 | buildSettings = {
248 | ALWAYS_SEARCH_USER_PATHS = NO;
249 | CLANG_ANALYZER_NONNULL = YES;
250 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
251 | CLANG_CXX_LIBRARY = "libc++";
252 | CLANG_ENABLE_MODULES = YES;
253 | CLANG_ENABLE_OBJC_ARC = YES;
254 | CLANG_WARN_BOOL_CONVERSION = YES;
255 | CLANG_WARN_CONSTANT_CONVERSION = YES;
256 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
257 | CLANG_WARN_EMPTY_BODY = YES;
258 | CLANG_WARN_ENUM_CONVERSION = YES;
259 | CLANG_WARN_INT_CONVERSION = YES;
260 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
261 | CLANG_WARN_UNREACHABLE_CODE = YES;
262 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
263 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
264 | COPY_PHASE_STRIP = NO;
265 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
266 | ENABLE_NS_ASSERTIONS = NO;
267 | ENABLE_STRICT_OBJC_MSGSEND = YES;
268 | GCC_C_LANGUAGE_STANDARD = gnu99;
269 | GCC_NO_COMMON_BLOCKS = YES;
270 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
271 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
272 | GCC_WARN_UNDECLARED_SELECTOR = YES;
273 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
274 | GCC_WARN_UNUSED_FUNCTION = YES;
275 | GCC_WARN_UNUSED_VARIABLE = YES;
276 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
277 | MTL_ENABLE_DEBUG_INFO = NO;
278 | SDKROOT = iphoneos;
279 | TARGETED_DEVICE_FAMILY = "1,2";
280 | VALIDATE_PRODUCT = YES;
281 | };
282 | name = Release;
283 | };
284 | B175CDEC1D3795CB009B5D52 /* Debug */ = {
285 | isa = XCBuildConfiguration;
286 | buildSettings = {
287 | INFOPLIST_FILE = "$(SRCROOT)/WXProgressWindow/Demo/Info.plist";
288 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
289 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
290 | PRODUCT_BUNDLE_IDENTIFIER = com.cmbchina.Test;
291 | PRODUCT_NAME = "$(TARGET_NAME)";
292 | };
293 | name = Debug;
294 | };
295 | B175CDED1D3795CB009B5D52 /* Release */ = {
296 | isa = XCBuildConfiguration;
297 | buildSettings = {
298 | INFOPLIST_FILE = "$(SRCROOT)/WXProgressWindow/Demo/Info.plist";
299 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
300 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
301 | PRODUCT_BUNDLE_IDENTIFIER = com.cmbchina.Test;
302 | PRODUCT_NAME = "$(TARGET_NAME)";
303 | };
304 | name = Release;
305 | };
306 | /* End XCBuildConfiguration section */
307 |
308 | /* Begin XCConfigurationList section */
309 | B175CDD41D3795CA009B5D52 /* Build configuration list for PBXProject "WXProgressWindow" */ = {
310 | isa = XCConfigurationList;
311 | buildConfigurations = (
312 | B175CDE91D3795CB009B5D52 /* Debug */,
313 | B175CDEA1D3795CB009B5D52 /* Release */,
314 | );
315 | defaultConfigurationIsVisible = 0;
316 | defaultConfigurationName = Release;
317 | };
318 | B175CDEB1D3795CB009B5D52 /* Build configuration list for PBXNativeTarget "WXProgressWindow" */ = {
319 | isa = XCConfigurationList;
320 | buildConfigurations = (
321 | B175CDEC1D3795CB009B5D52 /* Debug */,
322 | B175CDED1D3795CB009B5D52 /* Release */,
323 | );
324 | defaultConfigurationIsVisible = 0;
325 | defaultConfigurationName = Release;
326 | };
327 | /* End XCConfigurationList section */
328 | };
329 | rootObject = B175CDD11D3795CA009B5D52 /* Project object */;
330 | }
331 |
--------------------------------------------------------------------------------
/WXProgressWindow/Demo/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 |
28 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
70 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
129 |
135 |
142 |
143 |
144 |
145 |
152 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
--------------------------------------------------------------------------------
/WXProgressWindow.xcodeproj/xcuserdata/luo.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
20 |
21 |
22 |
24 |
36 |
37 |
38 |
40 |
52 |
53 |
54 |
56 |
68 |
69 |
70 |
72 |
84 |
85 |
99 |
100 |
114 |
115 |
116 |
117 |
118 |
120 |
132 |
133 |
134 |
136 |
148 |
149 |
150 |
152 |
164 |
165 |
179 |
180 |
194 |
195 |
196 |
197 |
198 |
200 |
212 |
213 |
214 |
216 |
228 |
229 |
230 |
232 |
244 |
245 |
246 |
248 |
260 |
261 |
262 |
264 |
276 |
277 |
278 |
280 |
292 |
293 |
294 |
296 |
308 |
309 |
323 |
324 |
338 |
339 |
340 |
341 |
342 |
344 |
356 |
357 |
358 |
360 |
372 |
373 |
374 |
376 |
388 |
389 |
390 |
392 |
404 |
405 |
406 |
408 |
420 |
421 |
422 |
424 |
436 |
437 |
438 |
440 |
452 |
453 |
454 |
456 |
468 |
469 |
470 |
472 |
484 |
485 |
486 |
488 |
500 |
501 |
502 |
504 |
516 |
517 |
518 |
520 |
532 |
533 |
534 |
536 |
548 |
549 |
550 |
552 |
564 |
565 |
566 |
568 |
580 |
581 |
582 |
584 |
596 |
597 |
598 |
600 |
612 |
613 |
614 |
616 |
628 |
629 |
630 |
632 |
644 |
645 |
646 |
648 |
660 |
661 |
675 |
676 |
690 |
691 |
692 |
693 |
694 |
696 |
708 |
709 |
723 |
724 |
738 |
739 |
740 |
741 |
742 |
744 |
756 |
757 |
758 |
760 |
772 |
773 |
774 |
776 |
788 |
789 |
790 |
792 |
804 |
805 |
819 |
820 |
834 |
835 |
836 |
837 |
838 |
840 |
852 |
853 |
854 |
856 |
868 |
869 |
870 |
872 |
884 |
885 |
886 |
888 |
900 |
901 |
902 |
904 |
916 |
917 |
918 |
920 |
932 |
933 |
934 |
936 |
948 |
949 |
950 |
952 |
964 |
965 |
966 |
968 |
980 |
981 |
982 |
984 |
996 |
997 |
998 |
1000 |
1012 |
1013 |
1014 |
1016 |
1028 |
1029 |
1030 |
1032 |
1044 |
1045 |
1059 |
1060 |
1074 |
1075 |
1089 |
1090 |
1091 |
1092 |
1093 |
1095 |
1107 |
1108 |
1122 |
1123 |
1137 |
1138 |
1139 |
1140 |
1141 |
1143 |
1155 |
1156 |
1157 |
1159 |
1171 |
1172 |
1173 |
1175 |
1187 |
1188 |
1189 |
1191 |
1203 |
1204 |
1205 |
1207 |
1219 |
1220 |
1221 |
1223 |
1235 |
1236 |
1237 |
1239 |
1251 |
1252 |
1253 |
1255 |
1267 |
1268 |
1269 |
1270 |
1271 |
--------------------------------------------------------------------------------