├── XieFeng
└── README.md
├── ZhouShaoXiang
├── README.md
└── ScaryBugs
│ ├── ScaryBugs
│ ├── logo1.png
│ ├── centipede.jpg
│ ├── ladybug.jpg
│ ├── potatoBug.jpg
│ ├── wolfSpider.jpg
│ ├── centipedeThumb.jpg
│ ├── ladybugThumb.jpg
│ ├── potatoBugThumb.jpg
│ ├── wolfSpiderThumb.jpg
│ ├── shockedface2_empty.png
│ ├── shockedface2_full.png
│ ├── shockedface2_half.png
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── logo1.png
│ │ │ └── Contents.json
│ │ └── LaunchImage.launchimage
│ │ │ ├── iOS Simulator Screen Shot 2014年11月4日 15.44.32.png
│ │ │ ├── iOS Simulator Screen Shot 2014年11月4日 15.44.32-1.png
│ │ │ └── Contents.json
│ ├── iOS Simulator Screen Shot 2014年11月4日 15.44.32.png
│ ├── attribution.txt
│ ├── MasterViewController.h
│ ├── AppDelegate.h
│ ├── RWTUIImageExtras.h
│ ├── main.m
│ ├── DetailViewController.h
│ ├── RWTScaryBugsData.h
│ ├── RWTScaryBugsData.m
│ ├── RWTScaryBugsDoc.h
│ ├── RWTScaryBugsDoc.m
│ ├── RWTRateView.h
│ ├── DetailViewController.m
│ ├── Info.plist
│ ├── AppDelegate.m
│ ├── RWTUIImageExtras.m
│ ├── SVProgressHUD.h
│ ├── MasterViewController.m
│ ├── Base.lproj
│ │ ├── LaunchScreen.xib
│ │ └── Main.storyboard
│ ├── RWTRateView.m
│ └── SVProgressHUD.m
│ ├── ScaryBugs.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── project.pbxproj
│ └── ScaryBugsTests
│ ├── Info.plist
│ └── ScaryBugsTests.m
├── .gitignore
└── README.md
/XieFeng/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/README.md:
--------------------------------------------------------------------------------
1 | ## 周绍祥
2 | 在这保存你的Task代码,提交并Push。
3 | 先试一下单独修改
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/logo1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zekunyan/iOS-Tasks/HEAD/ZhouShaoXiang/ScaryBugs/ScaryBugs/logo1.png
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/centipede.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zekunyan/iOS-Tasks/HEAD/ZhouShaoXiang/ScaryBugs/ScaryBugs/centipede.jpg
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/ladybug.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zekunyan/iOS-Tasks/HEAD/ZhouShaoXiang/ScaryBugs/ScaryBugs/ladybug.jpg
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/potatoBug.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zekunyan/iOS-Tasks/HEAD/ZhouShaoXiang/ScaryBugs/ScaryBugs/potatoBug.jpg
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/wolfSpider.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zekunyan/iOS-Tasks/HEAD/ZhouShaoXiang/ScaryBugs/ScaryBugs/wolfSpider.jpg
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/centipedeThumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zekunyan/iOS-Tasks/HEAD/ZhouShaoXiang/ScaryBugs/ScaryBugs/centipedeThumb.jpg
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/ladybugThumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zekunyan/iOS-Tasks/HEAD/ZhouShaoXiang/ScaryBugs/ScaryBugs/ladybugThumb.jpg
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/potatoBugThumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zekunyan/iOS-Tasks/HEAD/ZhouShaoXiang/ScaryBugs/ScaryBugs/potatoBugThumb.jpg
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/wolfSpiderThumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zekunyan/iOS-Tasks/HEAD/ZhouShaoXiang/ScaryBugs/ScaryBugs/wolfSpiderThumb.jpg
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/shockedface2_empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zekunyan/iOS-Tasks/HEAD/ZhouShaoXiang/ScaryBugs/ScaryBugs/shockedface2_empty.png
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/shockedface2_full.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zekunyan/iOS-Tasks/HEAD/ZhouShaoXiang/ScaryBugs/ScaryBugs/shockedface2_full.png
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/shockedface2_half.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zekunyan/iOS-Tasks/HEAD/ZhouShaoXiang/ScaryBugs/ScaryBugs/shockedface2_half.png
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/Images.xcassets/AppIcon.appiconset/logo1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zekunyan/iOS-Tasks/HEAD/ZhouShaoXiang/ScaryBugs/ScaryBugs/Images.xcassets/AppIcon.appiconset/logo1.png
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/iOS Simulator Screen Shot 2014年11月4日 15.44.32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zekunyan/iOS-Tasks/HEAD/ZhouShaoXiang/ScaryBugs/ScaryBugs/iOS Simulator Screen Shot 2014年11月4日 15.44.32.png
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/Images.xcassets/LaunchImage.launchimage/iOS Simulator Screen Shot 2014年11月4日 15.44.32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zekunyan/iOS-Tasks/HEAD/ZhouShaoXiang/ScaryBugs/ScaryBugs/Images.xcassets/LaunchImage.launchimage/iOS Simulator Screen Shot 2014年11月4日 15.44.32.png
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/Images.xcassets/LaunchImage.launchimage/iOS Simulator Screen Shot 2014年11月4日 15.44.32-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zekunyan/iOS-Tasks/HEAD/ZhouShaoXiang/ScaryBugs/ScaryBugs/Images.xcassets/LaunchImage.launchimage/iOS Simulator Screen Shot 2014年11月4日 15.44.32-1.png
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/attribution.txt:
--------------------------------------------------------------------------------
1 | potatoBug.png: From jmtorres: http://www.sxc.hu/profile/jmtorres
2 | centipede.png: From unknown: http://www.sxc.hu/photo/657236
3 | wolfSpider.png: from juliaf: http://www.sxc.hu/profile/juliaf
4 | ladybug.png: From unknown: http://www.sxc.hu/photo/1231251
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/MasterViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // MasterViewController.h
3 | // ScaryBugs
4 | //
5 | // Created by ZhouShaoxiang on 14-11-3.
6 | // Copyright (c) 2014年 Rabiiit. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface MasterViewController : UITableViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // ScaryBugs
4 | //
5 | // Created by ZhouShaoxiang on 14-11-3.
6 | // Copyright (c) 2014年 Rabiiit. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/RWTUIImageExtras.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImageExtras.h
3 | // ScaryBugs
4 | //
5 | // Created by Ray Wenderlich on 8/23/10.
6 | // Copyright 2010 Ray Wenderlich. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "UIkit/UIkit.h"
11 | @interface UIImage (Extras)
12 |
13 | - (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize;
14 |
15 | @end
16 |
17 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // ScaryBugs
4 | //
5 | // Created by ZhouShaoxiang on 14-11-3.
6 | // Copyright (c) 2014年 Rabiiit. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/DetailViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DetailViewController.h
3 | // ScaryBugs
4 | //
5 | // Created by ZhouShaoxiang on 14-11-3.
6 | // Copyright (c) 2014年 Rabiiit. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DetailViewController : UIViewController
12 |
13 | @property (strong, nonatomic) id detailItem;
14 | @property (weak, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/RWTScaryBugsData.h:
--------------------------------------------------------------------------------
1 | //
2 | // RWTScaryBugsData.h
3 | // ScaryBugs
4 | //
5 | // Created by ZhouShaoxiang on 14-11-3.
6 | // Copyright (c) 2014年 Rabiiit. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface RWTScaryBugsData : NSObject
12 |
13 | @property (strong)NSString *title;
14 | @property (assign)float rateing;
15 |
16 | - (id)initWithTitle:(NSString *) title rating:(float)rating;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/RWTScaryBugsData.m:
--------------------------------------------------------------------------------
1 | //
2 | // RWTScaryBugsData.m
3 | // ScaryBugs
4 | //
5 | // Created by ZhouShaoxiang on 14-11-3.
6 | // Copyright (c) 2014年 Rabiiit. All rights reserved.
7 | //
8 |
9 | #import "RWTScaryBugsData.h"
10 |
11 | @implementation RWTScaryBugsData
12 |
13 | @synthesize title = _title;
14 | @synthesize rateing = _rateing;
15 |
16 | - (id)initWithTitle:(NSString *)title rating:(float)rating{
17 | if(self = [super init]){
18 | self.title = title;
19 | self.rateing = rating;
20 | }
21 | return self;
22 | }
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | *.xccheckout
14 | *.moved-aside
15 | DerivedData
16 | *.hmap
17 | *.ipa
18 | *.xcuserstate
19 |
20 | # CocoaPods
21 | #
22 | # We recommend against adding the Pods directory to your .gitignore. However
23 | # you should judge for yourself, the pros and cons are mentioned at:
24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
25 | #
26 | # Pods/
27 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/RWTScaryBugsDoc.h:
--------------------------------------------------------------------------------
1 | //
2 | // RWTScaryBugsDoc.h
3 | // ScaryBugs
4 | //
5 | // Created by ZhouShaoxiang on 14-11-3.
6 | // Copyright (c) 2014年 Rabiiit. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @class RWTScaryBugsData;
13 |
14 | @interface RWTScaryBugsDoc : NSObject
15 |
16 | @property(strong) RWTScaryBugsData *data;
17 | @property(strong) UIImage *thumbimage;
18 | @property(strong) UIImage *fullimage;
19 |
20 | - (id)initWithTitle:(NSString *)title rating:(float)rating thumbimage:(UIImage *)thumbimage fullimage:(UIImage *)fullimage;
21 |
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "7.0",
8 | "filename" : "iOS Simulator Screen Shot 2014年11月4日 15.44.32.png",
9 | "scale" : "2x"
10 | },
11 | {
12 | "extent" : "full-screen",
13 | "idiom" : "iphone",
14 | "subtype" : "retina4",
15 | "filename" : "iOS Simulator Screen Shot 2014年11月4日 15.44.32-1.png",
16 | "minimum-system-version" : "7.0",
17 | "orientation" : "portrait",
18 | "scale" : "2x"
19 | }
20 | ],
21 | "info" : {
22 | "version" : 1,
23 | "author" : "xcode"
24 | }
25 | }
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/Images.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 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/RWTScaryBugsDoc.m:
--------------------------------------------------------------------------------
1 | //
2 | // RWTScaryBugsDoc.m
3 | // ScaryBugs
4 | //
5 | // Created by ZhouShaoxiang on 14-11-3.
6 | // Copyright (c) 2014年 Rabiiit. All rights reserved.
7 | //
8 |
9 | #import "RWTScaryBugsDoc.h"
10 | #import "RWTScaryBugsData.h"
11 |
12 | @implementation RWTScaryBugsDoc
13 |
14 | @synthesize data = _data;
15 | @synthesize thumbimage = _thumbimage;
16 | @synthesize fullimage = _fullimage;
17 |
18 | - (id)initWithTitle:(NSString *)title rating:(float)rating thumbimage:(UIImage *)thumbimage fullimage:(UIImage *)fullimage{
19 | if((self = [super init])){
20 | self.data = [[RWTScaryBugsData alloc]initWithTitle:title rating:rating];
21 | self.thumbimage = thumbimage;
22 | self.fullimage = fullimage;
23 | }
24 | return self;
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugsTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.Rabiiit.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/RWTRateView.h:
--------------------------------------------------------------------------------
1 | //
2 | // RateView.h
3 | // CustomView
4 | //
5 | // Created by Ray Wenderlich on 2/17/12.
6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class RWTRateView;
12 |
13 | @protocol RWTRateViewDelegate
14 | - (void)rateView:(RWTRateView *)rateView ratingDidChange:(float)rating;
15 | @end
16 |
17 | @interface RWTRateView : UIView
18 |
19 | @property (strong, nonatomic) UIImage *notSelectedImage;
20 | @property (strong, nonatomic) UIImage *halfSelectedImage;
21 | @property (strong, nonatomic) UIImage *fullSelectedImage;
22 | @property (assign, nonatomic) float rating;
23 | @property (assign) BOOL editable;
24 | @property (strong) NSMutableArray * imageViews;
25 | @property (assign, nonatomic) int maxRating;
26 | @property (assign) int midMargin;
27 | @property (assign) int leftMargin;
28 | @property (assign) CGSize minImageSize;
29 | @property (assign) id delegate;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugsTests/ScaryBugsTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // ScaryBugsTests.m
3 | // ScaryBugsTests
4 | //
5 | // Created by ZhouShaoxiang on 14-11-3.
6 | // Copyright (c) 2014年 Rabiiit. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface ScaryBugsTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation ScaryBugsTests
17 |
18 | - (void)setUp {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown {
24 | // Put teardown code here. This method is called after the invocation of each test method in the class.
25 | [super tearDown];
26 | }
27 |
28 | - (void)testExample {
29 | // This is an example of a functional test case.
30 | XCTAssert(YES, @"Pass");
31 | }
32 |
33 | - (void)testPerformanceExample {
34 | // This is an example of a performance test case.
35 | [self measureBlock:^{
36 | // Put the code you want to measure the time of here.
37 | }];
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/DetailViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DetailViewController.m
3 | // ScaryBugs
4 | //
5 | // Created by ZhouShaoxiang on 14-11-3.
6 | // Copyright (c) 2014年 Rabiiit. All rights reserved.
7 | //
8 |
9 | #import "DetailViewController.h"
10 |
11 | @interface DetailViewController ()
12 |
13 | @end
14 |
15 | @implementation DetailViewController
16 |
17 | #pragma mark - Managing the detail item
18 |
19 | - (void)setDetailItem:(id)newDetailItem {
20 | if (_detailItem != newDetailItem) {
21 | _detailItem = newDetailItem;
22 |
23 | // Update the view.
24 | [self configureView];
25 | }
26 | }
27 |
28 | - (void)configureView {
29 | // Update the user interface for the detail item.
30 | if (self.detailItem) {
31 | self.detailDescriptionLabel.text = [self.detailItem description];
32 | }
33 | }
34 |
35 | - (void)viewDidLoad {
36 | [super viewDidLoad];
37 | // Do any additional setup after loading the view, typically from a nib.
38 | [self configureView];
39 | }
40 |
41 | - (void)didReceiveMemoryWarning {
42 | [super didReceiveMemoryWarning];
43 | // Dispose of any resources that can be recreated.
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.Rabiiit.$(PRODUCT_NAME:rfc1034identifier)
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 | UIStatusBarTintParameters
34 |
35 | UINavigationBar
36 |
37 | Style
38 | UIBarStyleDefault
39 | Translucent
40 |
41 |
42 |
43 | UISupportedInterfaceOrientations
44 |
45 | UIInterfaceOrientationPortrait
46 | UIInterfaceOrientationLandscapeLeft
47 | UIInterfaceOrientationLandscapeRight
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // ScaryBugs
4 | //
5 | // Created by ZhouShaoxiang on 14-11-3.
6 | // Copyright (c) 2014年 Rabiiit. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "DetailViewController.h"
11 |
12 | @interface AppDelegate ()
13 |
14 | @end
15 |
16 | @implementation AppDelegate
17 |
18 |
19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
20 | // Override point for customization after application launch.
21 | return YES;
22 | }
23 |
24 | - (void)applicationWillResignActive:(UIApplication *)application {
25 | // 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.
26 | // 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.
27 | }
28 |
29 | - (void)applicationDidEnterBackground:(UIApplication *)application {
30 | // 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.
31 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
32 | }
33 |
34 | - (void)applicationWillEnterForeground:(UIApplication *)application {
35 | // 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.
36 | }
37 |
38 | - (void)applicationDidBecomeActive:(UIApplication *)application {
39 | // 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.
40 | }
41 |
42 | - (void)applicationWillTerminate:(UIApplication *)application {
43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/RWTUIImageExtras.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIImageExtras.m
3 | // ScaryBugs
4 | //
5 | // Created by Ray Wenderlich on 8/23/10.
6 | // Copyright 2010 Ray Wenderlich. All rights reserved.
7 | //
8 |
9 | #import "RWTUIImageExtras.h"
10 |
11 | @implementation UIImage (Extras)
12 |
13 | - (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize
14 | {
15 | UIImage *sourceImage = self;
16 | UIImage *newImage = nil;
17 | CGSize imageSize = sourceImage.size;
18 | CGFloat width = imageSize.width;
19 | CGFloat height = imageSize.height;
20 | CGFloat targetWidth = targetSize.width;
21 | CGFloat targetHeight = targetSize.height;
22 | CGFloat scaleFactor = 0.0;
23 | CGFloat scaledWidth = targetWidth;
24 | CGFloat scaledHeight = targetHeight;
25 | CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
26 |
27 | if (CGSizeEqualToSize(imageSize, targetSize) == NO)
28 | {
29 | CGFloat widthFactor = targetWidth / width;
30 | CGFloat heightFactor = targetHeight / height;
31 |
32 | if (widthFactor > heightFactor)
33 | scaleFactor = widthFactor; // scale to fit height
34 | else
35 | scaleFactor = heightFactor; // scale to fit width
36 | scaledWidth = ceil(width * scaleFactor);
37 | scaledHeight = ceil(height * scaleFactor);
38 |
39 | // center the image
40 | if (widthFactor > heightFactor)
41 | {
42 | thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
43 | }
44 | else if (widthFactor < heightFactor)
45 | {
46 | thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
47 | }
48 | }
49 |
50 | UIGraphicsBeginImageContext(targetSize); // this will crop
51 |
52 | CGRect thumbnailRect = CGRectZero;
53 | thumbnailRect.origin = thumbnailPoint;
54 | thumbnailRect.size.width = scaledWidth;
55 | thumbnailRect.size.height = scaledHeight;
56 |
57 | [sourceImage drawInRect:thumbnailRect];
58 |
59 | newImage = UIGraphicsGetImageFromCurrentImageContext();
60 | if(newImage == nil)
61 | NSLog(@"could not scale image");
62 |
63 | //pop the context to get back to the default
64 | UIGraphicsEndImageContext();
65 | return newImage;
66 | }
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/SVProgressHUD.h:
--------------------------------------------------------------------------------
1 | //
2 | // SVProgressHUD.h
3 | //
4 | // Created by Sam Vermette on 27.03.11.
5 | // Copyright 2011 Sam Vermette. All rights reserved.
6 | //
7 | // https://github.com/samvermette/SVProgressHUD
8 | //
9 |
10 | #import
11 | #import
12 |
13 | extern NSString * const SVProgressHUDDidReceiveTouchEventNotification;
14 | extern NSString * const SVProgressHUDWillDisappearNotification;
15 | extern NSString * const SVProgressHUDDidDisappearNotification;
16 | extern NSString * const SVProgressHUDWillAppearNotification;
17 | extern NSString * const SVProgressHUDDidAppearNotification;
18 |
19 | extern NSString * const SVProgressHUDStatusUserInfoKey;
20 |
21 | typedef NS_ENUM(NSUInteger, SVProgressHUDMaskType) {
22 | SVProgressHUDMaskTypeNone = 1, // allow user interactions while HUD is displayed
23 | SVProgressHUDMaskTypeClear, // don't allow
24 | SVProgressHUDMaskTypeBlack, // don't allow and dim the UI in the back of the HUD
25 | SVProgressHUDMaskTypeGradient // don't allow and dim the UI with a a-la-alert-view bg gradient
26 | };
27 |
28 | @interface SVProgressHUD : UIView
29 |
30 | #pragma mark - Customization
31 |
32 | + (void)setBackgroundColor:(UIColor*)color; // default is [UIColor whiteColor]
33 | + (void)setForegroundColor:(UIColor*)color; // default is [UIColor blackColor]
34 | + (void)setRingThickness:(CGFloat)width; // default is 4 pt
35 | + (void)setFont:(UIFont*)font; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]
36 | + (void)setSuccessImage:(UIImage*)image; // default is bundled success image from Glyphish
37 | + (void)setErrorImage:(UIImage*)image; // default is bundled error image from Glyphish
38 |
39 | #pragma mark - Show Methods
40 |
41 | + (void)show;
42 | + (void)showWithMaskType:(SVProgressHUDMaskType)maskType;
43 | + (void)showWithStatus:(NSString*)status;
44 | + (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType;
45 |
46 | + (void)showProgress:(float)progress;
47 | + (void)showProgress:(float)progress status:(NSString*)status;
48 | + (void)showProgress:(float)progress status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType;
49 |
50 | + (void)setStatus:(NSString*)string; // change the HUD loading status while it's showing
51 |
52 | // stops the activity indicator, shows a glyph + status, and dismisses HUD 1s later
53 | + (void)showSuccessWithStatus:(NSString*)string;
54 | + (void)showErrorWithStatus:(NSString *)string;
55 | + (void)showImage:(UIImage*)image status:(NSString*)status; // use 28x28 white pngs
56 |
57 | + (void)setOffsetFromCenter:(UIOffset)offset;
58 | + (void)resetOffsetFromCenter;
59 |
60 | + (void)popActivity;
61 | + (void)dismiss;
62 |
63 | + (BOOL)isVisible;
64 |
65 | @end
66 |
67 |
68 | @interface SVIndefiniteAnimatedView : UIView
69 |
70 | @property (nonatomic, assign) CGFloat strokeThickness;
71 | @property (nonatomic, assign) CGFloat radius;
72 | @property (nonatomic, strong) UIColor *strokeColor;
73 |
74 | @end
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/MasterViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // MasterViewController.m
3 | // ScaryBugs
4 | //
5 | // Created by ZhouShaoxiang on 14-11-3.
6 | // Copyright (c) 2014年 Rabiiit. All rights reserved.
7 | //
8 |
9 | #import "MasterViewController.h"
10 | #import "DetailViewController.h"
11 |
12 | @interface MasterViewController ()
13 |
14 | @property NSMutableArray *objects;
15 | @end
16 |
17 | @implementation MasterViewController
18 |
19 | - (void)awakeFromNib {
20 | [super awakeFromNib];
21 | }
22 |
23 | - (void)viewDidLoad {
24 | [super viewDidLoad];
25 | // Do any additional setup after loading the view, typically from a nib.
26 | self.navigationItem.leftBarButtonItem = self.editButtonItem;
27 |
28 | UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
29 | self.navigationItem.rightBarButtonItem = addButton;
30 | }
31 |
32 | - (void)didReceiveMemoryWarning {
33 | [super didReceiveMemoryWarning];
34 | // Dispose of any resources that can be recreated.
35 | }
36 |
37 | - (void)insertNewObject:(id)sender {
38 | if (!self.objects) {
39 | self.objects = [[NSMutableArray alloc] init];
40 | }
41 | [self.objects insertObject:[NSDate date] atIndex:0];
42 | NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
43 | [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
44 | }
45 |
46 | #pragma mark - Segues
47 |
48 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
49 | if ([[segue identifier] isEqualToString:@"showDetail"]) {
50 | NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
51 | NSDate *object = self.objects[indexPath.row];
52 | [[segue destinationViewController] setDetailItem:object];
53 | }
54 | }
55 |
56 | #pragma mark - Table View
57 |
58 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
59 | return 1;
60 | }
61 |
62 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
63 | return self.objects.count;
64 | }
65 |
66 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
67 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
68 |
69 | NSDate *object = self.objects[indexPath.row];
70 | cell.textLabel.text = [object description];
71 | return cell;
72 | }
73 |
74 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
75 | // Return NO if you do not want the specified item to be editable.
76 | return YES;
77 | }
78 |
79 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
80 | if (editingStyle == UITableViewCellEditingStyleDelete) {
81 | [self.objects removeObjectAtIndex:indexPath.row];
82 | [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
83 | } else if (editingStyle == UITableViewCellEditingStyleInsert) {
84 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
85 | }
86 | }
87 |
88 | @end
89 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/RWTRateView.m:
--------------------------------------------------------------------------------
1 | //
2 | // RateView.m
3 | // CustomView
4 | //
5 | // Created by Ray Wenderlich on 2/17/12.
6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved.
7 | //
8 |
9 | #import "RWTRateView.h"
10 |
11 | @implementation RWTRateView
12 |
13 | @synthesize notSelectedImage = _notSelectedImage;
14 | @synthesize halfSelectedImage = _halfSelectedImage;
15 | @synthesize fullSelectedImage = _fullSelectedImage;
16 | @synthesize rating = _rating;
17 | @synthesize editable = _editable;
18 | @synthesize imageViews = _imageViews;
19 | @synthesize maxRating = _maxRating;
20 | @synthesize midMargin = _midMargin;
21 | @synthesize leftMargin = _leftMargin;
22 | @synthesize minImageSize = _minImageSize;
23 | @synthesize delegate = _delegate;
24 |
25 | - (void)baseInit {
26 | _notSelectedImage = nil;
27 | _halfSelectedImage = nil;
28 | _fullSelectedImage = nil;
29 | _rating = 0;
30 | _editable = NO;
31 | _imageViews = [[NSMutableArray alloc] init];
32 | _maxRating = 5;
33 | _midMargin = 5;
34 | _leftMargin = 0;
35 | _minImageSize = CGSizeMake(5, 5);
36 | _delegate = nil;
37 | }
38 |
39 | - (id)initWithFrame:(CGRect)frame
40 | {
41 | self = [super initWithFrame:frame];
42 | if (self) {
43 | [self baseInit];
44 | }
45 | return self;
46 | }
47 |
48 | - (id)initWithCoder:(NSCoder *)aDecoder {
49 | if ((self = [super initWithCoder:aDecoder])) {
50 | [self baseInit];
51 | }
52 | return self;
53 | }
54 |
55 | - (void)refresh {
56 | for(int i = 0; i < self.imageViews.count; ++i) {
57 | UIImageView *imageView = [self.imageViews objectAtIndex:i];
58 | if (self.rating >= i+1) {
59 | imageView.image = self.fullSelectedImage;
60 | } else if (self.rating > i) {
61 | imageView.image = self.halfSelectedImage;
62 | } else {
63 | imageView.image = self.notSelectedImage;
64 | }
65 | }
66 | }
67 |
68 | - (void)layoutSubviews {
69 | [super layoutSubviews];
70 |
71 | if (self.notSelectedImage == nil) return;
72 |
73 | float desiredImageWidth = (self.frame.size.width - (self.leftMargin*2) - (self.midMargin*self.imageViews.count)) / self.imageViews.count;
74 | float imageWidth = MAX(self.minImageSize.width, desiredImageWidth);
75 | float imageHeight = MAX(self.minImageSize.height, self.frame.size.height);
76 |
77 | for (int i = 0; i < self.imageViews.count; ++i) {
78 |
79 | UIImageView *imageView = [self.imageViews objectAtIndex:i];
80 | CGRect imageFrame = CGRectMake(self.leftMargin + i*(self.midMargin+imageWidth), 0, imageWidth, imageHeight);
81 | imageView.frame = imageFrame;
82 |
83 | }
84 |
85 | }
86 |
87 | - (void)setMaxRating:(int)maxRating {
88 | _maxRating = maxRating;
89 |
90 | // Remove old image views
91 | for(int i = 0; i < self.imageViews.count; ++i) {
92 | UIImageView *imageView = (UIImageView *) [self.imageViews objectAtIndex:i];
93 | [imageView removeFromSuperview];
94 | }
95 | [self.imageViews removeAllObjects];
96 |
97 | // Add new image views
98 | for(int i = 0; i < maxRating; ++i) {
99 | UIImageView *imageView = [[UIImageView alloc] init];
100 | imageView.contentMode = UIViewContentModeScaleAspectFit;
101 | [self.imageViews addObject:imageView];
102 | [self addSubview:imageView];
103 | }
104 |
105 | // Relayout and refresh
106 | [self setNeedsLayout];
107 | [self refresh];
108 | }
109 |
110 | - (void)setNotSelectedImage:(UIImage *)image {
111 | _notSelectedImage = image;
112 | [self refresh];
113 | }
114 |
115 | - (void)setHalfSelectedImage:(UIImage *)image {
116 | _halfSelectedImage = image;
117 | [self refresh];
118 | }
119 |
120 | - (void)setFullSelectedImage:(UIImage *)image {
121 | _fullSelectedImage = image;
122 | [self refresh];
123 | }
124 |
125 | - (void)setRating:(float)rating {
126 | _rating = rating;
127 | [self refresh];
128 | }
129 |
130 | - (void)handleTouchAtLocation:(CGPoint)touchLocation {
131 | if (!self.editable) return;
132 |
133 | int newRating = 0;
134 | for(int i = self.imageViews.count - 1; i >= 0; i--) {
135 | UIImageView *imageView = [self.imageViews objectAtIndex:i];
136 | if (touchLocation.x > imageView.frame.origin.x) {
137 | newRating = i+1;
138 | break;
139 | }
140 | }
141 |
142 | self.rating = newRating;
143 | }
144 |
145 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
146 | UITouch *touch = [touches anyObject];
147 | CGPoint touchLocation = [touch locationInView:self];
148 | [self handleTouchAtLocation:touchLocation];
149 | }
150 |
151 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
152 | UITouch *touch = [touches anyObject];
153 | CGPoint touchLocation = [touch locationInView:self];
154 | [self handleTouchAtLocation:touchLocation];
155 | }
156 |
157 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
158 | [self.delegate rateView:self ratingDidChange:self.rating];
159 | }
160 |
161 | @end
162 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # iOS Tasks
2 |
3 | >ITEC学习iOS的同学的Github聚集地 =。=
4 | >iOS开发的学习是个漫长而有趣的过程,加油吧~
5 |
6 | ## Git
7 | Git是目前最好用的分布式版本管理系统了,作为一个程序猿,这个是必备技能。
8 | 主页:[https://git-scm.com](https://git-scm.com)
9 | Pro Git教程:[https://git-scm.com/book/zh/v1](https://git-scm.com/book/zh/v1)
10 | 推荐的GUI软件:SourceTree
11 | 国内比较好的Git托管平台:[Coding](https://git-scm.com/book/zh/v1)
12 |
13 | 自己在Coding上建个账号,在本地建个Git仓库,试试提交、分支、push、pull等特型。
14 |
15 | 强烈建议使用[http://gitignore.io/](http://gitignore.io/)生成gitignore文件!
16 |
17 | ## 开发环境
18 | ### 硬件环境
19 | Mac和iPhone.
20 |
21 | ### IDE
22 | Xcode 7 + 各种插件,推荐使用[Alcatraz](http://alcatraz.io/)插件管理器安装、管理插件。
23 | 当然,大名鼎鼎的Jetbrains公司的[AppCode](https://www.jetbrains.com/objc)也很不错!
24 |
25 |
26 | ## 学习
27 | ### 好书
28 | 推荐一个比较好的电子书下载网站:[http://it-ebooks.info](http://it-ebooks.info)
29 | 如果从零开始学习的话,由一本比较好的书入手是最好的,推荐的书如下:
30 |
31 | #### 1. Objective-C
32 |
33 | Gitbook的书:[Objective-C-Tutorials](https://www.gitbook.com/book/tangjr/objective-c-tutorials/details)
34 |
35 | Objective-C程序设计
36 | 
37 |
38 | #### 2. Swift
39 | * 最好的当然是苹果iBooks的Swift官方教程。
40 | * 官方的中文翻译版:[《The Swift Programming Language》中文版](https://www.gitbook.com/book/numbbbbb/-the-swift-programming-language-/details), [
41 | 苹果官方文档 Using Swift with Cocoa and Objective-C 中文翻译版](https://www.gitbook.com/book/mengxiangpingx/using-swift-with-cocoa-and-objective-c/details)
42 | * 还有猫神的 [Swifter: 100个Swift开发必备Tip](http://product.dangdang.com/23695580.html)也非常棒!
43 |
44 | 
45 |
46 | #### 3. iOS编程
47 | iOS编程-第四版
48 | 
49 |
50 | #### 4. 设计模式
51 | Objective-C编程之道-iOS设计模式解析
52 | 
53 |
54 | #### 5. 代码整洁之道
55 | 
56 |
57 | ### 编程语言
58 | 开发iOS的主要编程语言是Object-C(cocoa框架),当然还有C语言,C++等等。(最新的Swift刚到2.0版本,迭代比较快,以后一定是主流。本教程以OC为主)C++大部分用来开发图像、音视频等性能敏感的库,一般的应用只会涉及到Object-C。
59 |
60 | 目前Object-C的开发、维护基本上也就是Apple在做,所以学习Object-C最好最权威的地方就是Apple developer官网[https://developer.apple.com/devcenter/ios/index.action](https://developer.apple.com/devcenter/ios/index.action)
61 |
62 | 这里是几个比较好的官方教程:
63 | * [Object-C基本教程。](https://developer.apple.com/library/mac/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html)
64 | * [面向对象编程:Object-Oriented Programming with Objective-C](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/OOP_ObjC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40005149)。
65 | * [Block专题教程。这个非常强大!](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html#//apple_ref/doc/uid/TP40007502)
66 | * [线程: Threading Programming Guide。](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/Introduction/Introduction.html#//apple_ref/doc/uid/10000057i)
67 | * [字符串:String Programming Guide。](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Strings/introStrings.html#//apple_ref/doc/uid/10000035i)
68 | * [异常处理:Exception Programming Topics。](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Exceptions/Exceptions.html#//apple_ref/doc/uid/10000012i)
69 | * [并发编程:Concurrency Programming Guide。](https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008091)
70 | * [集合类:Collections Programming Topics。](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Collections/Collections.html#//apple_ref/doc/uid/10000034i)
71 |
72 | 当然,还有许多非常好的第三方教程,如:[tutorialspoint](http://www.tutorialspoint.com/objective_c/index.htm)
73 |
74 | ### 书
75 | 推荐一些电子书
76 |
77 | * [Programming iOS 7, 4th Edition](http://it-ebooks.info/book/3138/)
78 | * [Beginning iOS 5 Development](http://it-ebooks.info/book/508/)
79 | * [iOS 7 Programming Fundamentals](http://it-ebooks.info/book/3084/)
80 | * [Learn iOS 7 App Development](http://it-ebooks.info/book/3143/)
81 | * [More iOS 6 Development](http://www.it-ebooks.info/book/1973/)
82 | * [Beginning iOS 7 Development](http://www.it-ebooks.info/book/3901/)
83 | * [The Core iOS Developer's Cookbook, 5th Edition](http://www.it-ebooks.info/book/3675/)
84 | * [Beginning iOS Programming](http://www.it-ebooks.info/book/3663/)
85 | * [Application Development in iOS 7](http://www.it-ebooks.info/book/3545/)
86 | * [Learning Cocoa with Objective-C, 4th Edition](http://www.it-ebooks.info/book/3323/)
87 | * [Professional iOS Programming](http://www.it-ebooks.info/book/3834/)
88 | * [iOS Components and Frameworks](http://www.it-ebooks.info/book/3684/)
89 | * [iOS Drawing](http://www.it-ebooks.info/book/3683/)
90 | * [iOS Auto Layout Demystified, 2nd Edition](http://www.it-ebooks.info/book/3681/)
91 | * [Learn iOS 7 App Development](http://www.it-ebooks.info/book/3143/)
92 | * [iOS 7 Programming Cookbook](http://www.it-ebooks.info/book/3083/)
93 |
94 | ### iOS开发
95 | 有了一定的OC基础以后,就可以着手做几个小东西玩玩,练练手。iOS的体系很庞大,所以一开始最好先按照简单的教程来做一些Demo。当然,[官方的教程](https://developer.apple.com/library/ios/navigation/#)是非常全面的,但是未免有些吓人=。=,太多了。。。所以在此推荐一个非常好的网站:[www.raywenderlich.com](http://www.raywenderlich.com/),新手可以按照里面的教程,做些Demo应用,攒点成就感~~
96 |
97 | 当然,大神们的博客是要多多阅读的:[中文 iOS/Mac 开发博客列表](https://github.com/tangqiaoboy/iOSBlogCN).
98 |
99 | **遇到问题多Google(不许用Baidu =。= ),stackoverflow是你最好的伙伴**
100 |
101 | ## 任务
102 | #### 1. Task1: 做一个简单的笔记应用。
103 | 要求:
104 | * 只用记录文字,有标题、正文、创建时间等基本信息。
105 | * 一共两个页面,首页是所有笔记的列表,点击一条笔记进入笔记的详细内容页面,可以编辑笔记。
106 | * 笔记可以创建、修改、删除、加星标记等。
107 | * 用SQLite数据库保存笔记数据(可以用FMDB第三方库)。
108 | * 发挥你的创造力!
109 |
110 | #### 2. Task2: 做一个简单的天气应用
111 | 百度的免费天气API:[http://apistore.baidu.com/apiworks/servicedetail/112.html](http://apistore.baidu.com/apiworks/servicedetail/112.html)
112 | 要求:
113 | * 可以搜索城市。
114 | * 可以在本地保存要查看的城市列表,进入应用时更新城市天气。
115 | * 可以显示7天内的天气,具体看API可以提供什么。
116 | * 参考墨迹天气等App的设计。
117 | * 发挥你的创造力!
118 |
119 | ## 第三方库
120 | 很多时候,我们可以减少重复的制造轮子,多用用别人的库,可以很大的提升效率。当然,阅读别人的优质代码也是一种学习。
121 |
122 | 第三方库管理工具:强烈简易[CocoaPods](http://cocoapods.org/)。
123 |
124 | 这是冰岩的酷站推荐的一个iOS的常用[第三方库合集](http://github.ibireme.com/github/list/ios/)。
125 |
126 | Awesome系列
127 | 
128 |
129 | 列举几个好用、常用的。
130 |
131 | * [AFNetworking](https://github.com/AFNetworking/AFNetworking):一个优秀的网络请求库。
132 | * [FMDB](https://github.com/ccgus/fmdb):一个封装了iOS的SQLite的库,可以方便的操作数据库,事务、并发什么的,都不在话下。
133 | * [SVPullToRefresh](https://github.com/samvermette/SVPullToRefresh):一个UITableView的Category扩展,超级方便的增加下拉刷新、上拉加载更多的功能。
134 | * [SVSegmentedControl](https://github.com/samvermette/SVSegmentedControl):不错的Tab switch控件。
135 | * [SVProgressHUD](https://github.com/TransitApp/SVProgressHUD):iOS风格的简易提醒对话框。
136 | * [SDWebImage](https://github.com/rs/SDWebImage):简单强大的,带有内存、文件缓存的图片加载库。
137 | * [CRToast](https://github.com/cruffenach/CRToast):漂亮的Status栏Notification。
138 | * [KLCPopup](https://github.com/jmascia/KLCPopup):炫酷的Popup弹出UIView。
139 | * [FDStackView](https://github.com/forkingdog/FDStackView):向下兼容的UIStackView!
140 | * [UITableView-FDTemplateLayoutCell](https://github.com/forkingdog/UITableView-FDTemplateLayoutCell):最方便的自动计算UITableViewCell高度并缓存的库。
141 | * [MJExtension](https://github.com/CoderMJLee/MJExtension):MJ写的Model库。
142 | * [iCarousel](https://github.com/nicklockwood/iCarousel):具有3D效果的浏览组件!
143 | * [Mantle](https://github.com/Mantle/Mantle): 又一个优秀的Model库。
144 | * [Masonry](https://github.com/SnapKit/Masonry):最人性化的用代码写Autolayout的库。
145 | * [Aspects](https://github.com/steipete/Aspects):AOP库。
146 | * [PNChart](https://github.com/kevinzhow/PNChart):显示各种图表,如饼状图、柱状图、折线图。
147 |
148 | 另外,[Facebook](https://github.com/facebook)的开源库也是炫酷的不行啊,太多了。
149 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 64EA89F21A0711DB00A9CF4C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 64EA89F11A0711DB00A9CF4C /* main.m */; };
11 | 64EA89F51A0711DB00A9CF4C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 64EA89F41A0711DB00A9CF4C /* AppDelegate.m */; };
12 | 64EA89F81A0711DB00A9CF4C /* MasterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 64EA89F71A0711DB00A9CF4C /* MasterViewController.m */; };
13 | 64EA89FB1A0711DB00A9CF4C /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 64EA89FA1A0711DB00A9CF4C /* DetailViewController.m */; };
14 | 64EA89FE1A0711DB00A9CF4C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 64EA89FC1A0711DB00A9CF4C /* Main.storyboard */; };
15 | 64EA8A001A0711DB00A9CF4C /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 64EA89FF1A0711DB00A9CF4C /* Images.xcassets */; };
16 | 64EA8A031A0711DB00A9CF4C /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 64EA8A011A0711DB00A9CF4C /* LaunchScreen.xib */; };
17 | 64EA8A0F1A0711DB00A9CF4C /* ScaryBugsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 64EA8A0E1A0711DB00A9CF4C /* ScaryBugsTests.m */; };
18 | /* End PBXBuildFile section */
19 |
20 | /* Begin PBXContainerItemProxy section */
21 | 64EA8A091A0711DB00A9CF4C /* PBXContainerItemProxy */ = {
22 | isa = PBXContainerItemProxy;
23 | containerPortal = 64EA89E41A0711DB00A9CF4C /* Project object */;
24 | proxyType = 1;
25 | remoteGlobalIDString = 64EA89EB1A0711DB00A9CF4C;
26 | remoteInfo = ScaryBugs;
27 | };
28 | /* End PBXContainerItemProxy section */
29 |
30 | /* Begin PBXFileReference section */
31 | 64EA89EC1A0711DB00A9CF4C /* ScaryBugs.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ScaryBugs.app; sourceTree = BUILT_PRODUCTS_DIR; };
32 | 64EA89F01A0711DB00A9CF4C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
33 | 64EA89F11A0711DB00A9CF4C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
34 | 64EA89F31A0711DB00A9CF4C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
35 | 64EA89F41A0711DB00A9CF4C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
36 | 64EA89F61A0711DB00A9CF4C /* MasterViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MasterViewController.h; sourceTree = ""; };
37 | 64EA89F71A0711DB00A9CF4C /* MasterViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MasterViewController.m; sourceTree = ""; };
38 | 64EA89F91A0711DB00A9CF4C /* DetailViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = ""; };
39 | 64EA89FA1A0711DB00A9CF4C /* DetailViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DetailViewController.m; sourceTree = ""; };
40 | 64EA89FD1A0711DB00A9CF4C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
41 | 64EA89FF1A0711DB00A9CF4C /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
42 | 64EA8A021A0711DB00A9CF4C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
43 | 64EA8A081A0711DB00A9CF4C /* ScaryBugsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ScaryBugsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
44 | 64EA8A0D1A0711DB00A9CF4C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
45 | 64EA8A0E1A0711DB00A9CF4C /* ScaryBugsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScaryBugsTests.m; sourceTree = ""; };
46 | /* End PBXFileReference section */
47 |
48 | /* Begin PBXFrameworksBuildPhase section */
49 | 64EA89E91A0711DB00A9CF4C /* Frameworks */ = {
50 | isa = PBXFrameworksBuildPhase;
51 | buildActionMask = 2147483647;
52 | files = (
53 | );
54 | runOnlyForDeploymentPostprocessing = 0;
55 | };
56 | 64EA8A051A0711DB00A9CF4C /* Frameworks */ = {
57 | isa = PBXFrameworksBuildPhase;
58 | buildActionMask = 2147483647;
59 | files = (
60 | );
61 | runOnlyForDeploymentPostprocessing = 0;
62 | };
63 | /* End PBXFrameworksBuildPhase section */
64 |
65 | /* Begin PBXGroup section */
66 | 64EA89E31A0711DB00A9CF4C = {
67 | isa = PBXGroup;
68 | children = (
69 | 64EA89EE1A0711DB00A9CF4C /* ScaryBugs */,
70 | 64EA8A0B1A0711DB00A9CF4C /* ScaryBugsTests */,
71 | 64EA89ED1A0711DB00A9CF4C /* Products */,
72 | );
73 | sourceTree = "";
74 | };
75 | 64EA89ED1A0711DB00A9CF4C /* Products */ = {
76 | isa = PBXGroup;
77 | children = (
78 | 64EA89EC1A0711DB00A9CF4C /* ScaryBugs.app */,
79 | 64EA8A081A0711DB00A9CF4C /* ScaryBugsTests.xctest */,
80 | );
81 | name = Products;
82 | sourceTree = "";
83 | };
84 | 64EA89EE1A0711DB00A9CF4C /* ScaryBugs */ = {
85 | isa = PBXGroup;
86 | children = (
87 | 64EA89F31A0711DB00A9CF4C /* AppDelegate.h */,
88 | 64EA89F41A0711DB00A9CF4C /* AppDelegate.m */,
89 | 64EA89F61A0711DB00A9CF4C /* MasterViewController.h */,
90 | 64EA89F71A0711DB00A9CF4C /* MasterViewController.m */,
91 | 64EA89F91A0711DB00A9CF4C /* DetailViewController.h */,
92 | 64EA89FA1A0711DB00A9CF4C /* DetailViewController.m */,
93 | 64EA89FC1A0711DB00A9CF4C /* Main.storyboard */,
94 | 64EA89FF1A0711DB00A9CF4C /* Images.xcassets */,
95 | 64EA8A011A0711DB00A9CF4C /* LaunchScreen.xib */,
96 | 64EA89EF1A0711DB00A9CF4C /* Supporting Files */,
97 | );
98 | path = ScaryBugs;
99 | sourceTree = "";
100 | };
101 | 64EA89EF1A0711DB00A9CF4C /* Supporting Files */ = {
102 | isa = PBXGroup;
103 | children = (
104 | 64EA89F01A0711DB00A9CF4C /* Info.plist */,
105 | 64EA89F11A0711DB00A9CF4C /* main.m */,
106 | );
107 | name = "Supporting Files";
108 | sourceTree = "";
109 | };
110 | 64EA8A0B1A0711DB00A9CF4C /* ScaryBugsTests */ = {
111 | isa = PBXGroup;
112 | children = (
113 | 64EA8A0E1A0711DB00A9CF4C /* ScaryBugsTests.m */,
114 | 64EA8A0C1A0711DB00A9CF4C /* Supporting Files */,
115 | );
116 | path = ScaryBugsTests;
117 | sourceTree = "";
118 | };
119 | 64EA8A0C1A0711DB00A9CF4C /* Supporting Files */ = {
120 | isa = PBXGroup;
121 | children = (
122 | 64EA8A0D1A0711DB00A9CF4C /* Info.plist */,
123 | );
124 | name = "Supporting Files";
125 | sourceTree = "";
126 | };
127 | /* End PBXGroup section */
128 |
129 | /* Begin PBXNativeTarget section */
130 | 64EA89EB1A0711DB00A9CF4C /* ScaryBugs */ = {
131 | isa = PBXNativeTarget;
132 | buildConfigurationList = 64EA8A121A0711DB00A9CF4C /* Build configuration list for PBXNativeTarget "ScaryBugs" */;
133 | buildPhases = (
134 | 64EA89E81A0711DB00A9CF4C /* Sources */,
135 | 64EA89E91A0711DB00A9CF4C /* Frameworks */,
136 | 64EA89EA1A0711DB00A9CF4C /* Resources */,
137 | );
138 | buildRules = (
139 | );
140 | dependencies = (
141 | );
142 | name = ScaryBugs;
143 | productName = ScaryBugs;
144 | productReference = 64EA89EC1A0711DB00A9CF4C /* ScaryBugs.app */;
145 | productType = "com.apple.product-type.application";
146 | };
147 | 64EA8A071A0711DB00A9CF4C /* ScaryBugsTests */ = {
148 | isa = PBXNativeTarget;
149 | buildConfigurationList = 64EA8A151A0711DB00A9CF4C /* Build configuration list for PBXNativeTarget "ScaryBugsTests" */;
150 | buildPhases = (
151 | 64EA8A041A0711DB00A9CF4C /* Sources */,
152 | 64EA8A051A0711DB00A9CF4C /* Frameworks */,
153 | 64EA8A061A0711DB00A9CF4C /* Resources */,
154 | );
155 | buildRules = (
156 | );
157 | dependencies = (
158 | 64EA8A0A1A0711DB00A9CF4C /* PBXTargetDependency */,
159 | );
160 | name = ScaryBugsTests;
161 | productName = ScaryBugsTests;
162 | productReference = 64EA8A081A0711DB00A9CF4C /* ScaryBugsTests.xctest */;
163 | productType = "com.apple.product-type.bundle.unit-test";
164 | };
165 | /* End PBXNativeTarget section */
166 |
167 | /* Begin PBXProject section */
168 | 64EA89E41A0711DB00A9CF4C /* Project object */ = {
169 | isa = PBXProject;
170 | attributes = {
171 | LastUpgradeCheck = 0610;
172 | ORGANIZATIONNAME = Rabiiit;
173 | TargetAttributes = {
174 | 64EA89EB1A0711DB00A9CF4C = {
175 | CreatedOnToolsVersion = 6.1;
176 | };
177 | 64EA8A071A0711DB00A9CF4C = {
178 | CreatedOnToolsVersion = 6.1;
179 | TestTargetID = 64EA89EB1A0711DB00A9CF4C;
180 | };
181 | };
182 | };
183 | buildConfigurationList = 64EA89E71A0711DB00A9CF4C /* Build configuration list for PBXProject "ScaryBugs" */;
184 | compatibilityVersion = "Xcode 3.2";
185 | developmentRegion = English;
186 | hasScannedForEncodings = 0;
187 | knownRegions = (
188 | en,
189 | Base,
190 | );
191 | mainGroup = 64EA89E31A0711DB00A9CF4C;
192 | productRefGroup = 64EA89ED1A0711DB00A9CF4C /* Products */;
193 | projectDirPath = "";
194 | projectRoot = "";
195 | targets = (
196 | 64EA89EB1A0711DB00A9CF4C /* ScaryBugs */,
197 | 64EA8A071A0711DB00A9CF4C /* ScaryBugsTests */,
198 | );
199 | };
200 | /* End PBXProject section */
201 |
202 | /* Begin PBXResourcesBuildPhase section */
203 | 64EA89EA1A0711DB00A9CF4C /* Resources */ = {
204 | isa = PBXResourcesBuildPhase;
205 | buildActionMask = 2147483647;
206 | files = (
207 | 64EA89FE1A0711DB00A9CF4C /* Main.storyboard in Resources */,
208 | 64EA8A031A0711DB00A9CF4C /* LaunchScreen.xib in Resources */,
209 | 64EA8A001A0711DB00A9CF4C /* Images.xcassets in Resources */,
210 | );
211 | runOnlyForDeploymentPostprocessing = 0;
212 | };
213 | 64EA8A061A0711DB00A9CF4C /* Resources */ = {
214 | isa = PBXResourcesBuildPhase;
215 | buildActionMask = 2147483647;
216 | files = (
217 | );
218 | runOnlyForDeploymentPostprocessing = 0;
219 | };
220 | /* End PBXResourcesBuildPhase section */
221 |
222 | /* Begin PBXSourcesBuildPhase section */
223 | 64EA89E81A0711DB00A9CF4C /* Sources */ = {
224 | isa = PBXSourcesBuildPhase;
225 | buildActionMask = 2147483647;
226 | files = (
227 | 64EA89F51A0711DB00A9CF4C /* AppDelegate.m in Sources */,
228 | 64EA89F81A0711DB00A9CF4C /* MasterViewController.m in Sources */,
229 | 64EA89F21A0711DB00A9CF4C /* main.m in Sources */,
230 | 64EA89FB1A0711DB00A9CF4C /* DetailViewController.m in Sources */,
231 | );
232 | runOnlyForDeploymentPostprocessing = 0;
233 | };
234 | 64EA8A041A0711DB00A9CF4C /* Sources */ = {
235 | isa = PBXSourcesBuildPhase;
236 | buildActionMask = 2147483647;
237 | files = (
238 | 64EA8A0F1A0711DB00A9CF4C /* ScaryBugsTests.m in Sources */,
239 | );
240 | runOnlyForDeploymentPostprocessing = 0;
241 | };
242 | /* End PBXSourcesBuildPhase section */
243 |
244 | /* Begin PBXTargetDependency section */
245 | 64EA8A0A1A0711DB00A9CF4C /* PBXTargetDependency */ = {
246 | isa = PBXTargetDependency;
247 | target = 64EA89EB1A0711DB00A9CF4C /* ScaryBugs */;
248 | targetProxy = 64EA8A091A0711DB00A9CF4C /* PBXContainerItemProxy */;
249 | };
250 | /* End PBXTargetDependency section */
251 |
252 | /* Begin PBXVariantGroup section */
253 | 64EA89FC1A0711DB00A9CF4C /* Main.storyboard */ = {
254 | isa = PBXVariantGroup;
255 | children = (
256 | 64EA89FD1A0711DB00A9CF4C /* Base */,
257 | );
258 | name = Main.storyboard;
259 | sourceTree = "";
260 | };
261 | 64EA8A011A0711DB00A9CF4C /* LaunchScreen.xib */ = {
262 | isa = PBXVariantGroup;
263 | children = (
264 | 64EA8A021A0711DB00A9CF4C /* Base */,
265 | );
266 | name = LaunchScreen.xib;
267 | sourceTree = "";
268 | };
269 | /* End PBXVariantGroup section */
270 |
271 | /* Begin XCBuildConfiguration section */
272 | 64EA8A101A0711DB00A9CF4C /* Debug */ = {
273 | isa = XCBuildConfiguration;
274 | buildSettings = {
275 | ALWAYS_SEARCH_USER_PATHS = NO;
276 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
277 | CLANG_CXX_LIBRARY = "libc++";
278 | CLANG_ENABLE_MODULES = YES;
279 | CLANG_ENABLE_OBJC_ARC = YES;
280 | CLANG_WARN_BOOL_CONVERSION = YES;
281 | CLANG_WARN_CONSTANT_CONVERSION = YES;
282 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
283 | CLANG_WARN_EMPTY_BODY = YES;
284 | CLANG_WARN_ENUM_CONVERSION = YES;
285 | CLANG_WARN_INT_CONVERSION = YES;
286 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
287 | CLANG_WARN_UNREACHABLE_CODE = YES;
288 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
289 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
290 | COPY_PHASE_STRIP = NO;
291 | ENABLE_STRICT_OBJC_MSGSEND = YES;
292 | GCC_C_LANGUAGE_STANDARD = gnu99;
293 | GCC_DYNAMIC_NO_PIC = NO;
294 | GCC_OPTIMIZATION_LEVEL = 0;
295 | GCC_PREPROCESSOR_DEFINITIONS = (
296 | "DEBUG=1",
297 | "$(inherited)",
298 | );
299 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
300 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
301 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
302 | GCC_WARN_UNDECLARED_SELECTOR = YES;
303 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
304 | GCC_WARN_UNUSED_FUNCTION = YES;
305 | GCC_WARN_UNUSED_VARIABLE = YES;
306 | IPHONEOS_DEPLOYMENT_TARGET = 8.1;
307 | MTL_ENABLE_DEBUG_INFO = YES;
308 | ONLY_ACTIVE_ARCH = YES;
309 | SDKROOT = iphoneos;
310 | };
311 | name = Debug;
312 | };
313 | 64EA8A111A0711DB00A9CF4C /* Release */ = {
314 | isa = XCBuildConfiguration;
315 | buildSettings = {
316 | ALWAYS_SEARCH_USER_PATHS = NO;
317 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
318 | CLANG_CXX_LIBRARY = "libc++";
319 | CLANG_ENABLE_MODULES = YES;
320 | CLANG_ENABLE_OBJC_ARC = YES;
321 | CLANG_WARN_BOOL_CONVERSION = YES;
322 | CLANG_WARN_CONSTANT_CONVERSION = YES;
323 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
324 | CLANG_WARN_EMPTY_BODY = YES;
325 | CLANG_WARN_ENUM_CONVERSION = YES;
326 | CLANG_WARN_INT_CONVERSION = YES;
327 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
328 | CLANG_WARN_UNREACHABLE_CODE = YES;
329 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
330 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
331 | COPY_PHASE_STRIP = YES;
332 | ENABLE_NS_ASSERTIONS = NO;
333 | ENABLE_STRICT_OBJC_MSGSEND = YES;
334 | GCC_C_LANGUAGE_STANDARD = gnu99;
335 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
336 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
337 | GCC_WARN_UNDECLARED_SELECTOR = YES;
338 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
339 | GCC_WARN_UNUSED_FUNCTION = YES;
340 | GCC_WARN_UNUSED_VARIABLE = YES;
341 | IPHONEOS_DEPLOYMENT_TARGET = 8.1;
342 | MTL_ENABLE_DEBUG_INFO = NO;
343 | SDKROOT = iphoneos;
344 | VALIDATE_PRODUCT = YES;
345 | };
346 | name = Release;
347 | };
348 | 64EA8A131A0711DB00A9CF4C /* Debug */ = {
349 | isa = XCBuildConfiguration;
350 | buildSettings = {
351 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
352 | INFOPLIST_FILE = ScaryBugs/Info.plist;
353 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
354 | PRODUCT_NAME = "$(TARGET_NAME)";
355 | };
356 | name = Debug;
357 | };
358 | 64EA8A141A0711DB00A9CF4C /* Release */ = {
359 | isa = XCBuildConfiguration;
360 | buildSettings = {
361 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
362 | INFOPLIST_FILE = ScaryBugs/Info.plist;
363 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
364 | PRODUCT_NAME = "$(TARGET_NAME)";
365 | };
366 | name = Release;
367 | };
368 | 64EA8A161A0711DB00A9CF4C /* Debug */ = {
369 | isa = XCBuildConfiguration;
370 | buildSettings = {
371 | BUNDLE_LOADER = "$(TEST_HOST)";
372 | FRAMEWORK_SEARCH_PATHS = (
373 | "$(SDKROOT)/Developer/Library/Frameworks",
374 | "$(inherited)",
375 | );
376 | GCC_PREPROCESSOR_DEFINITIONS = (
377 | "DEBUG=1",
378 | "$(inherited)",
379 | );
380 | INFOPLIST_FILE = ScaryBugsTests/Info.plist;
381 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
382 | PRODUCT_NAME = "$(TARGET_NAME)";
383 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ScaryBugs.app/ScaryBugs";
384 | };
385 | name = Debug;
386 | };
387 | 64EA8A171A0711DB00A9CF4C /* Release */ = {
388 | isa = XCBuildConfiguration;
389 | buildSettings = {
390 | BUNDLE_LOADER = "$(TEST_HOST)";
391 | FRAMEWORK_SEARCH_PATHS = (
392 | "$(SDKROOT)/Developer/Library/Frameworks",
393 | "$(inherited)",
394 | );
395 | INFOPLIST_FILE = ScaryBugsTests/Info.plist;
396 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
397 | PRODUCT_NAME = "$(TARGET_NAME)";
398 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ScaryBugs.app/ScaryBugs";
399 | };
400 | name = Release;
401 | };
402 | /* End XCBuildConfiguration section */
403 |
404 | /* Begin XCConfigurationList section */
405 | 64EA89E71A0711DB00A9CF4C /* Build configuration list for PBXProject "ScaryBugs" */ = {
406 | isa = XCConfigurationList;
407 | buildConfigurations = (
408 | 64EA8A101A0711DB00A9CF4C /* Debug */,
409 | 64EA8A111A0711DB00A9CF4C /* Release */,
410 | );
411 | defaultConfigurationIsVisible = 0;
412 | defaultConfigurationName = Release;
413 | };
414 | 64EA8A121A0711DB00A9CF4C /* Build configuration list for PBXNativeTarget "ScaryBugs" */ = {
415 | isa = XCConfigurationList;
416 | buildConfigurations = (
417 | 64EA8A131A0711DB00A9CF4C /* Debug */,
418 | 64EA8A141A0711DB00A9CF4C /* Release */,
419 | );
420 | defaultConfigurationIsVisible = 0;
421 | };
422 | 64EA8A151A0711DB00A9CF4C /* Build configuration list for PBXNativeTarget "ScaryBugsTests" */ = {
423 | isa = XCConfigurationList;
424 | buildConfigurations = (
425 | 64EA8A161A0711DB00A9CF4C /* Debug */,
426 | 64EA8A171A0711DB00A9CF4C /* Release */,
427 | );
428 | defaultConfigurationIsVisible = 0;
429 | };
430 | /* End XCConfigurationList section */
431 | };
432 | rootObject = 64EA89E41A0711DB00A9CF4C /* Project object */;
433 | }
434 |
--------------------------------------------------------------------------------
/ZhouShaoXiang/ScaryBugs/ScaryBugs/SVProgressHUD.m:
--------------------------------------------------------------------------------
1 | //
2 | // SVProgressHUD.m
3 | //
4 | // Created by Sam Vermette on 27.03.11.
5 | // Copyright 2011 Sam Vermette. All rights reserved.
6 | //
7 | // https://github.com/samvermette/SVProgressHUD
8 | //
9 |
10 | #if !__has_feature(objc_arc)
11 | #error SVProgressHUD is ARC only. Either turn on ARC for the project or use -fobjc-arc flag
12 | #endif
13 |
14 | #import "SVProgressHUD.h"
15 | #import
16 |
17 | NSString * const SVProgressHUDDidReceiveTouchEventNotification = @"SVProgressHUDDidReceiveTouchEventNotification";
18 | NSString * const SVProgressHUDWillDisappearNotification = @"SVProgressHUDWillDisappearNotification";
19 | NSString * const SVProgressHUDDidDisappearNotification = @"SVProgressHUDDidDisappearNotification";
20 | NSString * const SVProgressHUDWillAppearNotification = @"SVProgressHUDWillAppearNotification";
21 | NSString * const SVProgressHUDDidAppearNotification = @"SVProgressHUDDidAppearNotification";
22 |
23 | NSString * const SVProgressHUDStatusUserInfoKey = @"SVProgressHUDStatusUserInfoKey";
24 |
25 | static UIColor *SVProgressHUDBackgroundColor;
26 | static UIColor *SVProgressHUDForegroundColor;
27 | static CGFloat SVProgressHUDRingThickness;
28 | static UIFont *SVProgressHUDFont;
29 | static UIImage *SVProgressHUDSuccessImage;
30 | static UIImage *SVProgressHUDErrorImage;
31 |
32 | static const CGFloat SVProgressHUDRingRadius = 18;
33 | static const CGFloat SVProgressHUDRingNoTextRadius = 24;
34 | static const CGFloat SVProgressHUDParallaxDepthPoints = 10;
35 |
36 | @interface SVProgressHUD ()
37 |
38 | @property (nonatomic, readwrite) SVProgressHUDMaskType maskType;
39 | @property (nonatomic, strong, readonly) NSTimer *fadeOutTimer;
40 | @property (nonatomic, readonly, getter = isClear) BOOL clear;
41 |
42 | @property (nonatomic, strong) UIControl *overlayView;
43 | @property (nonatomic, strong) UIView *hudView;
44 | @property (nonatomic, strong) UILabel *stringLabel;
45 | @property (nonatomic, strong) UIImageView *imageView;
46 | @property (nonatomic, strong) SVIndefiniteAnimatedView *indefiniteAnimatedView;
47 |
48 | @property (nonatomic, readwrite) CGFloat progress;
49 | @property (nonatomic, readwrite) NSUInteger activityCount;
50 | @property (nonatomic, strong) CAShapeLayer *backgroundRingLayer;
51 | @property (nonatomic, strong) CAShapeLayer *ringLayer;
52 |
53 | @property (nonatomic, readonly) CGFloat visibleKeyboardHeight;
54 | @property (nonatomic, assign) UIOffset offsetFromCenter;
55 |
56 |
57 | - (void)showProgress:(float)progress
58 | status:(NSString*)string
59 | maskType:(SVProgressHUDMaskType)hudMaskType;
60 |
61 | - (void)showImage:(UIImage*)image
62 | status:(NSString*)status
63 | duration:(NSTimeInterval)duration;
64 |
65 | - (void)dismiss;
66 |
67 | - (void)setStatus:(NSString*)string;
68 | - (void)registerNotifications;
69 | - (NSDictionary *)notificationUserInfo;
70 | - (void)moveToPoint:(CGPoint)newCenter rotateAngle:(CGFloat)angle;
71 | - (void)positionHUD:(NSNotification*)notification;
72 | - (NSTimeInterval)displayDurationForString:(NSString*)string;
73 |
74 | @end
75 |
76 |
77 | @implementation SVProgressHUD
78 |
79 | + (SVProgressHUD*)sharedView {
80 | static dispatch_once_t once;
81 | static SVProgressHUD *sharedView;
82 | dispatch_once(&once, ^ { sharedView = [[self alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; });
83 | return sharedView;
84 | }
85 |
86 | #pragma mark - Setters
87 |
88 | + (void)setStatus:(NSString *)string {
89 | [[self sharedView] setStatus:string];
90 | }
91 |
92 | + (void)setBackgroundColor:(UIColor *)color {
93 | [self sharedView].hudView.backgroundColor = color;
94 | SVProgressHUDBackgroundColor = color;
95 | }
96 |
97 | + (void)setForegroundColor:(UIColor *)color {
98 | [self sharedView];
99 | SVProgressHUDForegroundColor = color;
100 | }
101 |
102 | + (void)setFont:(UIFont *)font {
103 | [self sharedView];
104 | SVProgressHUDFont = font;
105 | }
106 |
107 | + (void)setRingThickness:(CGFloat)width {
108 | [self sharedView];
109 | SVProgressHUDRingThickness = width;
110 | }
111 |
112 | + (void)setSuccessImage:(UIImage *)image {
113 | [self sharedView];
114 | SVProgressHUDSuccessImage = image;
115 | }
116 |
117 | + (void)setErrorImage:(UIImage *)image {
118 | [self sharedView];
119 | SVProgressHUDErrorImage = image;
120 | }
121 |
122 | #pragma mark - Show Methods
123 |
124 | + (void)show {
125 | [[self sharedView] showProgress:-1 status:nil maskType:SVProgressHUDMaskTypeNone];
126 | }
127 |
128 | + (void)showWithStatus:(NSString *)status {
129 | [[self sharedView] showProgress:-1 status:status maskType:SVProgressHUDMaskTypeNone];
130 | }
131 |
132 | + (void)showWithMaskType:(SVProgressHUDMaskType)maskType {
133 | [[self sharedView] showProgress:-1 status:nil maskType:maskType];
134 | }
135 |
136 | + (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType {
137 | [[self sharedView] showProgress:-1 status:status maskType:maskType];
138 | }
139 |
140 | + (void)showProgress:(float)progress {
141 | [[self sharedView] showProgress:progress status:nil maskType:SVProgressHUDMaskTypeNone];
142 | }
143 |
144 | + (void)showProgress:(float)progress status:(NSString *)status {
145 | [[self sharedView] showProgress:progress status:status maskType:SVProgressHUDMaskTypeNone];
146 | }
147 |
148 | + (void)showProgress:(float)progress status:(NSString *)status maskType:(SVProgressHUDMaskType)maskType {
149 | [[self sharedView] showProgress:progress status:status maskType:maskType];
150 | }
151 |
152 | #pragma mark - Show then dismiss methods
153 |
154 | + (void)showSuccessWithStatus:(NSString *)string {
155 | [self sharedView];
156 | [self showImage:SVProgressHUDSuccessImage status:string];
157 | }
158 |
159 | + (void)showErrorWithStatus:(NSString *)string {
160 | [self sharedView];
161 | [self showImage:SVProgressHUDErrorImage status:string];
162 | }
163 |
164 | + (void)showImage:(UIImage *)image status:(NSString *)string {
165 | NSTimeInterval displayInterval = [[SVProgressHUD sharedView] displayDurationForString:string];
166 | [[self sharedView] showImage:image status:string duration:displayInterval];
167 | }
168 |
169 |
170 | #pragma mark - Dismiss Methods
171 |
172 | + (void)popActivity {
173 | [self sharedView].activityCount--;
174 | if([self sharedView].activityCount == 0)
175 | [[self sharedView] dismiss];
176 | }
177 |
178 | + (void)dismiss {
179 | if ([self isVisible]) {
180 | [[self sharedView] dismiss];
181 | }
182 | }
183 |
184 |
185 | #pragma mark - Offset
186 |
187 | + (void)setOffsetFromCenter:(UIOffset)offset {
188 | [self sharedView].offsetFromCenter = offset;
189 | }
190 |
191 | + (void)resetOffsetFromCenter {
192 | [self setOffsetFromCenter:UIOffsetZero];
193 | }
194 |
195 | #pragma mark - Instance Methods
196 |
197 | - (id)initWithFrame:(CGRect)frame {
198 |
199 | if ((self = [super initWithFrame:frame])) {
200 | self.userInteractionEnabled = NO;
201 | self.backgroundColor = [UIColor clearColor];
202 | self.alpha = 0;
203 | self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
204 | self.activityCount = 0;
205 |
206 | SVProgressHUDBackgroundColor = [UIColor whiteColor];
207 | SVProgressHUDForegroundColor = [UIColor blackColor];
208 | if ([UIFont respondsToSelector:@selector(preferredFontForTextStyle:)]) {
209 | SVProgressHUDFont = [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline];
210 | } else {
211 | SVProgressHUDFont = [UIFont systemFontOfSize:14.0];
212 | SVProgressHUDBackgroundColor = [UIColor colorWithWhite:0 alpha:0.8];
213 | SVProgressHUDForegroundColor = [UIColor whiteColor];
214 | }
215 | if ([[UIImage class] instancesRespondToSelector:@selector(imageWithRenderingMode:)]) {
216 | SVProgressHUDSuccessImage = [[UIImage imageNamed:@"SVProgressHUD.bundle/success"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
217 | SVProgressHUDErrorImage = [[UIImage imageNamed:@"SVProgressHUD.bundle/error"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
218 | } else {
219 | SVProgressHUDSuccessImage = [UIImage imageNamed:@"SVProgressHUD.bundle/success"];
220 | SVProgressHUDErrorImage = [UIImage imageNamed:@"SVProgressHUD.bundle/error"];
221 | }
222 | SVProgressHUDRingThickness = 4;
223 | }
224 |
225 | return self;
226 | }
227 |
228 | - (void)drawRect:(CGRect)rect {
229 |
230 | CGContextRef context = UIGraphicsGetCurrentContext();
231 |
232 | switch (self.maskType) {
233 |
234 | case SVProgressHUDMaskTypeBlack: {
235 | [[UIColor colorWithWhite:0 alpha:0.5] set];
236 | CGContextFillRect(context, self.bounds);
237 | break;
238 | }
239 |
240 | case SVProgressHUDMaskTypeGradient: {
241 |
242 | size_t locationsCount = 2;
243 | CGFloat locations[2] = {0.0f, 1.0f};
244 | CGFloat colors[8] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.75f};
245 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
246 | CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, locationsCount);
247 | CGColorSpaceRelease(colorSpace);
248 |
249 | CGFloat freeHeight = self.bounds.size.height - self.visibleKeyboardHeight;
250 |
251 | CGPoint center = CGPointMake(self.bounds.size.width/2, freeHeight/2);
252 | float radius = MIN(self.bounds.size.width , self.bounds.size.height) ;
253 | CGContextDrawRadialGradient (context, gradient, center, 0, center, radius, kCGGradientDrawsAfterEndLocation);
254 | CGGradientRelease(gradient);
255 |
256 | break;
257 | }
258 | }
259 | }
260 |
261 | - (void)updatePosition {
262 |
263 | CGFloat hudWidth = 100;
264 | CGFloat hudHeight = 100;
265 | CGFloat stringHeightBuffer = 20;
266 | CGFloat stringAndImageHeightBuffer = 80;
267 |
268 | CGFloat stringWidth = 0;
269 | CGFloat stringHeight = 0;
270 | CGRect labelRect = CGRectZero;
271 |
272 | NSString *string = self.stringLabel.text;
273 | // False if it's text-only
274 | BOOL imageUsed = (self.imageView.image) || (self.imageView.hidden);
275 |
276 | if(string) {
277 | CGSize constraintSize = CGSizeMake(200, 300);
278 | CGRect stringRect;
279 | if ([string respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
280 | stringRect = [string boundingRectWithSize:constraintSize
281 | options:(NSStringDrawingUsesFontLeading|NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin)
282 | attributes:@{NSFontAttributeName: self.stringLabel.font}
283 | context:NULL];
284 | } else {
285 | CGSize stringSize;
286 | #ifdef __IPHONE_8_0
287 | stringSize = [string sizeWithAttributes:@{NSFontAttributeName:[UIFont fontWithName:self.stringLabel.font.fontName size:self.stringLabel.font.pointSize]}];
288 | #else
289 | stringSize = [string sizeWithFont:self.stringLabel.font constrainedToSize:CGSizeMake(200, 300)];
290 | #endif
291 | stringRect = CGRectMake(0.0f, 0.0f, stringSize.width, stringSize.height);
292 | }
293 | stringWidth = stringRect.size.width;
294 | stringHeight = ceil(stringRect.size.height);
295 |
296 | if (imageUsed)
297 | hudHeight = stringAndImageHeightBuffer + stringHeight;
298 | else
299 | hudHeight = stringHeightBuffer + stringHeight;
300 |
301 | if(stringWidth > hudWidth)
302 | hudWidth = ceil(stringWidth/2)*2;
303 |
304 | CGFloat labelRectY = imageUsed ? 68 : 9;
305 |
306 | if(hudHeight > 100) {
307 | labelRect = CGRectMake(12, labelRectY, hudWidth, stringHeight);
308 | hudWidth+=24;
309 | } else {
310 | hudWidth+=24;
311 | labelRect = CGRectMake(0, labelRectY, hudWidth, stringHeight);
312 | }
313 | }
314 |
315 | self.hudView.bounds = CGRectMake(0, 0, hudWidth, hudHeight);
316 |
317 | if(string)
318 | self.imageView.center = CGPointMake(CGRectGetWidth(self.hudView.bounds)/2, 36);
319 | else
320 | self.imageView.center = CGPointMake(CGRectGetWidth(self.hudView.bounds)/2, CGRectGetHeight(self.hudView.bounds)/2);
321 |
322 | self.stringLabel.hidden = NO;
323 | self.stringLabel.frame = labelRect;
324 |
325 | [CATransaction begin];
326 | [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
327 |
328 | if(string) {
329 | self.indefiniteAnimatedView.radius = SVProgressHUDRingRadius;
330 | [self.indefiniteAnimatedView sizeToFit];
331 |
332 | CGPoint center = CGPointMake((CGRectGetWidth(self.hudView.bounds)/2), 36);
333 | self.indefiniteAnimatedView.center = center;
334 |
335 | if(self.progress != -1)
336 | self.backgroundRingLayer.position = self.ringLayer.position = CGPointMake((CGRectGetWidth(self.hudView.bounds)/2), 36);
337 | }
338 | else {
339 | self.indefiniteAnimatedView.radius = SVProgressHUDRingNoTextRadius;
340 | [self.indefiniteAnimatedView sizeToFit];
341 |
342 | CGPoint center = CGPointMake((CGRectGetWidth(self.hudView.bounds)/2), CGRectGetHeight(self.hudView.bounds)/2);
343 | self.indefiniteAnimatedView.center = center;
344 |
345 | if(self.progress != -1)
346 | self.backgroundRingLayer.position = self.ringLayer.position = CGPointMake((CGRectGetWidth(self.hudView.bounds)/2), CGRectGetHeight(self.hudView.bounds)/2);
347 | }
348 |
349 | [CATransaction commit];
350 | }
351 |
352 | - (void)setStatus:(NSString *)string {
353 |
354 | self.stringLabel.text = string;
355 | [self updatePosition];
356 |
357 | }
358 |
359 | - (void)setFadeOutTimer:(NSTimer *)newTimer {
360 |
361 | if(_fadeOutTimer)
362 | [_fadeOutTimer invalidate], _fadeOutTimer = nil;
363 |
364 | if(newTimer)
365 | _fadeOutTimer = newTimer;
366 | }
367 |
368 |
369 | - (void)registerNotifications {
370 | [[NSNotificationCenter defaultCenter] addObserver:self
371 | selector:@selector(positionHUD:)
372 | name:UIApplicationDidChangeStatusBarOrientationNotification
373 | object:nil];
374 |
375 | [[NSNotificationCenter defaultCenter] addObserver:self
376 | selector:@selector(positionHUD:)
377 | name:UIKeyboardWillHideNotification
378 | object:nil];
379 |
380 | [[NSNotificationCenter defaultCenter] addObserver:self
381 | selector:@selector(positionHUD:)
382 | name:UIKeyboardDidHideNotification
383 | object:nil];
384 |
385 | [[NSNotificationCenter defaultCenter] addObserver:self
386 | selector:@selector(positionHUD:)
387 | name:UIKeyboardWillShowNotification
388 | object:nil];
389 |
390 | [[NSNotificationCenter defaultCenter] addObserver:self
391 | selector:@selector(positionHUD:)
392 | name:UIKeyboardDidShowNotification
393 | object:nil];
394 | }
395 |
396 |
397 | - (NSDictionary *)notificationUserInfo
398 | {
399 | return (self.stringLabel.text ? @{SVProgressHUDStatusUserInfoKey : self.stringLabel.text} : nil);
400 | }
401 |
402 |
403 | - (void)positionHUD:(NSNotification*)notification {
404 |
405 | CGFloat keyboardHeight;
406 | double animationDuration;
407 |
408 | UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
409 | // no transforms applied to window in iOS 8, but only if compiled with iOS 8 sdk as base sdk, otherwise system supports old rotation logic.
410 | BOOL ignoreOrientation = NO;
411 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
412 | if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) {
413 | ignoreOrientation = YES;
414 | }
415 | #endif
416 |
417 | if(notification) {
418 | NSDictionary* keyboardInfo = [notification userInfo];
419 | CGRect keyboardFrame = [[keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
420 | animationDuration = [[keyboardInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
421 |
422 | if(notification.name == UIKeyboardWillShowNotification || notification.name == UIKeyboardDidShowNotification) {
423 | if(ignoreOrientation || UIInterfaceOrientationIsPortrait(orientation))
424 | keyboardHeight = keyboardFrame.size.height;
425 | else
426 | keyboardHeight = keyboardFrame.size.width;
427 | } else
428 | keyboardHeight = 0;
429 | } else {
430 | keyboardHeight = self.visibleKeyboardHeight;
431 | }
432 |
433 | CGRect orientationFrame = self.window.bounds;
434 | CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;
435 |
436 | if(!ignoreOrientation && UIInterfaceOrientationIsLandscape(orientation)) {
437 | float temp = orientationFrame.size.width;
438 | orientationFrame.size.width = orientationFrame.size.height;
439 | orientationFrame.size.height = temp;
440 |
441 | temp = statusBarFrame.size.width;
442 | statusBarFrame.size.width = statusBarFrame.size.height;
443 | statusBarFrame.size.height = temp;
444 | }
445 |
446 | CGFloat activeHeight = orientationFrame.size.height;
447 |
448 | if(keyboardHeight > 0)
449 | activeHeight += statusBarFrame.size.height*2;
450 |
451 | activeHeight -= keyboardHeight;
452 | CGFloat posY = floor(activeHeight*0.45);
453 | CGFloat posX = orientationFrame.size.width/2;
454 |
455 | CGPoint newCenter;
456 | CGFloat rotateAngle;
457 |
458 | if (ignoreOrientation) {
459 | rotateAngle = 0.0;
460 | newCenter = CGPointMake(posX, posY);
461 | } else {
462 | switch (orientation) {
463 | case UIInterfaceOrientationPortraitUpsideDown:
464 | rotateAngle = M_PI;
465 | newCenter = CGPointMake(posX, orientationFrame.size.height-posY);
466 | break;
467 | case UIInterfaceOrientationLandscapeLeft:
468 | rotateAngle = -M_PI/2.0f;
469 | newCenter = CGPointMake(posY, posX);
470 | break;
471 | case UIInterfaceOrientationLandscapeRight:
472 | rotateAngle = M_PI/2.0f;
473 | newCenter = CGPointMake(orientationFrame.size.height-posY, posX);
474 | break;
475 | default: // as UIInterfaceOrientationPortrait
476 | rotateAngle = 0.0;
477 | newCenter = CGPointMake(posX, posY);
478 | break;
479 | }
480 | }
481 |
482 | if(notification) {
483 | [UIView animateWithDuration:animationDuration
484 | delay:0
485 | options:UIViewAnimationOptionAllowUserInteraction
486 | animations:^{
487 | [self moveToPoint:newCenter rotateAngle:rotateAngle];
488 | } completion:NULL];
489 | }
490 |
491 | else {
492 | [self moveToPoint:newCenter rotateAngle:rotateAngle];
493 | }
494 |
495 | }
496 |
497 | - (void)moveToPoint:(CGPoint)newCenter rotateAngle:(CGFloat)angle {
498 | self.hudView.transform = CGAffineTransformMakeRotation(angle);
499 | self.hudView.center = CGPointMake(newCenter.x + self.offsetFromCenter.horizontal, newCenter.y + self.offsetFromCenter.vertical);
500 | }
501 |
502 | - (void)overlayViewDidReceiveTouchEvent:(id)sender forEvent:(UIEvent *)event {
503 | [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidReceiveTouchEventNotification object:event];
504 | }
505 |
506 | #pragma mark - Master show/dismiss methods
507 |
508 | - (void)showProgress:(float)progress status:(NSString*)string maskType:(SVProgressHUDMaskType)hudMaskType {
509 |
510 | if(!self.overlayView.superview){
511 | NSEnumerator *frontToBackWindows = [[[UIApplication sharedApplication]windows]reverseObjectEnumerator];
512 |
513 | for (UIWindow *window in frontToBackWindows)
514 | if (window.windowLevel == UIWindowLevelNormal) {
515 | [window addSubview:self.overlayView];
516 | break;
517 | }
518 | }
519 |
520 | if(!self.superview)
521 | [self.overlayView addSubview:self];
522 |
523 | self.fadeOutTimer = nil;
524 | self.imageView.hidden = YES;
525 | self.maskType = hudMaskType;
526 | self.progress = progress;
527 |
528 | self.stringLabel.text = string;
529 | [self updatePosition];
530 |
531 | if(progress >= 0) {
532 | self.imageView.image = nil;
533 | self.imageView.hidden = NO;
534 | [self.indefiniteAnimatedView removeFromSuperview];
535 |
536 | self.ringLayer.strokeEnd = progress;
537 |
538 | if(progress == 0)
539 | self.activityCount++;
540 | }
541 | else {
542 | self.activityCount++;
543 | [self cancelRingLayerAnimation];
544 | [self.hudView addSubview:self.indefiniteAnimatedView];
545 | }
546 |
547 | if(self.maskType != SVProgressHUDMaskTypeNone) {
548 | self.overlayView.userInteractionEnabled = YES;
549 | self.accessibilityLabel = string;
550 | self.isAccessibilityElement = YES;
551 | }
552 | else {
553 | self.overlayView.userInteractionEnabled = NO;
554 | self.hudView.accessibilityLabel = string;
555 | self.hudView.isAccessibilityElement = YES;
556 | }
557 |
558 | [self.overlayView setHidden:NO];
559 | self.overlayView.backgroundColor = [UIColor clearColor];
560 | [self positionHUD:nil];
561 |
562 | if(self.alpha != 1) {
563 | NSDictionary *userInfo = [self notificationUserInfo];
564 | [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDWillAppearNotification
565 | object:nil
566 | userInfo:userInfo];
567 |
568 | [self registerNotifications];
569 | self.hudView.transform = CGAffineTransformScale(self.hudView.transform, 1.3, 1.3);
570 |
571 | if(self.isClear) {
572 | self.alpha = 1;
573 | self.hudView.alpha = 0;
574 | }
575 |
576 | [UIView animateWithDuration:0.15
577 | delay:0
578 | options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState
579 | animations:^{
580 | self.hudView.transform = CGAffineTransformScale(self.hudView.transform, 1/1.3, 1/1.3);
581 |
582 | if(self.isClear) // handle iOS 7 UIToolbar not answer well to hierarchy opacity change
583 | self.hudView.alpha = 1;
584 | else
585 | self.alpha = 1;
586 | }
587 | completion:^(BOOL finished){
588 | [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidAppearNotification
589 | object:nil
590 | userInfo:userInfo];
591 | UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil);
592 | UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, string);
593 | }];
594 |
595 | [self setNeedsDisplay];
596 | }
597 | }
598 |
599 | - (UIImage *)image:(UIImage *)image withTintColor:(UIColor *)color
600 | {
601 | CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
602 | UIGraphicsBeginImageContextWithOptions(rect.size, NO, image.scale);
603 | CGContextRef c = UIGraphicsGetCurrentContext();
604 | [image drawInRect:rect];
605 | CGContextSetFillColorWithColor(c, [color CGColor]);
606 | CGContextSetBlendMode(c, kCGBlendModeSourceAtop);
607 | CGContextFillRect(c, rect);
608 | UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext();
609 | UIGraphicsEndImageContext();
610 | return tintedImage;
611 | }
612 |
613 | - (void)showImage:(UIImage *)image status:(NSString *)string duration:(NSTimeInterval)duration {
614 | self.progress = -1;
615 | [self cancelRingLayerAnimation];
616 |
617 | if(![self.class isVisible])
618 | [self.class show];
619 |
620 | if ([self.imageView respondsToSelector:@selector(setTintColor:)]) {
621 | self.imageView.tintColor = SVProgressHUDForegroundColor;
622 | } else {
623 | image = [self image:image withTintColor:SVProgressHUDForegroundColor];
624 | }
625 | self.imageView.image = image;
626 | self.imageView.hidden = NO;
627 |
628 | self.stringLabel.text = string;
629 | [self updatePosition];
630 | [self.indefiniteAnimatedView removeFromSuperview];
631 |
632 | if(self.maskType != SVProgressHUDMaskTypeNone) {
633 | self.accessibilityLabel = string;
634 | self.isAccessibilityElement = YES;
635 | } else {
636 | self.hudView.accessibilityLabel = string;
637 | self.hudView.isAccessibilityElement = YES;
638 | }
639 |
640 | UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil);
641 | UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, string);
642 |
643 | self.fadeOutTimer = [NSTimer timerWithTimeInterval:duration target:self selector:@selector(dismiss) userInfo:nil repeats:NO];
644 | [[NSRunLoop mainRunLoop] addTimer:self.fadeOutTimer forMode:NSRunLoopCommonModes];
645 | }
646 |
647 | - (void)dismiss {
648 | NSDictionary *userInfo = [self notificationUserInfo];
649 | [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDWillDisappearNotification
650 | object:nil
651 | userInfo:userInfo];
652 |
653 | self.activityCount = 0;
654 | [UIView animateWithDuration:0.15
655 | delay:0
656 | options:UIViewAnimationCurveEaseIn | UIViewAnimationOptionAllowUserInteraction
657 | animations:^{
658 | self.hudView.transform = CGAffineTransformScale(self.hudView.transform, 0.8, 0.8);
659 | if(self.isClear) // handle iOS 7 UIToolbar not answer well to hierarchy opacity change
660 | self.hudView.alpha = 0;
661 | else
662 | self.alpha = 0;
663 | }
664 | completion:^(BOOL finished){
665 | if(self.alpha == 0 || self.hudView.alpha == 0) {
666 | self.alpha = 0;
667 | self.hudView.alpha = 0;
668 |
669 | [[NSNotificationCenter defaultCenter] removeObserver:self];
670 | [self cancelRingLayerAnimation];
671 | [_hudView removeFromSuperview];
672 | _hudView = nil;
673 |
674 | [_overlayView removeFromSuperview];
675 | _overlayView = nil;
676 |
677 | [_indefiniteAnimatedView removeFromSuperview];
678 | _indefiniteAnimatedView = nil;
679 |
680 | UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil);
681 |
682 | [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidDisappearNotification
683 | object:nil
684 | userInfo:userInfo];
685 |
686 | // Tell the rootViewController to update the StatusBar appearance
687 | UIViewController *rootController = [[UIApplication sharedApplication] keyWindow].rootViewController;
688 | if ([rootController respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {
689 | [rootController setNeedsStatusBarAppearanceUpdate];
690 | }
691 | // uncomment to make sure UIWindow is gone from app.windows
692 | //NSLog(@"%@", [UIApplication sharedApplication].windows);
693 | //NSLog(@"keyWindow = %@", [UIApplication sharedApplication].keyWindow);
694 | }
695 | }];
696 | }
697 |
698 |
699 | #pragma mark - Ring progress animation
700 |
701 | - (SVIndefiniteAnimatedView *)indefiniteAnimatedView {
702 | if (_indefiniteAnimatedView == nil) {
703 | _indefiniteAnimatedView = [[SVIndefiniteAnimatedView alloc] initWithFrame:CGRectZero];
704 | _indefiniteAnimatedView.radius = self.stringLabel.text ? SVProgressHUDRingRadius : SVProgressHUDRingNoTextRadius;
705 | [_indefiniteAnimatedView sizeToFit];
706 | }
707 | return _indefiniteAnimatedView;
708 | }
709 |
710 | - (CAShapeLayer *)ringLayer {
711 | if(!_ringLayer) {
712 | CGPoint center = CGPointMake(CGRectGetWidth(_hudView.frame)/2, CGRectGetHeight(_hudView.frame)/2);
713 | _ringLayer = [self createRingLayerWithCenter:center
714 | radius:SVProgressHUDRingRadius
715 | lineWidth:SVProgressHUDRingThickness
716 | color:SVProgressHUDForegroundColor];
717 | [self.hudView.layer addSublayer:_ringLayer];
718 | }
719 | return _ringLayer;
720 | }
721 |
722 | - (CAShapeLayer *)backgroundRingLayer {
723 | if(!_backgroundRingLayer) {
724 | CGPoint center = CGPointMake(CGRectGetWidth(_hudView.frame)/2, CGRectGetHeight(_hudView.frame)/2);
725 | _backgroundRingLayer = [self createRingLayerWithCenter:center
726 | radius:SVProgressHUDRingRadius
727 | lineWidth:SVProgressHUDRingThickness
728 | color:[SVProgressHUDForegroundColor colorWithAlphaComponent:0.1]];
729 | _backgroundRingLayer.strokeEnd = 1;
730 | [self.hudView.layer addSublayer:_backgroundRingLayer];
731 | }
732 | return _backgroundRingLayer;
733 | }
734 |
735 | - (void)cancelRingLayerAnimation {
736 | [CATransaction begin];
737 | [CATransaction setDisableActions:YES];
738 | [_hudView.layer removeAllAnimations];
739 |
740 | _ringLayer.strokeEnd = 0.0f;
741 | if (_ringLayer.superlayer) {
742 | [_ringLayer removeFromSuperlayer];
743 | }
744 | _ringLayer = nil;
745 |
746 | if (_backgroundRingLayer.superlayer) {
747 | [_backgroundRingLayer removeFromSuperlayer];
748 | }
749 | _backgroundRingLayer = nil;
750 |
751 | [CATransaction commit];
752 | }
753 |
754 | - (CAShapeLayer *)createRingLayerWithCenter:(CGPoint)center radius:(CGFloat)radius lineWidth:(CGFloat)lineWidth color:(UIColor *)color {
755 |
756 | UIBezierPath* smoothedPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(radius, radius) radius:radius startAngle:-M_PI_2 endAngle:(M_PI + M_PI_2) clockwise:YES];
757 |
758 | CAShapeLayer *slice = [CAShapeLayer layer];
759 | slice.contentsScale = [[UIScreen mainScreen] scale];
760 | slice.frame = CGRectMake(center.x-radius, center.y-radius, radius*2, radius*2);
761 | slice.fillColor = [UIColor clearColor].CGColor;
762 | slice.strokeColor = color.CGColor;
763 | slice.lineWidth = lineWidth;
764 | slice.lineCap = kCALineCapRound;
765 | slice.lineJoin = kCALineJoinBevel;
766 | slice.path = smoothedPath.CGPath;
767 | return slice;
768 | }
769 |
770 | #pragma mark - Utilities
771 |
772 | + (BOOL)isVisible {
773 | return ([self sharedView].alpha == 1);
774 | }
775 |
776 |
777 | #pragma mark - Getters
778 |
779 | - (NSTimeInterval)displayDurationForString:(NSString*)string {
780 | return MIN((float)string.length*0.06 + 0.3, 5.0);
781 | }
782 |
783 | - (BOOL)isClear { // used for iOS 7
784 | return (self.maskType == SVProgressHUDMaskTypeClear || self.maskType == SVProgressHUDMaskTypeNone);
785 | }
786 |
787 | - (UIControl *)overlayView {
788 | if(!_overlayView) {
789 | _overlayView = [[UIControl alloc] initWithFrame:[UIScreen mainScreen].bounds];
790 | _overlayView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
791 | _overlayView.backgroundColor = [UIColor clearColor];
792 | [_overlayView addTarget:self action:@selector(overlayViewDidReceiveTouchEvent:forEvent:) forControlEvents:UIControlEventTouchDown];
793 | }
794 | return _overlayView;
795 | }
796 |
797 | - (UIView *)hudView {
798 | if(!_hudView) {
799 | _hudView = [[UIView alloc] initWithFrame:CGRectZero];
800 | _hudView.backgroundColor = SVProgressHUDBackgroundColor;
801 | _hudView.layer.cornerRadius = 14;
802 | _hudView.layer.masksToBounds = YES;
803 |
804 | _hudView.autoresizingMask = (UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin |
805 | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin);
806 |
807 | if ([_hudView respondsToSelector:@selector(addMotionEffect:)]) {
808 | UIInterpolatingMotionEffect *effectX = [[UIInterpolatingMotionEffect alloc] initWithKeyPath: @"center.x" type: UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
809 | effectX.minimumRelativeValue = @(-SVProgressHUDParallaxDepthPoints);
810 | effectX.maximumRelativeValue = @(SVProgressHUDParallaxDepthPoints);
811 |
812 | UIInterpolatingMotionEffect *effectY = [[UIInterpolatingMotionEffect alloc] initWithKeyPath: @"center.y" type: UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
813 | effectY.minimumRelativeValue = @(-SVProgressHUDParallaxDepthPoints);
814 | effectY.maximumRelativeValue = @(SVProgressHUDParallaxDepthPoints);
815 |
816 | [_hudView addMotionEffect: effectX];
817 | [_hudView addMotionEffect: effectY];
818 | }
819 |
820 | [self addSubview:_hudView];
821 | }
822 | return _hudView;
823 | }
824 |
825 | - (UILabel *)stringLabel {
826 | if (_stringLabel == nil) {
827 | _stringLabel = [[UILabel alloc] initWithFrame:CGRectZero];
828 | _stringLabel.backgroundColor = [UIColor clearColor];
829 | _stringLabel.adjustsFontSizeToFitWidth = YES;
830 | _stringLabel.textAlignment = NSTextAlignmentCenter;
831 | _stringLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
832 | _stringLabel.textColor = SVProgressHUDForegroundColor;
833 | _stringLabel.font = SVProgressHUDFont;
834 | _stringLabel.numberOfLines = 0;
835 | }
836 |
837 | if(!_stringLabel.superview)
838 | [self.hudView addSubview:_stringLabel];
839 |
840 | return _stringLabel;
841 | }
842 |
843 | - (UIImageView *)imageView {
844 | if (_imageView == nil)
845 | _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 28, 28)];
846 |
847 | if(!_imageView.superview)
848 | [self.hudView addSubview:_imageView];
849 |
850 | return _imageView;
851 | }
852 |
853 |
854 | - (CGFloat)visibleKeyboardHeight {
855 |
856 | UIWindow *keyboardWindow = nil;
857 | for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
858 | if(![[testWindow class] isEqual:[UIWindow class]]) {
859 | keyboardWindow = testWindow;
860 | break;
861 | }
862 | }
863 |
864 | for (__strong UIView *possibleKeyboard in [keyboardWindow subviews]) {
865 | if([possibleKeyboard isKindOfClass:NSClassFromString(@"UIPeripheralHostView")] || [possibleKeyboard isKindOfClass:NSClassFromString(@"UIKeyboard")])
866 | return possibleKeyboard.bounds.size.height;
867 | }
868 |
869 | return 0;
870 | }
871 |
872 | @end
873 |
874 | #pragma mark SVIndefiniteAnimatedView
875 |
876 | @interface SVIndefiniteAnimatedView ()
877 |
878 | @property (nonatomic, strong) CAShapeLayer *indefiniteAnimatedLayer;
879 |
880 | @end
881 |
882 | @implementation SVIndefiniteAnimatedView
883 |
884 | - (id)initWithFrame:(CGRect)frame {
885 | if (self = [super initWithFrame:frame]) {
886 | self.strokeThickness = SVProgressHUDRingThickness;
887 | self.radius = SVProgressHUDRingRadius;
888 | self.strokeColor = SVProgressHUDForegroundColor;
889 | }
890 | return self;
891 | }
892 |
893 | - (void)willMoveToSuperview:(UIView *)newSuperview {
894 | if (newSuperview != nil) {
895 | [self layoutAnimatedLayer];
896 | }
897 | else {
898 | [_indefiniteAnimatedLayer removeFromSuperlayer];
899 | _indefiniteAnimatedLayer = nil;
900 | }
901 | }
902 |
903 | - (void)layoutAnimatedLayer {
904 | CALayer *layer = self.indefiniteAnimatedLayer;
905 |
906 | [self.layer addSublayer:layer];
907 | layer.position = CGPointMake(self.bounds.size.width - layer.bounds.size.width / 2, self.bounds.size.height - layer.bounds.size.height / 2);
908 | }
909 |
910 | - (CAShapeLayer*)indefiniteAnimatedLayer {
911 | if(!_indefiniteAnimatedLayer) {
912 | CGPoint arcCenter = CGPointMake(self.radius+self.strokeThickness/2+5, self.radius+self.strokeThickness/2+5);
913 | CGRect rect = CGRectMake(0, 0, arcCenter.x*2, arcCenter.y*2);
914 |
915 | UIBezierPath* smoothedPath = [UIBezierPath bezierPathWithArcCenter:arcCenter
916 | radius:self.radius
917 | startAngle:M_PI*3/2
918 | endAngle:M_PI/2+M_PI*5
919 | clockwise:YES];
920 |
921 | _indefiniteAnimatedLayer = [CAShapeLayer layer];
922 | _indefiniteAnimatedLayer.contentsScale = [[UIScreen mainScreen] scale];
923 | _indefiniteAnimatedLayer.frame = rect;
924 | _indefiniteAnimatedLayer.fillColor = [UIColor clearColor].CGColor;
925 | _indefiniteAnimatedLayer.strokeColor = self.strokeColor.CGColor;
926 | _indefiniteAnimatedLayer.lineWidth = self.strokeThickness;
927 | _indefiniteAnimatedLayer.lineCap = kCALineCapRound;
928 | _indefiniteAnimatedLayer.lineJoin = kCALineJoinBevel;
929 | _indefiniteAnimatedLayer.path = smoothedPath.CGPath;
930 |
931 | CALayer *maskLayer = [CALayer layer];
932 | maskLayer.contents = (id)[[UIImage imageNamed:@"SVProgressHUD.bundle/angle-mask@2x.png"] CGImage];
933 | maskLayer.frame = _indefiniteAnimatedLayer.bounds;
934 | _indefiniteAnimatedLayer.mask = maskLayer;
935 |
936 | NSTimeInterval animationDuration = 1;
937 | CAMediaTimingFunction *linearCurve = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
938 |
939 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
940 | animation.fromValue = 0;
941 | animation.toValue = [NSNumber numberWithFloat:M_PI*2];
942 | animation.duration = animationDuration;
943 | animation.timingFunction = linearCurve;
944 | animation.removedOnCompletion = NO;
945 | animation.repeatCount = INFINITY;
946 | animation.fillMode = kCAFillModeForwards;
947 | animation.autoreverses = NO;
948 | [_indefiniteAnimatedLayer.mask addAnimation:animation forKey:@"rotate"];
949 |
950 | CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
951 | animationGroup.duration = animationDuration;
952 | animationGroup.repeatCount = INFINITY;
953 | animationGroup.removedOnCompletion = NO;
954 | animationGroup.timingFunction = linearCurve;
955 |
956 | CABasicAnimation *strokeStartAnimation = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
957 | strokeStartAnimation.fromValue = @0.015;
958 | strokeStartAnimation.toValue = @0.515;
959 |
960 | CABasicAnimation *strokeEndAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
961 | strokeEndAnimation.fromValue = @0.485;
962 | strokeEndAnimation.toValue = @0.985;
963 |
964 | animationGroup.animations = @[strokeStartAnimation, strokeEndAnimation];
965 | [_indefiniteAnimatedLayer addAnimation:animationGroup forKey:@"progress"];
966 |
967 | }
968 | return _indefiniteAnimatedLayer;
969 | }
970 |
971 | - (void)setFrame:(CGRect)frame {
972 | [super setFrame:frame];
973 |
974 | if (self.superview != nil) {
975 | [self layoutAnimatedLayer];
976 | }
977 | }
978 |
979 | - (void)setRadius:(CGFloat)radius {
980 | _radius = radius;
981 |
982 | [_indefiniteAnimatedLayer removeFromSuperlayer];
983 | _indefiniteAnimatedLayer = nil;
984 |
985 | [self layoutAnimatedLayer];
986 | }
987 |
988 | - (void)setStrokeColor:(UIColor *)strokeColor {
989 | _strokeColor = strokeColor;
990 | _indefiniteAnimatedLayer.strokeColor = strokeColor.CGColor;
991 | }
992 |
993 | - (void)setStrokeThickness:(CGFloat)strokeThickness {
994 | _strokeThickness = strokeThickness;
995 | _indefiniteAnimatedLayer.lineWidth = _strokeThickness;
996 | }
997 |
998 | - (CGSize)sizeThatFits:(CGSize)size {
999 | return CGSizeMake((self.radius+self.strokeThickness/2+5)*2, (self.radius+self.strokeThickness/2+5)*2);
1000 | }
1001 |
1002 | @end
1003 |
--------------------------------------------------------------------------------