├── BarrageDemo
├── BarrageDemo.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── BarrageDemo.xccheckout
│ │ └── xcuserdata
│ │ │ └── sunli.xcuserdatad
│ │ │ ├── UserInterfaceState.xcuserstate
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcuserdata
│ │ └── sunli.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── BarrageDemo.xcscheme
│ │ └── xcschememanagement.plist
├── BarrageDemo
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Barrage
│ │ └── View
│ │ │ ├── BarrageItemView.h
│ │ │ ├── BarrageItemView.m
│ │ │ ├── BarrageProtocol.h
│ │ │ ├── BarrageView.h
│ │ │ └── BarrageView.m
│ ├── Base.lproj
│ │ ├── LaunchScreen.xib
│ │ └── Main.storyboard
│ ├── Images.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Info.plist
│ ├── ViewController.h
│ ├── ViewController.m
│ ├── main.m
│ └── public
│ │ ├── UIColor+Addition.h
│ │ ├── UIColor+Addition.m
│ │ ├── UIView+Metrics.h
│ │ └── UIView+Metrics.m
└── BarrageDemoTests
│ ├── BarrageDemoTests.m
│ └── Info.plist
├── GuideDemo
├── GuideDemo.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── GuideDemo.xccheckout
│ │ └── xcuserdata
│ │ │ └── sunli.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── sunli.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── GuideDemo.xcscheme
│ │ └── xcschememanagement.plist
├── GuideDemo
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Base.lproj
│ │ ├── LaunchScreen.xib
│ │ └── Main.storyboard
│ ├── GuideView.h
│ ├── GuideView.m
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── arrowDown.imageset
│ │ │ ├── Contents.json
│ │ │ └── fx_guide_arrow_down@2x.png
│ │ ├── btnMask.imageset
│ │ │ ├── Contents.json
│ │ │ └── fx_livRm_guide_moreItm_mask@2x.png
│ │ ├── fx_my_attention_guide_arrow.imageset
│ │ │ ├── Contents.json
│ │ │ └── fx_my_attention_guide_arrow@2x.png
│ │ ├── okBtn.imageset
│ │ │ ├── Contents.json
│ │ │ └── fx_livRm_guide_ok@2x.png
│ │ └── whiteMask.imageset
│ │ │ ├── Contents.json
│ │ │ └── whiteMask@2x.png
│ ├── Info.plist
│ ├── UIImage+Mask.h
│ ├── UIImage+Mask.m
│ ├── UIView+Layout.h
│ ├── UIView+Layout.m
│ ├── ViewController.h
│ ├── ViewController.m
│ └── main.m
└── GuideDemoTests
│ ├── GuideDemoTests.m
│ └── Info.plist
├── Socket
├── SocketApp
│ ├── SocketApp.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcuserdata
│ │ │ │ └── sunli.xcuserdatad
│ │ │ │ └── UserInterfaceState.xcuserstate
│ │ └── xcuserdata
│ │ │ └── sunli.xcuserdatad
│ │ │ ├── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ │ └── xcschemes
│ │ │ ├── SocketApp.xcscheme
│ │ │ └── xcschememanagement.plist
│ ├── SocketApp
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Base.lproj
│ │ │ ├── LaunchScreen.xib
│ │ │ └── Main.storyboard
│ │ ├── Images.xcassets
│ │ │ └── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ ├── Info.plist
│ │ ├── SocketHandle.h
│ │ ├── SocketHandle.m
│ │ ├── ViewController.h
│ │ ├── ViewController.m
│ │ ├── en.lproj
│ │ │ └── Main.strings
│ │ ├── ip
│ │ │ ├── GetIpAddress.h
│ │ │ ├── GetIpAddress.m
│ │ │ ├── IpAddress.c
│ │ │ └── IpAddress.h
│ │ └── main.m
│ └── SocketAppTests
│ │ ├── Info.plist
│ │ └── SocketAppTests.m
└── SocketServer
│ ├── SocketServer.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ └── sunli.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── sunli.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── SocketServer.xcscheme
│ │ └── xcschememanagement.plist
│ ├── SocketServer
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Base.lproj
│ │ ├── LaunchScreen.xib
│ │ └── Main.storyboard
│ ├── Images.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Info.plist
│ ├── MyServer.h
│ ├── MyServer.m
│ ├── ViewController.h
│ ├── ViewController.m
│ ├── ip
│ │ ├── GetIpAddress.h
│ │ ├── GetIpAddress.m
│ │ ├── IpAddress.c
│ │ └── IpAddress.h
│ └── main.m
│ └── SocketServerTests
│ ├── Info.plist
│ └── SocketServerTests.m
├── SpringAnimation
├── SpringAnimation.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ └── sunli.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── sunli.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── SpringAnimation.xcscheme
│ │ └── xcschememanagement.plist
└── SpringAnimation
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── ViewController.swift
├── WatchDemo
├── WatchApp Extension
│ ├── Assets.xcassets
│ │ └── Complication.complicationset
│ │ │ ├── Circular.imageset
│ │ │ └── Contents.json
│ │ │ ├── Contents.json
│ │ │ ├── Modular.imageset
│ │ │ └── Contents.json
│ │ │ └── Utilitarian.imageset
│ │ │ └── Contents.json
│ ├── ComplicationController.swift
│ ├── ExtensionDelegate.swift
│ ├── GlanceController.swift
│ ├── ImageInterfaceController.swift
│ ├── Info.plist
│ ├── InterfaceController.swift
│ ├── NotificationController.swift
│ └── PushNotificationPayload.apns
├── WatchApp
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ └── Interface.storyboard
│ ├── Info.plist
│ ├── dragon-0.png
│ ├── dragon-1.png
│ ├── dragon-2.png
│ ├── dragon-3.png
│ ├── dragon-4.png
│ └── dragon-5.png
├── WatchDemo.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ └── sunli.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── sunli.xcuserdatad
│ │ └── xcschemes
│ │ ├── Complication - WatchApp.xcscheme
│ │ ├── Glance - WatchApp.xcscheme
│ │ ├── Notification - WatchApp.xcscheme
│ │ ├── WatchApp.xcscheme
│ │ ├── WatchDemo.xcscheme
│ │ └── xcschememanagement.plist
└── WatchDemo
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── ViewController.swift
└── iOS9
└── UITestDemo
├── UITestDemo UI Tests
├── Info.plist
└── UITestDemo_UI_Tests.swift
├── UITestDemo.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── sunli.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ └── sunli.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ ├── UITestDemo.xcscheme
│ └── xcschememanagement.plist
└── UITestDemo
├── AppDelegate.swift
├── Assets.xcassets
└── AppIcon.appiconset
│ └── Contents.json
├── Base.lproj
├── LaunchScreen.storyboard
└── Main.storyboard
├── HomeViewController.swift
├── Info.plist
├── InfoViewController.swift
├── MessageViewController.swift
└── SButton.swift
/BarrageDemo/BarrageDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo.xcodeproj/project.xcworkspace/xcshareddata/BarrageDemo.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 3691C495-A016-43EB-BB0E-C773B077DCB7
9 | IDESourceControlProjectName
10 | BarrageDemo
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | AAF28B3800AAC178FEB0040B6DA855348904E4DE
14 | https://github.com/sunGd/demo
15 |
16 | IDESourceControlProjectPath
17 | BarrageDemo/BarrageDemo.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | AAF28B3800AAC178FEB0040B6DA855348904E4DE
21 | ../../..
22 |
23 | IDESourceControlProjectURL
24 | https://github.com/sunGd/demo
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | AAF28B3800AAC178FEB0040B6DA855348904E4DE
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | AAF28B3800AAC178FEB0040B6DA855348904E4DE
36 | IDESourceControlWCCName
37 | demo
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo.xcodeproj/project.xcworkspace/xcuserdata/sunli.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/BarrageDemo/BarrageDemo.xcodeproj/project.xcworkspace/xcuserdata/sunli.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo.xcodeproj/project.xcworkspace/xcuserdata/sunli.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges
6 |
7 | SnapshotAutomaticallyBeforeSignificantChanges
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo.xcodeproj/xcuserdata/sunli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo.xcodeproj/xcuserdata/sunli.xcuserdatad/xcschemes/BarrageDemo.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
77 |
83 |
84 |
85 |
86 |
87 |
88 |
94 |
96 |
102 |
103 |
104 |
105 |
107 |
108 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo.xcodeproj/xcuserdata/sunli.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | BarrageDemo.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | A13B92181B451234005C6645
16 |
17 | primary
18 |
19 |
20 | A13B92311B451234005C6645
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // BarrageDemo
4 | //
5 | // Created by 李剑钊 on 15/7/2.
6 | // Copyright (c) 2015年 sunli. 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 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // BarrageDemo
4 | //
5 | // Created by 李剑钊 on 15/7/2.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // 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.
25 | // 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.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // 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.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // 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.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo/Barrage/View/BarrageItemView.h:
--------------------------------------------------------------------------------
1 | //
2 | // BarrageItemView.h
3 | // BarrageDemo
4 | //
5 | // Created by 李剑钊 on 15/7/2.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "BarrageProtocol.h"
11 | #import "UIView+Metrics.h"
12 |
13 | @interface BarrageItemView : UIView
14 |
15 | /// default = 360
16 | @property (nonatomic, assign) NSInteger maxWidth;
17 | @property (nonatomic, strong) NSString *detail;
18 | @property (nonatomic, strong) UIColor *detailColor;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo/Barrage/View/BarrageItemView.m:
--------------------------------------------------------------------------------
1 | //
2 | // BarrageItemView.m
3 | // BarrageDemo
4 | //
5 | // Created by 李剑钊 on 15/7/2.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import "BarrageItemView.h"
10 | #import "UIColor+Addition.h"
11 |
12 | @interface BarrageItemView () {
13 | CGFloat mySpeed;
14 | CGFloat myCurDistance;
15 | }
16 |
17 | @property (nonatomic, strong) UILabel *detailLabel;
18 |
19 | @end
20 |
21 |
22 | @implementation BarrageItemView
23 |
24 | #pragma mark - life cycle
25 |
26 | - (instancetype)initWithFrame:(CGRect)frame {
27 | self = [super initWithFrame:frame];
28 | if (self) {
29 | self.maxWidth = 360;
30 | [self addSubview:self.detailLabel];
31 |
32 | }
33 | return self;
34 | }
35 |
36 | - (void)layoutSubviews {
37 | [super layoutSubviews];
38 | _detailLabel.frame = self.bounds;
39 | }
40 |
41 | - (void)dealloc {
42 |
43 | }
44 |
45 | #pragma mark - setter and getter
46 |
47 | - (void)setDetail:(NSString *)detail {
48 | if ([_detail isEqualToString:detail] == NO) {
49 | _detail = detail;
50 | _detailLabel.text = detail;
51 | CGSize size = [_detailLabel sizeThatFits:CGSizeMake(_maxWidth, 20)];
52 | self.bounds = CGRectMake(0, 0, size.width, size.height);
53 | }
54 | }
55 |
56 | - (UILabel *)detailLabel {
57 | if (!_detailLabel) {
58 | UILabel *label = [[UILabel alloc] init];
59 | label.textAlignment = NSTextAlignmentLeft;
60 | label.backgroundColor = [UIColor clearColor];
61 | label.textColor = [UIColor colorWithHexString:@"ffffff"];
62 | label.font = [UIFont systemFontOfSize:15];
63 | _detailLabel = label;
64 | }
65 | return _detailLabel;
66 | }
67 |
68 | - (void)setDetailColor:(UIColor *)detailColor {
69 | _detailColor = detailColor;
70 | _detailLabel.textColor = detailColor;
71 | }
72 |
73 | - (void)setSpeed:(CGFloat)speed {
74 | mySpeed = speed;
75 | }
76 |
77 | - (CGFloat)speed {
78 | return mySpeed;
79 | }
80 |
81 | - (void)setCurDistance:(CGFloat)curDistance {
82 | myCurDistance = curDistance;
83 | }
84 |
85 | - (CGFloat)curDistance {
86 | return myCurDistance;
87 | }
88 |
89 | @end
90 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo/Barrage/View/BarrageProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // BarrageProtocol.h
3 | // BarrageDemo
4 | //
5 | // Created by 李剑钊 on 15/7/2.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #ifndef BarrageDemo_BarrageProtocol_h
10 | #define BarrageDemo_BarrageProtocol_h
11 |
12 | #import
13 |
14 | @protocol BarrageItemProtocol
15 |
16 | /// 速度 point per second
17 | @property (nonatomic, readwrite) CGFloat speed;
18 |
19 | /// 当前路程,即弹幕跑了多长
20 | @property (nonatomic, assign) CGFloat curDistance;
21 |
22 | @end
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo/Barrage/View/BarrageView.h:
--------------------------------------------------------------------------------
1 | //
2 | // BarrageAnimation.h
3 | // BarrageDemo
4 | //
5 | // Created by 李剑钊 on 15/7/2.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "BarrageProtocol.h"
12 | @class UIView;
13 |
14 | typedef NS_ENUM(NSUInteger, BarrageAnimationState) {
15 | BarrageAnimationState_stop,
16 | BarrageAnimationState_playing,
17 | BarrageAnimationState_pause,
18 | };
19 |
20 | @class BarrageView;
21 |
22 | @protocol BarrageViewDataSource
23 | @required
24 | /// 提供弹幕视图源
25 | - (UIView *)itemForBarrage:(BarrageView *)barrage;
26 |
27 | @end
28 |
29 | @interface BarrageView : UIView
30 |
31 | /// 弹幕的行数,默认为1,开始以后,数量可以增加,但不能减少
32 | @property (nonatomic, assign) NSUInteger playSubQueueMaxCount;
33 |
34 | /// 弹幕的距离 default=16
35 | @property (nonatomic, assign) NSUInteger barrageDistance;
36 |
37 | /// 弹幕的平均速度,当旋转屏幕时,所有的正在播放的弹幕会设置成这个速度,避免出现重叠
38 | @property (nonatomic, assign) CGFloat barrageAverageSpeed;
39 |
40 | @property (nonatomic, weak) NSObject *dataSource;
41 |
42 | #pragma mark play control
43 |
44 | /// 弹幕播放状态
45 | @property (nonatomic, readonly) BarrageAnimationState state;
46 |
47 | - (BOOL)startBarrage;
48 |
49 | - (BOOL)pauseBarrage;
50 |
51 | - (BOOL)resumeBarrage;
52 |
53 | - (BOOL)stopBarrage;
54 |
55 | #pragma mark - item control
56 |
57 | /// 获取可重用的弹幕
58 | - (UIView *)dequeueReusableItem;
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo/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 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo/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 | }
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.sunli.$(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 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // BarrageDemo
4 | //
5 | // Created by 李剑钊 on 15/7/2.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // BarrageDemo
4 | //
5 | // Created by 李剑钊 on 15/7/2.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "BarrageView.h"
11 | #import "UIView+Metrics.h"
12 | #import "BarrageItemView.h"
13 |
14 | @interface ViewController ()
15 |
16 | @property (nonatomic, strong) BarrageView *barrageView;
17 | @property (nonatomic, strong) UIView *parentView;
18 |
19 | @property (nonatomic, strong) NSMutableArray *messagePool;
20 |
21 | @end
22 |
23 | @implementation ViewController
24 |
25 | - (void)viewDidLoad {
26 | [super viewDidLoad];
27 | // Do any additional setup after loading the view, typically from a nib.
28 |
29 | self.view.backgroundColor = [UIColor whiteColor];
30 | self.messagePool = [NSMutableArray array];
31 |
32 | _parentView = [[UIView alloc] initWithFrame:CGRectMake(0, 20, self.view.width, 150)];
33 | [self.view insertSubview:_parentView atIndex:0];
34 |
35 | BarrageView *barrage = [[BarrageView alloc] initWithFrame:_parentView.bounds];
36 | barrage.dataSource = self;
37 | barrage.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
38 | barrage.playSubQueueMaxCount = 3;
39 | barrage.backgroundColor = [UIColor blackColor];
40 | barrage.barrageAverageSpeed = 80;
41 | [_parentView addSubview:barrage];
42 | _barrageView = barrage;
43 | }
44 |
45 | - (void)didReceiveMemoryWarning {
46 | [super didReceiveMemoryWarning];
47 | // Dispose of any resources that can be recreated.
48 | }
49 |
50 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
51 | static NSInteger type = 0;
52 | for (NSInteger i = 0; i < 50; i ++) {
53 | NSString *title = nil;
54 | if (type == 0) {
55 | type = 1;
56 | title = @"1shihiaognaihoi";
57 | } else if (type == 1) {
58 | type = 2;
59 | title = @"HenHenH";
60 | } else if (type == 2) {
61 | type = 3;
62 | title = @"_@#!+-";
63 | } else if (type == 3) {
64 | type = 4;
65 | title = @"嘻嘻呵呵哈哈嘎嘎";
66 | } else {
67 | type = 0;
68 | title = @"10759651235215662164322346321523512";
69 | }
70 |
71 | [_messagePool addObject:title];
72 | }
73 | }
74 |
75 | - (IBAction)sendBtnTouch:(id)sender {
76 | [_messagePool addObject:@"我的消息"];
77 | }
78 |
79 | - (IBAction)buttonTouched:(id)sender {
80 | static BOOL rotate = NO;
81 | [UIView animateWithDuration:0.2 animations:^{
82 | if (rotate == NO) {
83 | rotate = YES;
84 | _parentView.size = CGSizeMake(self.view.height, 100);
85 | _parentView.center = CGPointMake(self.view.width/2, self.view.height/2);
86 | _parentView.transform = CGAffineTransformMakeRotation(M_PI/2);
87 | } else {
88 | rotate = NO;
89 | _parentView.transform = CGAffineTransformIdentity;
90 | _parentView.size = CGSizeMake(self.view.width, 150);
91 | _parentView.origin = CGPointMake(0, 20);
92 | }
93 | } completion:nil];
94 | }
95 |
96 | - (IBAction)pauseBtnTouch:(id)sender {
97 | [_barrageView pauseBarrage];
98 | }
99 | - (IBAction)resumeBtnTouch:(id)sender {
100 | [_barrageView resumeBarrage];
101 | }
102 |
103 | - (IBAction)startBtnTouch:(id)sender {
104 | [_barrageView startBarrage];
105 | }
106 |
107 | - (IBAction)stopBtnTouch:(id)sender {
108 | [_barrageView stopBarrage];
109 | [_messagePool removeAllObjects];
110 | }
111 |
112 | - (IBAction)removeBtnTouch:(id)sender {
113 | [_barrageView stopBarrage];
114 | _barrageView.dataSource = nil;
115 | [_barrageView removeFromSuperview];
116 | self.barrageView = nil;
117 | [_messagePool removeAllObjects];
118 | }
119 |
120 | #pragma mark - BarrageViewDataSource
121 |
122 | - (UIView *)itemForBarrage:(BarrageView *)barrage {
123 | NSString *title = [_messagePool firstObject];
124 | if (title) {
125 | [_messagePool removeObjectAtIndex:0];
126 |
127 | BarrageItemView *item = (BarrageItemView *)[barrage dequeueReusableItem];
128 | if (!item) {
129 | item = [BarrageItemView new];
130 | }
131 | item.speed = 80;
132 | BOOL highSpeed = (arc4random_uniform((int32_t)time(NULL)) % 100) < 10;
133 | if (highSpeed) {
134 | item.speed = 120;
135 | }
136 |
137 | item.detail = title;
138 | return item;
139 | }
140 | return nil;
141 | }
142 |
143 | @end
144 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // BarrageDemo
4 | //
5 | // Created by 李剑钊 on 15/7/2.
6 | // Copyright (c) 2015年 sunli. 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 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo/public/UIColor+Addition.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+Addition.h
3 | // QiaoQiaoMovie
4 | //
5 | // Created by zelong zou on 13-3-17.
6 | // Copyright (c) 2013年 prdoor. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | #define RGBACOLOR(r,g,b,a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:(a)]
13 |
14 | @interface UIColor (Addition)
15 | + (UIColor *) colorWithHexString: (NSString *) stringToConvert;
16 | + (UIColor *) colorWithHexString: (NSString *) stringToConvert alpha:(float) alpha;
17 | //颜色转字符串
18 | - (NSString *) changeUIColorToRGB;
19 | @end
20 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo/public/UIColor+Addition.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+Addition.m
3 | // QiaoQiaoMovie
4 | //
5 | // Created by zelong zou on 13-3-17.
6 | // Copyright (c) 2013年 prdoor. All rights reserved.
7 | //
8 |
9 | #import "UIColor+Addition.h"
10 | #define DEFAULT_VOID_COLOR [UIColor clearColor]
11 | @implementation UIColor (Addition)
12 |
13 | + (UIColor *) colorWithHexString: (NSString *) stringToConvert
14 | {
15 | NSString *cString = [[stringToConvert stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
16 |
17 | // String should be 6 or 8 characters
18 | if ([cString length] < 6) return DEFAULT_VOID_COLOR;
19 |
20 | // strip 0X if it appears
21 | if ([cString hasPrefix:@"0X"]) cString = [cString substringFromIndex:2];
22 | if ([cString hasPrefix:@"#"]) cString = [cString substringFromIndex:1];
23 | if ([cString length] != 6) return DEFAULT_VOID_COLOR;
24 | // Separate into r, g, b substrings
25 | NSRange range;
26 | range.location = 0;
27 | range.length = 2;
28 | NSString *rString = [cString substringWithRange:range];
29 |
30 | range.location = 2;
31 | NSString *gString = [cString substringWithRange:range];
32 |
33 | range.location = 4;
34 | NSString *bString = [cString substringWithRange:range];
35 |
36 | // Scan values
37 | unsigned int r, g, b;
38 | [[NSScanner scannerWithString:rString] scanHexInt:&r];
39 | [[NSScanner scannerWithString:gString] scanHexInt:&g];
40 | [[NSScanner scannerWithString:bString] scanHexInt:&b];
41 |
42 | return [UIColor colorWithRed:((float) r / 255.0f)
43 | green:((float) g / 255.0f)
44 | blue:((float) b / 255.0f)
45 | alpha:1.0f];
46 | }
47 |
48 | + (UIColor *) colorWithHexString: (NSString *) stringToConvert alpha:(float) alpha
49 | {
50 | NSString *cString = [[stringToConvert stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
51 |
52 | // String should be 6 or 8 characters
53 | if ([cString length] < 6) return DEFAULT_VOID_COLOR;
54 |
55 | // strip 0X if it appears
56 | if ([cString hasPrefix:@"0X"]) cString = [cString substringFromIndex:2];
57 | if ([cString hasPrefix:@"#"]) cString = [cString substringFromIndex:1];
58 | if ([cString length] != 6) return DEFAULT_VOID_COLOR;
59 | // Separate into r, g, b substrings
60 | NSRange range;
61 | range.location = 0;
62 | range.length = 2;
63 | NSString *rString = [cString substringWithRange:range];
64 |
65 | range.location = 2;
66 | NSString *gString = [cString substringWithRange:range];
67 |
68 | range.location = 4;
69 | NSString *bString = [cString substringWithRange:range];
70 |
71 | // Scan values
72 | unsigned int r, g, b;
73 | [[NSScanner scannerWithString:rString] scanHexInt:&r];
74 | [[NSScanner scannerWithString:gString] scanHexInt:&g];
75 | [[NSScanner scannerWithString:bString] scanHexInt:&b];
76 |
77 | return [UIColor colorWithRed:((float) r / 255.0f)
78 | green:((float) g / 255.0f)
79 | blue:((float) b / 255.0f)
80 | alpha:alpha];
81 | }
82 |
83 | //颜色转字符串
84 | - (NSString *) changeUIColorToRGB{
85 |
86 |
87 | const CGFloat *cs=CGColorGetComponents(self.CGColor);
88 |
89 |
90 | NSString *r = [NSString stringWithFormat:@"%@",[self ToHex:cs[0]*255]];
91 | NSString *g = [NSString stringWithFormat:@"%@",[self ToHex:cs[1]*255]];
92 | NSString *b = [NSString stringWithFormat:@"%@",[self ToHex:cs[2]*255]];
93 | return [NSString stringWithFormat:@"#%@%@%@",r,g,b];
94 | }
95 |
96 |
97 | //十进制转十六进制
98 | -(NSString *)ToHex:(int)tmpid
99 | {
100 | NSString *endtmp=@"";
101 | NSString *nLetterValue;
102 | NSString *nStrat;
103 | int ttmpig=tmpid%16;
104 | int tmp=tmpid/16;
105 | switch (ttmpig)
106 | {
107 | case 10:
108 | nLetterValue =@"A";break;
109 | case 11:
110 | nLetterValue =@"B";break;
111 | case 12:
112 | nLetterValue =@"C";break;
113 | case 13:
114 | nLetterValue =@"D";break;
115 | case 14:
116 | nLetterValue =@"E";break;
117 | case 15:
118 | nLetterValue =@"F";break;
119 | default:nLetterValue=[[NSString alloc]initWithFormat:@"%i",ttmpig];
120 |
121 | }
122 | switch (tmp)
123 | {
124 | case 10:
125 | nStrat =@"A";break;
126 | case 11:
127 | nStrat =@"B";break;
128 | case 12:
129 | nStrat =@"C";break;
130 | case 13:
131 | nStrat =@"D";break;
132 | case 14:
133 | nStrat =@"E";break;
134 | case 15:
135 | nStrat =@"F";break;
136 | default:nStrat=[[NSString alloc]initWithFormat:@"%i",tmp];
137 |
138 | }
139 | endtmp=[[NSString alloc]initWithFormat:@"%@%@",nStrat,nLetterValue];
140 | return endtmp;
141 | }
142 |
143 | @end
144 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo/public/UIView+Metrics.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Metrics.h
3 | // NeeFrame
4 | //
5 | // Created by ganvin on 14-4-14.
6 | // Copyright (c) 2014年 ganvin. All rights reserved.
7 | //
8 |
9 | #import
10 | /**
11 | * 方便的访问和设置View的属性
12 | */
13 | @interface UIView (Metrics)
14 |
15 | @property (assign, nonatomic) CGFloat top;
16 | @property (assign, nonatomic) CGFloat bottom;
17 | @property (assign, nonatomic) CGFloat left;
18 | @property (assign, nonatomic) CGFloat right;
19 |
20 | @property (assign, nonatomic) CGPoint offset;
21 | @property (assign, nonatomic) CGPoint position;
22 |
23 | @property (assign, nonatomic) CGFloat x;
24 | @property (assign, nonatomic) CGFloat y;
25 | @property (assign, nonatomic) CGFloat w;
26 | @property (assign, nonatomic) CGFloat h;
27 |
28 | @property (assign, nonatomic) CGFloat width;
29 | @property (assign, nonatomic) CGFloat height;
30 | @property (assign, nonatomic) CGSize size;
31 |
32 | @property (assign, nonatomic) CGFloat centerX;
33 | @property (assign, nonatomic) CGFloat centerY;
34 | @property (assign, nonatomic) CGPoint origin;
35 | @property (readonly, nonatomic) CGPoint boundsCenter;
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemo/public/UIView+Metrics.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Metrics.m
3 | // NeeFrame
4 | //
5 | // Created by ganvin on 14-4-14.
6 | // Copyright (c) 2014年 ganvin. All rights reserved.
7 | //
8 |
9 | #import "UIView+Metrics.h"
10 |
11 | @implementation UIView (Metrics)
12 |
13 | @dynamic top;
14 | @dynamic bottom;
15 | @dynamic left;
16 | @dynamic right;
17 |
18 | @dynamic width;
19 | @dynamic height;
20 |
21 | @dynamic offset;
22 | @dynamic position;
23 | @dynamic size;
24 |
25 | @dynamic x;
26 | @dynamic y;
27 | @dynamic w;
28 | @dynamic h;
29 |
30 | - (CGFloat)top
31 | {
32 | return self.frame.origin.y;
33 | }
34 |
35 | - (void)setTop:(CGFloat)top
36 | {
37 | CGRect frame = self.frame;
38 | frame.origin.y = top;
39 | self.frame = frame;
40 | }
41 |
42 | - (CGFloat)left
43 | {
44 | return self.frame.origin.x;
45 | }
46 |
47 | - (void)setLeft:(CGFloat)left
48 | {
49 | CGRect frame = self.frame;
50 | frame.origin.x = left;
51 | self.frame = frame;
52 | }
53 |
54 | - (CGFloat)width
55 | {
56 | return self.frame.size.width;
57 | }
58 |
59 | - (void)setWidth:(CGFloat)width
60 | {
61 | CGRect frame = self.frame;
62 | frame.size.width = width;
63 | self.frame = frame;
64 | }
65 |
66 | - (CGFloat)height
67 | {
68 | return self.frame.size.height;
69 | }
70 |
71 | - (void)setHeight:(CGFloat)height
72 | {
73 | CGRect frame = self.frame;
74 | frame.size.height = height;
75 | self.frame = frame;
76 | }
77 |
78 | - (CGFloat)bottom
79 | {
80 | return self.frame.size.height + self.frame.origin.y;
81 | }
82 |
83 | - (void)setBottom:(CGFloat)bottom
84 | {
85 | CGRect frame = self.frame;
86 | frame.origin.y = bottom - frame.size.height;
87 | self.frame = frame;
88 | }
89 |
90 | - (CGFloat)right
91 | {
92 | return self.frame.size.width + self.frame.origin.x;
93 | }
94 |
95 | - (void)setRight:(CGFloat)right
96 | {
97 | CGRect frame = self.frame;
98 | frame.origin.x = right - frame.size.width;
99 | self.frame = frame;
100 | }
101 |
102 | - (CGFloat)x
103 | {
104 | return self.frame.origin.x;
105 | }
106 |
107 | - (void)setX:(CGFloat)value
108 | {
109 | CGRect frame = self.frame;
110 | frame.origin.x = value;
111 | self.frame = frame;
112 | }
113 |
114 | - (CGFloat)y
115 | {
116 | return self.frame.origin.y;
117 | }
118 |
119 | - (void)setY:(CGFloat)value
120 | {
121 | CGRect frame = self.frame;
122 | frame.origin.y = value;
123 | self.frame = frame;
124 | }
125 |
126 | - (CGFloat)w
127 | {
128 | return self.frame.size.width;
129 | }
130 |
131 | - (void)setW:(CGFloat)width
132 | {
133 | CGRect frame = self.frame;
134 | frame.size.width = width;
135 | self.frame = frame;
136 | }
137 |
138 | - (CGFloat)h
139 | {
140 | return self.frame.size.height;
141 | }
142 |
143 | - (void)setH:(CGFloat)height
144 | {
145 | CGRect frame = self.frame;
146 | frame.size.height = height;
147 | self.frame = frame;
148 | }
149 |
150 | - (CGPoint)offset
151 | {
152 | CGPoint point = CGPointZero;
153 | UIView * view = self;
154 |
155 | while ( view )
156 | {
157 | point.x += view.frame.origin.x;
158 | point.y += view.frame.origin.y;
159 |
160 | view = view.superview;
161 | }
162 |
163 | return point;
164 | }
165 |
166 | - (void)setOffset:(CGPoint)offset
167 | {
168 | UIView * view = self;
169 | if ( nil == view )
170 | return;
171 |
172 | CGPoint point = offset;
173 |
174 | while ( view )
175 | {
176 | point.x += view.superview.frame.origin.x;
177 | point.y += view.superview.frame.origin.y;
178 |
179 | view = view.superview;
180 | }
181 |
182 | CGRect frame = self.frame;
183 | frame.origin = point;
184 | self.frame = frame;
185 | }
186 |
187 | - (CGPoint)position
188 | {
189 | return self.frame.origin;
190 | }
191 |
192 | - (void)setPosition:(CGPoint)pos
193 | {
194 | CGRect frame = self.frame;
195 | frame.origin = pos;
196 | self.frame = frame;
197 | }
198 |
199 | - (CGSize)size
200 | {
201 | return self.frame.size;
202 | }
203 |
204 | - (void)setSize:(CGSize)size
205 | {
206 | CGRect frame = self.frame;
207 | frame.size = size;
208 | self.frame = frame;
209 | }
210 |
211 | - (CGFloat)centerX
212 | {
213 | return self.center.x;
214 | }
215 |
216 | - (void)setCenterX:(CGFloat)centerX
217 | {
218 | CGPoint center = self.center;
219 | center.x = centerX;
220 | self.center = center;
221 | }
222 |
223 | - (CGFloat)centerY
224 | {
225 | return self.center.y;
226 | }
227 |
228 | - (void)setCenterY:(CGFloat)centerY
229 | {
230 | CGPoint center = self.center;
231 | center.y = centerY;
232 | self.center = center;
233 | }
234 |
235 | - (CGPoint)origin
236 | {
237 | return self.frame.origin;
238 | }
239 |
240 | - (void)setOrigin:(CGPoint)origin
241 | {
242 | CGRect frame = self.frame;
243 | frame.origin = origin;
244 | self.frame = frame;
245 | }
246 |
247 | - (CGPoint)boundsCenter
248 | {
249 | return CGPointMake( CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds) );
250 | }
251 |
252 | @end
253 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemoTests/BarrageDemoTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // BarrageDemoTests.m
3 | // BarrageDemoTests
4 | //
5 | // Created by 李剑钊 on 15/7/2.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface BarrageDemoTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation BarrageDemoTests
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 |
--------------------------------------------------------------------------------
/BarrageDemo/BarrageDemoTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.sunli.$(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 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo.xcodeproj/project.xcworkspace/xcshareddata/GuideDemo.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | D88DF8DD-7A75-4FD6-9645-E0C3716C090E
9 | IDESourceControlProjectName
10 | GuideDemo
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | AAF28B3800AAC178FEB0040B6DA855348904E4DE
14 | https://github.com/sunljz/demo
15 |
16 | IDESourceControlProjectPath
17 | GuideDemo/GuideDemo.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | AAF28B3800AAC178FEB0040B6DA855348904E4DE
21 | ../../..
22 |
23 | IDESourceControlProjectURL
24 | https://github.com/sunljz/demo
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | AAF28B3800AAC178FEB0040B6DA855348904E4DE
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | AAF28B3800AAC178FEB0040B6DA855348904E4DE
36 | IDESourceControlWCCName
37 | demo
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo.xcodeproj/project.xcworkspace/xcuserdata/sunli.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/GuideDemo/GuideDemo.xcodeproj/project.xcworkspace/xcuserdata/sunli.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo.xcodeproj/xcuserdata/sunli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo.xcodeproj/xcuserdata/sunli.xcuserdatad/xcschemes/GuideDemo.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
77 |
83 |
84 |
85 |
86 |
87 |
88 |
94 |
96 |
102 |
103 |
104 |
105 |
107 |
108 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo.xcodeproj/xcuserdata/sunli.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | GuideDemo.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | A10662F01B60C98D00B32E9E
16 |
17 | primary
18 |
19 |
20 | A10663091B60C98E00B32E9E
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // GuideDemo
4 | //
5 | // Created by 李剑钊 on 15/7/23.
6 | // Copyright (c) 2015年 sunli. 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 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // GuideDemo
4 | //
5 | // Created by 李剑钊 on 15/7/23.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // 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.
25 | // 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.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // 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.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // 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.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/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 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda.
21 |
22 |
23 |
24 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/GuideView.h:
--------------------------------------------------------------------------------
1 | //
2 | // GuideView.h
3 | // GuideDemo
4 | //
5 | // Created by 李剑钊 on 15/7/23.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface GuideView : UIView
12 |
13 | - (void)showInView:(UIView *)view maskBtn:(UIButton *)btn;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/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 | }
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/Images.xcassets/arrowDown.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "fx_guide_arrow_down@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/Images.xcassets/arrowDown.imageset/fx_guide_arrow_down@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/GuideDemo/GuideDemo/Images.xcassets/arrowDown.imageset/fx_guide_arrow_down@2x.png
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/Images.xcassets/btnMask.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "fx_livRm_guide_moreItm_mask@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/Images.xcassets/btnMask.imageset/fx_livRm_guide_moreItm_mask@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/GuideDemo/GuideDemo/Images.xcassets/btnMask.imageset/fx_livRm_guide_moreItm_mask@2x.png
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/Images.xcassets/fx_my_attention_guide_arrow.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "fx_my_attention_guide_arrow@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/Images.xcassets/fx_my_attention_guide_arrow.imageset/fx_my_attention_guide_arrow@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/GuideDemo/GuideDemo/Images.xcassets/fx_my_attention_guide_arrow.imageset/fx_my_attention_guide_arrow@2x.png
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/Images.xcassets/okBtn.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "fx_livRm_guide_ok@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/Images.xcassets/okBtn.imageset/fx_livRm_guide_ok@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/GuideDemo/GuideDemo/Images.xcassets/okBtn.imageset/fx_livRm_guide_ok@2x.png
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/Images.xcassets/whiteMask.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "whiteMask@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/Images.xcassets/whiteMask.imageset/whiteMask@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/GuideDemo/GuideDemo/Images.xcassets/whiteMask.imageset/whiteMask@2x.png
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.sunli.$(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 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/UIImage+Mask.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+Mask.h
3 | // GuideDemo
4 | //
5 | // Created by 李剑钊 on 15/7/24.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIImage (Mask)
12 |
13 | - (UIImage *)maskImage:(UIColor *)maskColor;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/UIImage+Mask.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+Mask.m
3 | // GuideDemo
4 | //
5 | // Created by 李剑钊 on 15/7/24.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import "UIImage+Mask.h"
10 |
11 | @implementation UIImage (Mask)
12 |
13 | - (UIImage *)maskImage:(UIColor *)maskColor
14 | {
15 | CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
16 |
17 | UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
18 |
19 | CGContextRef context = UIGraphicsGetCurrentContext();
20 | CGContextTranslateCTM(context, 0, rect.size.height);
21 | CGContextScaleCTM(context, 1.0, -1.0);
22 | CGContextClipToMask(context, rect, self.CGImage);
23 | CGContextSetFillColorWithColor(context, maskColor.CGColor);
24 | CGContextFillRect(context, rect);
25 |
26 | UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext();
27 |
28 | UIGraphicsEndImageContext();
29 |
30 | return smallImage;
31 | }
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/UIView+Layout.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Metrics.h
3 | // NeeFrame
4 | //
5 | // Created by 李剑钊 on 15/7/24.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import
10 | /**
11 | * 方便的访问和设置View的属性
12 | */
13 | @interface UIView (Layout)
14 |
15 | @property (assign, nonatomic) CGFloat top;
16 | @property (assign, nonatomic) CGFloat bottom;
17 | @property (assign, nonatomic) CGFloat left;
18 | @property (assign, nonatomic) CGFloat right;
19 |
20 | @property (assign, nonatomic) CGFloat x;
21 | @property (assign, nonatomic) CGFloat y;
22 | @property (assign, nonatomic) CGPoint origin;
23 |
24 | @property (assign, nonatomic) CGFloat centerX;
25 | @property (assign, nonatomic) CGFloat centerY;
26 |
27 | @property (assign, nonatomic) CGFloat width;
28 | @property (assign, nonatomic) CGFloat height;
29 | @property (assign, nonatomic) CGSize size;
30 |
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/UIView+Layout.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Metrics.m
3 | // NeeFrame
4 | //
5 | // Created by 李剑钊 on 15/7/24.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import "UIView+Layout.h"
10 |
11 | @implementation UIView (Layout)
12 |
13 | @dynamic top;
14 | @dynamic bottom;
15 | @dynamic left;
16 | @dynamic right;
17 |
18 | @dynamic width;
19 | @dynamic height;
20 |
21 | @dynamic size;
22 |
23 | @dynamic x;
24 | @dynamic y;
25 |
26 | - (CGFloat)top
27 | {
28 | return self.frame.origin.y;
29 | }
30 |
31 | - (void)setTop:(CGFloat)top
32 | {
33 | CGRect frame = self.frame;
34 | frame.origin.y = top;
35 | self.frame = frame;
36 | }
37 |
38 | - (CGFloat)left
39 | {
40 | return self.frame.origin.x;
41 | }
42 |
43 | - (void)setLeft:(CGFloat)left
44 | {
45 | CGRect frame = self.frame;
46 | frame.origin.x = left;
47 | self.frame = frame;
48 | }
49 |
50 | - (CGFloat)bottom
51 | {
52 | return self.frame.size.height + self.frame.origin.y;
53 | }
54 |
55 | - (void)setBottom:(CGFloat)bottom
56 | {
57 | CGRect frame = self.frame;
58 | frame.origin.y = bottom - frame.size.height;
59 | self.frame = frame;
60 | }
61 |
62 | - (CGFloat)right
63 | {
64 | return self.frame.size.width + self.frame.origin.x;
65 | }
66 |
67 | - (void)setRight:(CGFloat)right
68 | {
69 | CGRect frame = self.frame;
70 | frame.origin.x = right - frame.size.width;
71 | self.frame = frame;
72 | }
73 |
74 | - (CGFloat)x
75 | {
76 | return self.frame.origin.x;
77 | }
78 |
79 | - (void)setX:(CGFloat)value
80 | {
81 | CGRect frame = self.frame;
82 | frame.origin.x = value;
83 | self.frame = frame;
84 | }
85 |
86 | - (CGFloat)y
87 | {
88 | return self.frame.origin.y;
89 | }
90 |
91 | - (void)setY:(CGFloat)value
92 | {
93 | CGRect frame = self.frame;
94 | frame.origin.y = value;
95 | self.frame = frame;
96 | }
97 |
98 | - (CGPoint)origin
99 | {
100 | return self.frame.origin;
101 | }
102 |
103 | - (void)setOrigin:(CGPoint)origin
104 | {
105 | CGRect frame = self.frame;
106 | frame.origin = origin;
107 | self.frame = frame;
108 | }
109 |
110 | - (CGFloat)centerX
111 | {
112 | return self.center.x;
113 | }
114 |
115 | - (void)setCenterX:(CGFloat)centerX
116 | {
117 | CGPoint center = self.center;
118 | center.x = centerX;
119 | self.center = center;
120 | }
121 |
122 | - (CGFloat)centerY
123 | {
124 | return self.center.y;
125 | }
126 |
127 | - (void)setCenterY:(CGFloat)centerY
128 | {
129 | CGPoint center = self.center;
130 | center.y = centerY;
131 | self.center = center;
132 | }
133 |
134 | - (CGFloat)width
135 | {
136 | return self.frame.size.width;
137 | }
138 |
139 | - (void)setWidth:(CGFloat)width
140 | {
141 | CGRect frame = self.frame;
142 | frame.size.width = width;
143 | self.frame = frame;
144 | }
145 |
146 | - (CGFloat)height
147 | {
148 | return self.frame.size.height;
149 | }
150 |
151 | - (void)setHeight:(CGFloat)height
152 | {
153 | CGRect frame = self.frame;
154 | frame.size.height = height;
155 | self.frame = frame;
156 | }
157 |
158 | - (CGSize)size
159 | {
160 | return self.frame.size;
161 | }
162 |
163 | - (void)setSize:(CGSize)size
164 | {
165 | CGRect frame = self.frame;
166 | frame.size = size;
167 | self.frame = frame;
168 | }
169 |
170 | @end
171 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // GuideDemo
4 | //
5 | // Created by 李剑钊 on 15/7/23.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // GuideDemo
4 | //
5 | // Created by 李剑钊 on 15/7/23.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "UIView+Layout.h"
11 | #import "GuideView.h"
12 |
13 | @interface ViewController ()
14 |
15 | @property (weak, nonatomic) IBOutlet UITextView *textView;
16 | @property (weak, nonatomic) IBOutlet UIButton *button;
17 |
18 | @end
19 |
20 | @implementation ViewController
21 |
22 | - (void)viewDidLoad {
23 | [super viewDidLoad];
24 | // Do any additional setup after loading the view, typically from a nib.
25 | }
26 |
27 | - (void)didReceiveMemoryWarning {
28 | [super didReceiveMemoryWarning];
29 | // Dispose of any resources that can be recreated.
30 | }
31 |
32 | - (void)viewDidAppear:(BOOL)animated {
33 | GuideView *guide = [GuideView new];
34 | [guide showInView:self.view maskBtn:self.button];
35 | }
36 |
37 | - (void)viewWillLayoutSubviews {
38 | _textView.left = 8;
39 | _textView.top = 60;
40 | _textView.width = self.view.width - 16;
41 | _textView.height = self.view.height - 210;
42 |
43 | _button.centerX = self.view.width/2;
44 | _button.top = _textView.bottom + 16;
45 | }
46 |
47 | @end
48 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemo/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // GuideDemo
4 | //
5 | // Created by 李剑钊 on 15/7/23.
6 | // Copyright (c) 2015年 sunli. 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 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemoTests/GuideDemoTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // GuideDemoTests.m
3 | // GuideDemoTests
4 | //
5 | // Created by 李剑钊 on 15/7/23.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface GuideDemoTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation GuideDemoTests
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 |
--------------------------------------------------------------------------------
/GuideDemo/GuideDemoTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.sunli.$(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 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp.xcodeproj/project.xcworkspace/xcuserdata/sunli.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/Socket/SocketApp/SocketApp.xcodeproj/project.xcworkspace/xcuserdata/sunli.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp.xcodeproj/xcuserdata/sunli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp.xcodeproj/xcuserdata/sunli.xcuserdatad/xcschemes/SocketApp.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
77 |
83 |
84 |
85 |
86 |
87 |
88 |
94 |
96 |
102 |
103 |
104 |
105 |
107 |
108 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp.xcodeproj/xcuserdata/sunli.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SocketApp.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | A1D39B901B2EE46400B56E57
16 |
17 | primary
18 |
19 |
20 | A1D39BA91B2EE46400B56E57
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // SocketApp
4 | //
5 | // Created by 李剑钊 on 15/6/15.
6 | // Copyright (c) 2015年 sunli. 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 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // SocketApp
4 | //
5 | // Created by 李剑钊 on 15/6/15.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // 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.
25 | // 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.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // 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.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // 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.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp/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 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp/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 | }
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.kugou.$(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 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp/SocketHandle.h:
--------------------------------------------------------------------------------
1 | //
2 | // SocketHandle.h
3 | // SocketApp
4 | //
5 | // Created by 李剑钊 on 15/6/15.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @protocol SocketDelegate
12 | @optional
13 | - (void)socketDidReceiveText:(NSString *)text;
14 |
15 | @end
16 |
17 | @interface SocketHandle : NSObject
18 |
19 | @property (nonatomic, assign, readonly) BOOL isSocketOpened;
20 | @property (nonatomic, weak) iddelegate;
21 |
22 | - (void)initSocket:(NSString *)serverIp;
23 |
24 | - (void)sendData:(NSString *)str;
25 |
26 | - (void)closeSocket;
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp/SocketHandle.m:
--------------------------------------------------------------------------------
1 | //
2 | // SocketHandle.m
3 | // SocketApp
4 | //
5 | // Created by 李剑钊 on 15/6/15.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import "SocketHandle.h"
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 | #define PORT 6677
19 |
20 | @interface SocketHandle () {
21 |
22 | }
23 |
24 | @property (nonatomic, assign) BOOL isIniting;
25 | @property (nonatomic, assign) int app_socket;
26 |
27 | @end
28 |
29 | @implementation SocketHandle
30 |
31 | - (instancetype)init
32 | {
33 | self = [super init];
34 | if (self) {
35 |
36 | }
37 | return self;
38 | }
39 |
40 | - (void)initSocket:(NSString *)serverIp {
41 | if (_isIniting) {
42 | return;
43 | } else if (_isSocketOpened) {
44 | return;
45 | }
46 |
47 | self.isIniting = YES;
48 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
49 | NSString *host = serverIp;
50 |
51 | // 创建socket
52 | int app_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
53 | if (app_socket < 0) {
54 | NSLog(@"create socket failed");
55 | return;
56 | }
57 | self.app_socket = app_socket;
58 |
59 | struct hostent *remoteHostEnt = gethostbyname([host UTF8String]);
60 | if (remoteHostEnt == NULL) {
61 | NSLog(@"host name is error");
62 | return;
63 | }
64 | struct in_addr *remoteInAddr = (struct in_addr *)remoteHostEnt->h_addr_list[0];
65 | // 服务器socket地址结构
66 | struct sockaddr_in server_addr;
67 | bzero(&server_addr, sizeof(server_addr));
68 | server_addr.sin_family = AF_INET;
69 | server_addr.sin_addr.s_addr = remoteInAddr->s_addr;
70 | server_addr.sin_port = htons(PORT);
71 | int connect_result = connect(app_socket, (struct sockaddr *)&server_addr, sizeof(server_addr));
72 | if (connect_result < 0) {
73 | NSLog(@"connect error");
74 | return;
75 | }
76 |
77 | _isSocketOpened = YES;
78 | _isIniting = NO;
79 |
80 | while (_isSocketOpened) {
81 | char buffer[30000];
82 | int lenght = sizeof(buffer);
83 |
84 | ssize_t result = recv(app_socket, buffer, 30000, 0);
85 | if (result > 0) {
86 | [self didReceiveBuffer:(const char *)buffer];
87 | NSLog(@"receive data:%s",buffer);
88 | } else {
89 | NSLog(@"receive data failed");
90 | }
91 | }
92 | [self closeSocket];
93 | });
94 | }
95 |
96 | - (void)sendData:(NSString *)str {
97 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
98 | const char *buffer = [str UTF8String];
99 | ssize_t result = send(_app_socket, buffer, strlen(buffer), 0);
100 | if (result > 0) {
101 | NSLog(@"send data success");
102 | } else {
103 | NSLog(@"send data failed");
104 | }
105 | });
106 | }
107 |
108 | - (void)didReceiveBuffer:(const char *)buffer {
109 | NSString *text = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding];
110 | if ([_delegate respondsToSelector:@selector(socketDidReceiveText:)]) {
111 | if ([NSThread isMainThread]) {
112 | [_delegate socketDidReceiveText:text];
113 | } else {
114 | dispatch_async(dispatch_get_main_queue(), ^{
115 | [_delegate socketDidReceiveText:text];
116 | });
117 | }
118 | }
119 | }
120 |
121 | - (void)closeSocket {
122 | if (_isSocketOpened) {
123 | close(_app_socket);
124 | _isSocketOpened = NO;
125 | _isIniting = NO;
126 | }
127 | }
128 |
129 | @end
130 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // SocketApp
4 | //
5 | // Created by 李剑钊 on 15/6/15.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // SocketApp
4 | //
5 | // Created by 李剑钊 on 15/6/15.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "SocketHandle.h"
11 | #import "GetIpAddress.h"
12 |
13 | @interface ViewController ()
14 |
15 | @property (nonatomic, strong) SocketHandle *socketHan;
16 | @property (weak, nonatomic) IBOutlet UITextField *ipTextField;
17 | @property (weak, nonatomic) IBOutlet UITextField *inputTextField;
18 | @property (weak, nonatomic) IBOutlet UITextView *outputTextField;
19 |
20 | @end
21 |
22 | @implementation ViewController
23 |
24 | - (void)viewDidLoad {
25 | [super viewDidLoad];
26 | // Do any additional setup after loading the view, typically from a nib.
27 | }
28 |
29 | - (void)didReceiveMemoryWarning {
30 | [super didReceiveMemoryWarning];
31 | // Dispose of any resources that can be recreated.
32 | }
33 |
34 | #pragma mark - event
35 |
36 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
37 | [_inputTextField resignFirstResponder];
38 | [_ipTextField resignFirstResponder];
39 | }
40 |
41 | - (IBAction)connectBtnTouch:(id)sender {
42 | [self.socketHan initSocket:_ipTextField.text];
43 | }
44 |
45 | - (IBAction)closeBtnTouch:(id)sender {
46 | [_socketHan closeSocket];
47 | }
48 |
49 | - (IBAction)sendBtnTouch:(id)sender {
50 | NSString *text = [NSString stringWithFormat:@"App: %@",_inputTextField.text];
51 | [_socketHan sendData:text];
52 | [_inputTextField resignFirstResponder];
53 | }
54 |
55 | #pragma mark - socket delegate
56 |
57 | - (void)socketDidReceiveText:(NSString *)text {
58 | NSString *string = _outputTextField.text;
59 | if (!string) {
60 | string = @"";
61 | }
62 | if (string.length > 0) {
63 | string = [string stringByAppendingString:@"\n"];
64 | }
65 | string = [string stringByAppendingString:text];
66 | _outputTextField.text = string;
67 | }
68 |
69 | #pragma mark - getter and setter
70 |
71 | - (SocketHandle *)socketHan {
72 | if (!_socketHan) {
73 | _socketHan = [SocketHandle new];
74 | _socketHan.delegate = self;
75 | }
76 | return _socketHan;
77 | }
78 |
79 | @end
80 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp/en.lproj/Main.strings:
--------------------------------------------------------------------------------
1 |
2 | /* Class = "UIButton"; normalTitle = "Close"; ObjectID = "6Dy-XF-tgl"; */
3 | "6Dy-XF-tgl.normalTitle" = "Close";
4 |
5 | /* Class = "UILabel"; text = "Server Ip:"; ObjectID = "BTf-aT-EzF"; */
6 | "BTf-aT-EzF.text" = "Server Ip:";
7 |
8 | /* Class = "UIButton"; normalTitle = "Send"; ObjectID = "aTJ-bZ-DLQ"; */
9 | "aTJ-bZ-DLQ.normalTitle" = "Send";
10 |
11 | /* Class = "UIButton"; normalTitle = "Connect"; ObjectID = "foa-2F-67g"; */
12 | "foa-2F-67g.normalTitle" = "Connect";
13 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp/ip/GetIpAddress.h:
--------------------------------------------------------------------------------
1 | //
2 | // GetIpAddress.h
3 | // SocketServer
4 | //
5 | // Created by 李剑钊 on 15/6/16.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface GetIpAddress : NSObject
12 |
13 | + (NSString *)getDeviceIpAddress;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp/ip/GetIpAddress.m:
--------------------------------------------------------------------------------
1 | //
2 | // GetIpAddress.m
3 | // SocketServer
4 | //
5 | // Created by 李剑钊 on 15/6/16.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import "GetIpAddress.h"
10 | #import "IpAddress.h"
11 |
12 | @implementation GetIpAddress
13 |
14 | + (NSString *)getDeviceIpAddress {
15 | InitAddresses();
16 | GetIPAddresses();
17 | GetHWAddresses();
18 | NSString *ip = [NSString stringWithFormat:@"%s", ip_names[1]];
19 | FreeAddresses();
20 | return ip;
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp/ip/IpAddress.h:
--------------------------------------------------------------------------------
1 | //
2 | // IpAddress.h
3 | // SocketServer
4 | //
5 | // Created by 李剑钊 on 15/6/16.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #ifndef __SocketServer__IpAddress__
10 | #define __SocketServer__IpAddress__
11 |
12 | #include
13 |
14 | #define MAXADDRS 32
15 | extern char *if_names[MAXADDRS];
16 | extern char *ip_names[MAXADDRS];
17 | extern char *hw_addrs[MAXADDRS];
18 | extern unsigned long ip_addrs[MAXADDRS];
19 | // Function prototypes
20 | void InitAddresses();
21 | void FreeAddresses();
22 | void GetIPAddresses();
23 | void GetHWAddresses();
24 |
25 | #endif /* defined(__SocketServer__IpAddress__) */
26 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketApp/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // SocketApp
4 | //
5 | // Created by 李剑钊 on 15/6/15.
6 | // Copyright (c) 2015年 sunli. 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 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketAppTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.kugou.$(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 |
--------------------------------------------------------------------------------
/Socket/SocketApp/SocketAppTests/SocketAppTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // SocketAppTests.m
3 | // SocketAppTests
4 | //
5 | // Created by 李剑钊 on 15/6/15.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface SocketAppTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation SocketAppTests
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 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer.xcodeproj/project.xcworkspace/xcuserdata/sunli.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/Socket/SocketServer/SocketServer.xcodeproj/project.xcworkspace/xcuserdata/sunli.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer.xcodeproj/xcuserdata/sunli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer.xcodeproj/xcuserdata/sunli.xcuserdatad/xcschemes/SocketServer.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
77 |
83 |
84 |
85 |
86 |
87 |
88 |
94 |
96 |
102 |
103 |
104 |
105 |
107 |
108 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer.xcodeproj/xcuserdata/sunli.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SocketServer.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | A1D39B5B1B2EC90900B56E57
16 |
17 | primary
18 |
19 |
20 | A1D39B741B2EC90900B56E57
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // SocketServer
4 | //
5 | // Created by 李剑钊 on 15/6/15.
6 | // Copyright (c) 2015年 sunli. 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 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // SocketServer
4 | //
5 | // Created by 李剑钊 on 15/6/15.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // 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.
25 | // 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.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // 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.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // 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.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer/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 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer/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 | }
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.kugou.$(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 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer/MyServer.h:
--------------------------------------------------------------------------------
1 | //
2 | // MyServer.h
3 | // SocketServer
4 | //
5 | // Created by 李剑钊 on 15/6/15.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @protocol SocketDelegate
12 | @optional
13 | - (void)socketDidReceiveText:(NSString *)text;
14 |
15 | @end
16 |
17 | @interface MyServer : NSObject
18 |
19 | @property (nonatomic, assign, readonly) BOOL isSocketOpened;
20 | @property (nonatomic, weak) iddelegate;
21 |
22 | - (void)initSocket;
23 |
24 | - (void)sendData:(NSString *)text;
25 |
26 | - (void)closeSocket;
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer/MyServer.m:
--------------------------------------------------------------------------------
1 | //
2 | // MyServer.m
3 | // SocketServer
4 | //
5 | // Created by 李剑钊 on 15/6/15.
6 | // Copyright (c) 2015年 ;. All rights reserved.
7 | //
8 |
9 | #import "MyServer.h"
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #define PORT 6677
18 | #define MAXDATASIZE 100
19 | #define LENGTH_OF_LISTEN_QUEUE 20
20 | #define BUFFER_SIZE 30000
21 | #define THREAD_MAX 5
22 |
23 | @interface MyServer ()
24 |
25 | @property (nonatomic, assign) BOOL isIniting;
26 | @property (atomic, assign) int server_socket;
27 | @property (nonatomic, assign) int client_socket;
28 |
29 | @end
30 |
31 | @implementation MyServer
32 |
33 | - (instancetype)init
34 | {
35 | self = [super init];
36 | if (self) {
37 |
38 | }
39 | return self;
40 | }
41 |
42 | - (void)initSocket {
43 | if (_isIniting) {
44 | return;
45 | } else if (_isSocketOpened) {
46 | return;
47 | }
48 |
49 | self.isIniting = YES;
50 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
51 | // 服务器socket地址结构
52 | struct sockaddr_in server_addr;
53 | bzero(&server_addr, sizeof(server_addr));
54 | server_addr.sin_family = AF_INET;
55 | server_addr.sin_addr.s_addr = htons(INADDR_ANY);
56 | server_addr.sin_port = htons(PORT);
57 |
58 | // 创建socket
59 | int server_socket = socket(server_addr.sin_family, SOCK_STREAM, IPPROTO_TCP);
60 | if (server_socket < 0) {
61 | NSLog(@"create socket failed");
62 | return;
63 | }
64 | self.server_socket = server_socket;
65 |
66 | // 绑定socket
67 | int bind_socker = bind(server_socket, (const struct sockaddr *)&server_addr, sizeof(server_addr));
68 | if (bind_socker) {
69 | NSLog(@"bind socket failed");
70 | return;
71 | }
72 |
73 | int listen_socker = listen(server_socket, LENGTH_OF_LISTEN_QUEUE);
74 | if (listen_socker) {
75 | NSLog(@"listen socket failed");
76 | return;
77 | }
78 |
79 | _isSocketOpened = YES;
80 | _isIniting = NO;
81 |
82 | while (_isSocketOpened) {
83 | NSLog(@"socket star");
84 | struct sockaddr_in client_addr;
85 | socklen_t lenght = sizeof(client_addr);
86 |
87 | int new_client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &lenght);
88 | if (new_client_socket < 0) {
89 | NSLog(@"server accept failed");
90 | break;
91 | }
92 | self.client_socket = new_client_socket;
93 |
94 | NSLog(@"once client connected");
95 | [self readSocket:new_client_socket];
96 | }
97 |
98 | [self closeSocket];
99 | });
100 | }
101 |
102 | - (void)readSocket:(int)clientSocket {
103 | char buffer[BUFFER_SIZE];
104 | buffer[0] = ' ';
105 |
106 | while (buffer[0] != '\0') {
107 | bzero(buffer, BUFFER_SIZE);
108 | // 接收客户端的信息到buffer中
109 | recv(clientSocket, buffer, BUFFER_SIZE, 0);
110 | NSLog(@"client buffer:%s",buffer);
111 | NSString *text = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding];
112 | if ([_delegate respondsToSelector:@selector(socketDidReceiveText:)]) {
113 | if ([NSThread isMainThread]) {
114 | [_delegate socketDidReceiveText:text];
115 | } else {
116 | dispatch_async(dispatch_get_main_queue(), ^{
117 | [_delegate socketDidReceiveText:text];
118 | });
119 | }
120 | }
121 | }
122 |
123 | // NSLog(@"client close");
124 | // close(clientSocket);
125 | }
126 |
127 | - (void)sendData:(NSString *)text {
128 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
129 | const char *buffer = [text UTF8String];
130 | ssize_t result = send(_client_socket, buffer, strlen(buffer), 0);
131 | if (result < 0) {
132 | NSLog(@"send data failed");
133 | }
134 | });
135 | }
136 |
137 | - (void)closeSocket {
138 | if (_isSocketOpened) {
139 | close(_server_socket);
140 | _isSocketOpened = NO;
141 | _isIniting = NO;
142 | }
143 | }
144 |
145 | @end
146 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // SocketServer
4 | //
5 | // Created by 李剑钊 on 15/6/15.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // SocketServer
4 | //
5 | // Created by 李剑钊 on 15/6/15.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "MyServer.h"
11 | #import "GetIpAddress.h"
12 |
13 | @interface ViewController ()
14 |
15 | @property (nonatomic, strong) MyServer *server;
16 | @property (weak, nonatomic) IBOutlet UILabel *ipLabel;
17 | @property (weak, nonatomic) IBOutlet UITextField *inputTextField;
18 | @property (weak, nonatomic) IBOutlet UITextView *outputTextView;
19 |
20 | @end
21 |
22 | @implementation ViewController
23 |
24 | - (void)viewDidLoad {
25 | [super viewDidLoad];
26 | // Do any additional setup after loading the view, typically from a nib.
27 | _ipLabel.text = [GetIpAddress getDeviceIpAddress];
28 | }
29 |
30 | - (void)didReceiveMemoryWarning {
31 | [super didReceiveMemoryWarning];
32 | // Dispose of any resources that can be recreated.
33 | }
34 |
35 | #pragma mark - event
36 |
37 | - (IBAction)initSocketBtnTouch:(id)sender {
38 | [self.server initSocket];
39 | }
40 |
41 | - (IBAction)closeBtnTouch:(id)sender {
42 | [_server closeSocket];
43 | }
44 | - (IBAction)sendBtnTouch:(id)sender {
45 | NSString *text = [NSString stringWithFormat:@"Server: %@",_inputTextField.text];
46 | [_server sendData:text];
47 | [_inputTextField resignFirstResponder];
48 | }
49 |
50 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
51 | [_inputTextField resignFirstResponder];
52 | }
53 |
54 | #pragma mark - socket delegate
55 |
56 | - (void)socketDidReceiveText:(NSString *)text {
57 | NSString *string = _outputTextView.text;
58 | if (!string) {
59 | string = @"";
60 | }
61 | if (string.length > 0) {
62 | string = [string stringByAppendingString:@"\n"];
63 | }
64 | string = [string stringByAppendingString:text];
65 | _outputTextView.text = string;
66 | }
67 |
68 | #pragma mark - getter and setter
69 |
70 | - (MyServer *)server {
71 | if (!_server) {
72 | _server = [MyServer new];
73 | _server.delegate = self;
74 | }
75 | return _server;
76 | }
77 |
78 | @end
79 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer/ip/GetIpAddress.h:
--------------------------------------------------------------------------------
1 | //
2 | // GetIpAddress.h
3 | // SocketServer
4 | //
5 | // Created by 李剑钊 on 15/6/16.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface GetIpAddress : NSObject
12 |
13 | + (NSString *)getDeviceIpAddress;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer/ip/GetIpAddress.m:
--------------------------------------------------------------------------------
1 | //
2 | // GetIpAddress.m
3 | // SocketServer
4 | //
5 | // Created by 李剑钊 on 15/6/16.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import "GetIpAddress.h"
10 | #import "IpAddress.h"
11 |
12 | @implementation GetIpAddress
13 |
14 | + (NSString *)getDeviceIpAddress {
15 | InitAddresses();
16 | GetIPAddresses();
17 | GetHWAddresses();
18 | NSString *ip = [NSString stringWithFormat:@"%s", ip_names[1]];
19 | FreeAddresses();
20 | return ip;
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer/ip/IpAddress.h:
--------------------------------------------------------------------------------
1 | //
2 | // IpAddress.h
3 | // SocketServer
4 | //
5 | // Created by 李剑钊 on 15/6/16.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #ifndef __SocketServer__IpAddress__
10 | #define __SocketServer__IpAddress__
11 |
12 | #include
13 |
14 | #define MAXADDRS 32
15 | extern char *if_names[MAXADDRS];
16 | extern char *ip_names[MAXADDRS];
17 | extern char *hw_addrs[MAXADDRS];
18 | extern unsigned long ip_addrs[MAXADDRS];
19 | // Function prototypes
20 | void InitAddresses();
21 | void FreeAddresses();
22 | void GetIPAddresses();
23 | void GetHWAddresses();
24 |
25 | #endif /* defined(__SocketServer__IpAddress__) */
26 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServer/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // SocketServer
4 | //
5 | // Created by 李剑钊 on 15/6/15.
6 | // Copyright (c) 2015年 sunli. 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 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServerTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.kugou.$(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 |
--------------------------------------------------------------------------------
/Socket/SocketServer/SocketServerTests/SocketServerTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // SocketServerTests.m
3 | // SocketServerTests
4 | //
5 | // Created by 李剑钊 on 15/6/15.
6 | // Copyright (c) 2015年 sunli. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface SocketServerTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation SocketServerTests
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 |
--------------------------------------------------------------------------------
/SpringAnimation/SpringAnimation.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SpringAnimation/SpringAnimation.xcodeproj/project.xcworkspace/xcuserdata/sunli.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/SpringAnimation/SpringAnimation.xcodeproj/project.xcworkspace/xcuserdata/sunli.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/SpringAnimation/SpringAnimation.xcodeproj/xcuserdata/sunli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/SpringAnimation/SpringAnimation.xcodeproj/xcuserdata/sunli.xcuserdatad/xcschemes/SpringAnimation.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/SpringAnimation/SpringAnimation.xcodeproj/xcuserdata/sunli.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SpringAnimation.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | A15005071B6737F800B9A7B1
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/SpringAnimation/SpringAnimation/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SpringAnimation
4 | //
5 | // Created by 李剑钊 on 15/7/28.
6 | // Copyright © 2015年 sunli. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/SpringAnimation/SpringAnimation/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/SpringAnimation/SpringAnimation/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
26 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/SpringAnimation/SpringAnimation/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/SpringAnimation/SpringAnimation/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/SpringAnimation/SpringAnimation/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // SpringAnimation
4 | //
5 | // Created by 李剑钊 on 15/7/28.
6 | // Copyright © 2015年 sunli. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import QuartzCore
11 |
12 | class ViewController: UIViewController {
13 |
14 | @IBOutlet weak var label: UILabel!
15 |
16 | override func viewDidLoad() {
17 | super.viewDidLoad()
18 | // Do any additional setup after loading the view, typically from a nib.
19 | }
20 |
21 | override func didReceiveMemoryWarning() {
22 | super.didReceiveMemoryWarning()
23 | // Dispose of any resources that can be recreated.
24 | }
25 |
26 | override func touchesEnded(touches: Set, withEvent event: UIEvent?) {
27 | let spring = CASpringAnimation(keyPath: "position.x")
28 | spring.damping = 5;
29 | spring.stiffness = 100;
30 | spring.mass = 1;
31 | spring.initialVelocity = -30;
32 | spring.fromValue = label.layer.position.x;
33 | spring.toValue = label.layer.position.x + 50;
34 | spring.duration = spring.settlingDuration;
35 | label.layer.addAnimation(spring, forKey: spring.keyPath);
36 | }
37 | /*
38 | mass 质量,影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩的幅度越大
39 | stiffness 刚度系数(劲度系数/弹性系数),刚度系数越大,形变产生的力就越大,运动越快
40 | damping 阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快
41 | initialVelocity 初始速率
42 | settlingDuration 结算时间 返回弹簧动画到停止时的估算时间,根据当前的动画参数估算
43 | */
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/WatchDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "watch",
5 | "screenWidth" : "{130,145}",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "watch",
10 | "screenWidth" : "{146,165}",
11 | "scale" : "2x"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/WatchDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "assets" : [
3 | {
4 | "idiom" : "watch",
5 | "filename" : "Circular.imageset",
6 | "role" : "circular"
7 | },
8 | {
9 | "idiom" : "watch",
10 | "filename" : "Modular.imageset",
11 | "role" : "modular"
12 | },
13 | {
14 | "idiom" : "watch",
15 | "filename" : "Utilitarian.imageset",
16 | "role" : "utilitarian"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/WatchDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "watch",
5 | "screenWidth" : "{130,145}",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "watch",
10 | "screenWidth" : "{146,165}",
11 | "scale" : "2x"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/WatchDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "watch",
5 | "screenWidth" : "{130,145}",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "watch",
10 | "screenWidth" : "{146,165}",
11 | "scale" : "2x"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/WatchDemo/WatchApp Extension/ComplicationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ComplicationController.swift
3 | // WatchApp Extension
4 | //
5 | // Created by 李剑钊 on 15/7/30.
6 | // Copyright © 2015年 sunli. All rights reserved.
7 | //
8 |
9 | import ClockKit
10 |
11 |
12 | class ComplicationController: NSObject, CLKComplicationDataSource {
13 |
14 | // MARK: - Timeline Configuration
15 |
16 | func getSupportedTimeTravelDirectionsForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationTimeTravelDirections) -> Void) {
17 | handler([.Forward, .Backward])
18 | }
19 |
20 | func getTimelineStartDateForComplication(complication: CLKComplication, withHandler handler: (NSDate?) -> Void) {
21 | handler(nil)
22 | }
23 |
24 | func getTimelineEndDateForComplication(complication: CLKComplication, withHandler handler: (NSDate?) -> Void) {
25 | handler(nil)
26 | }
27 |
28 | func getPrivacyBehaviorForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationPrivacyBehavior) -> Void) {
29 | handler(.ShowOnLockScreen)
30 | }
31 |
32 | // MARK: - Timeline Population
33 |
34 | func getCurrentTimelineEntryForComplication(complication: CLKComplication, withHandler handler: ((CLKComplicationTimelineEntry?) -> Void)) {
35 | // Call the handler with the current timeline entry
36 | handler(nil)
37 | }
38 |
39 | func getTimelineEntriesForComplication(complication: CLKComplication, beforeDate date: NSDate, limit: Int, withHandler handler: (([CLKComplicationTimelineEntry]?) -> Void)) {
40 | // Call the handler with the timeline entries prior to the given date
41 | handler(nil)
42 | }
43 |
44 | func getTimelineEntriesForComplication(complication: CLKComplication, afterDate date: NSDate, limit: Int, withHandler handler: (([CLKComplicationTimelineEntry]?) -> Void)) {
45 | // Call the handler with the timeline entries after to the given date
46 | handler(nil)
47 | }
48 |
49 | // MARK: - Update Scheduling
50 |
51 | func getNextRequestedUpdateDateWithHandler(handler: (NSDate?) -> Void) {
52 | // Call the handler with the date when you would next like to be given the opportunity to update your complication content
53 | handler(nil);
54 | }
55 |
56 | // MARK: - Placeholder Templates
57 |
58 | func getPlaceholderTemplateForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationTemplate?) -> Void) {
59 | // This method will be called once per supported complication, and the results will be cached
60 | handler(nil)
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/WatchDemo/WatchApp Extension/ExtensionDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExtensionDelegate.swift
3 | // WatchApp Extension
4 | //
5 | // Created by 李剑钊 on 15/7/30.
6 | // Copyright © 2015年 sunli. All rights reserved.
7 | //
8 |
9 | import WatchKit
10 |
11 | class ExtensionDelegate: NSObject, WKExtensionDelegate {
12 |
13 | func applicationDidFinishLaunching() {
14 | // Perform any final initialization of your application.
15 | }
16 |
17 | func applicationDidBecomeActive() {
18 | // 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.
19 | }
20 |
21 | func applicationWillResignActive() {
22 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
23 | // Use this method to pause ongoing tasks, disable timers, etc.
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/WatchDemo/WatchApp Extension/GlanceController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GlanceController.swift
3 | // WatchApp Extension
4 | //
5 | // Created by 李剑钊 on 15/7/30.
6 | // Copyright © 2015年 sunli. All rights reserved.
7 | //
8 |
9 | import WatchKit
10 | import Foundation
11 |
12 |
13 | class GlanceController: WKInterfaceController {
14 |
15 | override func awakeWithContext(context: AnyObject?) {
16 | super.awakeWithContext(context)
17 |
18 | // Configure interface objects here.
19 | }
20 |
21 | override func willActivate() {
22 | // This method is called when watch view controller is about to be visible to user
23 | super.willActivate()
24 | }
25 |
26 | override func didDeactivate() {
27 | // This method is called when watch view controller is no longer visible
28 | super.didDeactivate()
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/WatchDemo/WatchApp Extension/ImageInterfaceController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ImageInterfaceController.swift
3 | // WatchDemo
4 | //
5 | // Created by 李剑钊 on 15/8/4.
6 | // Copyright © 2015年 sunli. All rights reserved.
7 | //
8 |
9 | import WatchKit
10 | import Foundation
11 |
12 |
13 | class ImageInterfaceController: WKInterfaceController {
14 |
15 | @IBOutlet var imageView: WKInterfaceImage!
16 | override func awakeWithContext(context: AnyObject?) {
17 | super.awakeWithContext(context)
18 |
19 | // Configure interface objects here.
20 | }
21 |
22 | override func willActivate() {
23 | // This method is called when watch view controller is about to be visible to user
24 | super.willActivate()
25 |
26 | }
27 |
28 | override func didDeactivate() {
29 | // This method is called when watch view controller is no longer visible
30 | super.didDeactivate()
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/WatchDemo/WatchApp Extension/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | WatchApp Extension
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | XPC!
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | CLKComplicationPrincipalClass
26 | $(PRODUCT_MODULE_NAME).ComplicationController
27 | CLKComplicationSupportedFamilies
28 |
29 | CLKComplicationFamilyModularSmall
30 | CLKComplicationFamilyModularLarge
31 | CLKComplicationFamilyUtilitarianSmall
32 | CLKComplicationFamilyUtilitarianLarge
33 | CLKComplicationFamilyCircularSmall
34 |
35 | NSExtension
36 |
37 | NSExtensionAttributes
38 |
39 | WKAppBundleIdentifier
40 | com.sunli.WatchDemo.watchkitapp
41 |
42 | NSExtensionPointIdentifier
43 | com.apple.watchkit
44 |
45 | RemoteInterfacePrincipalClass
46 | $(PRODUCT_MODULE_NAME).InterfaceController
47 | WKExtensionDelegateClassName
48 | $(PRODUCT_MODULE_NAME).ExtensionDelegate
49 |
50 |
51 |
--------------------------------------------------------------------------------
/WatchDemo/WatchApp Extension/InterfaceController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InterfaceController.swift
3 | // WatchApp Extension
4 | //
5 | // Created by 李剑钊 on 15/7/30.
6 | // Copyright © 2015年 sunli. All rights reserved.
7 | //
8 |
9 | import WatchKit
10 | import Foundation
11 |
12 |
13 | class InterfaceController: WKInterfaceController {
14 |
15 | @IBOutlet var tipsLabel: WKInterfaceLabel!
16 | @IBOutlet var colorBtn: WKInterfaceButton!
17 | var colorStyle = 0;
18 |
19 | override func awakeWithContext(context: AnyObject?) {
20 | super.awakeWithContext(context)
21 |
22 | // Configure interface objects here.
23 | }
24 |
25 | override func willActivate() {
26 | // This method is called when watch view controller is about to be visible to user
27 | super.willActivate()
28 |
29 | self.configTipsLabel()
30 | }
31 |
32 | override func didDeactivate() {
33 | // This method is called when watch view controller is no longer visible
34 | super.didDeactivate()
35 | }
36 |
37 | func configTipsLabel() {
38 | let font = UIFont.systemFontOfSize(16)
39 | let helloDic = [NSFontAttributeName:font,NSForegroundColorAttributeName:UIColor.whiteColor()]
40 |
41 | let mAttr = NSMutableAttributedString(string: "Hello World!", attributes: helloDic)
42 |
43 | let nameDic = [NSFontAttributeName:font,NSForegroundColorAttributeName:UIColor.yellowColor()]
44 | let nameAttr = NSAttributedString(string: " I'm a Developer", attributes: nameDic)
45 |
46 | mAttr.appendAttributedString(nameAttr)
47 | tipsLabel.setAttributedText(mAttr)
48 | }
49 |
50 | @IBAction func buttonTouched() {
51 | if colorStyle == 0 {
52 | colorStyle = 1;
53 | colorBtn.setBackgroundColor(UIColor.grayColor())
54 | } else {
55 | colorStyle = 0;
56 | colorBtn.setBackgroundColor(UIColor.clearColor())
57 | }
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/WatchDemo/WatchApp Extension/NotificationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NotificationController.swift
3 | // WatchApp Extension
4 | //
5 | // Created by 李剑钊 on 15/7/30.
6 | // Copyright © 2015年 sunli. All rights reserved.
7 | //
8 |
9 | import WatchKit
10 | import Foundation
11 |
12 |
13 | class NotificationController: WKUserNotificationInterfaceController {
14 |
15 | override init() {
16 | // Initialize variables here.
17 | super.init()
18 |
19 | // Configure interface objects here.
20 | }
21 |
22 | override func willActivate() {
23 | // This method is called when watch view controller is about to be visible to user
24 | super.willActivate()
25 | }
26 |
27 | override func didDeactivate() {
28 | // This method is called when watch view controller is no longer visible
29 | super.didDeactivate()
30 | }
31 |
32 | /*
33 | override func didReceiveLocalNotification(localNotification: UILocalNotification, withCompletion completionHandler: ((WKUserNotificationInterfaceType) -> Void)) {
34 | // This method is called when a local notification needs to be presented.
35 | // Implement it if you use a dynamic notification interface.
36 | // Populate your dynamic notification interface as quickly as possible.
37 | //
38 | // After populating your dynamic notification interface call the completion block.
39 | completionHandler(.Custom)
40 | }
41 | */
42 |
43 | /*
44 | override func didReceiveRemoteNotification(remoteNotification: [NSObject : AnyObject], withCompletion completionHandler: ((WKUserNotificationInterfaceType) -> Void)) {
45 | // This method is called when a remote notification needs to be presented.
46 | // Implement it if you use a dynamic notification interface.
47 | // Populate your dynamic notification interface as quickly as possible.
48 | //
49 | // After populating your dynamic notification interface call the completion block.
50 | completionHandler(.Custom)
51 | }
52 | */
53 | }
54 |
--------------------------------------------------------------------------------
/WatchDemo/WatchApp Extension/PushNotificationPayload.apns:
--------------------------------------------------------------------------------
1 | {
2 | "aps": {
3 | "alert": {
4 | "body": "Test message",
5 | "title": "Optional title"
6 | },
7 | "category": "myCategory"
8 | },
9 |
10 | "WatchKit Simulator Actions": [
11 | {
12 | "title": "First Button",
13 | "identifier": "firstButtonAction"
14 | }
15 | ],
16 |
17 | "customKey": "Use this file to define a testing payload for your notifications. The aps dictionary specifies the category, alert text and title. The WatchKit Simulator Actions array can provide info for one or more action buttons in addition to the standard Dismiss button. Any other top level keys are custom payload. If you have multiple such JSON files in your project, you'll be able to select them when choosing to debug the notification interface of your Watch App."
18 | }
19 |
--------------------------------------------------------------------------------
/WatchDemo/WatchApp/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "24x24",
5 | "idiom" : "watch",
6 | "scale" : "2x",
7 | "role" : "notificationCenter",
8 | "subtype" : "38mm"
9 | },
10 | {
11 | "size" : "27.5x27.5",
12 | "idiom" : "watch",
13 | "scale" : "2x",
14 | "role" : "notificationCenter",
15 | "subtype" : "42mm"
16 | },
17 | {
18 | "size" : "29x29",
19 | "idiom" : "watch",
20 | "role" : "companionSettings",
21 | "scale" : "2x"
22 | },
23 | {
24 | "size" : "29x29",
25 | "idiom" : "watch",
26 | "role" : "companionSettings",
27 | "scale" : "3x"
28 | },
29 | {
30 | "size" : "40x40",
31 | "idiom" : "watch",
32 | "scale" : "2x",
33 | "role" : "appLauncher",
34 | "subtype" : "38mm"
35 | },
36 | {
37 | "size" : "44x44",
38 | "idiom" : "watch",
39 | "scale" : "2x",
40 | "role" : "longLook",
41 | "subtype" : "42mm"
42 | },
43 | {
44 | "size" : "86x86",
45 | "idiom" : "watch",
46 | "scale" : "2x",
47 | "role" : "quickLook",
48 | "subtype" : "38mm"
49 | },
50 | {
51 | "size" : "98x98",
52 | "idiom" : "watch",
53 | "scale" : "2x",
54 | "role" : "quickLook",
55 | "subtype" : "42mm"
56 | }
57 | ],
58 | "info" : {
59 | "version" : 1,
60 | "author" : "xcode"
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/WatchDemo/WatchApp/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/WatchDemo/WatchApp/Base.lproj/Interface.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
21 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/WatchDemo/WatchApp/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | WatchDemo
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | UISupportedInterfaceOrientations
26 |
27 | UIInterfaceOrientationPortrait
28 | UIInterfaceOrientationPortraitUpsideDown
29 |
30 | WKCompanionAppBundleIdentifier
31 | com.sunli.WatchDemo
32 | WKWatchKitApp
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/WatchDemo/WatchApp/dragon-0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/WatchDemo/WatchApp/dragon-0.png
--------------------------------------------------------------------------------
/WatchDemo/WatchApp/dragon-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/WatchDemo/WatchApp/dragon-1.png
--------------------------------------------------------------------------------
/WatchDemo/WatchApp/dragon-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/WatchDemo/WatchApp/dragon-2.png
--------------------------------------------------------------------------------
/WatchDemo/WatchApp/dragon-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/WatchDemo/WatchApp/dragon-3.png
--------------------------------------------------------------------------------
/WatchDemo/WatchApp/dragon-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/WatchDemo/WatchApp/dragon-4.png
--------------------------------------------------------------------------------
/WatchDemo/WatchApp/dragon-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/WatchDemo/WatchApp/dragon-5.png
--------------------------------------------------------------------------------
/WatchDemo/WatchDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/WatchDemo/WatchDemo.xcodeproj/project.xcworkspace/xcuserdata/sunli.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/WatchDemo/WatchDemo.xcodeproj/project.xcworkspace/xcuserdata/sunli.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/WatchDemo/WatchDemo.xcodeproj/xcuserdata/sunli.xcuserdatad/xcschemes/WatchDemo.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/WatchDemo/WatchDemo.xcodeproj/xcuserdata/sunli.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Complication - WatchApp.xcscheme
8 |
9 | orderHint
10 | 4
11 |
12 | Glance - WatchApp.xcscheme
13 |
14 | orderHint
15 | 3
16 |
17 | Notification - WatchApp.xcscheme
18 |
19 | orderHint
20 | 2
21 |
22 | WatchApp.xcscheme
23 |
24 | orderHint
25 | 1
26 |
27 | WatchDemo.xcscheme
28 |
29 | orderHint
30 | 0
31 |
32 |
33 | SuppressBuildableAutocreation
34 |
35 | A1F60A221B6A0F1F001C6348
36 |
37 | primary
38 |
39 |
40 | A1F60A391B6A0FBF001C6348
41 |
42 | primary
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/WatchDemo/WatchDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // WatchDemo
4 | //
5 | // Created by 李剑钊 on 15/7/30.
6 | // Copyright © 2015年 sunli. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/WatchDemo/WatchDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/WatchDemo/WatchDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/WatchDemo/WatchDemo/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 |
--------------------------------------------------------------------------------
/WatchDemo/WatchDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/WatchDemo/WatchDemo/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // WatchDemo
4 | //
5 | // Created by 李剑钊 on 15/7/30.
6 | // Copyright © 2015年 sunli. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | // Do any additional setup after loading the view, typically from a nib.
16 | }
17 |
18 | override func didReceiveMemoryWarning() {
19 | super.didReceiveMemoryWarning()
20 | // Dispose of any resources that can be recreated.
21 | }
22 |
23 |
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/iOS9/UITestDemo/UITestDemo UI Tests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/iOS9/UITestDemo/UITestDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/iOS9/UITestDemo/UITestDemo.xcodeproj/project.xcworkspace/xcuserdata/sunli.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunljz/demo/518258a6335ff8886f8c78edec5760a31204b72e/iOS9/UITestDemo/UITestDemo.xcodeproj/project.xcworkspace/xcuserdata/sunli.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/iOS9/UITestDemo/UITestDemo.xcodeproj/xcuserdata/sunli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/iOS9/UITestDemo/UITestDemo.xcodeproj/xcuserdata/sunli.xcuserdatad/xcschemes/UITestDemo.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
66 |
72 |
73 |
74 |
75 |
76 |
77 |
83 |
85 |
91 |
92 |
93 |
94 |
96 |
97 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/iOS9/UITestDemo/UITestDemo.xcodeproj/xcuserdata/sunli.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | UITestDemo.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | A13871361B318E690067A3D2
16 |
17 | primary
18 |
19 |
20 | A138714F1B31942F0067A3D2
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/iOS9/UITestDemo/UITestDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // UITestDemo
4 | //
5 | // Created by 李剑钊 on 15/6/17.
6 | // Copyright © 2015年 sunli. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/iOS9/UITestDemo/UITestDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/iOS9/UITestDemo/UITestDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
27 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/iOS9/UITestDemo/UITestDemo/HomeViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // UITestDemo
4 | //
5 | // Created by 李剑钊 on 15/6/17.
6 | // Copyright © 2015年 sunli. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | let name = "sun"
12 | let psd = "111111"
13 |
14 | let myTitle = "登录"
15 | let loadingText = "登录中.."
16 |
17 | var firstAppear = true;
18 |
19 | class HomeViewController: UIViewController {
20 | @IBOutlet weak var nameField: UITextField!
21 | @IBOutlet weak var psdField: UITextField!
22 |
23 |
24 |
25 | override func viewDidLoad() {
26 | super.viewDidLoad()
27 | // Do any additional setup after loading the view, typically from a nib.
28 | self.title = myTitle;
29 | }
30 |
31 | override func didReceiveMemoryWarning() {
32 | super.didReceiveMemoryWarning()
33 | // Dispose of any resources that can be recreated.
34 | }
35 |
36 | @IBAction func loginBtnTouch(sender: UIButton) {
37 | self.nameField.resignFirstResponder();
38 | self.psdField.resignFirstResponder();
39 | self.title = loadingText;
40 | sender.enabled = false
41 | let queue = NSOperationQueue.init();
42 | queue.addOperationWithBlock { () -> Void in
43 | // 模拟验证的过程
44 | NSThread.sleepForTimeInterval(2)
45 | NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
46 | self.title = myTitle;
47 | sender.enabled = true
48 | if self.nameField.text == name && self.psdField.text == psd {
49 | let userDef = NSUserDefaults.standardUserDefaults()
50 | userDef.setObject(self.nameField.text!, forKey: "name");
51 | let sb = UIStoryboard.init(name:"Main",bundle:NSBundle.mainBundle())
52 | let viewCro = sb.instantiateViewControllerWithIdentifier("InfoViewController")
53 | self.navigationController!.pushViewController(viewCro, animated: true)
54 | } else {
55 | let alert = UIAlertView.init(title:"",message:"登录失败",delegate:nil,cancelButtonTitle:"确定")
56 | alert.accessibilityIdentifier = "loginAlert"
57 | alert.accessibilityLabel = "loginAlert"
58 | alert.show()
59 | }
60 | })
61 | }
62 | }
63 |
64 | @IBAction func clearBtnTouch(sender: UIButton) {
65 | self.nameField.text = nil;
66 | self.psdField.text = nil;
67 | self.nameField.resignFirstResponder();
68 | self.psdField.resignFirstResponder();
69 | }
70 |
71 | func alertView(alertView: UIAlertView, didDismissWithButtonIndex buttonIndex: Int) {
72 |
73 | }
74 |
75 | override func touchesEnded(touches: Set, withEvent event: UIEvent?) {
76 | self.nameField.resignFirstResponder();
77 | self.psdField.resignFirstResponder();
78 | }
79 |
80 | override func viewDidAppear(animated: Bool) {
81 |
82 | }
83 | }
84 |
85 | extension HomeViewController: UIAlertViewDelegate {
86 |
87 | }
--------------------------------------------------------------------------------
/iOS9/UITestDemo/UITestDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/iOS9/UITestDemo/UITestDemo/InfoViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InfoViewController.swift
3 | // UITestDemo
4 | //
5 | // Created by 李剑钊 on 15/6/17.
6 | // Copyright © 2015年 sunli. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | let sexKey = "sex"
12 | let agekey = "age"
13 | let feelingKey = "feeling"
14 |
15 | class InfoViewController: UIViewController {
16 | @IBOutlet weak var sexSwitch: UISwitch!
17 | @IBOutlet weak var ageLabel: UILabel!
18 | @IBOutlet weak var ageStep: UIStepper!
19 | @IBOutlet weak var feelingTxtView: UITextView!
20 | @IBOutlet weak var modifyBtn: UIButton!
21 |
22 | var isChangingInfo = false
23 |
24 | override func viewDidLoad() {
25 | super.viewDidLoad()
26 |
27 | // Do any additional setup after loading the view.
28 | self.ageStep.accessibilityIdentifier = "ageStep"
29 | self.ageStep.minimumValue = 0
30 | self.ageStep.maximumValue = 100
31 | self.sexSwitch.enabled = false;
32 | self.ageStep.enabled = false;
33 | self.feelingTxtView.userInteractionEnabled = false;
34 |
35 | self.title = "读取中.."
36 | let queue = NSOperationQueue.init();
37 | queue.addOperationWithBlock { () -> Void in
38 | // 模拟读取数据的过程
39 | NSThread.sleepForTimeInterval(2)
40 | NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
41 | self.configInfoView()
42 | })
43 | }
44 | }
45 |
46 | override func didReceiveMemoryWarning() {
47 | super.didReceiveMemoryWarning()
48 | // Dispose of any resources that can be recreated.
49 | }
50 |
51 |
52 | func configInfoView() {
53 | let userDef = NSUserDefaults.standardUserDefaults()
54 | self.title = userDef.stringForKey("name")
55 | self.sexSwitch.on = userDef.boolForKey(sexKey)
56 | let age = userDef.stringForKey(agekey)
57 | self.ageLabel.text = age;
58 | if age != nil {
59 | self.ageStep.value = Double(age!)!
60 | }
61 | self.feelingTxtView.text = userDef.stringForKey(feelingKey)
62 | }
63 |
64 | @IBAction func modifyBtnTouch(sender: UIButton) {
65 | if self.isChangingInfo {
66 | self.toSaveInfo()
67 | } else {
68 | self.toModifyInfo()
69 | }
70 | }
71 |
72 | func toModifyInfo() {
73 | self.isChangingInfo = true;
74 | self.modifyBtn.setTitle("完成", forState: UIControlState.Normal)
75 | self.sexSwitch.enabled = true;
76 | self.ageStep.enabled = true;
77 | self.feelingTxtView.userInteractionEnabled = true;
78 | }
79 |
80 | func toSaveInfo() {
81 | self.isChangingInfo = false;
82 | self.feelingTxtView.resignFirstResponder()
83 | self.modifyBtn.setTitle("修改", forState: UIControlState.Normal)
84 | self.sexSwitch.enabled = false;
85 | self.ageStep.enabled = false;
86 | self.feelingTxtView.userInteractionEnabled = false;
87 |
88 | let myTitle = self.title
89 | self.title = "保存中.."
90 | self.modifyBtn.enabled = false
91 |
92 | let queue = NSOperationQueue.init()
93 | queue.addOperationWithBlock { () -> Void in
94 | // 模拟网络请求过程
95 | NSThread.sleepForTimeInterval(2)
96 | NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
97 | self.title = myTitle;
98 | self.modifyBtn.enabled = true
99 |
100 | let userDef = NSUserDefaults.standardUserDefaults()
101 | userDef.setBool(self.sexSwitch.on, forKey: sexKey)
102 | let age = String(Int(self.ageStep.value))
103 | userDef.setObject(age, forKey: agekey)
104 | let text = self.feelingTxtView.text;
105 | if text != nil {
106 | userDef.setObject(text, forKey: feelingKey)
107 | } else {
108 | userDef.removeObjectForKey(feelingKey)
109 | }
110 | })
111 | }
112 | }
113 |
114 | @IBAction func ageStepValueChanged(sender: UIStepper) {
115 | let age = String(Int(self.ageStep.value))
116 | self.ageLabel.text = age;
117 | }
118 |
119 | @IBAction func clearBtnTouch(sender: AnyObject) {
120 | self.feelingTxtView.resignFirstResponder()
121 | }
122 |
123 | override func touchesEnded(touches: Set, withEvent event: UIEvent?) {
124 | self.feelingTxtView.resignFirstResponder()
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/iOS9/UITestDemo/UITestDemo/MessageViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MessageViewController.swift
3 | // UITestDemo
4 | //
5 | // Created by 李剑钊 on 15/6/23.
6 | // Copyright © 2015年 sunli. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | let cellId = "cellId"
12 |
13 | class MessageViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
14 | @IBOutlet weak var tableView: UITableView!
15 | var dataList:[String]? = nil
16 |
17 | override func viewDidLoad() {
18 | super.viewDidLoad()
19 |
20 | // Do any additional setup after loading the view.
21 | self.title = "读取中.."
22 | // self.tableView.registerClass(MessageCell.classForCoder(), forCellReuseIdentifier: cellId)
23 |
24 | let queue = NSOperationQueue.init();
25 | queue.addOperationWithBlock { () -> Void in
26 | // 模拟读取数据的过程
27 | NSThread.sleepForTimeInterval(2)
28 | NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
29 | self.title = "我的消息"
30 | self.getData()
31 | self.tableView.reloadData()
32 | })
33 | }
34 | }
35 |
36 | override func didReceiveMemoryWarning() {
37 | super.didReceiveMemoryWarning()
38 | // Dispose of any resources that can be recreated.
39 | }
40 |
41 |
42 | func getData() {
43 | self.dataList = ["Hello,sun。恭喜你注册成功!","你的密码即将过期,请及时修改,以保证账户安全","你的密码已修改,请注意","你获得VIP体验券一张,有效期是一个月,请尽快使用,谢谢!","ksngoa将你添加为好友","sibo将你添加为好友","min将你拉入黑名单","恭喜你获得了1000个积分奖励,积分可以兑换VIP体验券、动态表情等礼物,详情可留意积分兑换页面。","消息错误"]
44 | }
45 |
46 | func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
47 | if self.dataList != nil {
48 | return self.dataList!.count
49 | } else {
50 | return 0
51 | }
52 | }
53 |
54 | func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
55 | let cell:MessageCell = tableView.dequeueReusableCellWithIdentifier(cellId, forIndexPath: indexPath) as! MessageCell
56 | if self.dataList == nil {
57 | return cell
58 | }
59 |
60 | if indexPath.row >= self.dataList!.count {
61 | return cell
62 | }
63 |
64 | let msg:String = self.dataList![indexPath.row]
65 | let label = cell.msgLabel
66 | label.text = msg
67 |
68 | return cell
69 | }
70 |
71 | func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
72 | return 80
73 | }
74 |
75 | func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
76 | tableView.deselectRowAtIndexPath(indexPath, animated: true)
77 | }
78 | }
79 |
80 | class MessageCell: UITableViewCell {
81 | @IBOutlet weak var msgLabel: UILabel!
82 | }
--------------------------------------------------------------------------------
/iOS9/UITestDemo/UITestDemo/SButton.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SButton.swift
3 | // UITestDemo
4 | //
5 | // Created by 李剑钊 on 15/6/19.
6 | // Copyright © 2015年 sunli. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /// 仅仅是为了测试子类而创建的
12 | class SButton: UIButton {
13 | override func awakeFromNib() {
14 | self.layer.cornerRadius = 4;
15 | self.layer.borderColor = UIColor.grayColor().CGColor;
16 | self.layer.borderWidth = 1;
17 | }
18 | /*
19 | // Only override drawRect: if you perform custom drawing.
20 | // An empty implementation adversely affects performance during animation.
21 | override func drawRect(rect: CGRect) {
22 | // Drawing code
23 | }
24 | */
25 |
26 | }
27 |
--------------------------------------------------------------------------------