├── BarrageKit
├── Assets.xcassets
│ ├── Contents.json
│ ├── Barrage_show.imageset
│ │ ├── Barrage_show@2x.png
│ │ └── Contents.json
│ ├── Barrage_close.imageset
│ │ ├── Barrage_close@2x.png
│ │ └── Contents.json
│ ├── Barrage_pause.imageset
│ │ ├── Barrage_pause@2x.png
│ │ └── Contents.json
│ ├── Barrage_scroll.imageset
│ │ ├── Barrage_scroll@2x.png
│ │ └── Contents.json
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── ViewController.h
├── BarrageKit
│ ├── BarrageKit.h
│ ├── BarrageScene.h
│ ├── BarrageModel.m
│ ├── BarrageModel.h
│ ├── BarrageManager.h
│ ├── BarrageManager.m
│ └── BarrageScene.m
├── AppDelegate.h
├── main.m
├── FirstViewController.h
├── FirstViewController.m
├── Info.plist
├── Base.lproj
│ ├── Main.storyboard
│ └── LaunchScreen.storyboard
├── BarrageEnum.h
├── FirstViewController.xib
├── AppDelegate.m
└── ViewController.m
├── BarrageKit.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── BarrageKitTests
├── Info.plist
└── BarrageKitTests.m
├── BarrageKitUITests
├── Info.plist
└── BarrageKitUITests.m
├── LICENSE
├── .gitignore
└── README.md
/BarrageKit/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/BarrageKit/Assets.xcassets/Barrage_show.imageset/Barrage_show@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiachenmu/BarrageKit/HEAD/BarrageKit/Assets.xcassets/Barrage_show.imageset/Barrage_show@2x.png
--------------------------------------------------------------------------------
/BarrageKit/Assets.xcassets/Barrage_close.imageset/Barrage_close@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiachenmu/BarrageKit/HEAD/BarrageKit/Assets.xcassets/Barrage_close.imageset/Barrage_close@2x.png
--------------------------------------------------------------------------------
/BarrageKit/Assets.xcassets/Barrage_pause.imageset/Barrage_pause@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiachenmu/BarrageKit/HEAD/BarrageKit/Assets.xcassets/Barrage_pause.imageset/Barrage_pause@2x.png
--------------------------------------------------------------------------------
/BarrageKit/Assets.xcassets/Barrage_scroll.imageset/Barrage_scroll@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiachenmu/BarrageKit/HEAD/BarrageKit/Assets.xcassets/Barrage_scroll.imageset/Barrage_scroll@2x.png
--------------------------------------------------------------------------------
/BarrageKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/BarrageKit/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // BarrageKit
4 | //
5 | // Created by jiachenmu on 16/8/25.
6 | // Copyright © 2016年 ManoBoo. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/BarrageKit/BarrageKit/BarrageKit.h:
--------------------------------------------------------------------------------
1 | //
2 | // BarrageKit.h
3 | // BarrageKit
4 | //
5 | // Created by jiachenmu on 16/8/25.
6 | // Copyright © 2016年 ManoBoo. All rights reserved.
7 | //
8 |
9 | #ifndef BarrageKit_h
10 | #define BarrageKit_h
11 |
12 | #import "BarrageManager.h"
13 |
14 |
15 |
16 | #endif /* BarrageKit_h */
17 |
--------------------------------------------------------------------------------
/BarrageKit/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // BarrageKit
4 | //
5 | // Created by jiachenmu on 16/8/25.
6 | // Copyright © 2016年 ManoBoo. 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 |
--------------------------------------------------------------------------------
/BarrageKit/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // BarrageKit
4 | //
5 | // Created by jiachenmu on 16/8/25.
6 | // Copyright © 2016年 ManoBoo. 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 |
--------------------------------------------------------------------------------
/BarrageKit/Assets.xcassets/Barrage_close.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "Barrage_close@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/BarrageKit/Assets.xcassets/Barrage_pause.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "Barrage_pause@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/BarrageKit/Assets.xcassets/Barrage_show.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "Barrage_show@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/BarrageKit/Assets.xcassets/Barrage_scroll.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "Barrage_scroll@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/BarrageKit/FirstViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // FirstViewController.h
3 | // BarrageKit
4 | //
5 | // Created by jiachenmu on 16/9/1.
6 | // Copyright © 2016年 ManoBoo. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface FirstViewController : UIViewController
12 |
13 | @end
14 |
15 | @interface Person : NSObject
16 |
17 | @property (strong, nonatomic) NSString *name;
18 | @property (assign, nonatomic) NSString *age;
19 |
20 | @end
21 |
22 | @interface Son : Person
23 |
24 | @end
--------------------------------------------------------------------------------
/BarrageKitTests/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 |
--------------------------------------------------------------------------------
/BarrageKitUITests/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 |
--------------------------------------------------------------------------------
/BarrageKit/BarrageKit/BarrageScene.h:
--------------------------------------------------------------------------------
1 | //
2 | // BarrageScene.h
3 | // BarrageKit
4 | //
5 | // Created by jiachenmu on 16/8/26.
6 | // Copyright © 2016年 ManoBoo. All rights reserved.
7 | // 弹幕View
8 |
9 | #import
10 |
11 | #import "BarrageModel.h"
12 |
13 | @class BarrageManager;
14 |
15 | @class BarrageScene;
16 |
17 | typedef void(^AnimationDidStopBlock)(BarrageScene *scene);
18 |
19 | @interface BarrageScene : UIView
20 |
21 | @property (copy, nonatomic) BarrageModel *model;
22 |
23 | @property (strong, nonatomic) UILabel *titleLabel;
24 |
25 | @property (strong, nonatomic) UIButton *voteButton;
26 |
27 | @property (copy, nonatomic) AnimationDidStopBlock animationDidStopBlock;
28 |
29 | - (void)scroll;
30 |
31 | - (void)pause;
32 |
33 | - (void)resume;
34 |
35 | - (void)close;
36 |
37 | - (instancetype)initWithFrame:(CGRect)frame Model:(BarrageModel *)model;
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/BarrageKitTests/BarrageKitTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // BarrageKitTests.m
3 | // BarrageKitTests
4 | //
5 | // Created by jiachenmu on 16/8/25.
6 | // Copyright © 2016年 ManoBoo. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface BarrageKitTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation BarrageKitTests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 | // Put setup code here. This method is called before the invocation of each test method in the class.
20 | }
21 |
22 | - (void)tearDown {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | [super tearDown];
25 | }
26 |
27 | - (void)testExample {
28 | // This is an example of a functional test case.
29 | // Use XCTAssert and related functions to verify your tests produce the correct results.
30 | }
31 |
32 | - (void)testPerformanceExample {
33 | // This is an example of a performance test case.
34 | [self measureBlock:^{
35 | // Put the code you want to measure the time of here.
36 | }];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 ManoBoo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/BarrageKit/FirstViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // FirstViewController.m
3 | // BarrageKit
4 | //
5 | // Created by jiachenmu on 16/9/1.
6 | // Copyright © 2016年 ManoBoo. All rights reserved.
7 | //
8 |
9 | #import "FirstViewController.h"
10 | #import "ViewController.h"
11 |
12 | @interface FirstViewController ()
13 |
14 | @property (strong, nonatomic) NSString *str;
15 |
16 | @end
17 |
18 | @implementation FirstViewController
19 |
20 | - (void)viewDidLoad {
21 | [super viewDidLoad];
22 | }
23 |
24 | - (void)didReceiveMemoryWarning {
25 | [super didReceiveMemoryWarning];
26 | // Dispose of any resources that can be recreated.
27 | }
28 |
29 | /*
30 | #pragma mark - Navigation
31 |
32 | // In a storyboard-based application, you will often want to do a little preparation before navigation
33 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
34 | // Get the new view controller using [segue destinationViewController].
35 | // Pass the selected object to the new view controller.
36 | }
37 | */
38 | - (IBAction)startBarrage:(id)sender {
39 | [self.navigationController pushViewController:[[ViewController alloc] init] animated:true];
40 | }
41 |
42 | @end
43 |
44 |
--------------------------------------------------------------------------------
/BarrageKit/BarrageKit/BarrageModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // BarrageModel.m
3 | // BarrageKit
4 | //
5 | // Created by jiachenmu on 16/8/25.
6 | // Copyright © 2016年 ManoBoo. All rights reserved.
7 | //
8 |
9 | #import "BarrageModel.h"
10 |
11 | @implementation BarrageModel
12 |
13 | #pragma mark - initialize(初始化)
14 |
15 | - (instancetype)init {
16 | if (self = [super init]) {
17 | self.numberID = 0;
18 | self.message = [[NSMutableAttributedString alloc] initWithString:@""];
19 | self.author = nil;
20 | self.object = nil;
21 | }
22 | return self;
23 | }
24 |
25 | - (instancetype)initWithNumberID:(NSInteger)numID BarrageContent:(NSMutableAttributedString *)message Author:(nullable id)author Object:(nullable id)object {
26 | BarrageModel *model = [[BarrageModel alloc] init];
27 | model.numberID = numID;
28 | model.message = message;
29 | model.author = author;
30 | model.object = object;
31 |
32 | return model;
33 | }
34 |
35 | - (instancetype)initWithNumberID:(NSInteger)numID BarrageContent:(NSMutableAttributedString *)message {
36 | return [self initWithNumberID:numID BarrageContent:message Author:nil Object:nil];
37 | }
38 |
39 | - (instancetype)initWithBarrageContent:(NSMutableAttributedString *)message {
40 | return [self initWithNumberID:0 BarrageContent:message];
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/BarrageKitUITests/BarrageKitUITests.m:
--------------------------------------------------------------------------------
1 | //
2 | // BarrageKitUITests.m
3 | // BarrageKitUITests
4 | //
5 | // Created by jiachenmu on 16/8/25.
6 | // Copyright © 2016年 ManoBoo. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface BarrageKitUITests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation BarrageKitUITests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 |
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 |
22 | // In UI tests it is usually best to stop immediately when a failure occurs.
23 | self.continueAfterFailure = NO;
24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
25 | [[[XCUIApplication alloc] init] launch];
26 |
27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
28 | }
29 |
30 | - (void)tearDown {
31 | // Put teardown code here. This method is called after the invocation of each test method in the class.
32 | [super tearDown];
33 | }
34 |
35 | - (void)testExample {
36 | // Use recording to get started writing UI tests.
37 | // Use XCTAssert and related functions to verify your tests produce the correct results.
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/BarrageKit/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "83.5x83.5",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xcuserstate
23 |
24 | ## Obj-C/Swift specific
25 | *.hmap
26 | *.ipa
27 | *.dSYM.zip
28 | *.dSYM
29 |
30 | # CocoaPods
31 | #
32 | # We recommend against adding the Pods directory to your .gitignore. However
33 | # you should judge for yourself, the pros and cons are mentioned at:
34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
35 | #
36 | # Pods/
37 |
38 | # Carthage
39 | #
40 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
41 | # Carthage/Checkouts
42 |
43 | Carthage/Build
44 |
45 | # fastlane
46 | #
47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
48 | # screenshots whenever they are needed.
49 | # For more information about the recommended setup visit:
50 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
51 |
52 | fastlane/report.xml
53 | fastlane/screenshots
54 |
55 | #Code Injection
56 | #
57 | # After new code Injection tools there's a generated folder /iOSInjectionProject
58 | # https://github.com/johnno1962/injectionforxcode
59 |
60 | iOSInjectionProject/
61 |
--------------------------------------------------------------------------------
/BarrageKit/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/BarrageKit/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 |
--------------------------------------------------------------------------------
/BarrageKit/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 |
--------------------------------------------------------------------------------
/BarrageKit/BarrageKit/BarrageModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // BarrageModel.h
3 | // BarrageKit
4 | //
5 | // Created by jiachenmu on 16/8/25.
6 | // Copyright © 2016年 ManoBoo. All rights reserved.
7 | // 弹幕Model
8 |
9 | #import
10 | #import
11 |
12 | #import "BarrageEnum.h"
13 |
14 | NS_ASSUME_NONNULL_BEGIN
15 |
16 | @interface BarrageModel : NSObject
17 |
18 | //MARK: 弹幕Model属性
19 |
20 | //弹幕ID barrage's id
21 | @property (assign, nonatomic) NSInteger numberID;
22 |
23 | //弹幕时间 barrage;s time
24 | @property (strong, nonatomic) NSString *time;
25 |
26 | //弹幕类型 barrage's type
27 | @property (assign, nonatomic) BarrageDisplayType barrageType;
28 |
29 | //弹幕速度 barrage's speed
30 | @property (assign, nonatomic) BarrageDisplaySpeedType speed;
31 |
32 | //弹幕滚动方向 barrage's direction
33 | @property (assign, nonatomic) BarrageScrollDirection direction;
34 |
35 | //弹幕位置 barage's location
36 | @property (assign, nonatomic) BarrageDisplayLocationType displayLocation;
37 |
38 | //弹幕所属的父View barrage's superView
39 | @property (weak, nonatomic) UIView *bindView;
40 |
41 | //弹幕内容 barrage's content
42 | @property (strong, nonatomic, nonnull) NSMutableAttributedString *message;
43 |
44 | //弹幕作者 barrage's author
45 | @property (strong, nonatomic, nullable) id author;
46 |
47 | //弹幕对象 goal object
48 | @property (strong, nonatomic, nullable) id object;
49 |
50 | //弹幕字体 barrage's textfont
51 | @property (copy, nonatomic) UIFont *font;
52 |
53 | //弹幕字体颜色 barrage's textColor
54 | @property (copy, nonatomic) UIColor *textColor;
55 |
56 | //MARK: 弹幕初始化方法
57 |
58 | - (instancetype)initWithNumberID:(NSInteger)numID BarrageContent:(NSMutableAttributedString *)message Author:(nullable id)author Object:(nullable id)object;
59 |
60 | - (instancetype)initWithNumberID:(NSInteger)numID BarrageContent:(NSMutableAttributedString *)message;
61 |
62 | - (instancetype)initWithBarrageContent:(NSMutableAttributedString *)message;
63 |
64 | @end
65 |
66 | NS_ASSUME_NONNULL_END
--------------------------------------------------------------------------------
/BarrageKit/BarrageEnum.h:
--------------------------------------------------------------------------------
1 | //
2 | // BarrageEnum.h
3 | // BarrageKit
4 | //
5 | // Created by jiachenmu on 16/8/29.
6 | // Copyright © 2016年 ManoBoo. All rights reserved.
7 | //
8 |
9 | #ifndef BarrageEnum_h
10 | #define BarrageEnum_h
11 |
12 | #define Weakself __weak typeof(self) weakSelf = self
13 |
14 | typedef NS_ENUM(NSInteger, BarrageStatusType) {
15 | BarrageStatusTypeNormal = 0,
16 | BarrageStatusTypePause,
17 | BarrageStatusTypeClose,
18 | };
19 |
20 | // 弹幕的滚动速度,单位为秒
21 | // scroll speed of barrage,in seconds
22 | typedef NS_ENUM(NSInteger, BarrageDisplaySpeedType) {
23 | BarrageDisplaySpeedTypeDefault = 10,
24 | BarrageDisplaySpeedTypeFast = 20,
25 | BarrageDisplaySpeedTypeFaster = 40,
26 | BarrageDisplaySpeedTypeMostFast = 60,
27 | };
28 |
29 | // 弹幕滚动的方向
30 | typedef NS_ENUM(NSInteger, BarrageScrollDirection) {
31 | BarrageScrollDirectRightToLeft = 0, /* <<<<< */
32 | BarrageScrollDirectLeftToRight = 1, /* >>>>> */
33 | BarrageScrollDirectBottomToTop = 2, /* ↑↑↑↑ */
34 | BarrageScrollDirectTopToBottom = 3, /* ↓↓↓↓ */
35 | };
36 |
37 | // 弹幕显示的位置 `default` 为页面全局
38 | // location of barrage, `default` is global page
39 | typedef NS_ENUM(NSInteger, BarrageDisplayLocationType) {
40 | BarrageDisplayLocationTypeDefault = 0,
41 | BarrageDisplayLocationTypeTop = 1,
42 | BarrageDisplayLocationTypeCenter = 2,
43 | BarrageDisplayLocationTypeBottom = 3,
44 | BarrageDisplayLocationTypeHidden,
45 | };
46 |
47 | // 弹幕的类型
48 | // type of barrage
49 | typedef NS_ENUM(NSInteger, BarrageDisplayType) {
50 | BarrageDisplayTypeDefault = 0, /* only text (纯文字弹幕) */
51 | BarrageDisplayTypeVote, /* text and vote(文字加投票) */
52 | BarrageDisplayTypeOther, /* other */
53 | };
54 |
55 | // 收到内存警告的清除策略
56 | typedef NS_ENUM(NSInteger, BarrageMemoryWarningMode) {
57 | BarrageMemoryWarningModeHalf = 0, //清除一半
58 | BarrageMemoryWarningModeAll, //清空缓冲池
59 | };
60 | #endif /* BarrageEnum_h */
61 |
--------------------------------------------------------------------------------
/BarrageKit/BarrageKit/BarrageManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // BarrageManager.h
3 | // BarrageKit
4 | //
5 | // Created by jiachenmu on 16/8/25.
6 | // Copyright © 2016年 ManoBoo. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | #import "BarrageEnum.h"
13 |
14 | #import "BarrageModel.h"
15 | #import "BarrageScene.h"
16 |
17 |
18 | @protocol BarrageManagerDelegate
19 |
20 | // 弹幕的数据来源,来源可以是数组或者 类型的
21 | // Data Sources of barrage, type can be ` NSArray ` or a BarrageModel
22 | - (id)barrageManagerDataSource;
23 |
24 | @end
25 |
26 | @interface BarrageManager : NSObject
27 |
28 | // 弹幕单例
29 | // barrage's singleton
30 | + (instancetype)shareManager;
31 |
32 | + (instancetype)manager;
33 |
34 | // 弹幕缓存池,下次可以从中取出来使用 barrage's cache
35 | - (NSMutableArray *)barrageCache;
36 |
37 | // 正在屏幕上显示的弹幕
38 | - (NSMutableArray *)barrageScenes;
39 |
40 | // 弹幕出现的ViewController, barrage's ViewController
41 | @property (weak, nonatomic) id delegate;
42 |
43 | // the view of show barrage (显示弹幕的View)
44 | @property (weak, nonatomic) UIView *bindingView;
45 |
46 | @property (assign, nonatomic) NSInteger scrollSpeed;
47 |
48 | // 获取弹幕的间隔, get barrages on time,
49 | @property (assign, nonatomic) NSTimeInterval refreshInterval;
50 |
51 | @property (assign, nonatomic) NSInteger displayLocation;
52 |
53 | @property (assign, nonatomic) NSInteger scrollDirection;
54 |
55 | // 文字限长
56 | @property (assign, nonatomic) NSInteger textLengthLimit;
57 |
58 | // 收到内存警告的清除策略
59 | @property (assign, nonatomic) BarrageMemoryWarningMode memoryMode;
60 |
61 | //主动获取弹幕 ,Take the initiative to obtain barrage
62 | - (void)startScroll;
63 |
64 | //被动接收弹幕数据,生成弹幕 ,Passive receiving a barrage of data
65 | /* data's type is ` BarrageModel ` or ` NSArray `*/
66 | - (void)showBarrageWithDataSource:(id)data;
67 |
68 | // pause or resume barrage
69 | - (void)pauseScroll;
70 |
71 | // show or close barrage
72 | - (void)closeBarrage;
73 |
74 | // 收到内存警告时,可以清除弹幕缓冲池,也可以清除一半的缓冲池
75 | - (void)didReceiveMemoryWarning;
76 |
77 | // 防止内存泄露
78 | - (void)toDealloc;
79 | @end
80 |
--------------------------------------------------------------------------------
/BarrageKit/FirstViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/BarrageKit/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // BarrageKit
4 | //
5 | // Created by jiachenmu on 16/8/25.
6 | // Copyright © 2016年 ManoBoo. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | #import "FirstViewController.h"
12 |
13 | @interface AppDelegate ()
14 |
15 | @end
16 |
17 | @implementation AppDelegate
18 |
19 |
20 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
21 | // Override point for customization after application launch.
22 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
23 | [self.window makeKeyAndVisible];
24 |
25 | FirstViewController *firstVC = [[FirstViewController alloc] init];
26 | UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:firstVC];
27 | self.window.rootViewController = nav;
28 |
29 | return YES;
30 | }
31 |
32 | - (void)applicationWillResignActive:(UIApplication *)application {
33 | // 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.
34 | // 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.
35 | }
36 |
37 | - (void)applicationDidEnterBackground:(UIApplication *)application {
38 | // 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.
39 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
40 | }
41 |
42 | - (void)applicationWillEnterForeground:(UIApplication *)application {
43 | // 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.
44 | }
45 |
46 | - (void)applicationDidBecomeActive:(UIApplication *)application {
47 | // 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.
48 | }
49 |
50 | - (void)applicationWillTerminate:(UIApplication *)application {
51 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
52 | }
53 |
54 | @end
55 |
--------------------------------------------------------------------------------
/BarrageKit/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // BarrageKit
4 | //
5 | // Created by jiachenmu on 16/8/25.
6 | // Copyright © 2016年 ManoBoo. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "BarrageKit.h"
11 |
12 |
13 | typedef void(^MultiParmsBlock)(NSString *p1, ...);
14 |
15 | @interface ViewController ()
16 |
17 | @property (strong, nonatomic) BarrageManager *manager;
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 | self.view.backgroundColor = [UIColor whiteColor];
27 |
28 | UIButton *showBtn = [[UIButton alloc] initWithFrame:CGRectMake(20, self.view.frame.size.height - 100, 30, 30)];
29 | [showBtn setImage:[UIImage imageNamed:@"Barrage_close"] forState:UIControlStateNormal];
30 | [showBtn setImage:[UIImage imageNamed:@"Barrage_show"] forState:UIControlStateSelected];
31 | [showBtn addTarget:self action:@selector(showBarrage:) forControlEvents:UIControlEventTouchUpInside];
32 | [showBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
33 | [self.view addSubview:showBtn];
34 |
35 | UIButton *pauseBtn = [[UIButton alloc] initWithFrame:CGRectMake(150, self.view.frame.size.height - 100, 30, 30)];
36 | [pauseBtn setImage:[UIImage imageNamed:@"Barrage_pause"] forState:UIControlStateNormal];
37 | [pauseBtn setImage:[UIImage imageNamed:@"Barrage_scroll"] forState:UIControlStateSelected];
38 | [pauseBtn addTarget:self action:@selector(pauseBarrage:) forControlEvents:UIControlEventTouchUpInside];
39 | [pauseBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
40 | [self.view addSubview:pauseBtn];
41 |
42 | _manager = [BarrageManager manager];
43 |
44 | //出现的View
45 | _manager.bindingView = self.view;
46 |
47 | //delegate
48 | _manager.delegate = self;
49 |
50 | //弹幕显示位置
51 | _manager.displayLocation = BarrageDisplayLocationTypeDefault;
52 |
53 | //滚动方向
54 | _manager.scrollDirection = BarrageScrollDirectRightToLeft;
55 |
56 | //滚动速度
57 | _manager.scrollSpeed = 30;
58 |
59 | //收到内存警告的处理方式
60 | _manager.memoryMode = BarrageMemoryWarningModeHalf;
61 |
62 | //刷新时间
63 | _manager.refreshInterval = 1.0;
64 |
65 | //开始滚动 manager主动获取弹幕,另外一种方式,`[_manager showBarrageWithDataSource:m]` 退出弹幕即可
66 | [_manager startScroll];
67 |
68 |
69 | //_manager被动接收弹幕
70 | // int a = arc4random() % 10000;
71 | // NSString *str = [NSString stringWithFormat:@"%d 呵呵哒",a];
72 | //
73 | // NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:str];
74 | // [attr addAttribute:NSForegroundColorAttributeName value:RandomColor() range:NSMakeRange(0, str.length)];
75 | //
76 | // BarrageModel *m = [[BarrageModel alloc] initWithBarrageContent:attr];
77 | // m.displayLocation = BarrageDisplayLocationTypeDefault;
78 | // m.barrageType = BarrageDisplayTypeVote;
79 |
80 | // [_manager showBarrageWithDataSource:m];
81 | }
82 |
83 | - (void)viewWillDisappear:(BOOL)animated {
84 | [_manager closeBarrage];
85 | [super viewWillDisappear:animated];
86 | }
87 |
88 | - (void)didReceiveMemoryWarning {
89 | [super didReceiveMemoryWarning];
90 | // Dispose of any resources that can be recreated.
91 |
92 | // 收到内存警告时,清楚弹幕缓冲池 When you receive a memory warning,clean the barrage's cache
93 | [_manager didReceiveMemoryWarning];
94 | }
95 |
96 | - (void)dealloc {
97 | [_manager toDealloc];
98 | }
99 |
100 | UIColor * RandomColor() {
101 | float a = (arc4random() % 255) / 255.0;
102 | float b = (arc4random() % 255) / 255.0;
103 | float c = (arc4random() % 255) / 255.0;
104 |
105 | return [UIColor colorWithRed:a green:b blue:c alpha:1.0];
106 | }
107 |
108 |
109 | #pragma mark - BarrageManagerDelegate
110 | - (id)barrageManagerDataSource {
111 |
112 | //演示需要:随机弹幕方向
113 | int barrageScrollDierct = arc4random() % 4;
114 | _manager.scrollDirection = (NSInteger)barrageScrollDierct;
115 |
116 | //生成弹幕信息
117 | int a = arc4random() % 10000;
118 | NSString *str = [NSString stringWithFormat:@"%d 呵呵哒",a];
119 |
120 | NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:str];
121 | [attr addAttribute:NSForegroundColorAttributeName value:RandomColor() range:NSMakeRange(0, str.length)];
122 |
123 | BarrageModel *m = [[BarrageModel alloc] initWithBarrageContent:attr];
124 | m.displayLocation = BarrageDisplayLocationTypeDefault;
125 | m.barrageType = BarrageDisplayTypeVote;
126 | return m;
127 | }
128 |
129 | - (void)showBarrage:(UIButton *)showBtn {
130 | showBtn.selected = !showBtn.isSelected;
131 | [_manager closeBarrage];
132 | }
133 |
134 | - (void)pauseBarrage:(UIButton *)pauseBtn{
135 | pauseBtn.selected = !pauseBtn.isSelected;
136 | [_manager pauseScroll];
137 | }
138 |
139 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
140 | UITouch *touch = [touches anyObject];
141 | CGPoint touchPoint = [touch locationInView:self.view];
142 | [[_manager barrageScenes] enumerateObjectsUsingBlock:^(BarrageScene * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
143 | if ([obj.layer.presentationLayer hitTest:touchPoint]) {
144 | //弹幕类型为投票类型时,为弹幕添加点击事件,请在此处添加
145 | /* if barrage's type is ` BarrageDisplayTypeVote `, add your code here*/
146 | NSLog(@"message = %@",obj.model.message.string);
147 | }
148 | }];
149 | }
150 | @end
151 |
152 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BarrageKit
2 | ManoBoo所写的一个弹幕小插件
3 | # BarrageKit弹幕插件
4 |
5 | 标签(空格分隔): BarrageKit
6 |
7 | ---
8 |
9 | ##前言
10 | ---
11 | ####现在直播这么火,好多直播框架,诸如[IJKMediaFramework](https://github.com/Bilibili/ijkplayer)等更是方便了直播类APP的开发,那我们也一起给它添砖加瓦吧。
12 |
13 | ##插件介绍
14 | ---
15 | 插件是基于Objective-C编写的,整体思路较为简单,功能包括:
16 |
17 | 1. 弹幕的滚动方向、滚动速度
18 | 2. 弹幕的暂停与恢复、显示与隐藏
19 | 3. 弹幕的类型:纯文字弹幕、投票类弹幕、其他等(可自定义)
20 | 4. 弹幕的推送方式:主动获取弹幕源、被动接收
21 | 5. 弹幕的缓存,避免大量弹幕出现时内存Boom
22 |
23 | **还有一些不完善的地方(比如弹幕的轨道现为随机生成,可能会重叠)及一些新的功能欢迎[issue](https://github.com/jiachenmu/BarrageKit/issues)**
24 | ##插件展示
25 | ---
26 |
27 | - 四个方向的弹幕滚动
28 |
29 | 
30 |
31 | - 弹幕的暂停与恢复
32 | 
33 | ---
34 | ##核心代码介绍
35 | ---
36 | ###①`BarrageManager`弹幕管理者
37 | **数组介绍:**
38 | - `_cachePool`为弹幕单元的缓冲数组,从屏幕上移除的`BarrageScene`会加入到该数组中
39 | - `_barrageScene`为当前屏幕上正在显示的弹幕显示单元的数组,弹幕显示的时候会加入到该数组中
40 |
41 |
42 | `BarrageManager` 作为弹幕的管理者,**流程**为:
43 |
44 | - 初始化弹幕manager,启动`timer`,主动拉取弹幕数据,调用`-delegate barrageManagerDataSource`返回数据。
45 | - 调用`- (void)showWithData:(id)data`方法显示弹幕,`data`可以为`BarrageModel`或`NSArray`格式
46 | - 判断缓冲池是否为空,为空则新建弹幕显示单元`BarrageScene`,并加入到`_barrageScene`数组中。若不为空,则取出`_cachePool`的`firstObject`进行重用并从`_cachePool`中移除,添加到`_barrageScene`中来
47 |
48 | ### ②`BarrageModel`弹幕模型
49 | ####`message`弹幕信息为`NSMutableAttributedString`类型,图片、表情等都可以使用了
50 | **模型属性:**
51 | ```
52 | //弹幕ID barrage's id
53 | @property (assign, nonatomic) NSInteger numberID;
54 |
55 | //弹幕时间 barrage;s time
56 | @property (strong, nonatomic) NSString *time;
57 |
58 | //弹幕类型 barrage's type
59 | @property (assign, nonatomic) BarrageDisplayType barrageType;
60 |
61 | //弹幕速度 barrage's speed
62 | @property (assign, nonatomic) BarrageDisplaySpeedType speed;
63 |
64 | //弹幕滚动方向 barrage's direction
65 | @property (assign, nonatomic) BarrageScrollDirection direction;
66 |
67 | //弹幕位置 barage's location
68 | @property (assign, nonatomic) BarrageDisplayLocationType displayLocation;
69 |
70 | //弹幕所属的父View barrage's superView
71 | @property (weak, nonatomic) UIView *bindView;
72 |
73 | //弹幕内容 barrage's content
74 | @property (strong, nonatomic, nonnull) NSMutableAttributedString *message;
75 |
76 | //弹幕作者 barrage's author
77 | @property (strong, nonatomic, nullable) id author;
78 |
79 | //弹幕对象 goal object
80 | @property (strong, nonatomic, nullable) id object;
81 |
82 | //弹幕字体 barrage's textfont
83 | @property (copy, nonatomic) UIFont *font;
84 |
85 | //弹幕字体颜色 barrage's textColor
86 | @property (copy, nonatomic) UIColor *textColor;
87 | ```
88 |
89 | ###③`BarrageScene`弹幕显示单元
90 |
91 | - 滚动Scroll
92 | - ①根据弹幕的滚动速度和滚动方向计算弹幕的滚动距离和所需要的时间
93 | - ②使用CABasicAnimation完成动画,后期弹幕的暂停和回复比较方便
94 | - ③弹幕滚动完毕后,执行`_animationDidStopBlock`,将该scene加入到`manager`的`cachePool`中等待被重用
95 |
96 | - 重用
97 | - 弹幕从`BarrageManager`的`cachePool`中取出来,根据`BarrageModel`弹幕信息重新初始化frame且重新开始动画
98 | - 暂停 pause
99 | - 暂停layer动画即可
100 |
101 | ```
102 | CFTimeInterval pausedTime = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil];
103 | self.layer.speed = 0.0;
104 | self.layer.timeOffset = pausedTime;
105 | ```
106 |
107 | - 恢复 resume
108 | - 恢复layer动画即可
109 |
110 | ```
111 | CFTimeInterval pausedTime = [self.layer timeOffset];
112 | self.layer.timeOffset = 0.0;
113 | self.layer.beginTime = 0.0;
114 | self.layer.speed = 1.0;
115 | CFTimeInterval timeSincePause = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
116 | self.layer.beginTime = timeSincePause;
117 | ```
118 |
119 |
120 | - 关闭 close
121 | ```
122 | [self.layer removeAllAnimations];
123 | [self removeFromSuperview];
124 | ```
125 |
126 | ##插件使用
127 | [下载项目]()导入到项目中,使用时`import 'BarrageKit.h'`即可
128 | ```
129 | _manager = [BarrageManager manager];
130 |
131 | //出现的View
132 | _manager.bindingView = self.view;
133 |
134 | //delegate
135 | _manager.delegate = self;
136 |
137 | //弹幕显示位置
138 | _manager.displayLocation = BarrageDisplayLocationTypeDefault;
139 |
140 | //滚动方向
141 | _manager.scrollDirection = BarrageScrollDirectRightToLeft;
142 |
143 | //滚动速度
144 | _manager.scrollSpeed = 30;
145 |
146 | //收到内存警告的处理方式
147 | _manager.memoryMode = BarrageMemoryWarningModeHalf;
148 |
149 | //刷新时间
150 | _manager.refreshInterval = 1.0;
151 |
152 | //开始滚动 manager主动获取弹幕,另外一种方式,`[_manager showBarrageWithDataSource:m]` 退出弹幕即可
153 | [_manager startScroll];
154 | ```
155 | **Tips:**
156 | - ①如果弹幕为投票类型的弹幕时,请重写`ViewController`的`touchesBegan` 方法
157 |
158 | ```
159 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
160 | UITouch *touch = [touches anyObject];
161 | CGPoint touchPoint = [touch locationInView:self.view];
162 | [[_manager barrageScenes] enumerateObjectsUsingBlock:^(BarrageScene * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
163 | if ([obj.layer.presentationLayer hitTest:touchPoint]) {
164 | //弹幕类型为投票类型时,为弹幕添加点击事件,请在此处添加
165 | /* if barrage's type is ` BarrageDisplayTypeVote `, add your code here*/
166 | NSLog(@"message = %@",obj.model.message.string);
167 | }
168 | }];
169 | }
170 | ```
171 |
172 | - ②重写`ViewController`的`dealloc`方法,执行`BarrageManager`的`toDealloc`
173 | - ③ViewController收到内存警告时,`[_manager didReceiveMemoryWarning];`将会按照`memoryMode`指定的方法清楚缓冲池
174 | ```
175 | - (void)didReceiveMemoryWarning {
176 | [super didReceiveMemoryWarning];
177 | // Dispose of any resources that can be recreated.
178 |
179 | // 收到内存警告时,清楚弹幕缓冲池 When you receive a memory warning,clean the barrage's cache
180 | [_manager didReceiveMemoryWarning];
181 | }
182 | ```
183 | - ④如果要高度自定义弹幕显示,可以修改`BarrageScene`中的初始化代码
184 |
185 |
186 | ##最后
187 | ###大家查看项目后,欢迎[issue](https://github.com/jiachenmu/BarrageKit/issues),同时有其他的功能或建议欢迎提出来,简书、github均可。
188 | - [项目及Demo下载地址](https://github.com/jiachenmu/BarrageKit)
189 | - 
190 |
--------------------------------------------------------------------------------
/BarrageKit/BarrageKit/BarrageManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // BarrageManager.m
3 | // BarrageKit
4 | //
5 | // Created by jiachenmu on 16/8/25.
6 | // Copyright © 2016年 ManoBoo. All rights reserved.
7 | //
8 |
9 | #import "BarrageManager.h"
10 |
11 | @interface BarrageManager ()
12 |
13 | @property (assign, nonatomic) BarrageStatusType currentStatus;
14 |
15 | @property (strong, nonatomic) NSMutableArray *cachePool;
16 |
17 | @property (strong, nonatomic) NSMutableArray *barrageScene;
18 |
19 | @property (strong, nonatomic) NSTimer *timer;
20 |
21 | @end
22 |
23 | @implementation BarrageManager
24 |
25 | #pragma mark - create manager(初始化方法)
26 |
27 | // singleton 单例
28 | static BarrageManager *instance;
29 | //+ (instancetype)shareManager {
30 | // static BarrageManager *manager;
31 | // static dispatch_once_t onceToken;
32 | // dispatch_once(&onceToken, ^{
33 | // manager = [[BarrageManager alloc] init];
34 | // });
35 | // return manager;
36 | //}
37 |
38 | + (instancetype)shareManager {
39 | if (!instance) {
40 | instance = [[BarrageManager alloc] init];
41 | }
42 | return instance;
43 | }
44 |
45 | + (instancetype)manager {
46 | return [[BarrageManager alloc] init];
47 | }
48 |
49 | - (instancetype)init
50 | {
51 | self = [super init];
52 | if (self) {
53 | _scrollSpeed = BarrageDisplaySpeedTypeDefault;
54 | _displayLocation = BarrageDisplayLocationTypeDefault;
55 | _cachePool = [NSMutableArray array];
56 | _barrageScene = [NSMutableArray array];
57 | }
58 | return self;
59 | }
60 |
61 | - (void)dealloc {
62 | [_timer invalidate];
63 | _timer = nil;
64 | [_cachePool removeAllObjects];
65 | [_barrageScene removeAllObjects];
66 | NSLog(@"BarrageManager dealloc~");
67 | }
68 |
69 | - (NSMutableArray *)barrageCache {
70 | return _cachePool;
71 | }
72 |
73 | - (NSMutableArray *)barrageScenes {
74 | return _barrageScene;
75 | }
76 |
77 | - (void)setRefreshInterval:(NSTimeInterval)refreshInterval {
78 | _refreshInterval = refreshInterval;
79 | _timer = [NSTimer scheduledTimerWithTimeInterval:_refreshInterval target:self selector:@selector(buildBarrageScene) userInfo:nil repeats:true];
80 | [_timer setFireDate:[NSDate distantFuture]];
81 | }
82 |
83 |
84 | #pragma mark - method(调用方法)
85 | - (void)buildBarrageScene {
86 | /* build barrage model */
87 | if (![_delegate respondsToSelector:@selector(barrageManagerDataSource)]) {
88 | return;
89 | }
90 | id data = [_delegate barrageManagerDataSource];
91 | if (!data) {
92 | return;
93 | }
94 | [self showWithData:data];
95 | }
96 |
97 | - (void)showBarrageWithDataSource:(id)data {
98 | if (!data) {
99 | return;
100 | }
101 | [self showWithData:data];
102 | }
103 |
104 | - (void)showWithData:(id)data {
105 | /*
106 | 1. determine receiver's type (查看接受对象是否为单个对象或者对象数组)
107 | 2. determine build a new scene OR Taken from the buffer pool inside (查看是否需要新建弹幕)
108 | */
109 | _currentStatus = BarrageStatusTypeNormal;
110 | @autoreleasepool {
111 | dispatch_async(dispatch_get_main_queue(), ^{
112 | if ([data isKindOfClass:[BarrageModel class]]) {
113 | //only a BarrageModel
114 | BarrageModel *model = data;
115 | model = [self sync_BarrageManagerConfigure:model];
116 | //先查看缓冲池是否为空
117 | if (_cachePool.count < 1) {
118 | // nil
119 | BarrageScene *scene = [[BarrageScene alloc] initWithFrame:CGRectZero Model:model];
120 | [_barrageScene addObject:scene];
121 | [_bindingView addSubview:scene];
122 | Weakself;
123 | scene.animationDidStopBlock = ^(BarrageScene *scene_){
124 | [weakSelf.cachePool addObject:scene_];
125 | [weakSelf.barrageScene removeObject:scene_];
126 | [scene_ removeFromSuperview];
127 | };
128 | [scene scroll];
129 |
130 | }else {
131 | //从缓冲池获取到Scene后,将其从缓冲池中移除
132 | // NSLog(@"get from cache");
133 | BarrageScene *scene = _cachePool.firstObject;
134 | [_barrageScene addObject:scene];
135 | [_cachePool removeObjectAtIndex:0];
136 | scene.model = model;
137 |
138 | [_bindingView addSubview:scene];
139 | [scene scroll];
140 | }
141 | }else {
142 | // more than one barrage
143 | NSArray *modelArray = data;
144 | [modelArray enumerateObjectsUsingBlock:^(BarrageModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
145 | BarrageModel *model = [self sync_BarrageManagerConfigure:obj];
146 | //先查看缓冲池是否为空
147 | if (_cachePool.count < 1) {
148 | // nil
149 | BarrageScene *scene = [[BarrageScene alloc] initWithFrame:CGRectZero Model:model];
150 | [_barrageScene addObject:scene];
151 | [_bindingView addSubview:scene];
152 | Weakself;
153 | scene.animationDidStopBlock = ^(BarrageScene *scene_){
154 | [weakSelf.cachePool addObject:scene_];
155 | [weakSelf.barrageScene removeObject:scene_];
156 | [scene_ removeFromSuperview];
157 | };
158 | [scene scroll];
159 |
160 | }else {
161 | //从缓冲池获取到Scene后,将其从缓冲池中移除
162 | // NSLog(@"get from cache");
163 | BarrageScene *scene = _cachePool.firstObject;
164 | [_barrageScene addObject:scene];
165 | [_cachePool removeObjectAtIndex:0];
166 | scene.model = model;
167 |
168 | [_bindingView addSubview:scene];
169 | [scene scroll];
170 | }
171 | }];
172 | }
173 | });
174 | }
175 | }
176 |
177 | -(BarrageModel *) sync_BarrageManagerConfigure:(BarrageModel *)model {
178 | model.speed = _scrollSpeed;
179 | model.direction = _scrollDirection;
180 | model.bindView = _bindingView;
181 | return model;
182 | }
183 |
184 | #pragma mark - Barrage Scroll / Pause / Cloese
185 |
186 | - (void)startScroll {
187 | [_timer setFireDate:[NSDate date]];
188 | }
189 |
190 | - (void)pauseScroll {
191 | if (_currentStatus == BarrageStatusTypeClose) {
192 | return;
193 | }
194 | if (_currentStatus == BarrageStatusTypeNormal) {
195 | //将屏幕上的弹幕都暂停下来,并且停止获取新的弹幕
196 | [_timer setFireDate:[NSDate distantFuture]];
197 |
198 | [self.barrageScenes enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
199 | BarrageScene *scene = obj;
200 | [scene pause];
201 | }];
202 | _currentStatus = BarrageStatusTypePause;
203 | }else if (_currentStatus == BarrageStatusTypePause) {
204 | [_timer setFireDate:[NSDate date]];
205 | [self.barrageScenes enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
206 | BarrageScene *scene = obj;
207 | [scene resume];
208 | }];
209 | _currentStatus = BarrageStatusTypeNormal;
210 | }
211 | }
212 |
213 | - (void)closeBarrage {
214 | if (_currentStatus == BarrageStatusTypeNormal) {
215 | _currentStatus = BarrageStatusTypeClose;
216 | [_timer setFireDate:[NSDate distantFuture]];
217 |
218 | [self.barrageScenes enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
219 | BarrageScene *scene = obj;
220 | [scene close];
221 | }];
222 |
223 | }else if (_currentStatus == BarrageStatusTypeClose || _currentStatus == BarrageStatusTypePause) {
224 | _currentStatus = BarrageStatusTypeNormal;
225 | [_timer setFireDate:[NSDate date]];
226 | }
227 | }
228 |
229 | - (void)toDealloc {
230 |
231 | [_timer invalidate];
232 | _timer = nil;
233 | [_cachePool removeAllObjects];
234 | [_barrageScene removeAllObjects];
235 | }
236 |
237 | - (void)didReceiveMemoryWarning {
238 | switch (_memoryMode) {
239 | case BarrageMemoryWarningModeHalf:
240 | [self cleanHalfCache];
241 | break;
242 | case BarrageMemoryWarningModeAll:
243 | [self cleanAllCache];
244 | break;
245 | default:
246 | break;
247 | }
248 | }
249 |
250 | - (void)cleanHalfCache {
251 | NSRange range = NSMakeRange(0, _cachePool.count / 2);
252 | [_cachePool removeObjectsInRange:range];
253 | }
254 |
255 | - (void)cleanAllCache {
256 | [_cachePool removeAllObjects];
257 | }
258 |
259 | @end
260 |
--------------------------------------------------------------------------------
/BarrageKit/BarrageKit/BarrageScene.m:
--------------------------------------------------------------------------------
1 | //
2 | // BarrageScene.m
3 | // BarrageKit
4 | //
5 | // Created by jiachenmu on 16/8/26.
6 | // Copyright © 2016年 ManoBoo. All rights reserved.
7 | //
8 | #import
9 |
10 | #import "BarrageManager.h"
11 | #import "BarrageScene.h"
12 |
13 | @implementation BarrageScene
14 |
15 | - (instancetype)initWithModel:(BarrageModel *)model {
16 | self = [super init];
17 | if (self) {
18 | [self setupUI];
19 | }
20 | return self;
21 | }
22 |
23 | - (instancetype)initWithFrame:(CGRect)frame Model:(BarrageModel *)model{
24 | self = [super initWithFrame:frame];
25 | if (self) {
26 | [self setupUI];
27 | self.model = model;
28 | }
29 | return self;
30 | }
31 |
32 | - (void)dealloc {
33 | // NSLog(@"scene dealloc");
34 | }
35 |
36 | - (void)setupUI {
37 | // text
38 | _titleLabel = [[UILabel alloc] initWithFrame:self.bounds];
39 | _titleLabel.font = [UIFont systemFontOfSize:12.0];
40 | [self addSubview:_titleLabel];
41 |
42 | // button
43 | _voteButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 0, 12)];
44 | _voteButton.hidden = true;
45 | _voteButton.titleLabel.font = [UIFont systemFontOfSize:12.0];
46 | [_voteButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
47 | [_voteButton setTitle:@"Vote" forState:UIControlStateNormal];
48 | [self addSubview:_voteButton];
49 | }
50 |
51 | // 加入到SuperView后 开始滚动
52 | - (void)scroll {
53 |
54 | //计算动画距离、时间 calculate time of scroll barrage
55 | CGFloat distance = 0.0;
56 | CGPoint goalPoint = CGPointZero;
57 | switch (_model.direction) {
58 | case BarrageScrollDirectRightToLeft:
59 | distance = CGRectGetWidth(_model.bindView.bounds);
60 | goalPoint = CGPointMake(-CGRectGetWidth(self.frame), CGRectGetMinY(self.frame));
61 | break;
62 | case BarrageScrollDirectLeftToRight:
63 | distance = CGRectGetWidth(_model.bindView.bounds);
64 | goalPoint = CGPointMake(CGRectGetWidth(_model.bindView.bounds) + CGRectGetWidth(self.frame), CGRectGetMinY(self.frame));
65 | break;
66 | case BarrageScrollDirectBottomToTop:
67 | distance = CGRectGetHeight(_model.bindView.bounds);
68 | goalPoint = CGPointMake(CGRectGetMinX(self.frame), -CGRectGetHeight(self.frame));
69 | break;
70 | case BarrageScrollDirectTopToBottom:
71 | distance = CGRectGetHeight(_model.bindView.bounds);
72 | goalPoint = CGPointMake(CGRectGetMinX(self.frame), CGRectGetHeight(self.frame) + CGRectGetMaxY(_model.bindView.bounds));
73 | break;
74 | default:
75 | break;
76 | }
77 | NSTimeInterval time = distance / _model.speed;
78 |
79 | CGRect goalFrame = self.frame;
80 | goalFrame.origin = goalPoint;
81 |
82 | // layer执行动画
83 |
84 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
85 | animation.delegate = self;
86 | animation.removedOnCompletion = true;
87 | animation.autoreverses = false;
88 | animation.fillMode = kCAFillModeForwards;
89 |
90 | [animation setToValue:[NSValue valueWithCGPoint:CenterPoint(goalFrame)]];
91 | [animation setDuration:time];
92 | [self.layer addAnimation:animation forKey:@"kAnimation_BarrageScene"];
93 | }
94 |
95 | - (void)setModel:(BarrageModel *)model {
96 | _model = model;
97 | [self calculateFrame];
98 | }
99 |
100 | - (void)pause {
101 | CFTimeInterval pausedTime = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil];
102 | self.layer.speed = 0.0;
103 | self.layer.timeOffset = pausedTime;
104 | }
105 |
106 | - (void)resume {
107 | CFTimeInterval pausedTime = [self.layer timeOffset];
108 | self.layer.timeOffset = 0.0;
109 | self.layer.beginTime = 0.0;
110 | self.layer.speed = 1.0;
111 | CFTimeInterval timeSincePause = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
112 | self.layer.beginTime = timeSincePause;
113 | }
114 |
115 | - (void)close {
116 | [self.layer removeAllAnimations];
117 | [self removeFromSuperview];
118 | }
119 |
120 | #pragma mark - 计算Frame
121 | - (void)calculateFrame {
122 | /* 1. setup UI (基础UI设置) */
123 | _titleLabel.attributedText = _model.message;
124 | // _titleLabel.textColor = _model.textColor;
125 |
126 | /* 2. determine barrage's type (判断弹幕类型) */
127 | switch (_model.barrageType) {
128 | case BarrageDisplayTypeVote:
129 | // --投票类型--
130 | [_titleLabel sizeToFit];
131 | _voteButton.hidden = false;
132 | [_voteButton sizeToFit];
133 | CGRect frame = _voteButton.frame;
134 | frame.origin.x = CGRectGetMaxX(_titleLabel.frame);
135 | frame.origin.y = CGRectGetMinY(_titleLabel.frame);
136 | frame.size.height = CGRectGetHeight(_titleLabel.frame);
137 | _voteButton.frame = frame;
138 | self.bounds = CGRectMake(0, 0, CGRectGetWidth(_titleLabel.frame) + CGRectGetWidth(_voteButton.frame), CGRectGetHeight(_titleLabel.frame));
139 | break;
140 | case BarrageDisplayTypeOther:
141 | // --其他类型--
142 |
143 | break;
144 | default:
145 | // --BarrageDisplayTypeDefault--
146 | _voteButton.hidden = true;
147 | [_titleLabel sizeToFit];
148 | self.bounds = _titleLabel.bounds;
149 | break;
150 | }
151 |
152 | //计算弹幕随机位置
153 | self.frame = [self calculateBarrageSceneFrameWithModel:_model];
154 | }
155 |
156 | //MARK: 随机计算弹幕的Frame
157 | -(CGRect) calculateBarrageSceneFrameWithModel:(BarrageModel *)model {
158 | CGPoint originPoint;
159 | CGRect sourceFrame = CGRectZero;
160 | switch (model.displayLocation) {
161 | case BarrageDisplayLocationTypeDefault:
162 | sourceFrame = model.bindView.bounds;
163 | break;
164 | case BarrageDisplayLocationTypeTop:
165 | sourceFrame = CGRectMake(0, 0, CGRectGetWidth(model.bindView.bounds), CGRectGetHeight(model.bindView.bounds) / 3.0);
166 | break;
167 | case BarrageDisplayLocationTypeCenter:
168 | sourceFrame = CGRectMake(0, CGRectGetHeight(model.bindView.bounds) / 3.0, CGRectGetWidth(model.bindView.bounds), CGRectGetHeight(model.bindView.bounds) / 3.0);
169 | break;
170 | case BarrageDisplayLocationTypeBottom:
171 | sourceFrame = CGRectMake(0, CGRectGetHeight(model.bindView.bounds) / 3.0 * 2.0, CGRectGetWidth(model.bindView.bounds), CGRectGetHeight(model.bindView.bounds) / 3.0);
172 | break;
173 | default:
174 | break;
175 | }
176 | switch (model.direction) {
177 | case BarrageScrollDirectRightToLeft:
178 | originPoint = CGPointMake(CGRectGetMaxX(sourceFrame), RandomBetween(0, CGRectGetHeight(sourceFrame) - CGRectGetHeight(self.bounds)));
179 | break;
180 | case BarrageScrollDirectLeftToRight:
181 | originPoint = CGPointMake(-CGRectGetWidth(self.bounds), RandomBetween(0, CGRectGetHeight(sourceFrame) - CGRectGetHeight(self.bounds)));
182 | break;
183 | case BarrageScrollDirectBottomToTop:
184 | originPoint = CGPointMake(RandomBetween(0, CGRectGetWidth(sourceFrame)), CGRectGetMaxY(sourceFrame) + CGRectGetHeight(self.bounds));
185 | break;
186 | case BarrageScrollDirectTopToBottom:
187 | originPoint = CGPointMake(RandomBetween(0, CGRectGetWidth(sourceFrame)), -CGRectGetHeight(self.bounds));
188 | break;
189 | default:
190 | break;
191 | }
192 |
193 | CGRect frame = self.frame;
194 | frame.origin = originPoint;
195 |
196 | return frame;
197 | }
198 |
199 | #pragma mark - AnimatonDelegate
200 |
201 | // stop
202 | - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
203 | if (flag) {
204 | __weak typeof(self) SELF = self;
205 |
206 | if (_animationDidStopBlock) {
207 | _animationDidStopBlock(SELF);
208 | }
209 | }
210 | }
211 |
212 | - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
213 |
214 | if ([_voteButton pointInside:point withEvent:event]) {
215 | NSLog(@"click~~~");
216 | }
217 | return [super hitTest:point withEvent:event];
218 | }
219 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
220 | NSLog(@"touchesBegan");
221 | }
222 |
223 | #pragma mark - Other Method
224 | //随机返回某个区间范围内的值 return a ` float ` Between `smallerNumber ` and ` largerNumber `
225 | float RandomBetween(float smallerNumber, float largerNumber) {
226 | //设置精确的位数
227 | int precision = 100;
228 | //先取得他们之间的差值
229 | float subtraction = largerNumber - smallerNumber;
230 | //取绝对值
231 | subtraction = ABS(subtraction);
232 | //乘以精度的位数
233 | subtraction *= precision;
234 | //在差值间随机
235 | float randomNumber = arc4random() % ((int)subtraction+1);
236 | //随机的结果除以精度的位数
237 | randomNumber /= precision;
238 | //将随机的值加到较小的值上
239 | float result = MIN(smallerNumber, largerNumber) + randomNumber;
240 | //返回结果
241 | return result;
242 | }
243 |
244 | //返回一个Frame的中心点
245 | CGPoint CenterPoint(CGRect rect) {
246 | return CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
247 | }
248 | @end
249 |
--------------------------------------------------------------------------------
/BarrageKit.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 460B279F1D6EC7DE00E5FB1D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 460B279E1D6EC7DE00E5FB1D /* main.m */; };
11 | 460B27A21D6EC7DE00E5FB1D /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 460B27A11D6EC7DE00E5FB1D /* AppDelegate.m */; };
12 | 460B27A51D6EC7DE00E5FB1D /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 460B27A41D6EC7DE00E5FB1D /* ViewController.m */; };
13 | 460B27A81D6EC7DF00E5FB1D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 460B27A61D6EC7DF00E5FB1D /* Main.storyboard */; };
14 | 460B27AA1D6EC7DF00E5FB1D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 460B27A91D6EC7DF00E5FB1D /* Assets.xcassets */; };
15 | 460B27AD1D6EC7DF00E5FB1D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 460B27AB1D6EC7DF00E5FB1D /* LaunchScreen.storyboard */; };
16 | 460B27B81D6EC7DF00E5FB1D /* BarrageKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 460B27B71D6EC7DF00E5FB1D /* BarrageKitTests.m */; };
17 | 460B27C31D6EC7DF00E5FB1D /* BarrageKitUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 460B27C21D6EC7DF00E5FB1D /* BarrageKitUITests.m */; };
18 | 460B27D51D6EC9A800E5FB1D /* BarrageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 460B27D41D6EC9A800E5FB1D /* BarrageManager.m */; };
19 | 460B27D91D6ECFC200E5FB1D /* BarrageModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 460B27D81D6ECFC200E5FB1D /* BarrageModel.m */; };
20 | 464D6D2E1D70310A00454DF6 /* BarrageScene.m in Sources */ = {isa = PBXBuildFile; fileRef = 464D6D2D1D70310A00454DF6 /* BarrageScene.m */; };
21 | 464D6D331D77DC1400454DF6 /* FirstViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 464D6D311D77DC1400454DF6 /* FirstViewController.m */; };
22 | 464D6D341D77DC1400454DF6 /* FirstViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 464D6D321D77DC1400454DF6 /* FirstViewController.xib */; };
23 | /* End PBXBuildFile section */
24 |
25 | /* Begin PBXContainerItemProxy section */
26 | 460B27B41D6EC7DF00E5FB1D /* PBXContainerItemProxy */ = {
27 | isa = PBXContainerItemProxy;
28 | containerPortal = 460B27921D6EC7DE00E5FB1D /* Project object */;
29 | proxyType = 1;
30 | remoteGlobalIDString = 460B27991D6EC7DE00E5FB1D;
31 | remoteInfo = BarrageKit;
32 | };
33 | 460B27BF1D6EC7DF00E5FB1D /* PBXContainerItemProxy */ = {
34 | isa = PBXContainerItemProxy;
35 | containerPortal = 460B27921D6EC7DE00E5FB1D /* Project object */;
36 | proxyType = 1;
37 | remoteGlobalIDString = 460B27991D6EC7DE00E5FB1D;
38 | remoteInfo = BarrageKit;
39 | };
40 | /* End PBXContainerItemProxy section */
41 |
42 | /* Begin PBXFileReference section */
43 | 460B279A1D6EC7DE00E5FB1D /* BarrageKit.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BarrageKit.app; sourceTree = BUILT_PRODUCTS_DIR; };
44 | 460B279E1D6EC7DE00E5FB1D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
45 | 460B27A01D6EC7DE00E5FB1D /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
46 | 460B27A11D6EC7DE00E5FB1D /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
47 | 460B27A31D6EC7DE00E5FB1D /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
48 | 460B27A41D6EC7DE00E5FB1D /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
49 | 460B27A71D6EC7DF00E5FB1D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
50 | 460B27A91D6EC7DF00E5FB1D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
51 | 460B27AC1D6EC7DF00E5FB1D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
52 | 460B27AE1D6EC7DF00E5FB1D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
53 | 460B27B31D6EC7DF00E5FB1D /* BarrageKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BarrageKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
54 | 460B27B71D6EC7DF00E5FB1D /* BarrageKitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BarrageKitTests.m; sourceTree = ""; };
55 | 460B27B91D6EC7DF00E5FB1D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
56 | 460B27BE1D6EC7DF00E5FB1D /* BarrageKitUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BarrageKitUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
57 | 460B27C21D6EC7DF00E5FB1D /* BarrageKitUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BarrageKitUITests.m; sourceTree = ""; };
58 | 460B27C41D6EC7DF00E5FB1D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
59 | 460B27D31D6EC9A800E5FB1D /* BarrageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BarrageManager.h; path = BarrageKit/BarrageManager.h; sourceTree = ""; };
60 | 460B27D41D6EC9A800E5FB1D /* BarrageManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BarrageManager.m; path = BarrageKit/BarrageManager.m; sourceTree = ""; };
61 | 460B27D61D6EC9F100E5FB1D /* BarrageKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BarrageKit.h; path = BarrageKit/BarrageKit.h; sourceTree = ""; };
62 | 460B27D71D6ECFC200E5FB1D /* BarrageModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BarrageModel.h; path = BarrageKit/BarrageModel.h; sourceTree = ""; };
63 | 460B27D81D6ECFC200E5FB1D /* BarrageModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BarrageModel.m; path = BarrageKit/BarrageModel.m; sourceTree = ""; };
64 | 464D6D2C1D70310A00454DF6 /* BarrageScene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BarrageScene.h; path = BarrageKit/BarrageScene.h; sourceTree = ""; };
65 | 464D6D2D1D70310A00454DF6 /* BarrageScene.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BarrageScene.m; path = BarrageKit/BarrageScene.m; sourceTree = ""; };
66 | 464D6D2F1D742E2E00454DF6 /* BarrageEnum.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BarrageEnum.h; sourceTree = ""; };
67 | 464D6D301D77DC1400454DF6 /* FirstViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FirstViewController.h; sourceTree = ""; };
68 | 464D6D311D77DC1400454DF6 /* FirstViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FirstViewController.m; sourceTree = ""; };
69 | 464D6D321D77DC1400454DF6 /* FirstViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FirstViewController.xib; sourceTree = ""; };
70 | /* End PBXFileReference section */
71 |
72 | /* Begin PBXFrameworksBuildPhase section */
73 | 460B27971D6EC7DE00E5FB1D /* Frameworks */ = {
74 | isa = PBXFrameworksBuildPhase;
75 | buildActionMask = 2147483647;
76 | files = (
77 | );
78 | runOnlyForDeploymentPostprocessing = 0;
79 | };
80 | 460B27B01D6EC7DF00E5FB1D /* Frameworks */ = {
81 | isa = PBXFrameworksBuildPhase;
82 | buildActionMask = 2147483647;
83 | files = (
84 | );
85 | runOnlyForDeploymentPostprocessing = 0;
86 | };
87 | 460B27BB1D6EC7DF00E5FB1D /* Frameworks */ = {
88 | isa = PBXFrameworksBuildPhase;
89 | buildActionMask = 2147483647;
90 | files = (
91 | );
92 | runOnlyForDeploymentPostprocessing = 0;
93 | };
94 | /* End PBXFrameworksBuildPhase section */
95 |
96 | /* Begin PBXGroup section */
97 | 460B27911D6EC7DE00E5FB1D = {
98 | isa = PBXGroup;
99 | children = (
100 | 460B279C1D6EC7DE00E5FB1D /* BarrageKit */,
101 | 460B27B61D6EC7DF00E5FB1D /* BarrageKitTests */,
102 | 460B27C11D6EC7DF00E5FB1D /* BarrageKitUITests */,
103 | 460B279B1D6EC7DE00E5FB1D /* Products */,
104 | );
105 | sourceTree = "";
106 | };
107 | 460B279B1D6EC7DE00E5FB1D /* Products */ = {
108 | isa = PBXGroup;
109 | children = (
110 | 460B279A1D6EC7DE00E5FB1D /* BarrageKit.app */,
111 | 460B27B31D6EC7DF00E5FB1D /* BarrageKitTests.xctest */,
112 | 460B27BE1D6EC7DF00E5FB1D /* BarrageKitUITests.xctest */,
113 | );
114 | name = Products;
115 | sourceTree = "";
116 | };
117 | 460B279C1D6EC7DE00E5FB1D /* BarrageKit */ = {
118 | isa = PBXGroup;
119 | children = (
120 | 460B27A01D6EC7DE00E5FB1D /* AppDelegate.h */,
121 | 460B27A11D6EC7DE00E5FB1D /* AppDelegate.m */,
122 | 464D6D301D77DC1400454DF6 /* FirstViewController.h */,
123 | 464D6D311D77DC1400454DF6 /* FirstViewController.m */,
124 | 464D6D321D77DC1400454DF6 /* FirstViewController.xib */,
125 | 460B27A31D6EC7DE00E5FB1D /* ViewController.h */,
126 | 460B27A41D6EC7DE00E5FB1D /* ViewController.m */,
127 | 460B27D21D6EC8CD00E5FB1D /* BarrageKit */,
128 | 460B27D01D6EC8B900E5FB1D /* Other */,
129 | );
130 | path = BarrageKit;
131 | sourceTree = "";
132 | };
133 | 460B279D1D6EC7DE00E5FB1D /* Supporting Files */ = {
134 | isa = PBXGroup;
135 | children = (
136 | 460B279E1D6EC7DE00E5FB1D /* main.m */,
137 | );
138 | name = "Supporting Files";
139 | sourceTree = "";
140 | };
141 | 460B27B61D6EC7DF00E5FB1D /* BarrageKitTests */ = {
142 | isa = PBXGroup;
143 | children = (
144 | 460B27B71D6EC7DF00E5FB1D /* BarrageKitTests.m */,
145 | 460B27B91D6EC7DF00E5FB1D /* Info.plist */,
146 | );
147 | path = BarrageKitTests;
148 | sourceTree = "";
149 | };
150 | 460B27C11D6EC7DF00E5FB1D /* BarrageKitUITests */ = {
151 | isa = PBXGroup;
152 | children = (
153 | 460B27C21D6EC7DF00E5FB1D /* BarrageKitUITests.m */,
154 | 460B27C41D6EC7DF00E5FB1D /* Info.plist */,
155 | );
156 | path = BarrageKitUITests;
157 | sourceTree = "";
158 | };
159 | 460B27D01D6EC8B900E5FB1D /* Other */ = {
160 | isa = PBXGroup;
161 | children = (
162 | 460B27A61D6EC7DF00E5FB1D /* Main.storyboard */,
163 | 460B27A91D6EC7DF00E5FB1D /* Assets.xcassets */,
164 | 460B27AB1D6EC7DF00E5FB1D /* LaunchScreen.storyboard */,
165 | 460B27AE1D6EC7DF00E5FB1D /* Info.plist */,
166 | 460B279D1D6EC7DE00E5FB1D /* Supporting Files */,
167 | );
168 | name = Other;
169 | sourceTree = "";
170 | };
171 | 460B27D21D6EC8CD00E5FB1D /* BarrageKit */ = {
172 | isa = PBXGroup;
173 | children = (
174 | 460B27D61D6EC9F100E5FB1D /* BarrageKit.h */,
175 | 464D6D2F1D742E2E00454DF6 /* BarrageEnum.h */,
176 | 460B27D31D6EC9A800E5FB1D /* BarrageManager.h */,
177 | 460B27D41D6EC9A800E5FB1D /* BarrageManager.m */,
178 | 460B27D71D6ECFC200E5FB1D /* BarrageModel.h */,
179 | 460B27D81D6ECFC200E5FB1D /* BarrageModel.m */,
180 | 464D6D2C1D70310A00454DF6 /* BarrageScene.h */,
181 | 464D6D2D1D70310A00454DF6 /* BarrageScene.m */,
182 | );
183 | name = BarrageKit;
184 | sourceTree = "";
185 | };
186 | /* End PBXGroup section */
187 |
188 | /* Begin PBXNativeTarget section */
189 | 460B27991D6EC7DE00E5FB1D /* BarrageKit */ = {
190 | isa = PBXNativeTarget;
191 | buildConfigurationList = 460B27C71D6EC7DF00E5FB1D /* Build configuration list for PBXNativeTarget "BarrageKit" */;
192 | buildPhases = (
193 | 460B27961D6EC7DE00E5FB1D /* Sources */,
194 | 460B27971D6EC7DE00E5FB1D /* Frameworks */,
195 | 460B27981D6EC7DE00E5FB1D /* Resources */,
196 | );
197 | buildRules = (
198 | );
199 | dependencies = (
200 | );
201 | name = BarrageKit;
202 | productName = BarrageKit;
203 | productReference = 460B279A1D6EC7DE00E5FB1D /* BarrageKit.app */;
204 | productType = "com.apple.product-type.application";
205 | };
206 | 460B27B21D6EC7DF00E5FB1D /* BarrageKitTests */ = {
207 | isa = PBXNativeTarget;
208 | buildConfigurationList = 460B27CA1D6EC7DF00E5FB1D /* Build configuration list for PBXNativeTarget "BarrageKitTests" */;
209 | buildPhases = (
210 | 460B27AF1D6EC7DF00E5FB1D /* Sources */,
211 | 460B27B01D6EC7DF00E5FB1D /* Frameworks */,
212 | 460B27B11D6EC7DF00E5FB1D /* Resources */,
213 | );
214 | buildRules = (
215 | );
216 | dependencies = (
217 | 460B27B51D6EC7DF00E5FB1D /* PBXTargetDependency */,
218 | );
219 | name = BarrageKitTests;
220 | productName = BarrageKitTests;
221 | productReference = 460B27B31D6EC7DF00E5FB1D /* BarrageKitTests.xctest */;
222 | productType = "com.apple.product-type.bundle.unit-test";
223 | };
224 | 460B27BD1D6EC7DF00E5FB1D /* BarrageKitUITests */ = {
225 | isa = PBXNativeTarget;
226 | buildConfigurationList = 460B27CD1D6EC7DF00E5FB1D /* Build configuration list for PBXNativeTarget "BarrageKitUITests" */;
227 | buildPhases = (
228 | 460B27BA1D6EC7DF00E5FB1D /* Sources */,
229 | 460B27BB1D6EC7DF00E5FB1D /* Frameworks */,
230 | 460B27BC1D6EC7DF00E5FB1D /* Resources */,
231 | );
232 | buildRules = (
233 | );
234 | dependencies = (
235 | 460B27C01D6EC7DF00E5FB1D /* PBXTargetDependency */,
236 | );
237 | name = BarrageKitUITests;
238 | productName = BarrageKitUITests;
239 | productReference = 460B27BE1D6EC7DF00E5FB1D /* BarrageKitUITests.xctest */;
240 | productType = "com.apple.product-type.bundle.ui-testing";
241 | };
242 | /* End PBXNativeTarget section */
243 |
244 | /* Begin PBXProject section */
245 | 460B27921D6EC7DE00E5FB1D /* Project object */ = {
246 | isa = PBXProject;
247 | attributes = {
248 | LastUpgradeCheck = 0730;
249 | ORGANIZATIONNAME = ManoBoo;
250 | TargetAttributes = {
251 | 460B27991D6EC7DE00E5FB1D = {
252 | CreatedOnToolsVersion = 7.3;
253 | DevelopmentTeam = 67442AUEW4;
254 | };
255 | 460B27B21D6EC7DF00E5FB1D = {
256 | CreatedOnToolsVersion = 7.3;
257 | TestTargetID = 460B27991D6EC7DE00E5FB1D;
258 | };
259 | 460B27BD1D6EC7DF00E5FB1D = {
260 | CreatedOnToolsVersion = 7.3;
261 | TestTargetID = 460B27991D6EC7DE00E5FB1D;
262 | };
263 | };
264 | };
265 | buildConfigurationList = 460B27951D6EC7DE00E5FB1D /* Build configuration list for PBXProject "BarrageKit" */;
266 | compatibilityVersion = "Xcode 3.2";
267 | developmentRegion = English;
268 | hasScannedForEncodings = 0;
269 | knownRegions = (
270 | en,
271 | Base,
272 | );
273 | mainGroup = 460B27911D6EC7DE00E5FB1D;
274 | productRefGroup = 460B279B1D6EC7DE00E5FB1D /* Products */;
275 | projectDirPath = "";
276 | projectRoot = "";
277 | targets = (
278 | 460B27991D6EC7DE00E5FB1D /* BarrageKit */,
279 | 460B27B21D6EC7DF00E5FB1D /* BarrageKitTests */,
280 | 460B27BD1D6EC7DF00E5FB1D /* BarrageKitUITests */,
281 | );
282 | };
283 | /* End PBXProject section */
284 |
285 | /* Begin PBXResourcesBuildPhase section */
286 | 460B27981D6EC7DE00E5FB1D /* Resources */ = {
287 | isa = PBXResourcesBuildPhase;
288 | buildActionMask = 2147483647;
289 | files = (
290 | 460B27AD1D6EC7DF00E5FB1D /* LaunchScreen.storyboard in Resources */,
291 | 460B27AA1D6EC7DF00E5FB1D /* Assets.xcassets in Resources */,
292 | 460B27A81D6EC7DF00E5FB1D /* Main.storyboard in Resources */,
293 | 464D6D341D77DC1400454DF6 /* FirstViewController.xib in Resources */,
294 | );
295 | runOnlyForDeploymentPostprocessing = 0;
296 | };
297 | 460B27B11D6EC7DF00E5FB1D /* Resources */ = {
298 | isa = PBXResourcesBuildPhase;
299 | buildActionMask = 2147483647;
300 | files = (
301 | );
302 | runOnlyForDeploymentPostprocessing = 0;
303 | };
304 | 460B27BC1D6EC7DF00E5FB1D /* Resources */ = {
305 | isa = PBXResourcesBuildPhase;
306 | buildActionMask = 2147483647;
307 | files = (
308 | );
309 | runOnlyForDeploymentPostprocessing = 0;
310 | };
311 | /* End PBXResourcesBuildPhase section */
312 |
313 | /* Begin PBXSourcesBuildPhase section */
314 | 460B27961D6EC7DE00E5FB1D /* Sources */ = {
315 | isa = PBXSourcesBuildPhase;
316 | buildActionMask = 2147483647;
317 | files = (
318 | 460B27D91D6ECFC200E5FB1D /* BarrageModel.m in Sources */,
319 | 460B27A51D6EC7DE00E5FB1D /* ViewController.m in Sources */,
320 | 464D6D331D77DC1400454DF6 /* FirstViewController.m in Sources */,
321 | 460B27A21D6EC7DE00E5FB1D /* AppDelegate.m in Sources */,
322 | 460B27D51D6EC9A800E5FB1D /* BarrageManager.m in Sources */,
323 | 460B279F1D6EC7DE00E5FB1D /* main.m in Sources */,
324 | 464D6D2E1D70310A00454DF6 /* BarrageScene.m in Sources */,
325 | );
326 | runOnlyForDeploymentPostprocessing = 0;
327 | };
328 | 460B27AF1D6EC7DF00E5FB1D /* Sources */ = {
329 | isa = PBXSourcesBuildPhase;
330 | buildActionMask = 2147483647;
331 | files = (
332 | 460B27B81D6EC7DF00E5FB1D /* BarrageKitTests.m in Sources */,
333 | );
334 | runOnlyForDeploymentPostprocessing = 0;
335 | };
336 | 460B27BA1D6EC7DF00E5FB1D /* Sources */ = {
337 | isa = PBXSourcesBuildPhase;
338 | buildActionMask = 2147483647;
339 | files = (
340 | 460B27C31D6EC7DF00E5FB1D /* BarrageKitUITests.m in Sources */,
341 | );
342 | runOnlyForDeploymentPostprocessing = 0;
343 | };
344 | /* End PBXSourcesBuildPhase section */
345 |
346 | /* Begin PBXTargetDependency section */
347 | 460B27B51D6EC7DF00E5FB1D /* PBXTargetDependency */ = {
348 | isa = PBXTargetDependency;
349 | target = 460B27991D6EC7DE00E5FB1D /* BarrageKit */;
350 | targetProxy = 460B27B41D6EC7DF00E5FB1D /* PBXContainerItemProxy */;
351 | };
352 | 460B27C01D6EC7DF00E5FB1D /* PBXTargetDependency */ = {
353 | isa = PBXTargetDependency;
354 | target = 460B27991D6EC7DE00E5FB1D /* BarrageKit */;
355 | targetProxy = 460B27BF1D6EC7DF00E5FB1D /* PBXContainerItemProxy */;
356 | };
357 | /* End PBXTargetDependency section */
358 |
359 | /* Begin PBXVariantGroup section */
360 | 460B27A61D6EC7DF00E5FB1D /* Main.storyboard */ = {
361 | isa = PBXVariantGroup;
362 | children = (
363 | 460B27A71D6EC7DF00E5FB1D /* Base */,
364 | );
365 | name = Main.storyboard;
366 | sourceTree = "";
367 | };
368 | 460B27AB1D6EC7DF00E5FB1D /* LaunchScreen.storyboard */ = {
369 | isa = PBXVariantGroup;
370 | children = (
371 | 460B27AC1D6EC7DF00E5FB1D /* Base */,
372 | );
373 | name = LaunchScreen.storyboard;
374 | sourceTree = "";
375 | };
376 | /* End PBXVariantGroup section */
377 |
378 | /* Begin XCBuildConfiguration section */
379 | 460B27C51D6EC7DF00E5FB1D /* Debug */ = {
380 | isa = XCBuildConfiguration;
381 | buildSettings = {
382 | ALWAYS_SEARCH_USER_PATHS = NO;
383 | CLANG_ANALYZER_NONNULL = YES;
384 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
385 | CLANG_CXX_LIBRARY = "libc++";
386 | CLANG_ENABLE_MODULES = YES;
387 | CLANG_ENABLE_OBJC_ARC = YES;
388 | CLANG_WARN_BOOL_CONVERSION = YES;
389 | CLANG_WARN_CONSTANT_CONVERSION = YES;
390 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
391 | CLANG_WARN_EMPTY_BODY = YES;
392 | CLANG_WARN_ENUM_CONVERSION = YES;
393 | CLANG_WARN_INT_CONVERSION = YES;
394 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
395 | CLANG_WARN_UNREACHABLE_CODE = YES;
396 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
397 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
398 | COPY_PHASE_STRIP = NO;
399 | DEBUG_INFORMATION_FORMAT = dwarf;
400 | ENABLE_STRICT_OBJC_MSGSEND = YES;
401 | ENABLE_TESTABILITY = YES;
402 | GCC_C_LANGUAGE_STANDARD = gnu99;
403 | GCC_DYNAMIC_NO_PIC = NO;
404 | GCC_NO_COMMON_BLOCKS = YES;
405 | GCC_OPTIMIZATION_LEVEL = 0;
406 | GCC_PREPROCESSOR_DEFINITIONS = (
407 | "DEBUG=1",
408 | "$(inherited)",
409 | );
410 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
411 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
412 | GCC_WARN_UNDECLARED_SELECTOR = YES;
413 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
414 | GCC_WARN_UNUSED_FUNCTION = YES;
415 | GCC_WARN_UNUSED_VARIABLE = YES;
416 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
417 | MTL_ENABLE_DEBUG_INFO = YES;
418 | ONLY_ACTIVE_ARCH = YES;
419 | SDKROOT = iphoneos;
420 | TARGETED_DEVICE_FAMILY = "1,2";
421 | };
422 | name = Debug;
423 | };
424 | 460B27C61D6EC7DF00E5FB1D /* Release */ = {
425 | isa = XCBuildConfiguration;
426 | buildSettings = {
427 | ALWAYS_SEARCH_USER_PATHS = NO;
428 | CLANG_ANALYZER_NONNULL = YES;
429 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
430 | CLANG_CXX_LIBRARY = "libc++";
431 | CLANG_ENABLE_MODULES = YES;
432 | CLANG_ENABLE_OBJC_ARC = YES;
433 | CLANG_WARN_BOOL_CONVERSION = YES;
434 | CLANG_WARN_CONSTANT_CONVERSION = YES;
435 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
436 | CLANG_WARN_EMPTY_BODY = YES;
437 | CLANG_WARN_ENUM_CONVERSION = YES;
438 | CLANG_WARN_INT_CONVERSION = YES;
439 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
440 | CLANG_WARN_UNREACHABLE_CODE = YES;
441 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
442 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
443 | COPY_PHASE_STRIP = NO;
444 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
445 | ENABLE_NS_ASSERTIONS = NO;
446 | ENABLE_STRICT_OBJC_MSGSEND = YES;
447 | GCC_C_LANGUAGE_STANDARD = gnu99;
448 | GCC_NO_COMMON_BLOCKS = YES;
449 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
450 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
451 | GCC_WARN_UNDECLARED_SELECTOR = YES;
452 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
453 | GCC_WARN_UNUSED_FUNCTION = YES;
454 | GCC_WARN_UNUSED_VARIABLE = YES;
455 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
456 | MTL_ENABLE_DEBUG_INFO = NO;
457 | SDKROOT = iphoneos;
458 | TARGETED_DEVICE_FAMILY = "1,2";
459 | VALIDATE_PRODUCT = YES;
460 | };
461 | name = Release;
462 | };
463 | 460B27C81D6EC7DF00E5FB1D /* Debug */ = {
464 | isa = XCBuildConfiguration;
465 | buildSettings = {
466 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
467 | CODE_SIGN_IDENTITY = "iPhone Developer";
468 | INFOPLIST_FILE = BarrageKit/Info.plist;
469 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
470 | PRODUCT_BUNDLE_IDENTIFIER = ManoBoo.Inc.BarrageKit;
471 | PRODUCT_NAME = "$(TARGET_NAME)";
472 | };
473 | name = Debug;
474 | };
475 | 460B27C91D6EC7DF00E5FB1D /* Release */ = {
476 | isa = XCBuildConfiguration;
477 | buildSettings = {
478 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
479 | CODE_SIGN_IDENTITY = "iPhone Developer";
480 | INFOPLIST_FILE = BarrageKit/Info.plist;
481 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
482 | PRODUCT_BUNDLE_IDENTIFIER = ManoBoo.Inc.BarrageKit;
483 | PRODUCT_NAME = "$(TARGET_NAME)";
484 | };
485 | name = Release;
486 | };
487 | 460B27CB1D6EC7DF00E5FB1D /* Debug */ = {
488 | isa = XCBuildConfiguration;
489 | buildSettings = {
490 | BUNDLE_LOADER = "$(TEST_HOST)";
491 | INFOPLIST_FILE = BarrageKitTests/Info.plist;
492 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
493 | PRODUCT_BUNDLE_IDENTIFIER = ManoBoo.Inc.BarrageKitTests;
494 | PRODUCT_NAME = "$(TARGET_NAME)";
495 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BarrageKit.app/BarrageKit";
496 | };
497 | name = Debug;
498 | };
499 | 460B27CC1D6EC7DF00E5FB1D /* Release */ = {
500 | isa = XCBuildConfiguration;
501 | buildSettings = {
502 | BUNDLE_LOADER = "$(TEST_HOST)";
503 | INFOPLIST_FILE = BarrageKitTests/Info.plist;
504 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
505 | PRODUCT_BUNDLE_IDENTIFIER = ManoBoo.Inc.BarrageKitTests;
506 | PRODUCT_NAME = "$(TARGET_NAME)";
507 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BarrageKit.app/BarrageKit";
508 | };
509 | name = Release;
510 | };
511 | 460B27CE1D6EC7DF00E5FB1D /* Debug */ = {
512 | isa = XCBuildConfiguration;
513 | buildSettings = {
514 | INFOPLIST_FILE = BarrageKitUITests/Info.plist;
515 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
516 | PRODUCT_BUNDLE_IDENTIFIER = ManoBoo.Inc.BarrageKitUITests;
517 | PRODUCT_NAME = "$(TARGET_NAME)";
518 | TEST_TARGET_NAME = BarrageKit;
519 | };
520 | name = Debug;
521 | };
522 | 460B27CF1D6EC7DF00E5FB1D /* Release */ = {
523 | isa = XCBuildConfiguration;
524 | buildSettings = {
525 | INFOPLIST_FILE = BarrageKitUITests/Info.plist;
526 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
527 | PRODUCT_BUNDLE_IDENTIFIER = ManoBoo.Inc.BarrageKitUITests;
528 | PRODUCT_NAME = "$(TARGET_NAME)";
529 | TEST_TARGET_NAME = BarrageKit;
530 | };
531 | name = Release;
532 | };
533 | /* End XCBuildConfiguration section */
534 |
535 | /* Begin XCConfigurationList section */
536 | 460B27951D6EC7DE00E5FB1D /* Build configuration list for PBXProject "BarrageKit" */ = {
537 | isa = XCConfigurationList;
538 | buildConfigurations = (
539 | 460B27C51D6EC7DF00E5FB1D /* Debug */,
540 | 460B27C61D6EC7DF00E5FB1D /* Release */,
541 | );
542 | defaultConfigurationIsVisible = 0;
543 | defaultConfigurationName = Release;
544 | };
545 | 460B27C71D6EC7DF00E5FB1D /* Build configuration list for PBXNativeTarget "BarrageKit" */ = {
546 | isa = XCConfigurationList;
547 | buildConfigurations = (
548 | 460B27C81D6EC7DF00E5FB1D /* Debug */,
549 | 460B27C91D6EC7DF00E5FB1D /* Release */,
550 | );
551 | defaultConfigurationIsVisible = 0;
552 | defaultConfigurationName = Release;
553 | };
554 | 460B27CA1D6EC7DF00E5FB1D /* Build configuration list for PBXNativeTarget "BarrageKitTests" */ = {
555 | isa = XCConfigurationList;
556 | buildConfigurations = (
557 | 460B27CB1D6EC7DF00E5FB1D /* Debug */,
558 | 460B27CC1D6EC7DF00E5FB1D /* Release */,
559 | );
560 | defaultConfigurationIsVisible = 0;
561 | defaultConfigurationName = Release;
562 | };
563 | 460B27CD1D6EC7DF00E5FB1D /* Build configuration list for PBXNativeTarget "BarrageKitUITests" */ = {
564 | isa = XCConfigurationList;
565 | buildConfigurations = (
566 | 460B27CE1D6EC7DF00E5FB1D /* Debug */,
567 | 460B27CF1D6EC7DF00E5FB1D /* Release */,
568 | );
569 | defaultConfigurationIsVisible = 0;
570 | defaultConfigurationName = Release;
571 | };
572 | /* End XCConfigurationList section */
573 | };
574 | rootObject = 460B27921D6EC7DE00E5FB1D /* Project object */;
575 | }
576 |
--------------------------------------------------------------------------------