├── 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 | ![image](https://github.com/HuangGY1993/GYSpectrum/blob/master//display.gif) 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 | --------------------------------------------------------------------------------