├── PDLiveRoom ├── PDLiveRoom │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── test.imageset │ │ │ ├── test.jpg │ │ │ └── Contents.json │ │ ├── cell1.imageset │ │ │ ├── cell1.png │ │ │ └── Contents.json │ │ ├── cell2.imageset │ │ │ ├── cell2.png │ │ │ └── Contents.json │ │ ├── cell3.imageset │ │ │ ├── cell3.png │ │ │ └── Contents.json │ │ ├── click.imageset │ │ │ ├── click.png │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── PDChatModel.m │ ├── PDBaseViewController.h │ ├── PDLiveRoomViewController.h │ ├── PDEmitterView.h │ ├── UIColorExt.h │ ├── PDLiveAppDelegate.h │ ├── PDChatModel.h │ ├── main.m │ ├── PDChatTableViewCell.h │ ├── NSAttributeString+Extent.h │ ├── PDBaseViewController.m │ ├── PrefixHeader.pch │ ├── PDBlurImageEffects.h │ ├── Header.h │ ├── PDTableViewDataSource.h │ ├── NSAttributeString+Extent.m │ ├── Info.plist │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ ├── UIColorExt.m │ ├── PDLiveAppDelegate.m │ ├── PDChatTableViewCell.m │ ├── PDTableViewDataSource.m │ ├── PDEmitterView.m │ ├── PDLiveRoomViewController.m │ └── PDBlurImageEffects.m └── PDLiveRoom.xcodeproj │ ├── xcuserdata │ └── pengdong.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ └── PDLiveRoom.xcscheme │ ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── pengdong.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ └── project.pbxproj └── README.md /PDLiveRoom/PDLiveRoom/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/Assets.xcassets/test.imageset/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdcodeunder/PDLiveRoom/HEAD/PDLiveRoom/PDLiveRoom/Assets.xcassets/test.imageset/test.jpg -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/Assets.xcassets/cell1.imageset/cell1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdcodeunder/PDLiveRoom/HEAD/PDLiveRoom/PDLiveRoom/Assets.xcassets/cell1.imageset/cell1.png -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/Assets.xcassets/cell2.imageset/cell2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdcodeunder/PDLiveRoom/HEAD/PDLiveRoom/PDLiveRoom/Assets.xcassets/cell2.imageset/cell2.png -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/Assets.xcassets/cell3.imageset/cell3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdcodeunder/PDLiveRoom/HEAD/PDLiveRoom/PDLiveRoom/Assets.xcassets/cell3.imageset/cell3.png -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/Assets.xcassets/click.imageset/click.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdcodeunder/PDLiveRoom/HEAD/PDLiveRoom/PDLiveRoom/Assets.xcassets/click.imageset/click.png -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom.xcodeproj/xcuserdata/pengdong.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/PDChatModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // PDChatModel.m 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import "PDChatModel.h" 10 | 11 | @implementation PDChatModel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom.xcodeproj/project.xcworkspace/xcuserdata/pengdong.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pdcodeunder/PDLiveRoom/HEAD/PDLiveRoom/PDLiveRoom.xcodeproj/project.xcworkspace/xcuserdata/pengdong.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/PDBaseViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PDBaseViewController.h 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PDBaseViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/PDLiveRoomViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PDLiveRoomViewController.h 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import "PDBaseViewController.h" 10 | 11 | @interface PDLiveRoomViewController : PDBaseViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/PDEmitterView.h: -------------------------------------------------------------------------------- 1 | // 2 | // PDEmitterView.h 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PDEmitterView : UIView 12 | 13 | /** 14 | * 发射 15 | */ 16 | - (void)sendUpEmitter; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/UIColorExt.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColorExt.h 3 | // ElectricCarRent 4 | // 5 | // Created by 彭懂 on 16/3/31. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIColor (UIColorExt) 12 | 13 | + (UIColor *)colorWithHexString: (NSString *)color; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/PDLiveAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PDLiveAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/PDChatModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // PDChatModel.h 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PDChatModel : NSObject 12 | 13 | @property (nonatomic, copy) NSString *nickName; 14 | @property (nonatomic, copy) NSString *chatText; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "PDLiveAppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([PDLiveAppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PDLiveRoom 2 | 有人问我现在直播APP很火,动态的评论和点赞效果怎么做的。趁着最近有点时间就写了个demo供大家参考: 3 | 4 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/Assets.xcassets/test.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "test.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/Assets.xcassets/cell1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "cell1.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/Assets.xcassets/cell2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "cell2.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/Assets.xcassets/cell3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "cell3.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/Assets.xcassets/click.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "click.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/PDChatTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // PDChatTableViewCell.h 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PDChatTableViewCell : UITableViewCell 12 | 13 | + (instancetype)createChatTableViewCellWithTableView:(UITableView *)tableView; 14 | 15 | - (void)setCellAttributTitle:(NSAttributedString *)str; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/NSAttributeString+Extent.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSAttributeString+Extent.h 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSAttributedString (NSAttributeString_Extent) 12 | 13 | + (NSAttributedString *)attributedStringWithStr:(NSString *)string anotherString:(NSString *)anotherStr andColor:(UIColor *)color; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/PDBaseViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // PDBaseViewController.m 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import "PDBaseViewController.h" 10 | 11 | @interface PDBaseViewController () 12 | 13 | @end 14 | 15 | @implementation PDBaseViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | self.view.backgroundColor = [UIColor whiteColor]; 20 | 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/PrefixHeader.pch: -------------------------------------------------------------------------------- 1 | // 2 | // PrefixHeader.pch 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #ifndef PrefixHeader_pch 10 | #define PrefixHeader_pch 11 | 12 | // Include any system framework and library headers here that should be included in all compilation units. 13 | // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file. 14 | 15 | #import "Header.h" 16 | 17 | #endif /* PrefixHeader_pch */ 18 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom.xcodeproj/xcuserdata/pengdong.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PDLiveRoom.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | E75336411D7E714A004E0C90 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/PDBlurImageEffects.h: -------------------------------------------------------------------------------- 1 | // 2 | // PDBlurImageEffects.h 3 | // PDBlurImage 4 | // 5 | // Created by 彭懂 on 16/9/5. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface PDBlurImageEffects : NSObject 13 | 14 | /** 15 | * 不同效果的图片输出 16 | */ 17 | + (UIImage *)pd_imageEffectLightFromImage:(UIImage *)inputImage; 18 | + (UIImage *)pd_imageEffectExtraLightFromImage:(UIImage *)inputImage; 19 | + (UIImage *)pd_imageEffectDarkFromImage:(UIImage *)inputImage; 20 | + (UIImage *)pd_imageEffectTintFromImage:(UIImage *)inputImage andEffectColor:(UIColor *)tintColor; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Header.h 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #ifndef Header_h 10 | #define Header_h 11 | 12 | #import "UIColorExt.h" 13 | 14 | #define ColorWithHex(Hex) [UIColor colorWithHexString:Hex] 15 | 16 | #define kCColorZuHe @[ \ 17 | ColorWithHex(@"#ff4646"), \ 18 | ColorWithHex(@"#008aff"), \ 19 | ColorWithHex(@"#00dcd4"), \ 20 | ColorWithHex(@"#ffb900"), \ 21 | ColorWithHex(@"#ff5a23"), \ 22 | ColorWithHex(@"#ff66cc"), \ 23 | ColorWithHex(@"#33cc33"), \ 24 | ColorWithHex(@"#cc6633"), \ 25 | ColorWithHex(@"#9933cc"), \ 26 | ColorWithHex(@"#990000"), \ 27 | ]; 28 | 29 | #endif /* Header_h */ 30 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/PDTableViewDataSource.h: -------------------------------------------------------------------------------- 1 | // 2 | // PDTableViewModel.h 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | typedef UITableViewCell *(^PDTableViewCellBlock)(UIColor *color, id model); 13 | @interface PDTableViewDataSource : NSObject 14 | 15 | /** 16 | * 设置数据源 17 | */ 18 | @property (nonatomic, strong) NSMutableArray *dataSourceArr; 19 | 20 | /** 21 | * 设置cell配置block 22 | */ 23 | @property (nonatomic, copy) PDTableViewCellBlock tableViewCell; 24 | 25 | /** 26 | * 设置是否是按组还是row yes : row no : section 默认是yes 27 | */ 28 | @property (nonatomic, assign) BOOL isRow; 29 | 30 | /** 31 | * 设置tableviewcell的高度 32 | */ 33 | @property (nonatomic, assign) CGFloat rowHeight; 34 | 35 | /** 36 | * 设置tableview头部view 默认无 37 | */ 38 | @property (nonatomic, strong) UIView *headView; 39 | 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/NSAttributeString+Extent.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSAttributeString+Extent.m 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import "NSAttributeString+Extent.h" 10 | 11 | @implementation NSAttributedString (NSAttributeString_Extent) 12 | 13 | + (NSAttributedString *)attributedStringWithStr:(NSString *)string anotherString:(NSString *)anotherStr andColor:(UIColor *)color 14 | { 15 | NSString *Str = [NSString stringWithFormat:@"%@ %@", string, anotherStr]; 16 | NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:Str]; 17 | [attributedStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:14.0] range:NSMakeRange(0, Str.length)]; 18 | [attributedStr addAttribute:NSForegroundColorAttributeName value:color range:NSMakeRange(0, string.length)]; 19 | [attributedStr addAttribute:NSForegroundColorAttributeName value:[UIColor grayColor] range:NSMakeRange(Str.length - anotherStr.length, anotherStr.length)]; 20 | return attributedStr; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/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 | } -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/UIColorExt.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColorExt.m 3 | // ElectricCarRent 4 | // 5 | // Created by 彭懂 on 16/3/31. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import "UIColorExt.h" 10 | 11 | @implementation UIColor (UIColorExt) 12 | 13 | + (UIColor *) colorWithHexString: (NSString *)color 14 | { 15 | NSString *cString = [[color stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString]; 16 | 17 | // String should be 6 or 8 characters 18 | if ([cString length] < 6) { 19 | return [UIColor clearColor]; 20 | } 21 | 22 | // strip 0X if it appears 23 | if ([cString hasPrefix:@"0X"]) 24 | cString = [cString substringFromIndex:2]; 25 | if ([cString hasPrefix:@"#"]) 26 | cString = [cString substringFromIndex:1]; 27 | if ([cString length] != 6) 28 | return [UIColor clearColor]; 29 | 30 | // Separate into r, g, b substrings 31 | NSRange range; 32 | range.location = 0; 33 | range.length = 2; 34 | 35 | //r 36 | NSString *rString = [cString substringWithRange:range]; 37 | 38 | //g 39 | range.location = 2; 40 | NSString *gString = [cString substringWithRange:range]; 41 | 42 | //b 43 | range.location = 4; 44 | NSString *bString = [cString substringWithRange:range]; 45 | 46 | // Scan values 47 | unsigned int r, g, b; 48 | [[NSScanner scannerWithString:rString] scanHexInt:&r]; 49 | [[NSScanner scannerWithString:gString] scanHexInt:&g]; 50 | [[NSScanner scannerWithString:bString] scanHexInt:&b]; 51 | 52 | return [UIColor colorWithRed:((float) r / 255.0f) green:((float) g / 255.0f) blue:((float) b / 255.0f) alpha:1.0f]; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/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 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/PDLiveAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import "PDLiveAppDelegate.h" 10 | 11 | @interface PDLiveAppDelegate () 12 | 13 | @end 14 | 15 | @implementation PDLiveAppDelegate 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 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/PDChatTableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // PDChatTableViewCell.m 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import "PDChatTableViewCell.h" 10 | 11 | @interface PDChatTableViewCell () 12 | 13 | /** 14 | * 此处可以用lable直接使用 15 | */ 16 | @property (nonatomic, strong) UIView *mainView; 17 | 18 | @end 19 | 20 | @implementation PDChatTableViewCell 21 | 22 | + (instancetype)createChatTableViewCellWithTableView:(UITableView *)tableView 23 | { 24 | PDChatTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"PDChatTableViewCell"]; 25 | if (!cell) { 26 | cell = [[PDChatTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"PDChatTableViewCell"]; 27 | } 28 | return cell; 29 | } 30 | 31 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 32 | { 33 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 34 | if (self) { 35 | self.backgroundColor = [UIColor clearColor]; 36 | self.contentView.backgroundColor = [UIColor clearColor]; 37 | self.selectionStyle = UITableViewCellSelectionStyleNone; 38 | 39 | self.textLabel.font = [UIFont systemFontOfSize:14.0]; 40 | self.textLabel.transform = CGAffineTransformMakeScale(1, -1); 41 | [self setUpCellUI]; 42 | } 43 | return self; 44 | } 45 | 46 | - (void)setUpCellUI { 47 | UIView *cornerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)]; 48 | cornerView.backgroundColor = [UIColor whiteColor]; 49 | cornerView.layer.cornerRadius = 3.0; 50 | cornerView.layer.masksToBounds = YES; 51 | [self.contentView insertSubview:cornerView belowSubview:self.textLabel]; 52 | self.mainView = cornerView; 53 | } 54 | 55 | - (void)setCellAttributTitle:(NSAttributedString *)str 56 | { 57 | // 这里就不考虑多行的情况了,可以根据具体需求具体对待 58 | self.textLabel.attributedText = str; 59 | CGRect rect = [str.string boundingRectWithSize:CGSizeMake(0, 18) options: NSStringDrawingTruncatesLastVisibleLine attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14.0]} context:nil]; 60 | self.mainView.frame = CGRectMake(0, 0, 30 + rect.size.width, 30); 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/PDTableViewDataSource.m: -------------------------------------------------------------------------------- 1 | // 2 | // PDTableViewModel.m 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import "PDTableViewDataSource.h" 10 | #import "PDChatModel.h" 11 | 12 | @interface PDTableViewDataSource () 13 | 14 | @property (nonatomic, strong) NSMutableDictionary *nickColorDic; 15 | 16 | @end 17 | 18 | @implementation PDTableViewDataSource 19 | 20 | - (instancetype)init 21 | { 22 | self = [super init]; 23 | if (self) { 24 | self.isRow = YES; 25 | self.dataSourceArr = [[NSMutableArray alloc] init]; 26 | self.nickColorDic = [[NSMutableDictionary alloc] init]; 27 | } 28 | return self; 29 | } 30 | 31 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableVie 32 | { 33 | if (self.isRow) { 34 | return 1; 35 | } else { 36 | return self.dataSourceArr.count; 37 | } 38 | } 39 | 40 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 41 | { 42 | if (self.isRow) { 43 | return self.dataSourceArr.count; 44 | } else { 45 | return 1; 46 | } 47 | } 48 | 49 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 50 | { 51 | return self.rowHeight; 52 | } 53 | 54 | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 55 | { 56 | if (self.headView) { 57 | return self.headView; 58 | } 59 | return nil; 60 | } 61 | 62 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 63 | { 64 | PDChatModel *model = self.dataSourceArr[indexPath.section]; 65 | UITableViewCell *cell = nil; 66 | if (self.tableViewCell) { 67 | UIColor *color = self.nickColorDic[model.nickName]; 68 | if (!color) { 69 | NSArray *colors = kCColorZuHe; 70 | color = (UIColor *)colors[arc4random() % 10]; 71 | [self.nickColorDic setObject:color forKey:model.nickName]; 72 | } 73 | cell = self.tableViewCell(color, model); 74 | } else { 75 | cell = [[UITableViewCell alloc] init]; 76 | } 77 | return cell; 78 | } 79 | 80 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 81 | { 82 | if (self.headView) { 83 | return self.headView.bounds.size.height; 84 | } 85 | return 0; 86 | } 87 | 88 | - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section 89 | { 90 | return 5.0; 91 | } 92 | 93 | - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section 94 | { 95 | return [[UIView alloc] init]; 96 | } 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom.xcodeproj/xcuserdata/pengdong.xcuserdatad/xcschemes/PDLiveRoom.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 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/PDEmitterView.m: -------------------------------------------------------------------------------- 1 | // 2 | // PDEmitterView.m 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import "PDEmitterView.h" 10 | 11 | @interface PDEmitterView () 12 | 13 | @property (nonatomic, strong) NSMutableArray *keepArray; 14 | @property (nonatomic, strong) NSMutableArray *deletArray; 15 | @property (nonatomic, assign) NSInteger zanCount; 16 | 17 | @end 18 | 19 | @implementation PDEmitterView 20 | 21 | // 采用tableview的回收机制 22 | - (NSMutableArray *)keepArray 23 | { 24 | if (!_keepArray) { 25 | _keepArray = [[NSMutableArray alloc] init]; 26 | } 27 | return _keepArray; 28 | } 29 | 30 | - (NSMutableArray *)deletArray 31 | { 32 | if (!_deletArray) { 33 | _deletArray = [[NSMutableArray alloc] init]; 34 | } 35 | return _deletArray; 36 | } 37 | 38 | - (instancetype)initWithFrame:(CGRect)frame 39 | { 40 | self = [super initWithFrame:frame]; 41 | if (self) { 42 | self.zanCount = 0; 43 | } 44 | return self; 45 | } 46 | 47 | - (void)sendUpEmitter 48 | { 49 | _zanCount ++; 50 | if (_zanCount == INT_MAX) { 51 | _zanCount = 0; 52 | } 53 | CALayer *shipLabyer = nil; 54 | if (self.deletArray.count > 0) { 55 | shipLabyer = [self.deletArray firstObject]; 56 | [self.deletArray removeObject:shipLabyer]; 57 | } else { 58 | shipLabyer = [CALayer layer]; 59 | shipLabyer.contents = (__bridge id _Nullable)([UIImage imageNamed:[NSString stringWithFormat:@"cell%zd", arc4random() % 3 + 1]].CGImage); 60 | shipLabyer.contentsScale = [UIScreen mainScreen].scale; 61 | shipLabyer.frame = CGRectMake(self.bounds.size.width / 2.0, self.bounds.size.height, 40, 40); 62 | shipLabyer.transform = CATransform3DMakeRotation(M_PI_2, 0, 0, 1); 63 | } 64 | shipLabyer.opacity = 1.0; 65 | [self.layer addSublayer:shipLabyer]; 66 | [self.keepArray addObject:shipLabyer]; 67 | 68 | [self animationKeyFrameWithLayer:shipLabyer]; 69 | } 70 | 71 | - (void)animationKeyFrameWithLayer:(CALayer *)layer 72 | { 73 | NSInteger with = self.bounds.size.width; 74 | NSInteger height = self.bounds.size.height; 75 | UIBezierPath *path = [UIBezierPath bezierPath]; 76 | [path moveToPoint:CGPointMake(self.bounds.size.width / 2.0, self.bounds.size.height)]; 77 | [path addCurveToPoint:CGPointMake(arc4random() % with, 0) controlPoint1:CGPointMake((arc4random() % with) / 2.0, (arc4random() % height) / 2.0) controlPoint2:CGPointMake((with / 2.0) + (arc4random() % with) / 2.0, height / 2.0 + (arc4random() % height) / 2.0)]; 78 | 79 | CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 80 | animation.duration = 1.2 + (arc4random() % 9) / 10.0; 81 | animation.rotationMode = kCAAnimationRotateAuto; 82 | animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 83 | animation.path = path.CGPath; 84 | animation.fillMode = kCAFillModeForwards; 85 | 86 | // 缩放 87 | CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 88 | scaleAnimation.fromValue = [NSNumber numberWithFloat:1.1]; 89 | scaleAnimation.toValue = [NSNumber numberWithFloat:0.7]; 90 | scaleAnimation.duration = 1 + (arc4random() % 10) / 10.0; 91 | 92 | CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 93 | alphaAnimation.fromValue = @(1.0); 94 | alphaAnimation.toValue = @(0); 95 | alphaAnimation.duration = animation.duration; 96 | alphaAnimation.fillMode = kCAFillModeForwards; 97 | 98 | CAAnimationGroup *animationGroup = [CAAnimationGroup animation]; 99 | animationGroup.repeatCount = 1; 100 | animationGroup.removedOnCompletion = NO; 101 | animationGroup.duration = animation.duration; 102 | animationGroup.fillMode = kCAFillModeForwards; 103 | animationGroup.animations = @[animation, scaleAnimation, alphaAnimation]; 104 | animationGroup.delegate = self; 105 | [layer addAnimation:animationGroup forKey:[NSString stringWithFormat:@"animation%zd", _zanCount]]; 106 | } 107 | 108 | - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag 109 | { 110 | CALayer *layer = [self.keepArray firstObject]; 111 | [layer removeAllAnimations]; 112 | [self.deletArray addObject:layer]; 113 | [layer removeFromSuperlayer]; 114 | [self.keepArray removeObject:layer]; 115 | } 116 | 117 | @end 118 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/PDLiveRoomViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // PDLiveRoomViewController.m 3 | // PDLiveRoom 4 | // 5 | // Created by 彭懂 on 16/9/6. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import "PDLiveRoomViewController.h" 10 | #import "PDBlurImageEffects.h" 11 | #import "PDTableViewDataSource.h" 12 | #import "PDChatModel.h" 13 | #import "PDChatTableViewCell.h" 14 | #import "NSAttributeString+Extent.h" 15 | #import "PDEmitterView.h" 16 | 17 | static const NSInteger maxCell = 7; 18 | @interface PDLiveRoomViewController () 19 | 20 | @property (nonatomic, strong) PDTableViewDataSource *dataSource; 21 | @property (nonatomic, strong) NSMutableArray *nickArr; 22 | @property (nonatomic, strong) NSMutableArray *textArr; 23 | @property (nonatomic, strong) UITableView *tableView; 24 | @property (nonatomic, strong) PDEmitterView *emitterView; 25 | 26 | @end 27 | 28 | @implementation PDLiveRoomViewController 29 | 30 | - (PDTableViewDataSource *)dataSource 31 | { 32 | if (!_dataSource) { 33 | _dataSource = [[PDTableViewDataSource alloc] init]; 34 | _dataSource.isRow = NO; 35 | } 36 | return _dataSource; 37 | } 38 | 39 | - (NSMutableArray *)nickArr 40 | { 41 | if (!_nickArr) { 42 | _nickArr = [[NSMutableArray alloc] init]; 43 | } 44 | return _nickArr; 45 | } 46 | 47 | - (NSMutableArray *)textArr 48 | { 49 | if (!_textArr) { 50 | _textArr = [[NSMutableArray alloc] init]; 51 | } 52 | return _textArr; 53 | } 54 | 55 | - (void)viewDidLoad { 56 | [super viewDidLoad]; 57 | [self setUpUI]; 58 | } 59 | 60 | - (void)setUpUI { 61 | UIImageView *backImage = [[UIImageView alloc] initWithImage:[PDBlurImageEffects pd_imageEffectLightFromImage:[UIImage imageNamed:@"test"]]]; 62 | backImage.frame = self.view.bounds; 63 | [self.view addSubview:backImage]; 64 | [self createTableView]; 65 | 66 | [self setUpDataSource]; 67 | } 68 | 69 | - (void)createTableView { 70 | UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(10, 100, 200, 667 - 100 - 60) style:UITableViewStylePlain]; 71 | tableView.showsVerticalScrollIndicator = NO; 72 | tableView.showsHorizontalScrollIndicator = NO; 73 | tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 74 | tableView.backgroundView = [[UIView alloc] init]; 75 | tableView.backgroundColor = [UIColor clearColor]; 76 | tableView.dataSource = self.dataSource; 77 | tableView.delegate = self.dataSource; 78 | self.dataSource.rowHeight = 30; 79 | [self.view addSubview:tableView]; 80 | tableView.transform = CGAffineTransformMakeScale(1, -1); 81 | self.tableView = tableView; 82 | 83 | [self tableViewConfig]; 84 | 85 | [self setUpEmitterView]; 86 | } 87 | 88 | - (void)tableViewConfig { 89 | __block PDLiveRoomViewController *blockSelf = self; 90 | self.dataSource.tableViewCell = ^UITableViewCell *(UIColor *color, id model) { 91 | PDChatTableViewCell *cell = [PDChatTableViewCell createChatTableViewCellWithTableView:blockSelf.tableView]; 92 | PDChatModel *chatModel = model; 93 | [cell setCellAttributTitle:[NSAttributedString attributedStringWithStr:chatModel.nickName anotherString:chatModel.chatText andColor:color]]; 94 | return cell; 95 | }; 96 | } 97 | 98 | /** 99 | * 设置点赞 100 | */ 101 | - (void)setUpEmitterView { 102 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 103 | btn.frame = CGRectMake(300, 667.0 - 75, 40, 40); 104 | [btn setImage:[UIImage imageNamed:@"click"] forState:UIControlStateNormal]; 105 | [btn addTarget:self action:@selector(emitterClicked:) forControlEvents:UIControlEventTouchUpInside]; 106 | [self.view addSubview:btn]; 107 | 108 | PDEmitterView *emitterVeiw = [[PDEmitterView alloc] initWithFrame:CGRectMake(300, 667.0 - 60 - 400, 60, 400)]; 109 | [self.view addSubview:emitterVeiw]; 110 | self.emitterView = emitterVeiw; 111 | } 112 | 113 | - (void)emitterClicked:(UIButton *)sender 114 | { 115 | [self.emitterView sendUpEmitter]; 116 | } 117 | 118 | /** 119 | * 造点假数据 120 | */ 121 | - (void)setUpDataSource 122 | { 123 | for (NSInteger i = 0; i < 6; i++) { 124 | NSString *nick = [NSString stringWithFormat:@"用户%zd", i]; 125 | NSMutableString *text = [[NSMutableString alloc] initWithString:@"哈"]; 126 | for (NSInteger j = 0; j <= i; j++) { 127 | [text appendFormat:@"哈"]; 128 | } 129 | [text appendFormat:@"%zd", i]; 130 | [self.nickArr addObject:nick]; 131 | [self.textArr addObject:text]; 132 | } 133 | [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(sendMessage) userInfo:nil repeats:YES]; 134 | } 135 | 136 | NSInteger number = 0; 137 | - (void)sendMessage 138 | { 139 | NSString *nick = self.nickArr[arc4random() % 6]; 140 | NSString *text = self.textArr[arc4random() % 6]; 141 | PDChatModel *model = [[PDChatModel alloc] init]; 142 | model.nickName = nick; 143 | model.chatText = text; 144 | [self.dataSource.dataSourceArr insertObject:model atIndex:0]; 145 | [self.tableView insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationTop]; 146 | if (self.dataSource.dataSourceArr.count > maxCell) { 147 | [self.dataSource.dataSourceArr removeLastObject]; 148 | [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:self.dataSource.dataSourceArr.count] withRowAnimation:UITableViewRowAnimationNone]; 149 | } 150 | // 自动发赞 151 | if (number % 2 == 0) { 152 | // [self.emitterView sendUpEmitter]; 153 | } 154 | number ++; 155 | } 156 | 157 | @end 158 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom/PDBlurImageEffects.m: -------------------------------------------------------------------------------- 1 | // 2 | // PDBlurImageEffects.m 3 | // PDBlurImage 4 | // 5 | // Created by 彭懂 on 16/9/5. 6 | // Copyright © 2016年 彭懂. All rights reserved. 7 | // 8 | 9 | #import "PDBlurImageEffects.h" 10 | @import Accelerate; 11 | 12 | @implementation PDBlurImageEffects 13 | 14 | + (UIImage *)pd_imageEffectLightFromImage:(UIImage *)inputImage 15 | { 16 | UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0.3]; 17 | return [self pd_imageToImage:inputImage withRadius:60 tintColor:tintColor saturationDeltaFactor:1.8]; 18 | } 19 | 20 | + (UIImage *)pd_imageEffectExtraLightFromImage:(UIImage *)inputImage 21 | { 22 | UIColor *tintColor = [UIColor colorWithWhite:0.97 alpha:0.82]; 23 | return [self pd_imageToImage:inputImage withRadius:40 tintColor:tintColor saturationDeltaFactor:1.8]; 24 | } 25 | 26 | + (UIImage *)pd_imageEffectDarkFromImage:(UIImage *)inputImage 27 | { 28 | UIColor *tintColor = [UIColor colorWithWhite:0.11 alpha:0.73]; 29 | return [self pd_imageToImage:inputImage withRadius:40 tintColor:tintColor saturationDeltaFactor:1.8]; 30 | } 31 | 32 | + (UIImage *)pd_imageEffectTintFromImage:(UIImage *)inputImage andEffectColor:(UIColor *)tintColor 33 | { 34 | const CGFloat colorAlpha = 0.6; 35 | UIColor *effectColor = tintColor; 36 | size_t componentCount = CGColorGetNumberOfComponents(tintColor.CGColor); 37 | if (componentCount == 2) { 38 | CGFloat b; 39 | if ([tintColor getWhite:&b alpha:NULL]) { 40 | effectColor = [UIColor colorWithWhite:b alpha:colorAlpha]; 41 | } 42 | } else { 43 | CGFloat r, g, b; 44 | if ([tintColor getRed:&r green:&g blue:&b alpha:NULL]) { 45 | effectColor = [UIColor colorWithRed:r green:g blue:b alpha:colorAlpha]; 46 | } 47 | } 48 | return [self pd_imageToImage:inputImage withRadius:20 tintColor:effectColor saturationDeltaFactor:-1]; 49 | } 50 | 51 | #pragma mark - 实现方法 52 | + (UIImage *)pd_imageToImage:(UIImage*)inputImage withRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor 53 | { 54 | #define ENABLE_BLUR 1 55 | #define ENABLE_SATURATION_ADJUSTMENT 1 56 | #define ENABLE_TINT 1 57 | if (inputImage.size.width < 1 || inputImage.size.height < 1) 58 | { 59 | return nil; 60 | } 61 | if (!inputImage.CGImage) 62 | { 63 | return nil; 64 | } 65 | 66 | BOOL hasBlur = blurRadius > __FLT_EPSILON__; 67 | BOOL hasSaturationChange = fabs(saturationDeltaFactor - 1.) > __FLT_EPSILON__; 68 | 69 | CGImageRef inputCGImage = inputImage.CGImage; 70 | CGFloat inputImageScale = inputImage.scale; 71 | CGBitmapInfo inputImageBitmapInfo = CGImageGetBitmapInfo(inputCGImage); 72 | CGImageAlphaInfo inputImageAlphaInfo = (inputImageBitmapInfo & kCGBitmapAlphaInfoMask); 73 | 74 | CGSize outputImageSizeInPoints = inputImage.size; 75 | CGRect outputImageRectInPoints = { CGPointZero, outputImageSizeInPoints }; 76 | 77 | BOOL useOpaqueContext; 78 | if (inputImageAlphaInfo == kCGImageAlphaNone || inputImageAlphaInfo == kCGImageAlphaNoneSkipLast || inputImageAlphaInfo == kCGImageAlphaNoneSkipFirst) 79 | useOpaqueContext = YES; 80 | else 81 | useOpaqueContext = NO; 82 | UIGraphicsBeginImageContextWithOptions(outputImageRectInPoints.size, useOpaqueContext, inputImageScale); 83 | CGContextRef outputContext = UIGraphicsGetCurrentContext(); 84 | CGContextScaleCTM(outputContext, 1.0, -1.0); 85 | CGContextTranslateCTM(outputContext, 0, -outputImageRectInPoints.size.height); 86 | 87 | if (hasBlur || hasSaturationChange) 88 | { 89 | vImage_Buffer effectInBuffer; 90 | vImage_Buffer scratchBuffer1; 91 | 92 | vImage_Buffer *inputBuffer; 93 | vImage_Buffer *outputBuffer; 94 | 95 | vImage_CGImageFormat format = { 96 | .bitsPerComponent = 8, 97 | .bitsPerPixel = 32, 98 | .colorSpace = NULL, 99 | .bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little, 100 | .version = 0, 101 | .decode = NULL, 102 | .renderingIntent = kCGRenderingIntentDefault 103 | }; 104 | 105 | vImage_Error e = vImageBuffer_InitWithCGImage(&effectInBuffer, &format, NULL, inputImage.CGImage, kvImagePrintDiagnosticsToConsole); 106 | if (e != kvImageNoError) 107 | { 108 | UIGraphicsEndImageContext(); 109 | return nil; 110 | } 111 | 112 | vImageBuffer_Init(&scratchBuffer1, effectInBuffer.height, effectInBuffer.width, format.bitsPerPixel, kvImageNoFlags); 113 | inputBuffer = &effectInBuffer; 114 | outputBuffer = &scratchBuffer1; 115 | #if ENABLE_BLUR 116 | if (hasBlur) 117 | { 118 | CGFloat inputRadius = blurRadius * inputImageScale; 119 | if (inputRadius - 2. < __FLT_EPSILON__) 120 | inputRadius = 2.; 121 | uint32_t radius = floor((inputRadius * 3. * sqrt(2 * M_PI) / 4 + 0.5) / 2); 122 | 123 | radius |= 1; // force radius to be odd so that the three box-blur methodology works. 124 | 125 | NSInteger tempBufferSize = vImageBoxConvolve_ARGB8888(inputBuffer, outputBuffer, NULL, 0, 0, radius, radius, NULL, kvImageGetTempBufferSize | kvImageEdgeExtend); 126 | void *tempBuffer = malloc(tempBufferSize); 127 | 128 | vImageBoxConvolve_ARGB8888(inputBuffer, outputBuffer, tempBuffer, 0, 0, radius, radius, NULL, kvImageEdgeExtend); 129 | vImageBoxConvolve_ARGB8888(outputBuffer, inputBuffer, tempBuffer, 0, 0, radius, radius, NULL, kvImageEdgeExtend); 130 | vImageBoxConvolve_ARGB8888(inputBuffer, outputBuffer, tempBuffer, 0, 0, radius, radius, NULL, kvImageEdgeExtend); 131 | 132 | free(tempBuffer); 133 | 134 | vImage_Buffer *temp = inputBuffer; 135 | inputBuffer = outputBuffer; 136 | outputBuffer = temp; 137 | } 138 | #endif 139 | 140 | #if ENABLE_SATURATION_ADJUSTMENT 141 | if (hasSaturationChange) 142 | { 143 | CGFloat s = saturationDeltaFactor; 144 | CGFloat floatingPointSaturationMatrix[] = { 145 | 0.0722 + 0.9278 * s, 0.0722 - 0.0722 * s, 0.0722 - 0.0722 * s, 0, 146 | 0.7152 - 0.7152 * s, 0.7152 + 0.2848 * s, 0.7152 - 0.7152 * s, 0, 147 | 0.2126 - 0.2126 * s, 0.2126 - 0.2126 * s, 0.2126 + 0.7873 * s, 0, 148 | 0, 0, 0, 1, 149 | }; 150 | const int32_t divisor = 256; 151 | NSUInteger matrixSize = sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[0]); 152 | int16_t saturationMatrix[matrixSize]; 153 | for (NSUInteger i = 0; i < matrixSize; ++i) { 154 | saturationMatrix[i] = (int16_t)roundf(floatingPointSaturationMatrix[i] * divisor); 155 | } 156 | vImageMatrixMultiply_ARGB8888(inputBuffer, outputBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags); 157 | 158 | vImage_Buffer *temp = inputBuffer; 159 | inputBuffer = outputBuffer; 160 | outputBuffer = temp; 161 | } 162 | #endif 163 | 164 | CGImageRef effectCGImage; 165 | if ( (effectCGImage = vImageCreateCGImageFromBuffer(inputBuffer, &format, &cleanupBuffer, NULL, kvImageNoAllocate, NULL)) == NULL ) { 166 | effectCGImage = vImageCreateCGImageFromBuffer(inputBuffer, &format, NULL, NULL, kvImageNoFlags, NULL); 167 | free(inputBuffer->data); 168 | } 169 | 170 | // draw effect image 171 | CGContextSaveGState(outputContext); 172 | CGContextDrawImage(outputContext, outputImageRectInPoints, effectCGImage); 173 | CGContextRestoreGState(outputContext); 174 | 175 | // Cleanup 176 | CGImageRelease(effectCGImage); 177 | free(outputBuffer->data); 178 | } 179 | else 180 | { 181 | // draw base image 182 | CGContextDrawImage(outputContext, outputImageRectInPoints, inputCGImage); 183 | } 184 | 185 | #if ENABLE_TINT 186 | // Add in color tint. 187 | if (tintColor) 188 | { 189 | CGContextSaveGState(outputContext); 190 | CGContextSetFillColorWithColor(outputContext, tintColor.CGColor); 191 | CGContextFillRect(outputContext, outputImageRectInPoints); 192 | CGContextRestoreGState(outputContext); 193 | } 194 | #endif 195 | 196 | // Output image is ready. 197 | UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext(); 198 | UIGraphicsEndImageContext(); 199 | 200 | return outputImage; 201 | #undef ENABLE_BLUR 202 | #undef ENABLE_SATURATION_ADJUSTMENT 203 | #undef ENABLE_TINT 204 | } 205 | 206 | void cleanupBuffer(void *userData, void *buf_data) 207 | { 208 | free(buf_data); 209 | } 210 | 211 | @end 212 | -------------------------------------------------------------------------------- /PDLiveRoom/PDLiveRoom.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E75336471D7E714A004E0C90 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E75336461D7E714A004E0C90 /* main.m */; }; 11 | E753364A1D7E714A004E0C90 /* PDLiveAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E75336491D7E714A004E0C90 /* PDLiveAppDelegate.m */; }; 12 | E75336501D7E714A004E0C90 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E753364E1D7E714A004E0C90 /* Main.storyboard */; }; 13 | E75336521D7E714A004E0C90 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E75336511D7E714A004E0C90 /* Assets.xcassets */; }; 14 | E75336551D7E714A004E0C90 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E75336531D7E714A004E0C90 /* LaunchScreen.storyboard */; }; 15 | E753365E1D7E7170004E0C90 /* PDLiveRoomViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E753365D1D7E7170004E0C90 /* PDLiveRoomViewController.m */; }; 16 | E75336611D7E7300004E0C90 /* PDBaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E75336601D7E7300004E0C90 /* PDBaseViewController.m */; }; 17 | E75336681D7E73A5004E0C90 /* PDBlurImageEffects.m in Sources */ = {isa = PBXBuildFile; fileRef = E75336671D7E73A5004E0C90 /* PDBlurImageEffects.m */; }; 18 | E753366B1D7E77EC004E0C90 /* PDTableViewDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = E753366A1D7E77EC004E0C90 /* PDTableViewDataSource.m */; }; 19 | E753366E1D7E7E15004E0C90 /* PDChatModel.m in Sources */ = {isa = PBXBuildFile; fileRef = E753366D1D7E7E15004E0C90 /* PDChatModel.m */; }; 20 | E75336731D7E8002004E0C90 /* UIColorExt.m in Sources */ = {isa = PBXBuildFile; fileRef = E75336721D7E8002004E0C90 /* UIColorExt.m */; }; 21 | E75336761D7E975A004E0C90 /* NSAttributeString+Extent.m in Sources */ = {isa = PBXBuildFile; fileRef = E75336751D7E975A004E0C90 /* NSAttributeString+Extent.m */; }; 22 | E75336791D7E9CA9004E0C90 /* PDChatTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = E75336781D7E9CA9004E0C90 /* PDChatTableViewCell.m */; }; 23 | E753367C1D7EB5E3004E0C90 /* PDEmitterView.m in Sources */ = {isa = PBXBuildFile; fileRef = E753367B1D7EB5E3004E0C90 /* PDEmitterView.m */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | E75336421D7E714A004E0C90 /* PDLiveRoom.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PDLiveRoom.app; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | E75336461D7E714A004E0C90 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 29 | E75336481D7E714A004E0C90 /* PDLiveAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PDLiveAppDelegate.h; sourceTree = ""; }; 30 | E75336491D7E714A004E0C90 /* PDLiveAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PDLiveAppDelegate.m; sourceTree = ""; }; 31 | E753364F1D7E714A004E0C90 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 32 | E75336511D7E714A004E0C90 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 33 | E75336541D7E714A004E0C90 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 34 | E75336561D7E714A004E0C90 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 35 | E753365C1D7E7170004E0C90 /* PDLiveRoomViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDLiveRoomViewController.h; sourceTree = ""; }; 36 | E753365D1D7E7170004E0C90 /* PDLiveRoomViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PDLiveRoomViewController.m; sourceTree = ""; }; 37 | E753365F1D7E7300004E0C90 /* PDBaseViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDBaseViewController.h; sourceTree = ""; }; 38 | E75336601D7E7300004E0C90 /* PDBaseViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PDBaseViewController.m; sourceTree = ""; }; 39 | E75336661D7E73A5004E0C90 /* PDBlurImageEffects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDBlurImageEffects.h; sourceTree = ""; }; 40 | E75336671D7E73A5004E0C90 /* PDBlurImageEffects.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PDBlurImageEffects.m; sourceTree = ""; }; 41 | E75336691D7E77EC004E0C90 /* PDTableViewDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDTableViewDataSource.h; sourceTree = ""; }; 42 | E753366A1D7E77EC004E0C90 /* PDTableViewDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PDTableViewDataSource.m; sourceTree = ""; }; 43 | E753366C1D7E7E15004E0C90 /* PDChatModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDChatModel.h; sourceTree = ""; }; 44 | E753366D1D7E7E15004E0C90 /* PDChatModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PDChatModel.m; sourceTree = ""; }; 45 | E753366F1D7E7E7F004E0C90 /* PrefixHeader.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrefixHeader.pch; sourceTree = ""; }; 46 | E75336701D7E7F75004E0C90 /* Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Header.h; sourceTree = ""; }; 47 | E75336711D7E8002004E0C90 /* UIColorExt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIColorExt.h; sourceTree = ""; }; 48 | E75336721D7E8002004E0C90 /* UIColorExt.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIColorExt.m; sourceTree = ""; }; 49 | E75336741D7E975A004E0C90 /* NSAttributeString+Extent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributeString+Extent.h"; sourceTree = ""; }; 50 | E75336751D7E975A004E0C90 /* NSAttributeString+Extent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributeString+Extent.m"; sourceTree = ""; }; 51 | E75336771D7E9CA9004E0C90 /* PDChatTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDChatTableViewCell.h; sourceTree = ""; }; 52 | E75336781D7E9CA9004E0C90 /* PDChatTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PDChatTableViewCell.m; sourceTree = ""; }; 53 | E753367A1D7EB5E3004E0C90 /* PDEmitterView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDEmitterView.h; sourceTree = ""; }; 54 | E753367B1D7EB5E3004E0C90 /* PDEmitterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PDEmitterView.m; sourceTree = ""; }; 55 | /* End PBXFileReference section */ 56 | 57 | /* Begin PBXFrameworksBuildPhase section */ 58 | E753363F1D7E714A004E0C90 /* Frameworks */ = { 59 | isa = PBXFrameworksBuildPhase; 60 | buildActionMask = 2147483647; 61 | files = ( 62 | ); 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | /* End PBXFrameworksBuildPhase section */ 66 | 67 | /* Begin PBXGroup section */ 68 | E75336391D7E714A004E0C90 = { 69 | isa = PBXGroup; 70 | children = ( 71 | E75336441D7E714A004E0C90 /* PDLiveRoom */, 72 | E75336431D7E714A004E0C90 /* Products */, 73 | ); 74 | sourceTree = ""; 75 | }; 76 | E75336431D7E714A004E0C90 /* Products */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | E75336421D7E714A004E0C90 /* PDLiveRoom.app */, 80 | ); 81 | name = Products; 82 | sourceTree = ""; 83 | }; 84 | E75336441D7E714A004E0C90 /* PDLiveRoom */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | E75336651D7E7390004E0C90 /* Tool */, 88 | E75336641D7E738A004E0C90 /* Model */, 89 | E75336631D7E7382004E0C90 /* Controller */, 90 | E75336621D7E737A004E0C90 /* view */, 91 | E75336451D7E714A004E0C90 /* Supporting Files */, 92 | ); 93 | path = PDLiveRoom; 94 | sourceTree = ""; 95 | }; 96 | E75336451D7E714A004E0C90 /* Supporting Files */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | E753366F1D7E7E7F004E0C90 /* PrefixHeader.pch */, 100 | E75336481D7E714A004E0C90 /* PDLiveAppDelegate.h */, 101 | E75336491D7E714A004E0C90 /* PDLiveAppDelegate.m */, 102 | E753364E1D7E714A004E0C90 /* Main.storyboard */, 103 | E75336511D7E714A004E0C90 /* Assets.xcassets */, 104 | E75336531D7E714A004E0C90 /* LaunchScreen.storyboard */, 105 | E75336561D7E714A004E0C90 /* Info.plist */, 106 | E75336461D7E714A004E0C90 /* main.m */, 107 | E75336701D7E7F75004E0C90 /* Header.h */, 108 | ); 109 | name = "Supporting Files"; 110 | sourceTree = ""; 111 | }; 112 | E75336621D7E737A004E0C90 /* view */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | E75336771D7E9CA9004E0C90 /* PDChatTableViewCell.h */, 116 | E75336781D7E9CA9004E0C90 /* PDChatTableViewCell.m */, 117 | E753367A1D7EB5E3004E0C90 /* PDEmitterView.h */, 118 | E753367B1D7EB5E3004E0C90 /* PDEmitterView.m */, 119 | ); 120 | name = view; 121 | sourceTree = ""; 122 | }; 123 | E75336631D7E7382004E0C90 /* Controller */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | E753365C1D7E7170004E0C90 /* PDLiveRoomViewController.h */, 127 | E753365D1D7E7170004E0C90 /* PDLiveRoomViewController.m */, 128 | E753365F1D7E7300004E0C90 /* PDBaseViewController.h */, 129 | E75336601D7E7300004E0C90 /* PDBaseViewController.m */, 130 | ); 131 | name = Controller; 132 | sourceTree = ""; 133 | }; 134 | E75336641D7E738A004E0C90 /* Model */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | E753366C1D7E7E15004E0C90 /* PDChatModel.h */, 138 | E753366D1D7E7E15004E0C90 /* PDChatModel.m */, 139 | ); 140 | name = Model; 141 | sourceTree = ""; 142 | }; 143 | E75336651D7E7390004E0C90 /* Tool */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | E75336711D7E8002004E0C90 /* UIColorExt.h */, 147 | E75336721D7E8002004E0C90 /* UIColorExt.m */, 148 | E75336691D7E77EC004E0C90 /* PDTableViewDataSource.h */, 149 | E753366A1D7E77EC004E0C90 /* PDTableViewDataSource.m */, 150 | E75336661D7E73A5004E0C90 /* PDBlurImageEffects.h */, 151 | E75336671D7E73A5004E0C90 /* PDBlurImageEffects.m */, 152 | E75336741D7E975A004E0C90 /* NSAttributeString+Extent.h */, 153 | E75336751D7E975A004E0C90 /* NSAttributeString+Extent.m */, 154 | ); 155 | name = Tool; 156 | sourceTree = ""; 157 | }; 158 | /* End PBXGroup section */ 159 | 160 | /* Begin PBXNativeTarget section */ 161 | E75336411D7E714A004E0C90 /* PDLiveRoom */ = { 162 | isa = PBXNativeTarget; 163 | buildConfigurationList = E75336591D7E714A004E0C90 /* Build configuration list for PBXNativeTarget "PDLiveRoom" */; 164 | buildPhases = ( 165 | E753363E1D7E714A004E0C90 /* Sources */, 166 | E753363F1D7E714A004E0C90 /* Frameworks */, 167 | E75336401D7E714A004E0C90 /* Resources */, 168 | ); 169 | buildRules = ( 170 | ); 171 | dependencies = ( 172 | ); 173 | name = PDLiveRoom; 174 | productName = PDLiveRoom; 175 | productReference = E75336421D7E714A004E0C90 /* PDLiveRoom.app */; 176 | productType = "com.apple.product-type.application"; 177 | }; 178 | /* End PBXNativeTarget section */ 179 | 180 | /* Begin PBXProject section */ 181 | E753363A1D7E714A004E0C90 /* Project object */ = { 182 | isa = PBXProject; 183 | attributes = { 184 | LastUpgradeCheck = 0730; 185 | ORGANIZATIONNAME = "彭懂"; 186 | TargetAttributes = { 187 | E75336411D7E714A004E0C90 = { 188 | CreatedOnToolsVersion = 7.3.1; 189 | }; 190 | }; 191 | }; 192 | buildConfigurationList = E753363D1D7E714A004E0C90 /* Build configuration list for PBXProject "PDLiveRoom" */; 193 | compatibilityVersion = "Xcode 3.2"; 194 | developmentRegion = English; 195 | hasScannedForEncodings = 0; 196 | knownRegions = ( 197 | en, 198 | Base, 199 | ); 200 | mainGroup = E75336391D7E714A004E0C90; 201 | productRefGroup = E75336431D7E714A004E0C90 /* Products */; 202 | projectDirPath = ""; 203 | projectRoot = ""; 204 | targets = ( 205 | E75336411D7E714A004E0C90 /* PDLiveRoom */, 206 | ); 207 | }; 208 | /* End PBXProject section */ 209 | 210 | /* Begin PBXResourcesBuildPhase section */ 211 | E75336401D7E714A004E0C90 /* Resources */ = { 212 | isa = PBXResourcesBuildPhase; 213 | buildActionMask = 2147483647; 214 | files = ( 215 | E75336551D7E714A004E0C90 /* LaunchScreen.storyboard in Resources */, 216 | E75336521D7E714A004E0C90 /* Assets.xcassets in Resources */, 217 | E75336501D7E714A004E0C90 /* Main.storyboard in Resources */, 218 | ); 219 | runOnlyForDeploymentPostprocessing = 0; 220 | }; 221 | /* End PBXResourcesBuildPhase section */ 222 | 223 | /* Begin PBXSourcesBuildPhase section */ 224 | E753363E1D7E714A004E0C90 /* Sources */ = { 225 | isa = PBXSourcesBuildPhase; 226 | buildActionMask = 2147483647; 227 | files = ( 228 | E75336681D7E73A5004E0C90 /* PDBlurImageEffects.m in Sources */, 229 | E75336791D7E9CA9004E0C90 /* PDChatTableViewCell.m in Sources */, 230 | E753364A1D7E714A004E0C90 /* PDLiveAppDelegate.m in Sources */, 231 | E75336761D7E975A004E0C90 /* NSAttributeString+Extent.m in Sources */, 232 | E75336471D7E714A004E0C90 /* main.m in Sources */, 233 | E753366B1D7E77EC004E0C90 /* PDTableViewDataSource.m in Sources */, 234 | E753366E1D7E7E15004E0C90 /* PDChatModel.m in Sources */, 235 | E75336731D7E8002004E0C90 /* UIColorExt.m in Sources */, 236 | E753367C1D7EB5E3004E0C90 /* PDEmitterView.m in Sources */, 237 | E753365E1D7E7170004E0C90 /* PDLiveRoomViewController.m in Sources */, 238 | E75336611D7E7300004E0C90 /* PDBaseViewController.m in Sources */, 239 | ); 240 | runOnlyForDeploymentPostprocessing = 0; 241 | }; 242 | /* End PBXSourcesBuildPhase section */ 243 | 244 | /* Begin PBXVariantGroup section */ 245 | E753364E1D7E714A004E0C90 /* Main.storyboard */ = { 246 | isa = PBXVariantGroup; 247 | children = ( 248 | E753364F1D7E714A004E0C90 /* Base */, 249 | ); 250 | name = Main.storyboard; 251 | sourceTree = ""; 252 | }; 253 | E75336531D7E714A004E0C90 /* LaunchScreen.storyboard */ = { 254 | isa = PBXVariantGroup; 255 | children = ( 256 | E75336541D7E714A004E0C90 /* Base */, 257 | ); 258 | name = LaunchScreen.storyboard; 259 | sourceTree = ""; 260 | }; 261 | /* End PBXVariantGroup section */ 262 | 263 | /* Begin XCBuildConfiguration section */ 264 | E75336571D7E714A004E0C90 /* Debug */ = { 265 | isa = XCBuildConfiguration; 266 | buildSettings = { 267 | ALWAYS_SEARCH_USER_PATHS = NO; 268 | CLANG_ANALYZER_NONNULL = YES; 269 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 270 | CLANG_CXX_LIBRARY = "libc++"; 271 | CLANG_ENABLE_MODULES = YES; 272 | CLANG_ENABLE_OBJC_ARC = YES; 273 | CLANG_WARN_BOOL_CONVERSION = YES; 274 | CLANG_WARN_CONSTANT_CONVERSION = YES; 275 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 276 | CLANG_WARN_EMPTY_BODY = YES; 277 | CLANG_WARN_ENUM_CONVERSION = YES; 278 | CLANG_WARN_INT_CONVERSION = YES; 279 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 280 | CLANG_WARN_UNREACHABLE_CODE = YES; 281 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 282 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 283 | COPY_PHASE_STRIP = NO; 284 | DEBUG_INFORMATION_FORMAT = dwarf; 285 | ENABLE_STRICT_OBJC_MSGSEND = YES; 286 | ENABLE_TESTABILITY = YES; 287 | GCC_C_LANGUAGE_STANDARD = gnu99; 288 | GCC_DYNAMIC_NO_PIC = NO; 289 | GCC_NO_COMMON_BLOCKS = YES; 290 | GCC_OPTIMIZATION_LEVEL = 0; 291 | GCC_PREPROCESSOR_DEFINITIONS = ( 292 | "DEBUG=1", 293 | "$(inherited)", 294 | ); 295 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 296 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 297 | GCC_WARN_UNDECLARED_SELECTOR = YES; 298 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 299 | GCC_WARN_UNUSED_FUNCTION = YES; 300 | GCC_WARN_UNUSED_VARIABLE = YES; 301 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 302 | MTL_ENABLE_DEBUG_INFO = YES; 303 | ONLY_ACTIVE_ARCH = YES; 304 | SDKROOT = iphoneos; 305 | TARGETED_DEVICE_FAMILY = "1,2"; 306 | }; 307 | name = Debug; 308 | }; 309 | E75336581D7E714A004E0C90 /* Release */ = { 310 | isa = XCBuildConfiguration; 311 | buildSettings = { 312 | ALWAYS_SEARCH_USER_PATHS = NO; 313 | CLANG_ANALYZER_NONNULL = YES; 314 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 315 | CLANG_CXX_LIBRARY = "libc++"; 316 | CLANG_ENABLE_MODULES = YES; 317 | CLANG_ENABLE_OBJC_ARC = YES; 318 | CLANG_WARN_BOOL_CONVERSION = YES; 319 | CLANG_WARN_CONSTANT_CONVERSION = YES; 320 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 321 | CLANG_WARN_EMPTY_BODY = YES; 322 | CLANG_WARN_ENUM_CONVERSION = YES; 323 | CLANG_WARN_INT_CONVERSION = YES; 324 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 325 | CLANG_WARN_UNREACHABLE_CODE = YES; 326 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 327 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 328 | COPY_PHASE_STRIP = NO; 329 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 330 | ENABLE_NS_ASSERTIONS = NO; 331 | ENABLE_STRICT_OBJC_MSGSEND = YES; 332 | GCC_C_LANGUAGE_STANDARD = gnu99; 333 | GCC_NO_COMMON_BLOCKS = YES; 334 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 335 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 336 | GCC_WARN_UNDECLARED_SELECTOR = YES; 337 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 338 | GCC_WARN_UNUSED_FUNCTION = YES; 339 | GCC_WARN_UNUSED_VARIABLE = YES; 340 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 341 | MTL_ENABLE_DEBUG_INFO = NO; 342 | SDKROOT = iphoneos; 343 | TARGETED_DEVICE_FAMILY = "1,2"; 344 | VALIDATE_PRODUCT = YES; 345 | }; 346 | name = Release; 347 | }; 348 | E753365A1D7E714A004E0C90 /* Debug */ = { 349 | isa = XCBuildConfiguration; 350 | buildSettings = { 351 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 352 | GCC_PRECOMPILE_PREFIX_HEADER = NO; 353 | GCC_PREFIX_HEADER = "$(SRCROOT)/PDLiveRoom/PrefixHeader.pch"; 354 | INFOPLIST_FILE = PDLiveRoom/Info.plist; 355 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 356 | PRODUCT_BUNDLE_IDENTIFIER = com.Dongba.PDLiveRoom; 357 | PRODUCT_NAME = "$(TARGET_NAME)"; 358 | }; 359 | name = Debug; 360 | }; 361 | E753365B1D7E714A004E0C90 /* Release */ = { 362 | isa = XCBuildConfiguration; 363 | buildSettings = { 364 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 365 | GCC_PRECOMPILE_PREFIX_HEADER = NO; 366 | GCC_PREFIX_HEADER = "$(SRCROOT)/PDLiveRoom/PrefixHeader.pch"; 367 | INFOPLIST_FILE = PDLiveRoom/Info.plist; 368 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 369 | PRODUCT_BUNDLE_IDENTIFIER = com.Dongba.PDLiveRoom; 370 | PRODUCT_NAME = "$(TARGET_NAME)"; 371 | }; 372 | name = Release; 373 | }; 374 | /* End XCBuildConfiguration section */ 375 | 376 | /* Begin XCConfigurationList section */ 377 | E753363D1D7E714A004E0C90 /* Build configuration list for PBXProject "PDLiveRoom" */ = { 378 | isa = XCConfigurationList; 379 | buildConfigurations = ( 380 | E75336571D7E714A004E0C90 /* Debug */, 381 | E75336581D7E714A004E0C90 /* Release */, 382 | ); 383 | defaultConfigurationIsVisible = 0; 384 | defaultConfigurationName = Release; 385 | }; 386 | E75336591D7E714A004E0C90 /* Build configuration list for PBXNativeTarget "PDLiveRoom" */ = { 387 | isa = XCConfigurationList; 388 | buildConfigurations = ( 389 | E753365A1D7E714A004E0C90 /* Debug */, 390 | E753365B1D7E714A004E0C90 /* Release */, 391 | ); 392 | defaultConfigurationIsVisible = 0; 393 | }; 394 | /* End XCConfigurationList section */ 395 | }; 396 | rootObject = E753363A1D7E714A004E0C90 /* Project object */; 397 | } 398 | --------------------------------------------------------------------------------