├── display.gif
├── GYSpectrum
├── GYSpectrum
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── Recording.imageset
│ │ │ ├── Recording@2x.png
│ │ │ ├── Recording@3x.png
│ │ │ └── Contents.json
│ │ ├── Recording-default.imageset
│ │ │ ├── Recording-default@2x.png
│ │ │ ├── Recording-default@3x.png
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── AppDelegate.h
│ ├── main.m
│ ├── ViewController.h
│ ├── SpectrumView.h
│ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ ├── Info.plist
│ ├── AppDelegate.m
│ ├── SpectrumView.m
│ └── ViewController.m
└── GYSpectrum.xcodeproj
│ ├── xcuserdata
│ ├── zhangqi.xcuserdatad
│ │ ├── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ └── GYSpectrum.xcscheme
│ ├── huangguoyu.xcuserdatad
│ │ ├── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ └── GYSpectrum.xcscheme
│ └── HuangGY.xcuserdatad
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── GYSpectrum.xcscheme
│ ├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ ├── HuangGY.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ │ ├── zhangqi.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ │ └── huangguoyu.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ └── project.pbxproj
└── README.md
/display.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuangGY1993/GYSpectrum/HEAD/display.gif
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/Assets.xcassets/Recording.imageset/Recording@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuangGY1993/GYSpectrum/HEAD/GYSpectrum/GYSpectrum/Assets.xcassets/Recording.imageset/Recording@2x.png
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/Assets.xcassets/Recording.imageset/Recording@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuangGY1993/GYSpectrum/HEAD/GYSpectrum/GYSpectrum/Assets.xcassets/Recording.imageset/Recording@3x.png
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum.xcodeproj/xcuserdata/zhangqi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/Assets.xcassets/Recording-default.imageset/Recording-default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuangGY1993/GYSpectrum/HEAD/GYSpectrum/GYSpectrum/Assets.xcassets/Recording-default.imageset/Recording-default@2x.png
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/Assets.xcassets/Recording-default.imageset/Recording-default@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuangGY1993/GYSpectrum/HEAD/GYSpectrum/GYSpectrum/Assets.xcassets/Recording-default.imageset/Recording-default@3x.png
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum.xcodeproj/project.xcworkspace/xcuserdata/HuangGY.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuangGY1993/GYSpectrum/HEAD/GYSpectrum/GYSpectrum.xcodeproj/project.xcworkspace/xcuserdata/HuangGY.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum.xcodeproj/project.xcworkspace/xcuserdata/zhangqi.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuangGY1993/GYSpectrum/HEAD/GYSpectrum/GYSpectrum.xcodeproj/project.xcworkspace/xcuserdata/zhangqi.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum.xcodeproj/project.xcworkspace/xcuserdata/huangguoyu.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HuangGY1993/GYSpectrum/HEAD/GYSpectrum/GYSpectrum.xcodeproj/project.xcworkspace/xcuserdata/huangguoyu.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // GYSpectrum
4 | //
5 | // Created by 黄国裕 on 16/8/19.
6 | // Copyright © 2016年 黄国裕. 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 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // GYSpectrum
4 | //
5 | // Created by 黄国裕 on 16/8/19.
6 | // Copyright © 2016年 黄国裕. 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 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/Assets.xcassets/Recording.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "Recording@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "Recording@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // GYSpectrum
4 | //
5 | // Created by 黄国裕 on 16/8/19.
6 | // Copyright © 2016年 黄国裕. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "SpectrumView.h"
11 | #import
12 | #import
13 |
14 | @interface ViewController : UIViewController
15 |
16 | @property (nonatomic,strong) AVAudioRecorder *audioRecorder;//音频录音机
17 |
18 | @end
19 |
20 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/Assets.xcassets/Recording-default.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "Recording-default@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "Recording-default@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum.xcodeproj/xcuserdata/huangguoyu.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum.xcodeproj/xcuserdata/HuangGY.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | GYSpectrum.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 696A5A531D66E3750006AE63
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum.xcodeproj/xcuserdata/huangguoyu.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | GYSpectrum.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 696A5A531D66E3750006AE63
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum.xcodeproj/xcuserdata/zhangqi.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | GYSpectrum.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 696A5A531D66E3750006AE63
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/SpectrumView.h:
--------------------------------------------------------------------------------
1 | //
2 | // SpectrumView.h
3 | // GYSpectrum
4 | //
5 | // Created by 黄国裕 on 16/8/19.
6 | // Copyright © 2016年 黄国裕. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SpectrumView : UIView
12 |
13 | @property (nonatomic, copy) void (^itemLevelCallback)();
14 |
15 | //
16 |
17 | @property (nonatomic) NSUInteger numberOfItems;
18 |
19 | @property (nonatomic) UIColor * itemColor;
20 |
21 | @property (nonatomic) CGFloat level;
22 |
23 | @property (nonatomic) UILabel *timeLabel;
24 |
25 | @property (nonatomic) NSString *text;
26 |
27 | @property (nonatomic) CGFloat middleInterval;
28 |
29 | - (void)start;
30 | - (void)stop;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GYSpectrum
2 | ### iOS音频频谱,仿QQ录音频谱
3 |
4 |
5 | 先上效果图:
6 |
7 | 
8 |
9 |
10 | 示例用法:
11 |
12 | SpectrumView * spectrumView = [[SpectrumView alloc] initWithFrame:CGRectMake(CGRectGetMidX(self.view.frame) - 100,180,200, 40.0)];
13 | spectrumView.text = [NSString stringWithFormat:@"%d",0];
14 | __weak SpectrumView * weakWaver = spectrumView;
15 | spectrumView.itemLevelCallback = ^() {
16 |
17 | [self.audioRecorder updateMeters];
18 |
19 | //取得第一个通道的音频,音频强度范围是-160到0
20 | float power = [self.audioRecorder averagePowerForChannel:0];
21 | weakWaver.level = power;
22 |
23 | };
24 | [self.view addSubview:spectrumView];
25 |
26 |
27 | 使用前请注意:
28 |
29 | SpectrumView.frame.size.width / SpectrumView.numberOfItems >= 5
30 |
31 | 默认SpectrumView.numberOfItems = 20 (可修改,必须为偶数),所以SpectrumView.frame.size.width默认要大于100
32 | 例如:SpectrumView * spectrumView = [[SpectrumView alloc] initWithFrame:CGRectMake(0,0,100,40)];
33 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/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 | }
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/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 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/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.1
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.1
23 | LSRequiresIPhoneOS
24 |
25 | NSMicrophoneUsageDescription
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationLandscapeLeft
39 | UIInterfaceOrientationLandscapeRight
40 |
41 | UISupportedInterfaceOrientations~ipad
42 |
43 | UIInterfaceOrientationPortrait
44 | UIInterfaceOrientationPortraitUpsideDown
45 | UIInterfaceOrientationLandscapeLeft
46 | UIInterfaceOrientationLandscapeRight
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/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 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // GYSpectrum
4 | //
5 | // Created by 黄国裕 on 16/8/19.
6 | // Copyright © 2016年 黄国裕. 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 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum.xcodeproj/xcuserdata/HuangGY.xcuserdatad/xcschemes/GYSpectrum.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 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum.xcodeproj/xcuserdata/zhangqi.xcuserdatad/xcschemes/GYSpectrum.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 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum.xcodeproj/xcuserdata/huangguoyu.xcuserdatad/xcschemes/GYSpectrum.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 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/SpectrumView.m:
--------------------------------------------------------------------------------
1 | //
2 | // SpectrumView.m
3 | // GYSpectrum
4 | //
5 | // Created by 黄国裕 on 16/8/19.
6 | // Copyright © 2016年 黄国裕. All rights reserved.
7 | //
8 |
9 | #import "SpectrumView.h"
10 |
11 | @interface SpectrumView ()
12 |
13 | @property (nonatomic, strong) NSMutableArray * levels;
14 | @property (nonatomic, strong) NSMutableArray * itemLineLayers;
15 | @property (nonatomic) CGFloat itemHeight;
16 | @property (nonatomic) CGFloat itemWidth;
17 | @property (nonatomic) CGFloat lineWidth;//自适应
18 |
19 | @property (nonatomic, strong) CADisplayLink *displayLink;
20 |
21 | @end
22 |
23 | @implementation SpectrumView
24 |
25 |
26 | - (id)init {
27 | NSLog(@"init");
28 | if(self = [super init]) {
29 | [self setup];
30 | }
31 |
32 | return self;
33 | }
34 |
35 |
36 |
37 | - (id)initWithFrame:(CGRect)frame {
38 | NSLog(@"initWithFrame");
39 | if (self = [super initWithFrame:frame]) {
40 | [self setup];
41 | }
42 |
43 | return self;
44 | }
45 |
46 | - (void)awakeFromNib
47 | {
48 | [super awakeFromNib];
49 | NSLog(@"awakeFromNib");
50 | [self setup];
51 | }
52 |
53 | - (void)setup {
54 |
55 | NSLog(@"setup");
56 |
57 | self.numberOfItems = 20.f;//偶数
58 |
59 | self.itemColor = [UIColor colorWithRed:241/255.f green:60/255.f blue:57/255.f alpha:1.0];
60 |
61 | self.middleInterval = 30.f;
62 |
63 | self.timeLabel = [[UILabel alloc]init];
64 | self.timeLabel.text = @"";
65 | [self.timeLabel setTextColor:[UIColor grayColor]];
66 | [self.timeLabel setTextAlignment:NSTextAlignmentCenter];
67 | [self addSubview:self.timeLabel];
68 | }
69 |
70 | #pragma mark - layout
71 |
72 | - (void)layoutSubviews {
73 | [super layoutSubviews];
74 |
75 | self.itemHeight = CGRectGetHeight(self.bounds);
76 | self.itemWidth = CGRectGetWidth(self.bounds);
77 |
78 | [self.timeLabel sizeToFit];
79 | self.timeLabel.center = CGPointMake(self.itemWidth * 0.5f, self.itemHeight * 0.5f);
80 |
81 | self.lineWidth = (self.itemWidth - self.middleInterval) / 2.f / self.numberOfItems;
82 | }
83 |
84 | #pragma mark - setter
85 |
86 | - (void)setItemColor:(UIColor *)itemColor {
87 | _itemColor = itemColor;
88 | for (CAShapeLayer *itemLine in self.itemLineLayers) {
89 | itemLine.strokeColor = [self.itemColor CGColor];
90 | }
91 | }
92 |
93 | - (void)setNumberOfItems:(NSUInteger)numberOfItems {
94 | if (_numberOfItems == numberOfItems) {
95 | return;
96 | }
97 | _numberOfItems = numberOfItems;
98 |
99 | self.levels = [[NSMutableArray alloc]init];
100 | for(int i = 0 ; i < self.numberOfItems / 2 ; i++){
101 | [self.levels addObject:@(0)];
102 | }
103 |
104 |
105 | for (CAShapeLayer *itemLine in self.itemLineLayers) {
106 | [itemLine removeFromSuperlayer];
107 | }
108 | self.itemLineLayers = [NSMutableArray array];
109 | for(int i=0; i < numberOfItems; i++) {
110 | CAShapeLayer *itemLine = [CAShapeLayer layer];
111 | itemLine.lineCap = kCALineCapButt;
112 | itemLine.lineJoin = kCALineJoinRound;
113 | itemLine.strokeColor = [[UIColor clearColor] CGColor];
114 | itemLine.fillColor = [[UIColor clearColor] CGColor];
115 | itemLine.strokeColor = [self.itemColor CGColor];
116 | itemLine.lineWidth = self.lineWidth;
117 |
118 | [self.layer addSublayer:itemLine];
119 | [self.itemLineLayers addObject:itemLine];
120 | }
121 | }
122 |
123 | - (void)setLineWidth:(CGFloat)lineWidth {
124 | if (_lineWidth != lineWidth) {
125 | _lineWidth = lineWidth;
126 | for (CAShapeLayer *itemLine in self.itemLineLayers) {
127 | itemLine.lineWidth = lineWidth;
128 | }
129 | }
130 | }
131 |
132 | - (void)setItemLevelCallback:(void (^)())itemLevelCallback {
133 | NSLog(@"setItemLevelCallback");
134 |
135 | _itemLevelCallback = itemLevelCallback;
136 |
137 | [self start];
138 |
139 | }
140 |
141 |
142 | - (void)setLevel:(CGFloat)level {
143 | //NSLog(@"setLevel:%f",level);
144 | level = (level+37.5)*3.2;
145 | if( level < 0 ) level = 0;
146 |
147 | [self.levels removeObjectAtIndex:self.numberOfItems/2-1];
148 | [self.levels insertObject:@(level / 6.f) atIndex:0];
149 |
150 | [self updateItems];
151 |
152 | }
153 |
154 |
155 | - (void)setText:(NSString *)text{
156 | self.timeLabel.text = text;
157 | }
158 |
159 | - (void)setMiddleInterval:(CGFloat)middleInterval {
160 | if (_middleInterval != middleInterval) {
161 | _middleInterval = middleInterval;
162 | [self setNeedsLayout];
163 | }
164 | }
165 |
166 |
167 | #pragma mark - update
168 |
169 | - (void)updateItems {
170 | //NSLog(@"updateMeters");
171 |
172 | UIGraphicsBeginImageContext(self.frame.size);
173 |
174 | int lineOffset = self.lineWidth * 2.f;
175 |
176 | int leftX = (self.itemWidth - self.middleInterval + self.lineWidth) / 2.f;
177 | int rightX = (self.itemWidth + self.middleInterval - self.lineWidth) / 2.f;
178 |
179 |
180 | for(int i = 0; i < self.numberOfItems / 2; i++) {
181 |
182 | CGFloat lineHeight = self.lineWidth + [self.levels[i] floatValue] * self.lineWidth / 2.f;
183 | //([[self.levels objectAtIndex:i]intValue]+1)*self.lineWidth/2.f;
184 | CGFloat lineTop = (self.itemHeight - lineHeight) / 2.f;
185 | CGFloat lineBottom = (self.itemHeight + lineHeight) / 2.f;
186 |
187 |
188 | leftX -= lineOffset;
189 |
190 | UIBezierPath *linePathLeft = [UIBezierPath bezierPath];
191 | [linePathLeft moveToPoint:CGPointMake(leftX, lineTop)];
192 | [linePathLeft addLineToPoint:CGPointMake(leftX, lineBottom)];
193 | CAShapeLayer *itemLine2 = [self.itemLineLayers objectAtIndex:i + self.numberOfItems / 2];
194 | itemLine2.path = [linePathLeft CGPath];
195 |
196 |
197 | rightX += lineOffset;
198 |
199 | UIBezierPath *linePathRight = [UIBezierPath bezierPath];
200 | [linePathRight moveToPoint:CGPointMake(rightX, lineTop)];
201 | [linePathRight addLineToPoint:CGPointMake(rightX, lineBottom)];
202 | CAShapeLayer *itemLine = [self.itemLineLayers objectAtIndex:i];
203 | itemLine.path = [linePathRight CGPath];
204 | }
205 |
206 | UIGraphicsEndImageContext();
207 | }
208 |
209 | - (void)start {
210 | if (self.displayLink == nil) {
211 | self.displayLink = [CADisplayLink displayLinkWithTarget:_itemLevelCallback selector:@selector(invoke)];
212 | self.displayLink.frameInterval = 6.f;
213 | [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
214 | }
215 | }
216 |
217 | - (void)stop {
218 | [self.displayLink invalidate];
219 | self.displayLink = nil;
220 | }
221 |
222 |
223 | /*
224 | // Only override drawRect: if you perform custom drawing.
225 | // An empty implementation adversely affects performance during animation.
226 | - (void)drawRect:(CGRect)rect {
227 | // Drawing code
228 | }
229 | */
230 |
231 | @end
232 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // GYSpectrum
4 | //
5 | // Created by 黄国裕 on 16/8/19.
6 | // Copyright © 2016年 黄国裕. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 |
11 | @interface ViewController ()
12 |
13 | @property (strong, nonatomic) UIButton *recordButton;
14 | @property (strong, nonatomic) UILabel *tipLabel;
15 |
16 | @property (strong, nonatomic) SpectrumView *spectrumView1;
17 | @property (strong, nonatomic) SpectrumView *spectrumView2;
18 | @property (strong, nonatomic) SpectrumView *spectrumView3;
19 |
20 | @end
21 |
22 | @implementation ViewController
23 |
24 | - (void)viewDidLoad {
25 | [super viewDidLoad];
26 |
27 | __weak ViewController *weakSelf = self;
28 |
29 | //Example 1
30 | self.spectrumView1 = [[SpectrumView alloc] initWithFrame:CGRectMake(CGRectGetMidX(self.view.bounds)-50,120,100, 40.0)];
31 | self.spectrumView1.text = [NSString stringWithFormat:@"%d",0];
32 | __weak SpectrumView * weakSpectrum = self.spectrumView1;
33 | self.spectrumView1.itemLevelCallback = ^() {
34 |
35 | [weakSelf.audioRecorder updateMeters];
36 | //取得第一个通道的音频,音频强度范围是-160到0
37 | float power= [weakSelf.audioRecorder averagePowerForChannel:0];
38 | weakSpectrum.level = power;
39 | };
40 | [self.view addSubview:self.spectrumView1];
41 |
42 |
43 | //Example 2
44 | self.spectrumView2 = [[SpectrumView alloc] initWithFrame:CGRectMake(CGRectGetMidX(self.view.bounds)-100,180,200, 50.0)];
45 | self.spectrumView2.text = [NSString stringWithFormat:@"%d",0];
46 | __weak SpectrumView * weakSpectrum1 = self.spectrumView2;
47 | self.spectrumView2.itemLevelCallback = ^() {
48 |
49 | [weakSelf.audioRecorder updateMeters];
50 | //取得第一个通道的音频,音频强度范围是-160到0
51 | float power= [weakSelf.audioRecorder averagePowerForChannel:0];
52 | weakSpectrum1.level = power;
53 | };
54 | [self.view addSubview:self.spectrumView2];
55 |
56 |
57 | //Example 3
58 | self.spectrumView3 = [[SpectrumView alloc] initWithFrame:CGRectMake(CGRectGetMidX(self.view.bounds)-150,240,300, 60.0)];
59 | self.spectrumView3.text = [NSString stringWithFormat:@"%d",0];
60 | self.spectrumView3.middleInterval = 50;
61 | __weak SpectrumView * weakSpectrum2 = self.spectrumView3;
62 | self.spectrumView3.itemLevelCallback = ^() {
63 |
64 | [weakSelf.audioRecorder updateMeters];
65 | //取得第一个通道的音频,音频强度范围是-160到0
66 | float power= [weakSelf.audioRecorder averagePowerForChannel:0];
67 | weakSpectrum2.level = power;
68 | };
69 | [self.view addSubview:self.spectrumView3];
70 |
71 |
72 | [self.view addSubview:self.recordButton];
73 | [self.view addSubview:self.tipLabel];
74 | }
75 |
76 |
77 | #pragma mark - getter 懒加载
78 |
79 | - (UIButton *)recordButton {
80 | if (!_recordButton) {
81 | _recordButton = [[UIButton alloc]init];
82 |
83 | [_recordButton setBackgroundImage:[UIImage imageNamed:@"Recording-default"] forState:UIControlStateNormal];
84 | [_recordButton setBackgroundImage:[UIImage imageNamed:@"Recording"] forState:UIControlStateFocused];
85 |
86 | // 开始
87 | [_recordButton addTarget:self action:@selector(recordStart:) forControlEvents:UIControlEventTouchDown];
88 | // 取消
89 | [_recordButton addTarget:self action:@selector(recordCancel:) forControlEvents: UIControlEventTouchUpOutside];
90 | //完成
91 | [_recordButton addTarget:self action:@selector(recordFinish:) forControlEvents:UIControlEventTouchUpInside];
92 | //移出
93 | [_recordButton addTarget:self action:@selector(recordTouchDragExit:) forControlEvents:UIControlEventTouchDragExit];
94 | //移入
95 | [_recordButton addTarget:self action:@selector(recordTouchDragEnter:) forControlEvents:UIControlEventTouchDragEnter];
96 | }
97 | return _recordButton;
98 | }
99 |
100 | - (UILabel *)tipLabel {
101 | if (!_tipLabel) {
102 | _tipLabel = [[UILabel alloc]init];
103 | _tipLabel.textColor = [UIColor lightGrayColor];
104 | _tipLabel.textAlignment = NSTextAlignmentCenter;
105 | }
106 | return _tipLabel;
107 | }
108 |
109 | /**
110 | * 获得录音机对象
111 | *
112 | * @return 录音机对象
113 | */
114 | - (AVAudioRecorder *)audioRecorder {
115 | if (!_audioRecorder) {
116 | [self setAudioSession];
117 | //创建录音文件保存路径
118 | NSURL *url=[self getSavePath];
119 | //创建录音格式设置
120 | NSDictionary *setting=[self getAudioSetting];
121 | //创建录音机
122 | NSError *error=nil;
123 | _audioRecorder=[[AVAudioRecorder alloc]initWithURL:url settings:setting error:&error];
124 | _audioRecorder.delegate=self;
125 | _audioRecorder.meteringEnabled=YES;//如果要监控声波则必须设置为YES
126 | if (error) {
127 | NSLog(@"创建录音机对象时发生错误,错误信息:%@",error.localizedDescription);
128 | return nil;
129 | }
130 | }
131 | return _audioRecorder;
132 | }
133 |
134 | #pragma mark - layout
135 |
136 | - (void)viewDidLayoutSubviews {
137 | [super viewDidLayoutSubviews];
138 |
139 | CGFloat width = self.view.bounds.size.width;
140 | CGFloat height = self.view.bounds.size.height;
141 |
142 | self.recordButton.frame = CGRectMake(width / 2.f - 50.f, height - 180.f, 100.f, 100.f);
143 | self.tipLabel.frame = CGRectMake(0, height - 240, width, 30);
144 | }
145 |
146 |
147 | #pragma mark - ControlEvents
148 |
149 | - (void)recordStart:(UIButton *)button {
150 | if (![self.audioRecorder isRecording]) {
151 | NSLog(@"录音开始");
152 | [self.audioRecorder record];
153 | self.tipLabel.text = @"正在录音";
154 | [self startAnimate];
155 | }
156 | }
157 |
158 |
159 | - (void)recordCancel:(UIButton *)button {
160 |
161 | if ([self.audioRecorder isRecording]) {
162 | NSLog(@"取消");
163 | [self.audioRecorder stop];
164 | self.tipLabel.text = @"";
165 |
166 | }
167 | }
168 |
169 | - (void)recordFinish:(UIButton *)button {
170 |
171 | if ([self.audioRecorder isRecording]) {
172 | NSLog(@"完成");
173 | [self.audioRecorder stop];
174 | self.tipLabel.text = @"";
175 |
176 | }
177 |
178 | }
179 |
180 | - (void)recordTouchDragExit:(UIButton *)button {
181 | if([self.audioRecorder isRecording]) {
182 | self.tipLabel.text = @"松开取消";
183 | [self stopAnimate];
184 | }
185 | }
186 |
187 | - (void)recordTouchDragEnter:(UIButton *)button {
188 | if([self.audioRecorder isRecording]) {
189 | self.tipLabel.text = @"正在录音";
190 | [self startAnimate];
191 | }
192 | }
193 |
194 |
195 | - (void)startAnimate {
196 | [self.spectrumView1 start];
197 | //[self.spectrumView2 start];
198 | [self.spectrumView3 start];
199 | }
200 |
201 | - (void)stopAnimate {
202 | [self.spectrumView1 stop];
203 | //[self.spectrumView2 stop];
204 | [self.spectrumView3 stop];
205 | }
206 |
207 |
208 |
209 | - (void)setAudioSession {
210 | AVAudioSession *session = [AVAudioSession sharedInstance];
211 | NSError *sessionError;
212 | //AVAudioSessionCategoryPlayAndRecord用于录音和播放
213 | [session setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];
214 | if(session == nil)
215 | NSLog(@"Error creating session: %@", [sessionError description]);
216 | else
217 | [session setActive:YES error:nil];
218 | }
219 |
220 |
221 | /**
222 | * 取得录音文件设置
223 | *
224 | * @return 录音设置
225 | */
226 | - (NSDictionary *)getAudioSetting {
227 | NSMutableDictionary *dicM=[NSMutableDictionary dictionary];
228 | //设置录音格式
229 | [dicM setObject:@(kAudioFormatMPEG4AAC) forKey:AVFormatIDKey];
230 | //设置录音采样率,8000是电话采样率,对于一般录音已经够了
231 | [dicM setObject:@(8000) forKey:AVSampleRateKey];
232 | //设置通道,这里采用单声道
233 | [dicM setObject:@(1) forKey:AVNumberOfChannelsKey];
234 | //每个采样点位数,分为8、16、24、32
235 | [dicM setObject:@(8) forKey:AVLinearPCMBitDepthKey];
236 | //是否使用浮点数采样
237 | [dicM setObject:@(YES) forKey:AVLinearPCMIsFloatKey];
238 | //....其他设置等
239 | return dicM;
240 | }
241 |
242 |
243 | /**
244 | * 取得录音文件保存路径
245 | *
246 | * @return 录音文件路径
247 | */
248 | - (NSURL *)getSavePath {
249 |
250 | // 在Documents目录下创建一个名为FileData的文件夹
251 | NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"AudioData"];
252 | NSLog(@"%@",path);
253 |
254 | NSFileManager *fileManager = [NSFileManager defaultManager];
255 | BOOL isDir = FALSE;
256 | BOOL isDirExist = [fileManager fileExistsAtPath:path isDirectory:&isDir];
257 | if(!(isDirExist && isDir)) {
258 | BOOL bCreateDir = [fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
259 | if(!bCreateDir){
260 | NSLog(@"创建文件夹失败!");
261 | }
262 | NSLog(@"创建文件夹成功,文件路径%@",path);
263 | }
264 |
265 | path = [path stringByAppendingPathComponent:@"myRecord.aac"];
266 | NSLog(@"file path:%@",path);
267 | NSURL *url=[NSURL fileURLWithPath:path];
268 | return url;
269 | }
270 |
271 |
272 | - (void)didReceiveMemoryWarning {
273 | [super didReceiveMemoryWarning];
274 | // Dispose of any resources that can be recreated.
275 | }
276 |
277 | @end
278 |
--------------------------------------------------------------------------------
/GYSpectrum/GYSpectrum.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 696A5A591D66E3760006AE63 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 696A5A581D66E3760006AE63 /* main.m */; };
11 | 696A5A5C1D66E3760006AE63 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 696A5A5B1D66E3760006AE63 /* AppDelegate.m */; };
12 | 696A5A5F1D66E3760006AE63 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 696A5A5E1D66E3760006AE63 /* ViewController.m */; };
13 | 696A5A621D66E3760006AE63 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 696A5A601D66E3760006AE63 /* Main.storyboard */; };
14 | 696A5A641D66E3760006AE63 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 696A5A631D66E3760006AE63 /* Assets.xcassets */; };
15 | 696A5A671D66E3760006AE63 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 696A5A651D66E3760006AE63 /* LaunchScreen.storyboard */; };
16 | 696A5A701D66E39C0006AE63 /* SpectrumView.m in Sources */ = {isa = PBXBuildFile; fileRef = 696A5A6F1D66E39C0006AE63 /* SpectrumView.m */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXFileReference section */
20 | 696A5A541D66E3750006AE63 /* GYSpectrum.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GYSpectrum.app; sourceTree = BUILT_PRODUCTS_DIR; };
21 | 696A5A581D66E3760006AE63 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
22 | 696A5A5A1D66E3760006AE63 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
23 | 696A5A5B1D66E3760006AE63 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
24 | 696A5A5D1D66E3760006AE63 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
25 | 696A5A5E1D66E3760006AE63 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
26 | 696A5A611D66E3760006AE63 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
27 | 696A5A631D66E3760006AE63 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
28 | 696A5A661D66E3760006AE63 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
29 | 696A5A681D66E3760006AE63 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
30 | 696A5A6E1D66E39C0006AE63 /* SpectrumView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpectrumView.h; sourceTree = ""; };
31 | 696A5A6F1D66E39C0006AE63 /* SpectrumView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SpectrumView.m; sourceTree = ""; };
32 | /* End PBXFileReference section */
33 |
34 | /* Begin PBXFrameworksBuildPhase section */
35 | 696A5A511D66E3750006AE63 /* Frameworks */ = {
36 | isa = PBXFrameworksBuildPhase;
37 | buildActionMask = 2147483647;
38 | files = (
39 | );
40 | runOnlyForDeploymentPostprocessing = 0;
41 | };
42 | /* End PBXFrameworksBuildPhase section */
43 |
44 | /* Begin PBXGroup section */
45 | 696A5A4B1D66E3750006AE63 = {
46 | isa = PBXGroup;
47 | children = (
48 | 696A5A561D66E3760006AE63 /* GYSpectrum */,
49 | 696A5A551D66E3750006AE63 /* Products */,
50 | );
51 | sourceTree = "";
52 | };
53 | 696A5A551D66E3750006AE63 /* Products */ = {
54 | isa = PBXGroup;
55 | children = (
56 | 696A5A541D66E3750006AE63 /* GYSpectrum.app */,
57 | );
58 | name = Products;
59 | sourceTree = "";
60 | };
61 | 696A5A561D66E3760006AE63 /* GYSpectrum */ = {
62 | isa = PBXGroup;
63 | children = (
64 | 696A5A5A1D66E3760006AE63 /* AppDelegate.h */,
65 | 696A5A5B1D66E3760006AE63 /* AppDelegate.m */,
66 | 696A5A6E1D66E39C0006AE63 /* SpectrumView.h */,
67 | 696A5A6F1D66E39C0006AE63 /* SpectrumView.m */,
68 | 696A5A5D1D66E3760006AE63 /* ViewController.h */,
69 | 696A5A5E1D66E3760006AE63 /* ViewController.m */,
70 | 696A5A601D66E3760006AE63 /* Main.storyboard */,
71 | 696A5A631D66E3760006AE63 /* Assets.xcassets */,
72 | 696A5A651D66E3760006AE63 /* LaunchScreen.storyboard */,
73 | 696A5A681D66E3760006AE63 /* Info.plist */,
74 | 696A5A571D66E3760006AE63 /* Supporting Files */,
75 | );
76 | path = GYSpectrum;
77 | sourceTree = "";
78 | };
79 | 696A5A571D66E3760006AE63 /* Supporting Files */ = {
80 | isa = PBXGroup;
81 | children = (
82 | 696A5A581D66E3760006AE63 /* main.m */,
83 | );
84 | name = "Supporting Files";
85 | sourceTree = "";
86 | };
87 | /* End PBXGroup section */
88 |
89 | /* Begin PBXNativeTarget section */
90 | 696A5A531D66E3750006AE63 /* GYSpectrum */ = {
91 | isa = PBXNativeTarget;
92 | buildConfigurationList = 696A5A6B1D66E3760006AE63 /* Build configuration list for PBXNativeTarget "GYSpectrum" */;
93 | buildPhases = (
94 | 696A5A501D66E3750006AE63 /* Sources */,
95 | 696A5A511D66E3750006AE63 /* Frameworks */,
96 | 696A5A521D66E3750006AE63 /* Resources */,
97 | );
98 | buildRules = (
99 | );
100 | dependencies = (
101 | );
102 | name = GYSpectrum;
103 | productName = GYSpectrum;
104 | productReference = 696A5A541D66E3750006AE63 /* GYSpectrum.app */;
105 | productType = "com.apple.product-type.application";
106 | };
107 | /* End PBXNativeTarget section */
108 |
109 | /* Begin PBXProject section */
110 | 696A5A4C1D66E3750006AE63 /* Project object */ = {
111 | isa = PBXProject;
112 | attributes = {
113 | LastUpgradeCheck = 0730;
114 | ORGANIZATIONNAME = "黄国裕";
115 | TargetAttributes = {
116 | 696A5A531D66E3750006AE63 = {
117 | CreatedOnToolsVersion = 7.3;
118 | DevelopmentTeam = 8M3985953F;
119 | ProvisioningStyle = Automatic;
120 | };
121 | };
122 | };
123 | buildConfigurationList = 696A5A4F1D66E3750006AE63 /* Build configuration list for PBXProject "GYSpectrum" */;
124 | compatibilityVersion = "Xcode 3.2";
125 | developmentRegion = English;
126 | hasScannedForEncodings = 0;
127 | knownRegions = (
128 | en,
129 | Base,
130 | );
131 | mainGroup = 696A5A4B1D66E3750006AE63;
132 | productRefGroup = 696A5A551D66E3750006AE63 /* Products */;
133 | projectDirPath = "";
134 | projectRoot = "";
135 | targets = (
136 | 696A5A531D66E3750006AE63 /* GYSpectrum */,
137 | );
138 | };
139 | /* End PBXProject section */
140 |
141 | /* Begin PBXResourcesBuildPhase section */
142 | 696A5A521D66E3750006AE63 /* Resources */ = {
143 | isa = PBXResourcesBuildPhase;
144 | buildActionMask = 2147483647;
145 | files = (
146 | 696A5A671D66E3760006AE63 /* LaunchScreen.storyboard in Resources */,
147 | 696A5A641D66E3760006AE63 /* Assets.xcassets in Resources */,
148 | 696A5A621D66E3760006AE63 /* Main.storyboard in Resources */,
149 | );
150 | runOnlyForDeploymentPostprocessing = 0;
151 | };
152 | /* End PBXResourcesBuildPhase section */
153 |
154 | /* Begin PBXSourcesBuildPhase section */
155 | 696A5A501D66E3750006AE63 /* Sources */ = {
156 | isa = PBXSourcesBuildPhase;
157 | buildActionMask = 2147483647;
158 | files = (
159 | 696A5A5F1D66E3760006AE63 /* ViewController.m in Sources */,
160 | 696A5A5C1D66E3760006AE63 /* AppDelegate.m in Sources */,
161 | 696A5A591D66E3760006AE63 /* main.m in Sources */,
162 | 696A5A701D66E39C0006AE63 /* SpectrumView.m in Sources */,
163 | );
164 | runOnlyForDeploymentPostprocessing = 0;
165 | };
166 | /* End PBXSourcesBuildPhase section */
167 |
168 | /* Begin PBXVariantGroup section */
169 | 696A5A601D66E3760006AE63 /* Main.storyboard */ = {
170 | isa = PBXVariantGroup;
171 | children = (
172 | 696A5A611D66E3760006AE63 /* Base */,
173 | );
174 | name = Main.storyboard;
175 | sourceTree = "";
176 | };
177 | 696A5A651D66E3760006AE63 /* LaunchScreen.storyboard */ = {
178 | isa = PBXVariantGroup;
179 | children = (
180 | 696A5A661D66E3760006AE63 /* Base */,
181 | );
182 | name = LaunchScreen.storyboard;
183 | sourceTree = "";
184 | };
185 | /* End PBXVariantGroup section */
186 |
187 | /* Begin XCBuildConfiguration section */
188 | 696A5A691D66E3760006AE63 /* Debug */ = {
189 | isa = XCBuildConfiguration;
190 | buildSettings = {
191 | ALWAYS_SEARCH_USER_PATHS = NO;
192 | CLANG_ANALYZER_NONNULL = YES;
193 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
194 | CLANG_CXX_LIBRARY = "libc++";
195 | CLANG_ENABLE_MODULES = YES;
196 | CLANG_ENABLE_OBJC_ARC = YES;
197 | CLANG_WARN_BOOL_CONVERSION = YES;
198 | CLANG_WARN_CONSTANT_CONVERSION = YES;
199 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
200 | CLANG_WARN_EMPTY_BODY = YES;
201 | CLANG_WARN_ENUM_CONVERSION = YES;
202 | CLANG_WARN_INT_CONVERSION = YES;
203 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
204 | CLANG_WARN_UNREACHABLE_CODE = YES;
205 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
206 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
207 | COPY_PHASE_STRIP = NO;
208 | DEBUG_INFORMATION_FORMAT = dwarf;
209 | ENABLE_STRICT_OBJC_MSGSEND = YES;
210 | ENABLE_TESTABILITY = YES;
211 | GCC_C_LANGUAGE_STANDARD = gnu99;
212 | GCC_DYNAMIC_NO_PIC = NO;
213 | GCC_NO_COMMON_BLOCKS = YES;
214 | GCC_OPTIMIZATION_LEVEL = 0;
215 | GCC_PREPROCESSOR_DEFINITIONS = (
216 | "DEBUG=1",
217 | "$(inherited)",
218 | );
219 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
220 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
221 | GCC_WARN_UNDECLARED_SELECTOR = YES;
222 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
223 | GCC_WARN_UNUSED_FUNCTION = YES;
224 | GCC_WARN_UNUSED_VARIABLE = YES;
225 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
226 | MTL_ENABLE_DEBUG_INFO = YES;
227 | ONLY_ACTIVE_ARCH = YES;
228 | SDKROOT = iphoneos;
229 | TARGETED_DEVICE_FAMILY = "1,2";
230 | };
231 | name = Debug;
232 | };
233 | 696A5A6A1D66E3760006AE63 /* Release */ = {
234 | isa = XCBuildConfiguration;
235 | buildSettings = {
236 | ALWAYS_SEARCH_USER_PATHS = NO;
237 | CLANG_ANALYZER_NONNULL = YES;
238 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
239 | CLANG_CXX_LIBRARY = "libc++";
240 | CLANG_ENABLE_MODULES = YES;
241 | CLANG_ENABLE_OBJC_ARC = YES;
242 | CLANG_WARN_BOOL_CONVERSION = YES;
243 | CLANG_WARN_CONSTANT_CONVERSION = YES;
244 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
245 | CLANG_WARN_EMPTY_BODY = YES;
246 | CLANG_WARN_ENUM_CONVERSION = YES;
247 | CLANG_WARN_INT_CONVERSION = YES;
248 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
249 | CLANG_WARN_UNREACHABLE_CODE = YES;
250 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
251 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
252 | COPY_PHASE_STRIP = NO;
253 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
254 | ENABLE_NS_ASSERTIONS = NO;
255 | ENABLE_STRICT_OBJC_MSGSEND = YES;
256 | GCC_C_LANGUAGE_STANDARD = gnu99;
257 | GCC_NO_COMMON_BLOCKS = YES;
258 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
259 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
260 | GCC_WARN_UNDECLARED_SELECTOR = YES;
261 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
262 | GCC_WARN_UNUSED_FUNCTION = YES;
263 | GCC_WARN_UNUSED_VARIABLE = YES;
264 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
265 | MTL_ENABLE_DEBUG_INFO = NO;
266 | SDKROOT = iphoneos;
267 | TARGETED_DEVICE_FAMILY = "1,2";
268 | VALIDATE_PRODUCT = YES;
269 | };
270 | name = Release;
271 | };
272 | 696A5A6C1D66E3760006AE63 /* Debug */ = {
273 | isa = XCBuildConfiguration;
274 | buildSettings = {
275 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
276 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
277 | DEVELOPMENT_TEAM = 8M3985953F;
278 | INFOPLIST_FILE = GYSpectrum/Info.plist;
279 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
280 | PRODUCT_BUNDLE_IDENTIFIER = HuangGY.GYSpectrumDemo;
281 | PRODUCT_NAME = "$(TARGET_NAME)";
282 | PROVISIONING_PROFILE_SPECIFIER = "";
283 | };
284 | name = Debug;
285 | };
286 | 696A5A6D1D66E3760006AE63 /* Release */ = {
287 | isa = XCBuildConfiguration;
288 | buildSettings = {
289 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
290 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
291 | DEVELOPMENT_TEAM = 8M3985953F;
292 | INFOPLIST_FILE = GYSpectrum/Info.plist;
293 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
294 | PRODUCT_BUNDLE_IDENTIFIER = HuangGY.GYSpectrumDemo;
295 | PRODUCT_NAME = "$(TARGET_NAME)";
296 | PROVISIONING_PROFILE_SPECIFIER = "";
297 | };
298 | name = Release;
299 | };
300 | /* End XCBuildConfiguration section */
301 |
302 | /* Begin XCConfigurationList section */
303 | 696A5A4F1D66E3750006AE63 /* Build configuration list for PBXProject "GYSpectrum" */ = {
304 | isa = XCConfigurationList;
305 | buildConfigurations = (
306 | 696A5A691D66E3760006AE63 /* Debug */,
307 | 696A5A6A1D66E3760006AE63 /* Release */,
308 | );
309 | defaultConfigurationIsVisible = 0;
310 | defaultConfigurationName = Release;
311 | };
312 | 696A5A6B1D66E3760006AE63 /* Build configuration list for PBXNativeTarget "GYSpectrum" */ = {
313 | isa = XCConfigurationList;
314 | buildConfigurations = (
315 | 696A5A6C1D66E3760006AE63 /* Debug */,
316 | 696A5A6D1D66E3760006AE63 /* Release */,
317 | );
318 | defaultConfigurationIsVisible = 0;
319 | defaultConfigurationName = Release;
320 | };
321 | /* End XCConfigurationList section */
322 | };
323 | rootObject = 696A5A4C1D66E3750006AE63 /* Project object */;
324 | }
325 |
--------------------------------------------------------------------------------