├── ImagesResource └── LemonBubble.gif ├── LemonBubble ├── LemonBubble-samples │ ├── Resource │ │ ├── icon_ppt.png │ │ ├── icon_error.png │ │ ├── icon_icon.png │ │ ├── icon_right.png │ │ ├── icon_wait.png │ │ ├── lkbubble1.jpg │ │ ├── lkbubble2.jpg │ │ ├── lkbubble3.jpg │ │ ├── lkbubble4.jpg │ │ ├── lkbubble5.jpg │ │ ├── lkbubble6.jpg │ │ ├── lkbubble7.jpg │ │ ├── lkbubble8.jpg │ │ └── icon_bottom.png │ ├── AppDelegate.h │ ├── main.m │ ├── ViewController.h │ ├── RoundFunctionButton.h │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ ├── RoundFunctionButton.m │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── AppDelegate.m │ └── ViewController.m ├── LemonBubble.xcodeproj │ ├── xcuserdata │ │ ├── LiuRi.xcuserdatad │ │ │ ├── xcdebugger │ │ │ │ └── Breakpoints_v2.xcbkptlist │ │ │ └── xcschemes │ │ │ │ ├── xcschememanagement.plist │ │ │ │ ├── LemonBubble.xcscheme │ │ │ │ └── LemonBubble-samples.xcscheme │ │ └── 1em0nsOft.xcuserdatad │ │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ │ └── xcschemes │ │ │ ├── xcschememanagement.plist │ │ │ ├── LemonBubble.xcscheme │ │ │ └── LemonBubble-samples.xcscheme │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ ├── LiuRi.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ │ │ └── 1em0nsOft.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── project.pbxproj └── LemonBubble │ ├── LemonBubble.h │ ├── LemonBubbleView.h │ ├── UIResponder+LemonBubble.h │ ├── LemonBubbleInfo.h │ ├── LemonBubbleInfo.m │ ├── LemonBubbleView.m │ └── UIResponder+LemonBubble.m ├── LemonBubble.podspec ├── LICENSE └── README.md /ImagesResource/LemonBubble.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemonITCN/LemonBubble/HEAD/ImagesResource/LemonBubble.gif -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/Resource/icon_ppt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemonITCN/LemonBubble/HEAD/LemonBubble/LemonBubble-samples/Resource/icon_ppt.png -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/Resource/icon_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemonITCN/LemonBubble/HEAD/LemonBubble/LemonBubble-samples/Resource/icon_error.png -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/Resource/icon_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemonITCN/LemonBubble/HEAD/LemonBubble/LemonBubble-samples/Resource/icon_icon.png -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/Resource/icon_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemonITCN/LemonBubble/HEAD/LemonBubble/LemonBubble-samples/Resource/icon_right.png -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/Resource/icon_wait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemonITCN/LemonBubble/HEAD/LemonBubble/LemonBubble-samples/Resource/icon_wait.png -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/Resource/lkbubble1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemonITCN/LemonBubble/HEAD/LemonBubble/LemonBubble-samples/Resource/lkbubble1.jpg -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/Resource/lkbubble2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemonITCN/LemonBubble/HEAD/LemonBubble/LemonBubble-samples/Resource/lkbubble2.jpg -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/Resource/lkbubble3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemonITCN/LemonBubble/HEAD/LemonBubble/LemonBubble-samples/Resource/lkbubble3.jpg -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/Resource/lkbubble4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemonITCN/LemonBubble/HEAD/LemonBubble/LemonBubble-samples/Resource/lkbubble4.jpg -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/Resource/lkbubble5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemonITCN/LemonBubble/HEAD/LemonBubble/LemonBubble-samples/Resource/lkbubble5.jpg -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/Resource/lkbubble6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemonITCN/LemonBubble/HEAD/LemonBubble/LemonBubble-samples/Resource/lkbubble6.jpg -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/Resource/lkbubble7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemonITCN/LemonBubble/HEAD/LemonBubble/LemonBubble-samples/Resource/lkbubble7.jpg -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/Resource/lkbubble8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemonITCN/LemonBubble/HEAD/LemonBubble/LemonBubble-samples/Resource/lkbubble8.jpg -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/Resource/icon_bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemonITCN/LemonBubble/HEAD/LemonBubble/LemonBubble-samples/Resource/icon_bottom.png -------------------------------------------------------------------------------- /LemonBubble/LemonBubble.xcodeproj/xcuserdata/LiuRi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble.xcodeproj/xcuserdata/1em0nsOft.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble.xcodeproj/project.xcworkspace/xcuserdata/LiuRi.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemonITCN/LemonBubble/HEAD/LemonBubble/LemonBubble.xcodeproj/project.xcworkspace/xcuserdata/LiuRi.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /LemonBubble/LemonBubble.xcodeproj/project.xcworkspace/xcuserdata/1em0nsOft.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemonITCN/LemonBubble/HEAD/LemonBubble/LemonBubble.xcodeproj/project.xcworkspace/xcuserdata/1em0nsOft.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /LemonBubble/LemonBubble/LemonBubble.h: -------------------------------------------------------------------------------- 1 | // 2 | // LemonBubble.h 3 | // LemonKit 4 | // 5 | // Created by 1em0nsOft on 16/8/30. 6 | // Copyright © 2016年 1em0nsOft. All rights reserved. 7 | // 8 | 9 | #ifndef LemonBubble_h 10 | #define LemonBubble_h 11 | 12 | #import "UIResponder+LemonBubble.h" 13 | 14 | #endif /* LemonBubble_h */ 15 | 16 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // LemonBubble-samples 4 | // 5 | // Created by 刘日 on 2016/12/17. 6 | // Copyright © 2016年 1em0nsOft. 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 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // LemonBubble-samples 4 | // 5 | // Created by 刘日 on 2016/12/17. 6 | // Copyright © 2016年 1em0nsOft. 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 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // LemonBubble-samples 4 | // 5 | // Created by 刘日 on 2016/12/17. 6 | // Copyright © 2016年 1em0nsOft. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "LemonBubble.h" 11 | #import "RoundFunctionButton.h" 12 | 13 | @interface ViewController : UIViewController 14 | 15 | @property (nonatomic , strong) UIScrollView *rootScrollView; 16 | 17 | @end 18 | 19 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/RoundFunctionButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // RoundFunctionButton.h 3 | // LemonBubble 4 | // 5 | // Created by 刘日 on 2016/12/18. 6 | // Copyright © 2016年 1em0nsOft. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface RoundFunctionButton : UIControl 12 | 13 | /** 14 | 图标视图 15 | */ 16 | @property (nonatomic , strong) UIImageView *iconView; 17 | /** 18 | 标题标签视图 19 | */ 20 | @property (nonatomic , strong) UILabel *titleLabel; 21 | 22 | - (instancetype)initWithWidth: (CGFloat)width 23 | x: (CGFloat)x 24 | y: (CGFloat)y; 25 | 26 | - (void)setTitle: (NSString *)title 27 | image: (UIImage *)image; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /LemonBubble.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "LemonBubble" 3 | s.version = "1.0.2" 4 | s.summary = "A very NB HUD view ! instead of MBProgressHUD and SVProgressHUD" 5 | s.description = <<-DESC 6 | A very NB HUD view ! instead of MBProgressHUD and SVProgressHUD. 7 | DESC 8 | s.homepage = "https://github.com/1em0nsOft/LemonBubble" 9 | s.license = 'MIT' 10 | s.author = { "1em0nsOft-Liuri" => "liuri@lemonsoft.net" } 11 | s.source = { :git => "https://github.com/1em0nsOft/LemonBubble.git", :tag => s.version.to_s } 12 | # s.social_media_url = 'https://www.lemonsoft.net' 13 | 14 | s.platform = :ios, '8.0' 15 | s.requires_arc = true 16 | 17 | s.source_files = 'LemonBubble/LemonBubble/*' 18 | s.frameworks = 'Foundation', 'CoreGraphics', 'UIKit' 19 | 20 | end -------------------------------------------------------------------------------- /LemonBubble/LemonBubble.xcodeproj/xcuserdata/LiuRi.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | LemonBubble-samples.xcscheme 8 | 9 | orderHint 10 | 1 11 | 12 | LemonBubble.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 5291A4D71E0539E800E8C03A 21 | 22 | primary 23 | 24 | 25 | 5291A4E71E053A1900E8C03A 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble.xcodeproj/xcuserdata/1em0nsOft.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | LemonBubble-samples.xcscheme 8 | 9 | orderHint 10 | 1 11 | 12 | LemonBubble.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 5291A4D71E0539E800E8C03A 21 | 22 | primary 23 | 24 | 25 | 5291A4E71E053A1900E8C03A 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | } 43 | ], 44 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 1em0nsOft 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LemonBubble 4 ObjC 2 | > 作者:1em0nsOft - LiuRi 3 | > 4 | > 版本:1.0.1 5 | > 6 | > 简介:这是一个完全Made in China的炫酷弹出指示层,他能让你快速的自定义任何样式的弹出框。 7 | 8 | 9 | 10 | - 先来看看我们的动画效果图吧 11 | 12 | ![image](https://raw.githubusercontent.com/1em0nsOft/LemonBubble/master/ImagesResource/LemonBubble.gif) 13 | 14 | 15 | 16 | - 怎么样,想用吗?您可以使用Cocoapods快速集成进你的项目哦: 17 | 18 | ```shell 19 | pod 'LemonBubble', '1.0.1' 20 | ``` 21 | 22 | 23 | 24 | - 这么变态的控件,怎么用啊?表着急,如果你想简单的用用,那么两行代码就搞定!一行是#import,一行是调用函数!即可快速的显示我们提供的默认样式,比如成功啊、失败啊、等待中啊 等等,自己去试试吧... 25 | 26 | ```objective-c 27 | // 先引入头文件 28 | #import "LemonBubble.h" 29 | // 然后载人和UIResponder的子类(UIViewController/UIView ...等)里面调用下面函数即可 30 | LKRightBubble(@"请求成功", 1); 31 | ``` 32 | 33 | 34 | 35 | - 当然,你也可以自定义各种样式,比如帧动画啊、改变弹出控件的大小啊、在上中下什么位置啊...等等等都可以,在这里不贴各种代码了,因为使用的方式太多了 ^_^ 36 | 37 | 38 | 39 | - 什么?这些功能还不够你用,或者你使用中有什么bug?快来告诉我,我帮你实现! 40 | 41 | > **意见和建议交流群**:**370157608** 42 | > 43 | > **作者邮箱:**[**liuri@lemonsoft.net**](mailto:liuri@lemonsoft.net) 44 | > 45 | > **我的QQ:188443213** 46 | 47 | 48 | 49 | - 怎么,作者就开发一个弹出控件就幸灾乐祸了?NO , 这只是开始,想开发iOS就用LemonKit,这是**一个能让你少写代码的框架@_@**,Github地址:https://github.com/1em0nsOft/LemonKit4iOS 50 | 51 | 52 | 53 | - 作者一定是精神病<( ̄3 ̄)> ,赶紧点一个star来安慰一下作者吧! -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/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 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UIStatusBarStyle 32 | UIStatusBarStyleLightContent 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | 37 | UIViewControllerBasedStatusBarAppearance 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/RoundFunctionButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // RoundFunctionButton.m 3 | // LemonBubble 4 | // 5 | // Created by 刘日 on 2016/12/18. 6 | // Copyright © 2016年 1em0nsOft. All rights reserved. 7 | // 8 | 9 | #import "RoundFunctionButton.h" 10 | 11 | #define PADDING 14 12 | 13 | @implementation RoundFunctionButton 14 | 15 | - (instancetype)initWithWidth: (CGFloat)width 16 | x: (CGFloat)x 17 | y: (CGFloat)y{ 18 | if (self = [super initWithFrame: CGRectMake(x, y, width, width)]) { 19 | CGFloat iconWidth = width / 5 * 3; 20 | CGFloat iconX = (width - iconWidth) / 2; 21 | self.iconView = [[UIImageView alloc] initWithFrame: CGRectMake(iconX, PADDING, iconWidth, iconWidth)]; 22 | self.iconView.contentMode = UIViewContentModeScaleAspectFit; 23 | CGFloat titleY = PADDING + 4 + iconWidth; 24 | CGFloat titleHeight = width - PADDING * 2 - iconWidth; 25 | CGFloat titleWidth = width - PADDING * 2; 26 | self.titleLabel = [[UILabel alloc] initWithFrame: CGRectMake(PADDING, titleY, titleWidth, titleHeight)]; 27 | self.titleLabel.textAlignment = NSTextAlignmentCenter; 28 | self.titleLabel.font = [UIFont systemFontOfSize: 11]; 29 | self.layer.borderWidth = 1; 30 | self.layer.borderColor = [UIColor colorWithRed: 0.7 green: 0.7 blue:0.7 alpha: 0.7].CGColor; 31 | self.layer.cornerRadius = PADDING; 32 | [self addSubview: self.iconView]; 33 | [self addSubview: self.titleLabel]; 34 | } 35 | return self; 36 | } 37 | 38 | - (void)setTitle: (NSString *)title 39 | image: (UIImage *)image{ 40 | self.titleLabel.text = title; 41 | self.iconView.image = image; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/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 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble/LemonBubbleView.h: -------------------------------------------------------------------------------- 1 | // 2 | // LemonBubbleView.h 3 | // LemonKit 4 | // 5 | // Created by 1em0nsOft on 16/8/30. 6 | // Copyright © 2016年 1em0nsOft. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "LemonBubbleInfo.h" 11 | 12 | /** 13 | * @author 1em0nsOft LiuRi 14 | * @date 2016-08-30 14:08:50 15 | * 16 | * @brief LK提示系列 - LK泡泡控件 17 | */ 18 | @interface LemonBubbleView : UIView 19 | 20 | /// @brief 进度属性 21 | @property (nonatomic) CGFloat progress; 22 | 23 | /** 24 | * @author 1em0nsOft LiuRi 25 | * @date 2016-08-30 16:08:41 26 | * 27 | * @brief 默认的LK泡泡控件 - 单例方法 28 | * 29 | * @return 默认的LK泡泡控件对象 30 | */ 31 | + (LemonBubbleView *)defaultBubbleView; 32 | 33 | 34 | /** 35 | 注册泡泡信息对象 36 | 37 | @param info 泡泡信息对象 38 | @param key 泡泡信息对象对应的键 39 | */ 40 | - (void)registerInfo: (LemonBubbleInfo *)info forKey: (NSString *)key; 41 | 42 | /** 43 | * @author 1em0nsOft LiuRi 44 | * @date 2016-08-30 16:08:53 45 | * 46 | * @brief 显示指定的信息模型对应的泡泡控件 47 | */ 48 | - (void)showWithInfo: (LemonBubbleInfo *)info; 49 | 50 | /** 51 | * @author 1em0nsOft LiuRi 52 | * @date 2016-08-30 16:08:53 53 | * 54 | * @brief 通过传入键来显示已经注册的指定样式泡泡控件 55 | */ 56 | - (void)showWithInfoKey: (NSString *)infoKey; 57 | 58 | /** 59 | * @author 1em0nsOft LiuRi 60 | * @date 2016-08-30 16:08:53 61 | * 62 | * @brief 显示指定的信息模型对应的泡泡控件,并指定的时间后隐藏 63 | * 64 | * @param info 样式信息模型 65 | * @param time 指定时间后隐藏泡泡控件的秒数 66 | */ 67 | - (void)showWithInfo: (LemonBubbleInfo *)info autoCloseTime: (CGFloat)time; 68 | 69 | /** 70 | * @author 1em0nsOft LiuRi 71 | * @date 2016-08-30 16:08:53 72 | * 73 | * @brief 显示指定的信息模型对应的泡泡控件,并指定的时间后隐藏 74 | * 75 | * @param infoKey 已注册的样式信息模型的键 76 | * @param time 指定时间后隐藏泡泡控件的秒数 77 | */ 78 | - (void)showWithInfoKey: (NSString *)infoKey autoCloseTime: (CGFloat)time; 79 | 80 | /** 81 | * @author 1em0nsOft LiuRi 82 | * @date 2016-08-30 16:08:40 83 | * 84 | * @brief 隐藏当前泡泡控件 85 | */ 86 | - (void)hide; 87 | 88 | /** 89 | * @author chenjunsheng 90 | * @date 2016-12-18 16:08:40 91 | * 92 | * @brief 定时隐藏当前泡泡控件 93 | */ 94 | - (void)hideWithCloseTime: (CGFloat)time; 95 | 96 | @end 97 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // LemonBubble-samples 4 | // 5 | // Created by 刘日 on 2016/12/17. 6 | // Copyright © 2016年 1em0nsOft. 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 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // 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. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // 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. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // 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. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble/UIResponder+LemonBubble.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIResponder+LemonBubble.h 3 | // LemonKit 4 | // 5 | // Created by 1em0nsOft on 16/8/30. 6 | // Copyright © 2016年 1em0nsOft. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "LemonBubbleView.h" 11 | 12 | // 展示一个带对号的提示信息 13 | #define LKRightBubble(title, time) [self showRightWithTitle: title autoCloseTime: time] 14 | // 展示一个带错误X的提示信息 15 | #define LKErrorBubble(title, time) [self showErrorWithTitle: title autoCloseTime: time] 16 | // 展示一个圆形的无限循环的进度条 17 | #define LKWaitBubble(title) [self showRoundProgressWithTitle: title] 18 | // 隐藏现在显示的泡泡控件 19 | #define LKHideBubble() [self hideBubble] 20 | // 定时隐藏现在显示的泡泡控件 21 | #define LKHideBubbleAfter(time) [self hideBubbleAfter: time] 22 | // 显示指定泡泡信息规定的泡泡控件 23 | #define LKShowBubbleInfo(info) [self showBubbleWithInfo: info] 24 | // 显示置顶的泡泡信息规定的泡泡控件,并在指定的时间后关闭 25 | #define LKShowBubbleInfoWithTime(info , duration) [self showBubbleWithInfo: info time: duration] 26 | 27 | /** 28 | 为了方便用户的使用,对UIResponder以及其所有子类进行扩展使用方法 29 | */ 30 | @interface UIResponder (LemonBubble) 31 | 32 | /** 33 | 获取默认的显示成功的泡泡信息对象,可以在此基础之上自定义 34 | 35 | @return 泡泡信息描述对象 36 | */ 37 | - (LemonBubbleInfo *)getDefaultRightBubbleInfo; 38 | 39 | /** 40 | 展示一个带对号的提示信息 41 | 42 | @param title 要提示的标题 43 | @param autoCloseTime 自动关闭的时间 44 | */ 45 | - (void)showRightWithTitle: (NSString *)title 46 | autoCloseTime: (CGFloat)autoCloseTime; 47 | 48 | /** 49 | 获取默认的显示加载中的泡泡信息对象,可以在此基础之上自定义 50 | 51 | @return 泡泡信息描述对象 52 | */ 53 | - (LemonBubbleInfo *)getDefaultRoundProgressBubbleInfo; 54 | 55 | /** 56 | 展示一个圆形的无限循环的进度条 57 | 58 | @param title 要提示的标题 59 | */ 60 | - (void)showRoundProgressWithTitle: (NSString *)title; 61 | 62 | /** 63 | 获取默认的显示错误的泡泡信息对象,可以在此基础之上自定义 64 | 65 | @return 泡泡信息描述对象 66 | */ 67 | - (LemonBubbleInfo *)getDefaultErrorBubbleInfo; 68 | 69 | /** 70 | 展示一个带错误X的提示信息 71 | 72 | @param title 提示信息的标题 73 | @param autoCloseTime 自动关闭的时间 74 | */ 75 | - (void)showErrorWithTitle: (NSString *)title 76 | autoCloseTime: (CGFloat)autoCloseTime; 77 | 78 | /** 79 | 隐藏现在显示的泡泡控件 80 | */ 81 | - (void)hideBubble; 82 | 83 | /** 84 | 定时隐藏现在显示的泡泡控件 85 | 86 | @param duration 等待的时间 87 | */ 88 | - (void)hideBubbleAfter: (CGFloat)duration; 89 | 90 | /** 91 | 显示指定泡泡信息规定的泡泡控件 92 | 93 | @param info 泡泡信息对象 94 | */ 95 | - (void)showBubbleWithInfo: (LemonBubbleInfo *)info; 96 | 97 | /** 98 | 显示置顶的泡泡信息规定的泡泡控件,并在指定的时间后关闭 99 | 100 | @param info 泡泡信息对象 101 | @param time 要关闭的延迟时间 102 | */ 103 | - (void)showBubbleWithInfo: (LemonBubbleInfo *)info time: (CGFloat)time; 104 | 105 | @end 106 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble.xcodeproj/xcuserdata/LiuRi.xcuserdatad/xcschemes/LemonBubble.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble.xcodeproj/xcuserdata/1em0nsOft.xcuserdatad/xcschemes/LemonBubble.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/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 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble/LemonBubbleInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // LemonBubbleInfo.h 3 | // LemonKit 4 | // 5 | // Created by 1em0nsOft on 16/9/12. 6 | // Copyright © 2016年 1em0nsOft. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /// @brief 自定义动画Block 12 | typedef void(^BLOCK_LK_BUBBLE_CUSTOM_ANIMATION) (CAShapeLayer *layer); 13 | /// @brief 进度被改变的Block,通常用于自定义进度动画 14 | typedef void(^BLOCK_LK_BUBBLE_ON_PROGRESS_CHANGED) (CAShapeLayer *layer , CGFloat progress); 15 | 16 | /// @brief 图文布局枚举 17 | typedef enum{ 18 | /// @brief 图上文下 19 | BUBBLE_LAYOUT_STYLE_ICON_TOP_TITLE_BOTTOM = 0, 20 | /// @brief 图下文上 21 | BUBBLE_LAYOUT_STYLE_ICON_BOTTOM_TITLE_TOP = 3, 22 | /// @brief 图左文右 23 | BUBBLE_LAYOUT_STYLE_ICON_LEFT_TITLE_RIGHT = 1, 24 | /// @brief 图右文左 25 | BUBBLE_LAYOUT_STYLE_ICON_RIGHT_TITLE_LEFT = 4, 26 | /// @brief 只显示图 27 | BUBBLE_LAYOUT_STYLE_ICON_ONLY = 2, 28 | /// @brief 只显示文 29 | BUBBLE_LAYOUT_STYLE_TITLE_ONLY = 5 30 | }BUBBLE_LAYOUT_STYLE; 31 | 32 | /// @brief LK泡泡控件位置枚举 33 | typedef enum{ 34 | /// @brief 位于屏幕顶部 35 | BUBBLE_LOCATION_STYLE_TOP = 0, 36 | /// @brief 位于屏幕中间 37 | BUBBLE_LOCATION_STYLE_CENTER, 38 | /// @breif 位于屏幕底部 39 | BUBBLE_LOCATION_STYLE_BOTTOM 40 | }BUBBLE_LOCATION_STYLE; 41 | 42 | /** 43 | 泡泡控件的信息描述对象,该类详细描述了泡泡对象的左右外观信息,控件可以根据泡泡信息对象来进行设置泡泡控件的外观属性 44 | */ 45 | @interface LemonBubbleInfo : NSObject 46 | 47 | /// @breif 泡泡控件的大小 48 | @property (nonatomic, assign) CGSize bubbleSize; 49 | /// @brief 泡泡控件的圆角半径 50 | @property (nonatomic, assign) CGFloat cornerRadius; 51 | /// @brief 图文布局属性 52 | @property (nonatomic, assign) BUBBLE_LAYOUT_STYLE layoutStyle; 53 | /// @brief 图标动画 54 | @property (nonatomic, assign) BLOCK_LK_BUBBLE_CUSTOM_ANIMATION iconAnimation; 55 | /// @brief 进度被改变的回调block 56 | @property (nonatomic, assign) BLOCK_LK_BUBBLE_ON_PROGRESS_CHANGED onProgressChanged; 57 | /// @brief 图标数组,如果该数组为空或者该对象为nil,那么显示自定义动画,如果图标为一张,那么固定显示那个图标,大于一张的时候显示图片帧动画 58 | @property (nonatomic, strong) NSArray *iconArray; 59 | /// @brief 要显示的标题 60 | @property (nonatomic, strong) NSString *title; 61 | /// @brief 帧动画时间间隔 62 | @property (nonatomic, assign) CGFloat frameAnimationTime; 63 | /// @brief 图标占比 0 - 1,图标控件的边长占高度的比例 64 | @property (nonatomic, assign) CGFloat proportionOfIcon; 65 | /// @brief 间距占比 0 - 1,图标控件和标题控件之间距离占整个控件的比例(如果横向布局那么就相当于宽度,纵向布局相当于高度) 66 | @property (nonatomic, assign) CGFloat proportionOfSpace; 67 | /// @brief 内边距占比 0 - 1,整个泡泡控件的内边距,x最终为左右的内边距,y最终为上下的内边距(左右内边距以宽度算最终的像素值,上下边距以高度算最终的像素值) 68 | @property (nonatomic, assign) CGPoint proportionOfPadding; 69 | /// @brief 位置样式 70 | @property (nonatomic, assign) BUBBLE_LOCATION_STYLE locationStyle; 71 | /// @brief 泡泡控件显示时偏移,当位置样式为上中的时候,偏移值是向下移动,当位置样式为底部时候,偏移值是向上移动 72 | @property (nonatomic, assign) CGFloat proportionOfDeviation; 73 | /// @brief 是否展示蒙版,展示蒙版后,显示泡泡控件时会产生一个蒙版层来拦截所有其他控件的点击事件 74 | @property (nonatomic, assign) BOOL isShowMaskView; 75 | /// @brief 蒙版颜色 76 | @property (nonatomic, strong) UIColor *maskColor; 77 | /// @brief 泡泡控件的背景色 78 | @property (nonatomic, strong) UIColor *backgroundColor; 79 | /// @brief 图标渲染色 80 | @property (nonatomic, strong) UIColor *iconColor; 81 | /// @brief 标题文字颜色 82 | @property (nonatomic, strong) UIColor *titleColor; 83 | /// @brief 标题字体大小 84 | @property (nonatomic, assign) CGFloat titleFontSize; 85 | /// @breif key,随机数,用于标志一个info的唯一性,关闭时候会通过这个验证 86 | @property (nonatomic, readonly) CGFloat key; 87 | 88 | /** 89 | 计算泡泡控件的整体frame 90 | 91 | @return 计算出的泡控件的frame 92 | */ 93 | - (CGRect)calBubbleViewFrame; 94 | 95 | /** 96 | 计算并设置图标控件和标题控件的frame 97 | 98 | @param iconView 要设置的图标控件 99 | @param titleView 要设置的标题控件 100 | */ 101 | - (void)calIconView:(UIImageView *)iconView andTitleView:(UILabel *)titleView; 102 | 103 | @end 104 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble.xcodeproj/xcuserdata/LiuRi.xcuserdatad/xcschemes/LemonBubble-samples.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 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble.xcodeproj/xcuserdata/1em0nsOft.xcuserdatad/xcschemes/LemonBubble-samples.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 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble-samples/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // LemonBubble-samples 4 | // 5 | // Created by 刘日 on 2016/12/17. 6 | // Copyright © 2016年 1em0nsOft. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "LemonBubble.h" 11 | 12 | #define COLUMN_COUNT 3 13 | #define PADDING 8 14 | 15 | @interface ViewController () 16 | 17 | @end 18 | 19 | @implementation ViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | RoundFunctionButton *btn1 = [self createWithIndex: 0]; 24 | [btn1 setTitle: @"成功的提示" image: [UIImage imageNamed: @"icon_right"]]; 25 | [btn1 addTarget: self action: @selector(right) forControlEvents: UIControlEventTouchUpInside]; 26 | [self.view addSubview: btn1]; 27 | 28 | RoundFunctionButton *btn2 = [self createWithIndex: 1]; 29 | [btn2 setTitle: @"失败的提示" image: [UIImage imageNamed: @"icon_error"]]; 30 | [btn2 addTarget: self action: @selector(error) forControlEvents: UIControlEventTouchUpInside]; 31 | [self.view addSubview: btn2]; 32 | 33 | RoundFunctionButton *btn3 = [self createWithIndex: 2]; 34 | [btn3 setTitle: @"等待的提示" image: [UIImage imageNamed: @"icon_wait"]]; 35 | [btn3 addTarget: self action: @selector(wait) forControlEvents: UIControlEventTouchUpInside]; 36 | [self.view addSubview: btn3]; 37 | 38 | RoundFunctionButton *btn4 = [self createWithIndex: 3]; 39 | [btn4 setTitle: @"在底部的提示" image: [UIImage imageNamed: @"icon_bottom"]]; 40 | [btn4 addTarget: self action: @selector(bottom) forControlEvents: UIControlEventTouchUpInside]; 41 | [self.view addSubview: btn4]; 42 | 43 | RoundFunctionButton *btn5 = [self createWithIndex: 4]; 44 | [btn5 setTitle: @"逐帧播放的提示" image: [UIImage imageNamed: @"icon_ppt"]]; 45 | [btn5 addTarget: self action: @selector(ppt) forControlEvents: UIControlEventTouchUpInside]; 46 | [self.view addSubview: btn5]; 47 | 48 | RoundFunctionButton *btn6 = [self createWithIndex: 5]; 49 | [btn6 setTitle: @"自定义图标的提示" image: [UIImage imageNamed: @"icon_icon"]]; 50 | [btn6 addTarget: self action: @selector(icon) forControlEvents: UIControlEventTouchUpInside]; 51 | [self.view addSubview: btn6]; 52 | } 53 | 54 | - (RoundFunctionButton *)createWithIndex: (NSInteger)index{ 55 | CGFloat width = ([UIScreen mainScreen].bounds.size.width - (COLUMN_COUNT + 1) * PADDING) / COLUMN_COUNT; 56 | CGFloat x = PADDING + (index % COLUMN_COUNT * (PADDING + width)); 57 | CGFloat y = PADDING + (index / COLUMN_COUNT * (PADDING + width)); 58 | return [[RoundFunctionButton alloc] initWithWidth: width x: x y: y]; 59 | } 60 | 61 | - (void)right{ 62 | LKRightBubble(@"这是一个成功的提示", 2); 63 | } 64 | 65 | - (void)error{ 66 | LKErrorBubble(@"这是一个失败的提示", 2); 67 | } 68 | 69 | - (void)wait{ 70 | LKWaitBubble(@"请求中..."); 71 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 72 | LKRightBubble(@"请求成功", 1); 73 | }); 74 | } 75 | 76 | - (void)bottom{ 77 | LemonBubbleInfo *myInfo = [self getDefaultRoundProgressBubbleInfo]; 78 | myInfo.locationStyle = BUBBLE_LOCATION_STYLE_BOTTOM; 79 | myInfo.layoutStyle = BUBBLE_LAYOUT_STYLE_ICON_LEFT_TITLE_RIGHT; 80 | myInfo.title = @"正在删除"; 81 | myInfo.bubbleSize = CGSizeMake(200, 50); 82 | myInfo.proportionOfDeviation = 0.1; 83 | LKShowBubbleInfo(myInfo); 84 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 85 | LKRightBubble(@"删除成功", 2); 86 | }); 87 | } 88 | 89 | - (void)ppt{ 90 | LemonBubbleInfo *frameInfo = [[LemonBubbleInfo alloc] init]; 91 | NSMutableArray *icons = [[NSMutableArray alloc] init]; 92 | for (int i = 1 ; i <= 8; i ++) { 93 | [icons addObject: [UIImage imageNamed: [NSString stringWithFormat: @"lkbubble%d.jpg" , i]]]; 94 | } 95 | frameInfo.iconArray = icons; 96 | // 在数组中依次放入多张图片即可实现多图循环播放 97 | frameInfo.backgroundColor = [UIColor colorWithRed: 238 / 255.0 green:238 / 255.0 blue:238 / 255.0 alpha:1]; 98 | // 动画的帧动画播放间隔 99 | frameInfo.frameAnimationTime = 0.15; 100 | frameInfo.title = @"正在加载中..."; 101 | frameInfo.titleColor = [UIColor darkGrayColor]; 102 | [[LemonBubbleView defaultBubbleView] showWithInfo: frameInfo]; 103 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 104 | LKErrorBubble(@"加载失败", 2); 105 | }); 106 | } 107 | 108 | - (void)icon{ 109 | LemonBubbleInfo *iconInfo = [[LemonBubbleInfo alloc] init]; 110 | // 把图标数组里面设置只有一张图片即可单图固定图标 111 | iconInfo.iconArray = @[[UIImage imageNamed: @"icon_icon"]]; 112 | iconInfo.backgroundColor = [UIColor colorWithRed: 0.95 green:0.95 blue:0.95 alpha:1]; 113 | iconInfo.titleColor = [UIColor darkGrayColor]; 114 | iconInfo.locationStyle = BUBBLE_LOCATION_STYLE_TOP; 115 | iconInfo.layoutStyle = BUBBLE_LAYOUT_STYLE_ICON_LEFT_TITLE_RIGHT; 116 | iconInfo.title = @"飞行模式已开启"; 117 | iconInfo.proportionOfDeviation = 0.05; 118 | iconInfo.bubbleSize = CGSizeMake(300, 60); 119 | LKShowBubbleInfoWithTime(iconInfo, 2); 120 | } 121 | 122 | @end 123 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble/LemonBubbleInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // LemonBubbleInfo.m 3 | // LemonKit 4 | // 5 | // Created by 1em0nsOft on 16/9/12. 6 | // Copyright © 2016年 1em0nsOft. All rights reserved. 7 | // 8 | 9 | #import "LemonBubbleInfo.h" 10 | 11 | @interface LemonBubbleInfo() 12 | 13 | @property(nonatomic, readwrite) CGFloat key; 14 | 15 | @end 16 | 17 | @implementation LemonBubbleInfo 18 | 19 | - (instancetype)init{ 20 | self = [super init]; 21 | if (self) { 22 | self.bubbleSize = CGSizeMake(180, 120); 23 | self.cornerRadius = 8; 24 | self.layoutStyle = BUBBLE_LAYOUT_STYLE_ICON_TOP_TITLE_BOTTOM; 25 | self.iconAnimation = nil; 26 | self.onProgressChanged = nil; 27 | self.iconArray = nil; 28 | self.title = @"LemonBubble"; 29 | self.frameAnimationTime = 0.1; 30 | self.proportionOfIcon = 0.675; 31 | self.proportionOfSpace = 0.1; 32 | self.proportionOfPadding = CGPointMake(0.1, 0.1); 33 | self.locationStyle = BUBBLE_LOCATION_STYLE_CENTER; 34 | self.proportionOfDeviation = 0; 35 | self.isShowMaskView = YES; 36 | self.maskColor = [UIColor colorWithRed: 0.1 green: 0.1 blue:0.1 alpha:0.2]; 37 | self.backgroundColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 0.8]; 38 | self.iconColor = [UIColor whiteColor]; 39 | self.titleColor = [UIColor whiteColor]; 40 | self.titleFontSize = 13; 41 | 42 | // 生成随机的key 43 | self.key = arc4random(); 44 | } 45 | return self; 46 | } 47 | 48 | - (instancetype)initWithTitle: (NSString *)title icon: (UIImage *)icon{ 49 | self = [self init]; 50 | if (self) { 51 | self.title = title; 52 | self.iconArray = @[icon]; 53 | } 54 | return self; 55 | } 56 | 57 | //计算文本高度 58 | - (CGSize)measureStringSize:(NSString *)text 59 | WithFont:(UIFont *)font 60 | constrainedToSize:(CGSize)size 61 | lineBreakMode:(NSLineBreakMode)lineBreakMode { 62 | NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 63 | [paragraphStyle setLineBreakMode:lineBreakMode]; 64 | NSDictionary *attributes = @{ NSFontAttributeName:font, NSParagraphStyleAttributeName : paragraphStyle }; 65 | CGSize tempSize = [text boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin |NSStringDrawingUsesFontLeading attributes:attributes context:nil].size; 66 | return CGSizeMake(ceilf(tempSize.width), ceilf(tempSize.height)); 67 | } 68 | 69 | - (CGRect)calBubbleViewFrame{ 70 | CGFloat y; 71 | switch (self.locationStyle) { 72 | case BUBBLE_LOCATION_STYLE_TOP: 73 | y = 0; 74 | break; 75 | case BUBBLE_LOCATION_STYLE_CENTER: 76 | y = ([UIScreen mainScreen].bounds.size.height - self.bubbleSize.height) / 2.0; 77 | break; 78 | case BUBBLE_LOCATION_STYLE_BOTTOM: 79 | y = [UIScreen mainScreen].bounds.size.height - self.bubbleSize.height; 80 | break; 81 | } 82 | y += (self.locationStyle != BUBBLE_LOCATION_STYLE_BOTTOM ? 1 : -1) * (self.proportionOfDeviation * [UIScreen mainScreen].bounds.size.height); 83 | return CGRectMake(([UIScreen mainScreen].bounds.size.width - self.bubbleSize.width) / 2, y, self.bubbleSize.width, self.bubbleSize.height); 84 | } 85 | 86 | //计算图标和文本,使其居中排列。 87 | - (void)calIconView:(UIImageView *)iconView 88 | andTitleView:(UILabel *)titleView { 89 | CGSize bubbleContentSize = 90 | CGSizeMake(self.bubbleSize.width * (1 - self.proportionOfPadding.x * 2), 91 | self.bubbleSize.height * (1 - self.proportionOfPadding.y * 2)); 92 | 93 | CGFloat iconWidth = (self.layoutStyle == BUBBLE_LAYOUT_STYLE_TITLE_ONLY) ? 0 : 94 | bubbleContentSize.height * self.proportionOfIcon; 95 | 96 | CGFloat baseX = self.bubbleSize.width * self.proportionOfPadding.x; 97 | CGFloat baseY = self.bubbleSize.height * self.proportionOfPadding.y; 98 | 99 | //计算文本高度,可能是单行也可能是多行 100 | //先假设是单行文本 101 | CGSize calTitleRect = [self.title sizeWithAttributes: @{NSFontAttributeName : [UIFont systemFontOfSize: self.titleFontSize]}]; 102 | CGFloat titleWidth = (self.layoutStyle == BUBBLE_LAYOUT_STYLE_ICON_TOP_TITLE_BOTTOM || 103 | self.layoutStyle == BUBBLE_LAYOUT_STYLE_ICON_BOTTOM_TITLE_TOP || 104 | self.layoutStyle == BUBBLE_LAYOUT_STYLE_TITLE_ONLY) ? 105 | bubbleContentSize.width : 106 | bubbleContentSize.width * (1 - self.proportionOfSpace) - iconWidth; 107 | //不能超过显示区域宽度 108 | if (titleWidth > calTitleRect.width) { 109 | titleWidth = calTitleRect.width; 110 | } 111 | //根据限定的宽度计算多行文本高度 112 | CGSize titleSize = [self measureStringSize:self.title 113 | WithFont:[UIFont systemFontOfSize:_titleFontSize] 114 | constrainedToSize:CGSizeMake(titleWidth, MAXFLOAT) 115 | lineBreakMode:NSLineBreakByWordWrapping]; 116 | CGFloat titleHeight = titleSize.height; 117 | //不能超过显示区域高度 118 | if (titleHeight > bubbleContentSize.height) { 119 | titleHeight = bubbleContentSize.height; 120 | } 121 | //初始化frame 122 | CGRect iconFrame = CGRectMake(baseX, baseY, iconWidth, iconWidth); 123 | CGRect titleFrame = CGRectMake(baseX, baseY, titleWidth, titleHeight); 124 | switch (self.layoutStyle) { 125 | case BUBBLE_LAYOUT_STYLE_ICON_TOP_TITLE_BOTTOM: { 126 | //图标+文本高度 127 | CGFloat contentHeight = iconWidth + bubbleContentSize.height * self.proportionOfSpace + titleHeight; 128 | //垂直居中,图标坐标 129 | iconFrame.origin.x = baseX + (bubbleContentSize.width - iconWidth) / 2.0; 130 | iconFrame.origin.y = baseY + (bubbleContentSize.height - contentHeight) / 2.0; 131 | //由图标Y坐标求出文本Y坐标 132 | titleFrame.origin.y = iconFrame.origin.y + iconWidth + bubbleContentSize.height * self.proportionOfSpace; 133 | titleFrame.origin.x = baseX + (bubbleContentSize.width - titleWidth) / 2.0; 134 | } 135 | break; 136 | case BUBBLE_LAYOUT_STYLE_ICON_BOTTOM_TITLE_TOP: { 137 | //图标+文本高度 138 | CGFloat contentHeight = iconWidth + bubbleContentSize.height * self.proportionOfSpace + titleHeight; 139 | //垂直居中,文本Y坐标 140 | titleFrame.origin.y = baseY + (bubbleContentSize.height - contentHeight) / 2.0; 141 | titleFrame.origin.x = baseX + (bubbleContentSize.width - titleWidth) / 2.0; 142 | //由文本坐标求出图标坐标 143 | iconFrame.origin.x = baseX + (bubbleContentSize.width - iconWidth) / 2.0; 144 | iconFrame.origin.y = titleFrame.origin.y + titleFrame.size.height + bubbleContentSize.height * self.proportionOfSpace; 145 | } 146 | break; 147 | case BUBBLE_LAYOUT_STYLE_ICON_LEFT_TITLE_RIGHT: { 148 | //图标+文本宽度 149 | CGFloat contentWidth = iconWidth + bubbleContentSize.width * self.proportionOfSpace + titleWidth; 150 | //水平居中,图标X坐标 151 | iconFrame.origin.x = baseX + (bubbleContentSize.width - contentWidth) / 2; 152 | iconFrame.origin.y = baseY + (bubbleContentSize.height - iconWidth) / 2; 153 | //由图标X坐标求出文本X坐标 154 | titleFrame.origin.x = iconFrame.origin.x + iconWidth + bubbleContentSize.width * self.proportionOfSpace; 155 | titleFrame.origin.y = baseY + (bubbleContentSize.height - titleHeight) / 2; 156 | } 157 | break; 158 | case BUBBLE_LAYOUT_STYLE_ICON_RIGHT_TITLE_LEFT: { 159 | //图标+文本宽度 160 | CGFloat contentWidth = iconWidth + bubbleContentSize.width * self.proportionOfSpace + titleWidth; 161 | //水平居中,文本X坐标 162 | titleFrame.origin.x = baseX + (bubbleContentSize.width - contentWidth) / 2; 163 | titleFrame.origin.y = baseY + (bubbleContentSize.height - titleHeight) / 2; 164 | //由文本坐标求出图标坐标 165 | iconFrame.origin.x = titleFrame.origin.x + titleFrame.size.width + bubbleContentSize.width * self.proportionOfSpace; 166 | iconFrame.origin.y = baseY + (bubbleContentSize.height - iconWidth) / 2; 167 | } 168 | break; 169 | case BUBBLE_LAYOUT_STYLE_ICON_ONLY: 170 | titleFrame = CGRectMake(0, 0, 0, 0); 171 | iconFrame.origin.x = baseX + (bubbleContentSize.width - iconWidth) / 2; 172 | iconFrame.origin.y = baseY + (bubbleContentSize.height - iconWidth) / 2; 173 | break; 174 | case BUBBLE_LAYOUT_STYLE_TITLE_ONLY: 175 | titleFrame.origin.x = baseX + (bubbleContentSize.width - titleWidth) / 2; 176 | titleFrame.origin.y = baseY + (bubbleContentSize.height - titleHeight) / 2; 177 | iconFrame = CGRectMake(0, 0, 0, 0); 178 | break; 179 | } 180 | iconView.frame = iconFrame; 181 | titleView.frame = titleFrame; 182 | } 183 | 184 | @end 185 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble/LemonBubbleView.m: -------------------------------------------------------------------------------- 1 | // 2 | // LemonBubbleView.m 3 | // LemonKit 4 | // 5 | // Created by 1em0nsOft on 16/8/30. 6 | // Copyright © 2016年 1em0nsOft. All rights reserved. 7 | // 8 | 9 | #import "LemonBubbleView.h" 10 | 11 | #define bubble_width 180 // 泡泡控件的宽度 12 | #define bubble_height 120// 泡泡控件的高度 13 | #define bubble_icon_width 60 // 泡泡控件中的图标边长 14 | #define bubble_padding 17 // 泡泡控件的顶部内边距,即图标距离顶部的长度 15 | #define bubble_icon_title_space 0 // 泡泡控件中图标和标题的空隙 16 | 17 | @interface LemonBubbleView() 18 | 19 | @property (nonatomic, strong) UIImageView *iconImageView; 20 | @property (nonatomic, strong) UILabel *titleLabel; 21 | @property (nonatomic, assign) BOOL *isShowing;// 是否正在显示中 22 | @property (nonatomic, strong) NSMutableDictionary *infoDic; 23 | /// @brief 当前正在显示的泡泡信息对象 24 | @property (nonatomic, strong) LemonBubbleInfo *currentInfo; 25 | /// @brief 当前自定义动画绘图的图层 26 | @property (nonatomic, strong) CAShapeLayer *currentDrawLayer; 27 | /// @brief 当前使用的图片帧动画计时器 28 | @property (nonatomic, strong) NSTimer *currentTimer; 29 | /// @brief 蒙版view 30 | @property (nonatomic, strong) UIView *maskView; 31 | 32 | @property (nonatomic, assign) CGFloat closeKey;// 关闭验证key,用来做关闭时候的延迟验证,当设置自动关闭之后,若在关闭之前出发了显示其他info的bubble,通过修改这个值保证不关闭其他样式的infoBubble 33 | @property (nonatomic, assign) NSInteger frameAnimationPlayIndex;// 帧动画播放的下标索引 34 | 35 | @end 36 | 37 | @implementation LemonBubbleView 38 | 39 | + (LemonBubbleView *)defaultBubbleView { 40 | static LemonBubbleView *defaultBubbleView = nil; 41 | static dispatch_once_t onceToken; 42 | 43 | dispatch_once(&onceToken, ^{ 44 | if (defaultBubbleView == nil) { 45 | defaultBubbleView = [[LemonBubbleView alloc] init]; 46 | } 47 | }); 48 | return defaultBubbleView; 49 | } 50 | 51 | - (instancetype)init{ 52 | if (self = [super init]) { 53 | UIWindow *keyWindow = [[[UIApplication sharedApplication] delegate] window]; 54 | self.frame = CGRectMake(keyWindow.center.x, keyWindow.center.y, 0, 0); 55 | self.infoDic = [[NSMutableDictionary alloc] init]; 56 | 57 | self.clipsToBounds = YES; 58 | self.iconImageView = [[UIImageView alloc] init]; 59 | _iconImageView.clipsToBounds = YES; 60 | self.titleLabel = [[UILabel alloc] init]; 61 | _titleLabel.adjustsFontSizeToFitWidth = YES; 62 | _titleLabel.minimumScaleFactor = 0.5; 63 | _titleLabel.lineBreakMode = NSLineBreakByCharWrapping; 64 | _titleLabel.textAlignment = NSTextAlignmentCenter; 65 | [_titleLabel setNumberOfLines: 0]; 66 | // 初始化蒙版控件 67 | self.maskView = [[UIView alloc] initWithFrame: [UIScreen mainScreen].bounds]; 68 | _maskView.hidden = YES; 69 | 70 | [self addSubview: _iconImageView]; 71 | [self addSubview: _titleLabel]; 72 | } 73 | return self; 74 | } 75 | 76 | - (void)registerInfo: (LemonBubbleInfo *)info forKey: (NSString *)key{ 77 | self.infoDic[key] = info; 78 | } 79 | 80 | /** 81 | * @author 1em0nsOft LiuRi 82 | * @date 2016-08-30 16:08:53 83 | * 84 | * @brief 显示指定的信息模型对应的泡泡控件 85 | */ 86 | - (void)showWithInfo: (LemonBubbleInfo *)info{ 87 | self.currentInfo = info; 88 | self.closeKey = _currentInfo.key;// 保存当前要关闭的key,防止关闭不需要关闭的bubble 89 | UIWindow *mWindow = [[[UIApplication sharedApplication] delegate] window];// 防止使用Storyboard的时候keywindow为nil 90 | if (info.isShowMaskView) 91 | [mWindow addSubview: _maskView]; 92 | [mWindow addSubview: self]; 93 | 94 | // 弹簧动画改变外观 95 | [UIView animateWithDuration: 0.45 96 | delay:0 97 | usingSpringWithDamping: 0.8 98 | initialSpringVelocity:0.9 99 | options: UIViewAnimationOptionCurveEaseInOut 100 | animations:^{ 101 | self.transform = CGAffineTransformMakeScale(1, 1); 102 | if (_currentDrawLayer) { 103 | [_currentDrawLayer removeFromSuperlayer]; 104 | } 105 | self.frame = [info calBubbleViewFrame]; 106 | _titleLabel.text = info.title; 107 | _titleLabel.font = [UIFont systemFontOfSize: info.titleFontSize]; 108 | [info calIconView: _iconImageView andTitleView: _titleLabel]; 109 | self.layer.cornerRadius = info.cornerRadius; 110 | 111 | if (info.iconArray == nil || info.iconArray.count == 0) { 112 | // 显示自定义动画 113 | if (info.iconAnimation) { 114 | _iconImageView.image = [[UIImage alloc] init]; 115 | self.currentDrawLayer = [CAShapeLayer layer]; 116 | _currentDrawLayer.fillColor = [UIColor clearColor].CGColor; 117 | _currentDrawLayer.frame = _iconImageView.bounds; 118 | [_iconImageView.layer addSublayer: _currentDrawLayer]; 119 | [_currentTimer invalidate]; 120 | dispatch_async(dispatch_get_main_queue(), ^{ 121 | info.iconAnimation(_currentDrawLayer); 122 | }); 123 | } 124 | } 125 | else if (info.iconArray.count == 1){// 显示单张图片 126 | [_currentTimer invalidate]; 127 | self.iconImageView.image = info.iconArray[0]; 128 | } 129 | else{// 逐帧连环动画 130 | self.frameAnimationPlayIndex = 0;// 帧动画播放索引归零 131 | self.iconImageView.image = _currentInfo.iconArray[0]; 132 | self.currentTimer = 133 | [NSTimer scheduledTimerWithTimeInterval: info.frameAnimationTime 134 | target: self 135 | selector: @selector(frameAnimationPlayer) 136 | userInfo: nil 137 | repeats: YES]; 138 | } 139 | // maskView 140 | if (_currentInfo.isShowMaskView && _maskView.hidden) { 141 | // 本次需要显示,但是之前已经隐藏 142 | _maskView.alpha = 0; 143 | _maskView.hidden = NO; 144 | } 145 | _maskView.alpha = _currentInfo.isShowMaskView ? 1 : 0; 146 | } completion:^(BOOL finished) { 147 | if(!_currentInfo.isShowMaskView){ 148 | _maskView.hidden = YES; 149 | [_maskView removeFromSuperview]; 150 | } 151 | }]; 152 | 153 | [UIView animateWithDuration: 0.45 154 | delay:0 155 | options:UIViewAnimationOptionTransitionCurlUp 156 | animations:^{ 157 | _titleLabel.textColor = info.titleColor; 158 | [self setBackgroundColor: info.backgroundColor]; 159 | _currentDrawLayer.strokeColor = info.iconColor.CGColor; 160 | _maskView.backgroundColor = _currentInfo.maskColor; 161 | self.alpha = 1; 162 | } completion:^(BOOL finished) { 163 | 164 | }]; 165 | } 166 | 167 | 168 | /** 169 | 帧动画播放器 - NSTimer调用 170 | */ 171 | - (void)frameAnimationPlayer{ 172 | self.iconImageView.image = _currentInfo.iconArray[_frameAnimationPlayIndex]; 173 | self.frameAnimationPlayIndex = (_frameAnimationPlayIndex + 1) % _currentInfo.iconArray.count; 174 | } 175 | 176 | /** 177 | * @author 1em0nsOft LiuRi 178 | * @date 2016-08-30 16:08:53 179 | * 180 | * @brief 通过传入键来显示已经注册的指定样式泡泡控件 181 | */ 182 | - (void)showWithInfoKey: (NSString *)infoKey{ 183 | if ([self.infoDic.allKeys containsObject: infoKey]){ 184 | [self showWithInfo: self.infoDic[infoKey]]; 185 | } 186 | } 187 | 188 | /** 189 | * @author 1em0nsOft LiuRi 190 | * @date 2016-08-30 16:08:53 191 | * 192 | * @brief 显示指定的信息模型对应的泡泡控件,并指定的时间后隐藏 193 | * 194 | * @param info 样式信息模型 195 | * @param time 指定时间后隐藏泡泡控件的秒数 196 | */ 197 | - (void)showWithInfo: (LemonBubbleInfo *)info autoCloseTime: (CGFloat)time{ 198 | [self showWithInfo: info]; 199 | [self performSelector: @selector(hide) 200 | withObject: self 201 | afterDelay: time + 0.2]; 202 | } 203 | 204 | /** 205 | * @author 1em0nsOft LiuRi 206 | * @date 2016-08-30 16:08:53 207 | * 208 | * @brief 显示指定的信息模型对应的泡泡控件,并指定的时间后隐藏 209 | * 210 | * @param infoKey 已注册的样式信息模型的键 211 | * @param time 指定时间后隐藏泡泡控件的秒数 212 | */ 213 | - (void)showWithInfoKey: (NSString *)infoKey autoCloseTime: (CGFloat)time{ 214 | if ([self.infoDic.allKeys containsObject: infoKey]){ 215 | [self showWithInfo: _infoDic[infoKey] 216 | autoCloseTime: time]; 217 | } 218 | } 219 | 220 | /** 221 | * @author chenjunsheng 222 | * @date 2016-12-18 16:08:40 223 | * 224 | * @brief 隐藏当前泡泡控件 225 | */ 226 | - (void)hideWithCloseTime: (CGFloat)time { 227 | [self performSelector: @selector(hide) 228 | withObject: self 229 | afterDelay: time]; 230 | } 231 | 232 | /** 233 | * @author 1em0nsOft LiuRi 234 | * @date 2016-08-30 16:08:40 235 | * 236 | * @brief 隐藏当前泡泡控件 237 | */ 238 | - (void)hide{ 239 | if (self.closeKey == _currentInfo.key){// 要关闭的key没有变化,可以关闭 240 | // 动画缩放,更改透明度使其动画隐藏 241 | [UIView animateWithDuration: 0.2 242 | delay: 0 243 | options: UIViewAnimationOptionCurveEaseOut 244 | animations:^{ 245 | self.transform = CGAffineTransformMakeScale(0.5f, 0.5f); 246 | _maskView.alpha = 0; 247 | self.alpha = 0; 248 | // 记得把定时器停了 249 | [_currentTimer invalidate]; 250 | } completion:^(BOOL finished) { 251 | // 从父层控件中移除 252 | [self removeFromSuperview]; 253 | [_maskView removeFromSuperview]; 254 | }]; 255 | } 256 | } 257 | 258 | - (void)setProgress:(CGFloat)progress{ 259 | self.progress = progress; 260 | if (_currentInfo.onProgressChanged != nil){ 261 | dispatch_async(dispatch_get_main_queue(), ^{ 262 | _currentInfo.onProgressChanged(_currentDrawLayer, progress); 263 | }); 264 | } 265 | } 266 | 267 | @end 268 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble/UIResponder+LemonBubble.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIResponder+LemonBubble.m 3 | // LemonKit 4 | // 5 | // Created by 1em0nsOft on 16/8/30. 6 | // Copyright © 2016年 1em0nsOft. All rights reserved. 7 | // 8 | 9 | #import "UIResponder+LemonBubble.h" 10 | 11 | @implementation UIResponder (LemonBubble) 12 | 13 | - (LemonBubbleInfo *)getDefaultRightBubbleInfo{ 14 | LemonBubbleInfo *info = [[LemonBubbleInfo alloc] init]; 15 | info.iconAnimation = ^(CAShapeLayer *layer){ 16 | const int STROKE_WIDTH = 3;// 默认的划线线条宽度 17 | 18 | // 绘制外部透明的圆形 19 | UIBezierPath *circlePath = [UIBezierPath bezierPath]; 20 | [circlePath addArcWithCenter: CGPointMake(layer.frame.size.width / 2, layer.frame.size.height / 2) radius:layer.frame.size.width / 2 - STROKE_WIDTH startAngle: 0 * M_PI/180 endAngle: 360 * M_PI/180 clockwise: NO]; 21 | // 创建外部透明圆形的图层 22 | CAShapeLayer *alphaLineLayer = [CAShapeLayer layer]; 23 | alphaLineLayer.path = circlePath.CGPath;// 设置透明圆形的绘图路径 24 | alphaLineLayer.strokeColor = [[UIColor colorWithCGColor: layer.strokeColor] colorWithAlphaComponent: 0.1].CGColor;// 设置图层的透明圆形的颜色 25 | alphaLineLayer.lineWidth = STROKE_WIDTH;// 设置圆形的线宽 26 | alphaLineLayer.fillColor = [UIColor clearColor].CGColor;// 填充颜色透明 27 | 28 | [layer addSublayer: alphaLineLayer];// 把外部半透明圆形的图层加到当前图层上 29 | 30 | // 设置当前图层的绘制属性 31 | layer.fillColor = [UIColor clearColor].CGColor; 32 | layer.lineCap = kCALineCapRound;// 圆角画笔 33 | layer.lineWidth = STROKE_WIDTH; 34 | 35 | // 半圆+动画的绘制路径初始化 36 | UIBezierPath *path = [UIBezierPath bezierPath]; 37 | // 绘制大半圆 38 | [path addArcWithCenter: CGPointMake(layer.frame.size.width / 2, layer.frame.size.height / 2) radius:layer.frame.size.width / 2 - STROKE_WIDTH startAngle: 67 * M_PI / 180 endAngle: -158 * M_PI / 180 clockwise: NO]; 39 | // 绘制对号第一笔 40 | [path addLineToPoint: CGPointMake(layer.frame.size.width * 0.42, layer.frame.size.width * 0.68)]; 41 | // 绘制对号第二笔 42 | [path addLineToPoint: CGPointMake(layer.frame.size.width * 0.75, layer.frame.size.width * 0.35)]; 43 | // 把路径设置为当前图层的路径 44 | layer.path = path.CGPath; 45 | 46 | CAMediaTimingFunction *timing = [[CAMediaTimingFunction alloc] initWithControlPoints:0.3 :0.6 :0.8 :1.1]; 47 | // 创建路径顺序绘制的动画 48 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath: @"strokeEnd"]; 49 | animation.duration = 0.5;// 动画使用时间 50 | animation.fromValue = [NSNumber numberWithInt: 0.0];// 从头 51 | animation.toValue = [NSNumber numberWithInt: 1.0];// 画到尾 52 | // 创建路径顺序从结尾开始消失的动画 53 | CABasicAnimation *strokeStartAnimation = [CABasicAnimation animationWithKeyPath: @"strokeStart"]; 54 | strokeStartAnimation.duration = 0.4;// 动画使用时间 55 | strokeStartAnimation.beginTime = CACurrentMediaTime() + 0.2;// 延迟0.2秒执行动画 56 | strokeStartAnimation.fromValue = [NSNumber numberWithFloat: 0.0];// 从开始消失 57 | strokeStartAnimation.toValue = [NSNumber numberWithFloat: 0.74];// 一直消失到整个绘制路径的74%,这个数没有啥技巧,一点点调试看效果,希望看此代码的人不要被这个数值怎么来的困惑 58 | strokeStartAnimation.timingFunction = timing; 59 | 60 | layer.strokeStart = 0.74;// 设置最终效果,防止动画结束之后效果改变 61 | layer.strokeEnd = 1.0; 62 | 63 | [layer addAnimation: animation forKey: @"strokeEnd"];// 添加俩动画 64 | [layer addAnimation: strokeStartAnimation forKey: @"strokeStart"]; 65 | }; 66 | info.title = @"成功"; 67 | info.backgroundColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.95 alpha:1]; 68 | info.iconColor = [UIColor colorWithRed: 0 / 255.0 green: 205 / 255.0 blue:0 alpha:1]; 69 | info.titleColor = [UIColor blackColor]; 70 | // info.layoutStyle = BUBBLE_LAYOUT_STYLE_ICON_LEFT_TITLE_RIGHT; 71 | info.bubbleSize = CGSizeMake(200, 130); 72 | 73 | return info; 74 | } 75 | 76 | - (void)showRightWithTitle: (NSString *)title autoCloseTime: (CGFloat)autoCloseTime{ 77 | LemonBubbleInfo *info = [self getDefaultRightBubbleInfo]; 78 | info.title = title; 79 | [[LemonBubbleView defaultBubbleView] showWithInfo: info autoCloseTime: autoCloseTime]; 80 | } 81 | 82 | - (LemonBubbleInfo *)getDefaultRoundProgressBubbleInfo{ 83 | LemonBubbleInfo *info = [[LemonBubbleInfo alloc] init]; 84 | info.iconAnimation = ^(CAShapeLayer *layer){ 85 | const int STROKE_WIDTH = 3; 86 | 87 | // 绘制外部透明的圆形 88 | UIBezierPath *circlePath = [UIBezierPath bezierPath]; 89 | [circlePath addArcWithCenter: CGPointMake(layer.frame.size.width / 2, layer.frame.size.height / 2) radius:layer.frame.size.width / 2 - STROKE_WIDTH startAngle: 0 * M_PI/180 endAngle: 360 * M_PI/180 clockwise: NO]; 90 | // 创建外部透明圆形的图层 91 | CAShapeLayer *alphaLineLayer = [CAShapeLayer layer]; 92 | alphaLineLayer.path = circlePath.CGPath;// 设置透明圆形的绘图路径 93 | alphaLineLayer.strokeColor = [[UIColor colorWithCGColor: layer.strokeColor] colorWithAlphaComponent: 0.1].CGColor;// 设置图层的透明圆形的颜色 94 | alphaLineLayer.lineWidth = STROKE_WIDTH;// 设置圆形的线宽 95 | alphaLineLayer.fillColor = [UIColor clearColor].CGColor;// 填充颜色透明 96 | 97 | [layer addSublayer: alphaLineLayer];// 把外部半透明圆形的图层加到当前图层上 98 | 99 | CAShapeLayer *drawLayer = [CAShapeLayer layer]; 100 | UIBezierPath *progressPath = [UIBezierPath bezierPath]; 101 | [progressPath addArcWithCenter: CGPointMake(layer.frame.size.width / 2, layer.frame.size.height / 2) radius:layer.frame.size.width / 2 - STROKE_WIDTH startAngle: 0 * M_PI / 180 endAngle: 360 * M_PI / 180 clockwise: YES]; 102 | 103 | drawLayer.lineWidth = STROKE_WIDTH; 104 | drawLayer.fillColor = [UIColor clearColor].CGColor; 105 | drawLayer.path = progressPath.CGPath; 106 | drawLayer.frame = drawLayer.bounds; 107 | drawLayer.strokeColor = layer.strokeColor; 108 | [layer addSublayer: drawLayer]; 109 | 110 | CAMediaTimingFunction *progressRotateTimingFunction = [CAMediaTimingFunction functionWithControlPoints:0.25 :0.80 :0.75 :1.00]; 111 | 112 | // 开始划线的动画 113 | CABasicAnimation *progressLongAnimation = [CABasicAnimation animationWithKeyPath: @"strokeEnd"]; 114 | progressLongAnimation.removedOnCompletion = NO; 115 | progressLongAnimation.fromValue = [NSNumber numberWithFloat: 0.0]; 116 | progressLongAnimation.toValue = [NSNumber numberWithFloat: 1.0]; 117 | progressLongAnimation.duration = 2; 118 | progressLongAnimation.timingFunction = progressRotateTimingFunction; 119 | progressLongAnimation.repeatCount = 10000; 120 | // 线条逐渐变短收缩的动画 121 | CABasicAnimation *progressLongEndAnimation = [CABasicAnimation animationWithKeyPath: @"strokeStart"]; 122 | progressLongEndAnimation.removedOnCompletion = NO; 123 | progressLongEndAnimation.fromValue = [NSNumber numberWithFloat: 0.0]; 124 | progressLongEndAnimation.toValue = [NSNumber numberWithFloat: 1.0]; 125 | progressLongEndAnimation.duration = 2; 126 | CAMediaTimingFunction *strokeStartTimingFunction = [[CAMediaTimingFunction alloc] initWithControlPoints: 0.65 : 0.0 :1.0 : 1.0]; 127 | progressLongEndAnimation.timingFunction = strokeStartTimingFunction; 128 | progressLongEndAnimation.repeatCount = 10000; 129 | // 线条不断旋转的动画 130 | CABasicAnimation *progressRotateAnimation = [CABasicAnimation animationWithKeyPath: @"transform.rotation.z"]; 131 | progressRotateAnimation.removedOnCompletion = NO; 132 | progressRotateAnimation.fromValue = [NSNumber numberWithFloat: 0.0]; 133 | progressRotateAnimation.toValue = [NSNumber numberWithFloat: M_PI / 180 * 360]; 134 | progressRotateAnimation.repeatCount = 1000000; 135 | progressRotateAnimation.duration = 6; 136 | 137 | [drawLayer addAnimation:progressLongAnimation forKey: @"strokeEnd"]; 138 | [layer addAnimation:progressRotateAnimation forKey: @"transfrom.rotation.z"]; 139 | [drawLayer addAnimation: progressLongEndAnimation forKey: @"strokeStart"]; 140 | }; 141 | info.title = @"请稍候..."; 142 | info.bubbleSize = CGSizeMake(140, 120); 143 | info.maskColor = [UIColor colorWithRed: 0.1 green:0.1 blue:0.1 alpha:0.4]; 144 | info.backgroundColor = [UIColor colorWithRed: 0.1 green:0.1 blue:0.1 alpha:0.8]; 145 | return info; 146 | } 147 | 148 | - (void)showRoundProgressWithTitle: (NSString *)title{ 149 | LemonBubbleInfo *info = [self getDefaultRoundProgressBubbleInfo]; 150 | info.title = title; 151 | [[LemonBubbleView defaultBubbleView] showWithInfo: info]; 152 | } 153 | 154 | - (LemonBubbleInfo *)getDefaultErrorBubbleInfo{ 155 | LemonBubbleInfo *info = [[LemonBubbleInfo alloc] init]; 156 | info.iconAnimation = ^(CAShapeLayer *layer){ 157 | const int STROKE_WIDTH = 3;// 默认的划线线条宽度 158 | 159 | // 绘制外部透明的圆形 160 | UIBezierPath *circlePath = [UIBezierPath bezierPath]; 161 | [circlePath addArcWithCenter: CGPointMake(layer.frame.size.width / 2, layer.frame.size.height / 2) radius:layer.frame.size.width / 2 - STROKE_WIDTH startAngle: 0 * M_PI/180 endAngle: 360 * M_PI/180 clockwise: NO]; 162 | // 创建外部透明圆形的图层 163 | CAShapeLayer *alphaLineLayer = [CAShapeLayer layer]; 164 | alphaLineLayer.path = circlePath.CGPath;// 设置透明圆形的绘图路径 165 | alphaLineLayer.strokeColor = [[UIColor colorWithCGColor: layer.strokeColor] colorWithAlphaComponent: 0.1].CGColor; 166 | // ↑ 设置图层的透明圆形的颜色,取图标颜色之后设置其对应的0.1透明度的颜色 167 | alphaLineLayer.lineWidth = STROKE_WIDTH;// 设置圆形的线宽 168 | alphaLineLayer.fillColor = [UIColor clearColor].CGColor;// 填充颜色透明 169 | 170 | [layer addSublayer: alphaLineLayer];// 把外部半透明圆形的图层加到当前图层上 171 | 172 | // 开始画叉的两条线,首先画逆时针旋转的线 173 | CAShapeLayer *leftLayer = [CAShapeLayer layer]; 174 | // 设置当前图层的绘制属性 175 | leftLayer.frame = layer.bounds; 176 | leftLayer.fillColor = [UIColor clearColor].CGColor; 177 | leftLayer.lineCap = kCALineCapRound;// 圆角画笔 178 | leftLayer.lineWidth = STROKE_WIDTH; 179 | leftLayer.strokeColor = layer.strokeColor; 180 | 181 | // 半圆+动画的绘制路径初始化 182 | UIBezierPath *leftPath = [UIBezierPath bezierPath]; 183 | // 绘制大半圆 184 | [leftPath addArcWithCenter: CGPointMake(layer.frame.size.width / 2, layer.frame.size.height / 2) radius:layer.frame.size.width / 2 - STROKE_WIDTH startAngle: -43 * M_PI / 180 endAngle: -315 * M_PI / 180 clockwise: NO]; 185 | [leftPath addLineToPoint: CGPointMake(layer.frame.size.width * 0.35, layer.frame.size.width * 0.35)]; 186 | // 把路径设置为当前图层的路径 187 | leftLayer.path = leftPath.CGPath; 188 | 189 | [layer addSublayer: leftLayer]; 190 | 191 | // 逆时针旋转的线 192 | CAShapeLayer *rightLayer = [CAShapeLayer layer]; 193 | // 设置当前图层的绘制属性 194 | rightLayer.frame = layer.bounds; 195 | rightLayer.fillColor = [UIColor clearColor].CGColor; 196 | rightLayer.lineCap = kCALineCapRound;// 圆角画笔 197 | rightLayer.lineWidth = STROKE_WIDTH; 198 | rightLayer.strokeColor = layer.strokeColor; 199 | 200 | // 半圆+动画的绘制路径初始化 201 | UIBezierPath *rightPath = [UIBezierPath bezierPath]; 202 | // 绘制大半圆 203 | [rightPath addArcWithCenter: CGPointMake(layer.frame.size.width / 2, layer.frame.size.height / 2) radius:layer.frame.size.width / 2 - STROKE_WIDTH startAngle: -128 * M_PI / 180 endAngle: 133 * M_PI / 180 clockwise: YES]; 204 | [rightPath addLineToPoint: CGPointMake(layer.frame.size.width * 0.65, layer.frame.size.width * 0.35)]; 205 | // 把路径设置为当前图层的路径 206 | rightLayer.path = rightPath.CGPath; 207 | 208 | [layer addSublayer: rightLayer]; 209 | 210 | 211 | CAMediaTimingFunction *timing = [[CAMediaTimingFunction alloc] initWithControlPoints:0.3 :0.6 :0.8 :1.1]; 212 | // 创建路径顺序绘制的动画 213 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath: @"strokeEnd"]; 214 | animation.duration = 0.5;// 动画使用时间 215 | animation.fromValue = [NSNumber numberWithInt: 0.0];// 从头 216 | animation.toValue = [NSNumber numberWithInt: 1.0];// 画到尾 217 | // 创建路径顺序从结尾开始消失的动画 218 | CABasicAnimation *strokeStartAnimation = [CABasicAnimation animationWithKeyPath: @"strokeStart"]; 219 | strokeStartAnimation.duration = 0.4;// 动画使用时间 220 | strokeStartAnimation.beginTime = CACurrentMediaTime() + 0.2;// 延迟0.2秒执行动画 221 | strokeStartAnimation.fromValue = [NSNumber numberWithFloat: 0.0];// 从开始消失 222 | strokeStartAnimation.toValue = [NSNumber numberWithFloat: 0.84];// 一直消失到整个绘制路径的84%,这个数没有啥技巧,一点点调试看效果,希望看此代码的人不要被这个数值怎么来的困惑 223 | strokeStartAnimation.timingFunction = timing; 224 | 225 | leftLayer.strokeStart = 0.84;// 设置最终效果,防止动画结束之后效果改变 226 | leftLayer.strokeEnd = 1.0; 227 | rightLayer.strokeStart = 0.84;// 设置最终效果,防止动画结束之后效果改变 228 | rightLayer.strokeEnd = 1.0; 229 | 230 | 231 | [leftLayer addAnimation: animation forKey: @"strokeEnd"];// 添加俩动画 232 | [leftLayer addAnimation: strokeStartAnimation forKey: @"strokeStart"]; 233 | [rightLayer addAnimation: animation forKey: @"strokeEnd"];// 添加俩动画 234 | [rightLayer addAnimation: strokeStartAnimation forKey: @"strokeStart"]; 235 | }; 236 | info.title = @"发生了一个错误"; 237 | info.backgroundColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.95 alpha:1]; 238 | info.iconColor = [UIColor colorWithRed: 255 / 255.0 green: 48 / 255.0 blue: 48 / 255.0 alpha:1]; 239 | info.titleColor = [UIColor blackColor]; 240 | info.layoutStyle = BUBBLE_LAYOUT_STYLE_ICON_TOP_TITLE_BOTTOM; 241 | info.bubbleSize = CGSizeMake(200, 130); 242 | return info; 243 | } 244 | 245 | - (void)showErrorWithTitle: (NSString *)title autoCloseTime: (CGFloat)autoCloseTime{ 246 | LemonBubbleInfo *info = [self getDefaultErrorBubbleInfo]; 247 | info.title = title; 248 | [[LemonBubbleView defaultBubbleView] showWithInfo: info autoCloseTime: autoCloseTime]; 249 | } 250 | 251 | - (void)hideBubble{ 252 | [[LemonBubbleView defaultBubbleView] hide]; 253 | } 254 | 255 | /** 256 | 定时隐藏现在显示的泡泡控件 257 | */ 258 | - (void)hideBubbleAfter:(CGFloat)duration { 259 | [[LemonBubbleView defaultBubbleView] hideWithCloseTime:duration]; 260 | } 261 | 262 | - (void)showBubbleWithInfo: (LemonBubbleInfo *)info{ 263 | [[LemonBubbleView defaultBubbleView] showWithInfo: info]; 264 | } 265 | 266 | - (void)showBubbleWithInfo: (LemonBubbleInfo *)info time: (CGFloat)time{ 267 | [[LemonBubbleView defaultBubbleView] showWithInfo: info autoCloseTime: time]; 268 | } 269 | 270 | @end 271 | -------------------------------------------------------------------------------- /LemonBubble/LemonBubble.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5291A4EC1E053A1900E8C03A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5291A4EB1E053A1900E8C03A /* main.m */; }; 11 | 5291A4EF1E053A1900E8C03A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5291A4EE1E053A1900E8C03A /* AppDelegate.m */; }; 12 | 5291A4F21E053A1900E8C03A /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5291A4F11E053A1900E8C03A /* ViewController.m */; }; 13 | 5291A4F51E053A1900E8C03A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5291A4F31E053A1900E8C03A /* Main.storyboard */; }; 14 | 5291A4F71E053A1900E8C03A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5291A4F61E053A1900E8C03A /* Assets.xcassets */; }; 15 | 5291A4FA1E053A1900E8C03A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5291A4F81E053A1900E8C03A /* LaunchScreen.storyboard */; }; 16 | 5291A5061E053AA000E8C03A /* LemonBubbleInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 5291A5011E053AA000E8C03A /* LemonBubbleInfo.m */; }; 17 | 5291A5071E053AA000E8C03A /* LemonBubbleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5291A5031E053AA000E8C03A /* LemonBubbleView.m */; }; 18 | 5291A5081E053AA000E8C03A /* UIResponder+LemonBubble.m in Sources */ = {isa = PBXBuildFile; fileRef = 5291A5051E053AA000E8C03A /* UIResponder+LemonBubble.m */; }; 19 | 52A842821E053D3E000D6A82 /* libLemonBubble.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5291A4D81E0539E800E8C03A /* libLemonBubble.a */; }; 20 | 52D26E7B1E06B524008ABC1F /* icon_bottom.png in Resources */ = {isa = PBXBuildFile; fileRef = 52D26E771E06B524008ABC1F /* icon_bottom.png */; }; 21 | 52D26E7C1E06B524008ABC1F /* icon_error.png in Resources */ = {isa = PBXBuildFile; fileRef = 52D26E781E06B524008ABC1F /* icon_error.png */; }; 22 | 52D26E7D1E06B524008ABC1F /* icon_right.png in Resources */ = {isa = PBXBuildFile; fileRef = 52D26E791E06B524008ABC1F /* icon_right.png */; }; 23 | 52D26E7E1E06B524008ABC1F /* icon_wait.png in Resources */ = {isa = PBXBuildFile; fileRef = 52D26E7A1E06B524008ABC1F /* icon_wait.png */; }; 24 | 52D26E811E06B5CE008ABC1F /* RoundFunctionButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 52D26E801E06B5CE008ABC1F /* RoundFunctionButton.m */; }; 25 | EA5E0CCE1E0A167C0082CC1B /* icon_ppt.png in Resources */ = {isa = PBXBuildFile; fileRef = EA5E0CC51E0A167C0082CC1B /* icon_ppt.png */; }; 26 | EA5E0CCF1E0A167C0082CC1B /* lkbubble1.jpg in Resources */ = {isa = PBXBuildFile; fileRef = EA5E0CC61E0A167C0082CC1B /* lkbubble1.jpg */; }; 27 | EA5E0CD01E0A167C0082CC1B /* lkbubble2.jpg in Resources */ = {isa = PBXBuildFile; fileRef = EA5E0CC71E0A167C0082CC1B /* lkbubble2.jpg */; }; 28 | EA5E0CD11E0A167C0082CC1B /* lkbubble3.jpg in Resources */ = {isa = PBXBuildFile; fileRef = EA5E0CC81E0A167C0082CC1B /* lkbubble3.jpg */; }; 29 | EA5E0CD21E0A167C0082CC1B /* lkbubble4.jpg in Resources */ = {isa = PBXBuildFile; fileRef = EA5E0CC91E0A167C0082CC1B /* lkbubble4.jpg */; }; 30 | EA5E0CD31E0A167C0082CC1B /* lkbubble5.jpg in Resources */ = {isa = PBXBuildFile; fileRef = EA5E0CCA1E0A167C0082CC1B /* lkbubble5.jpg */; }; 31 | EA5E0CD41E0A167C0082CC1B /* lkbubble6.jpg in Resources */ = {isa = PBXBuildFile; fileRef = EA5E0CCB1E0A167C0082CC1B /* lkbubble6.jpg */; }; 32 | EA5E0CD51E0A167C0082CC1B /* lkbubble7.jpg in Resources */ = {isa = PBXBuildFile; fileRef = EA5E0CCC1E0A167C0082CC1B /* lkbubble7.jpg */; }; 33 | EA5E0CD61E0A167C0082CC1B /* lkbubble8.jpg in Resources */ = {isa = PBXBuildFile; fileRef = EA5E0CCD1E0A167C0082CC1B /* lkbubble8.jpg */; }; 34 | EA5E0CD81E0A17840082CC1B /* icon_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = EA5E0CD71E0A17840082CC1B /* icon_icon.png */; }; 35 | /* End PBXBuildFile section */ 36 | 37 | /* Begin PBXCopyFilesBuildPhase section */ 38 | 5291A4D61E0539E800E8C03A /* CopyFiles */ = { 39 | isa = PBXCopyFilesBuildPhase; 40 | buildActionMask = 2147483647; 41 | dstPath = "include/$(PRODUCT_NAME)"; 42 | dstSubfolderSpec = 16; 43 | files = ( 44 | ); 45 | runOnlyForDeploymentPostprocessing = 0; 46 | }; 47 | /* End PBXCopyFilesBuildPhase section */ 48 | 49 | /* Begin PBXFileReference section */ 50 | 5291A4D81E0539E800E8C03A /* libLemonBubble.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libLemonBubble.a; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 5291A4E81E053A1900E8C03A /* LemonBubble-samples.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "LemonBubble-samples.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 5291A4EB1E053A1900E8C03A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 53 | 5291A4ED1E053A1900E8C03A /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 54 | 5291A4EE1E053A1900E8C03A /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 55 | 5291A4F01E053A1900E8C03A /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 56 | 5291A4F11E053A1900E8C03A /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 57 | 5291A4F41E053A1900E8C03A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 58 | 5291A4F61E053A1900E8C03A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 59 | 5291A4F91E053A1900E8C03A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 60 | 5291A4FB1E053A1900E8C03A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 61 | 5291A4FF1E053AA000E8C03A /* LemonBubble.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LemonBubble.h; sourceTree = ""; }; 62 | 5291A5001E053AA000E8C03A /* LemonBubbleInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LemonBubbleInfo.h; sourceTree = ""; }; 63 | 5291A5011E053AA000E8C03A /* LemonBubbleInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LemonBubbleInfo.m; sourceTree = ""; }; 64 | 5291A5021E053AA000E8C03A /* LemonBubbleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LemonBubbleView.h; sourceTree = ""; }; 65 | 5291A5031E053AA000E8C03A /* LemonBubbleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LemonBubbleView.m; sourceTree = ""; }; 66 | 5291A5041E053AA000E8C03A /* UIResponder+LemonBubble.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIResponder+LemonBubble.h"; sourceTree = ""; }; 67 | 5291A5051E053AA000E8C03A /* UIResponder+LemonBubble.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIResponder+LemonBubble.m"; sourceTree = ""; }; 68 | 52D26E771E06B524008ABC1F /* icon_bottom.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_bottom.png; sourceTree = ""; }; 69 | 52D26E781E06B524008ABC1F /* icon_error.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_error.png; sourceTree = ""; }; 70 | 52D26E791E06B524008ABC1F /* icon_right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_right.png; sourceTree = ""; }; 71 | 52D26E7A1E06B524008ABC1F /* icon_wait.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_wait.png; sourceTree = ""; }; 72 | 52D26E7F1E06B5CE008ABC1F /* RoundFunctionButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoundFunctionButton.h; sourceTree = ""; }; 73 | 52D26E801E06B5CE008ABC1F /* RoundFunctionButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoundFunctionButton.m; sourceTree = ""; }; 74 | EA5E0CC51E0A167C0082CC1B /* icon_ppt.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_ppt.png; sourceTree = ""; }; 75 | EA5E0CC61E0A167C0082CC1B /* lkbubble1.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lkbubble1.jpg; sourceTree = ""; }; 76 | EA5E0CC71E0A167C0082CC1B /* lkbubble2.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lkbubble2.jpg; sourceTree = ""; }; 77 | EA5E0CC81E0A167C0082CC1B /* lkbubble3.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lkbubble3.jpg; sourceTree = ""; }; 78 | EA5E0CC91E0A167C0082CC1B /* lkbubble4.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lkbubble4.jpg; sourceTree = ""; }; 79 | EA5E0CCA1E0A167C0082CC1B /* lkbubble5.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lkbubble5.jpg; sourceTree = ""; }; 80 | EA5E0CCB1E0A167C0082CC1B /* lkbubble6.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lkbubble6.jpg; sourceTree = ""; }; 81 | EA5E0CCC1E0A167C0082CC1B /* lkbubble7.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lkbubble7.jpg; sourceTree = ""; }; 82 | EA5E0CCD1E0A167C0082CC1B /* lkbubble8.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = lkbubble8.jpg; sourceTree = ""; }; 83 | EA5E0CD71E0A17840082CC1B /* icon_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_icon.png; sourceTree = ""; }; 84 | /* End PBXFileReference section */ 85 | 86 | /* Begin PBXFrameworksBuildPhase section */ 87 | 5291A4D51E0539E800E8C03A /* Frameworks */ = { 88 | isa = PBXFrameworksBuildPhase; 89 | buildActionMask = 2147483647; 90 | files = ( 91 | ); 92 | runOnlyForDeploymentPostprocessing = 0; 93 | }; 94 | 5291A4E51E053A1900E8C03A /* Frameworks */ = { 95 | isa = PBXFrameworksBuildPhase; 96 | buildActionMask = 2147483647; 97 | files = ( 98 | 52A842821E053D3E000D6A82 /* libLemonBubble.a in Frameworks */, 99 | ); 100 | runOnlyForDeploymentPostprocessing = 0; 101 | }; 102 | /* End PBXFrameworksBuildPhase section */ 103 | 104 | /* Begin PBXGroup section */ 105 | 5291A4CF1E0539E800E8C03A = { 106 | isa = PBXGroup; 107 | children = ( 108 | 5291A4DA1E0539E800E8C03A /* LemonBubble */, 109 | 5291A4E91E053A1900E8C03A /* LemonBubble-samples */, 110 | 5291A4D91E0539E800E8C03A /* Products */, 111 | ); 112 | sourceTree = ""; 113 | }; 114 | 5291A4D91E0539E800E8C03A /* Products */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 5291A4D81E0539E800E8C03A /* libLemonBubble.a */, 118 | 5291A4E81E053A1900E8C03A /* LemonBubble-samples.app */, 119 | ); 120 | name = Products; 121 | sourceTree = ""; 122 | }; 123 | 5291A4DA1E0539E800E8C03A /* LemonBubble */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 5291A4FF1E053AA000E8C03A /* LemonBubble.h */, 127 | 5291A5001E053AA000E8C03A /* LemonBubbleInfo.h */, 128 | 5291A5011E053AA000E8C03A /* LemonBubbleInfo.m */, 129 | 5291A5021E053AA000E8C03A /* LemonBubbleView.h */, 130 | 5291A5031E053AA000E8C03A /* LemonBubbleView.m */, 131 | 5291A5041E053AA000E8C03A /* UIResponder+LemonBubble.h */, 132 | 5291A5051E053AA000E8C03A /* UIResponder+LemonBubble.m */, 133 | ); 134 | path = LemonBubble; 135 | sourceTree = ""; 136 | }; 137 | 5291A4E91E053A1900E8C03A /* LemonBubble-samples */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | 52D26E761E06B417008ABC1F /* Resource */, 141 | 5291A4ED1E053A1900E8C03A /* AppDelegate.h */, 142 | 5291A4EE1E053A1900E8C03A /* AppDelegate.m */, 143 | 5291A4F01E053A1900E8C03A /* ViewController.h */, 144 | 5291A4F11E053A1900E8C03A /* ViewController.m */, 145 | 5291A4F31E053A1900E8C03A /* Main.storyboard */, 146 | 5291A4F61E053A1900E8C03A /* Assets.xcassets */, 147 | 5291A4F81E053A1900E8C03A /* LaunchScreen.storyboard */, 148 | 5291A4FB1E053A1900E8C03A /* Info.plist */, 149 | 5291A4EA1E053A1900E8C03A /* Supporting Files */, 150 | 52D26E7F1E06B5CE008ABC1F /* RoundFunctionButton.h */, 151 | 52D26E801E06B5CE008ABC1F /* RoundFunctionButton.m */, 152 | ); 153 | path = "LemonBubble-samples"; 154 | sourceTree = ""; 155 | }; 156 | 5291A4EA1E053A1900E8C03A /* Supporting Files */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 5291A4EB1E053A1900E8C03A /* main.m */, 160 | ); 161 | name = "Supporting Files"; 162 | sourceTree = ""; 163 | }; 164 | 52D26E761E06B417008ABC1F /* Resource */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | EA5E0CD71E0A17840082CC1B /* icon_icon.png */, 168 | 52D26E771E06B524008ABC1F /* icon_bottom.png */, 169 | 52D26E781E06B524008ABC1F /* icon_error.png */, 170 | 52D26E791E06B524008ABC1F /* icon_right.png */, 171 | 52D26E7A1E06B524008ABC1F /* icon_wait.png */, 172 | EA5E0CC51E0A167C0082CC1B /* icon_ppt.png */, 173 | EA5E0CC61E0A167C0082CC1B /* lkbubble1.jpg */, 174 | EA5E0CC71E0A167C0082CC1B /* lkbubble2.jpg */, 175 | EA5E0CC81E0A167C0082CC1B /* lkbubble3.jpg */, 176 | EA5E0CC91E0A167C0082CC1B /* lkbubble4.jpg */, 177 | EA5E0CCA1E0A167C0082CC1B /* lkbubble5.jpg */, 178 | EA5E0CCB1E0A167C0082CC1B /* lkbubble6.jpg */, 179 | EA5E0CCC1E0A167C0082CC1B /* lkbubble7.jpg */, 180 | EA5E0CCD1E0A167C0082CC1B /* lkbubble8.jpg */, 181 | ); 182 | path = Resource; 183 | sourceTree = ""; 184 | }; 185 | /* End PBXGroup section */ 186 | 187 | /* Begin PBXNativeTarget section */ 188 | 5291A4D71E0539E800E8C03A /* LemonBubble */ = { 189 | isa = PBXNativeTarget; 190 | buildConfigurationList = 5291A4E11E0539E800E8C03A /* Build configuration list for PBXNativeTarget "LemonBubble" */; 191 | buildPhases = ( 192 | 5291A4D41E0539E800E8C03A /* Sources */, 193 | 5291A4D51E0539E800E8C03A /* Frameworks */, 194 | 5291A4D61E0539E800E8C03A /* CopyFiles */, 195 | ); 196 | buildRules = ( 197 | ); 198 | dependencies = ( 199 | ); 200 | name = LemonBubble; 201 | productName = LemonBubble; 202 | productReference = 5291A4D81E0539E800E8C03A /* libLemonBubble.a */; 203 | productType = "com.apple.product-type.library.static"; 204 | }; 205 | 5291A4E71E053A1900E8C03A /* LemonBubble-samples */ = { 206 | isa = PBXNativeTarget; 207 | buildConfigurationList = 5291A4FC1E053A1900E8C03A /* Build configuration list for PBXNativeTarget "LemonBubble-samples" */; 208 | buildPhases = ( 209 | 5291A4E41E053A1900E8C03A /* Sources */, 210 | 5291A4E51E053A1900E8C03A /* Frameworks */, 211 | 5291A4E61E053A1900E8C03A /* Resources */, 212 | ); 213 | buildRules = ( 214 | ); 215 | dependencies = ( 216 | ); 217 | name = "LemonBubble-samples"; 218 | productName = "LemonBubble-samples"; 219 | productReference = 5291A4E81E053A1900E8C03A /* LemonBubble-samples.app */; 220 | productType = "com.apple.product-type.application"; 221 | }; 222 | /* End PBXNativeTarget section */ 223 | 224 | /* Begin PBXProject section */ 225 | 5291A4D01E0539E800E8C03A /* Project object */ = { 226 | isa = PBXProject; 227 | attributes = { 228 | LastUpgradeCheck = 0800; 229 | ORGANIZATIONNAME = 1em0nsOft; 230 | TargetAttributes = { 231 | 5291A4D71E0539E800E8C03A = { 232 | CreatedOnToolsVersion = 8.0; 233 | DevelopmentTeam = 2RD6E8WKY9; 234 | ProvisioningStyle = Automatic; 235 | }; 236 | 5291A4E71E053A1900E8C03A = { 237 | CreatedOnToolsVersion = 8.0; 238 | DevelopmentTeam = E9Z57RBU72; 239 | ProvisioningStyle = Automatic; 240 | }; 241 | }; 242 | }; 243 | buildConfigurationList = 5291A4D31E0539E800E8C03A /* Build configuration list for PBXProject "LemonBubble" */; 244 | compatibilityVersion = "Xcode 3.2"; 245 | developmentRegion = English; 246 | hasScannedForEncodings = 0; 247 | knownRegions = ( 248 | en, 249 | Base, 250 | ); 251 | mainGroup = 5291A4CF1E0539E800E8C03A; 252 | productRefGroup = 5291A4D91E0539E800E8C03A /* Products */; 253 | projectDirPath = ""; 254 | projectRoot = ""; 255 | targets = ( 256 | 5291A4D71E0539E800E8C03A /* LemonBubble */, 257 | 5291A4E71E053A1900E8C03A /* LemonBubble-samples */, 258 | ); 259 | }; 260 | /* End PBXProject section */ 261 | 262 | /* Begin PBXResourcesBuildPhase section */ 263 | 5291A4E61E053A1900E8C03A /* Resources */ = { 264 | isa = PBXResourcesBuildPhase; 265 | buildActionMask = 2147483647; 266 | files = ( 267 | 5291A4FA1E053A1900E8C03A /* LaunchScreen.storyboard in Resources */, 268 | EA5E0CD81E0A17840082CC1B /* icon_icon.png in Resources */, 269 | 5291A4F71E053A1900E8C03A /* Assets.xcassets in Resources */, 270 | EA5E0CD51E0A167C0082CC1B /* lkbubble7.jpg in Resources */, 271 | EA5E0CCF1E0A167C0082CC1B /* lkbubble1.jpg in Resources */, 272 | 52D26E7B1E06B524008ABC1F /* icon_bottom.png in Resources */, 273 | EA5E0CCE1E0A167C0082CC1B /* icon_ppt.png in Resources */, 274 | 52D26E7D1E06B524008ABC1F /* icon_right.png in Resources */, 275 | EA5E0CD61E0A167C0082CC1B /* lkbubble8.jpg in Resources */, 276 | 52D26E7C1E06B524008ABC1F /* icon_error.png in Resources */, 277 | EA5E0CD01E0A167C0082CC1B /* lkbubble2.jpg in Resources */, 278 | EA5E0CD11E0A167C0082CC1B /* lkbubble3.jpg in Resources */, 279 | EA5E0CD41E0A167C0082CC1B /* lkbubble6.jpg in Resources */, 280 | 5291A4F51E053A1900E8C03A /* Main.storyboard in Resources */, 281 | EA5E0CD31E0A167C0082CC1B /* lkbubble5.jpg in Resources */, 282 | 52D26E7E1E06B524008ABC1F /* icon_wait.png in Resources */, 283 | EA5E0CD21E0A167C0082CC1B /* lkbubble4.jpg in Resources */, 284 | ); 285 | runOnlyForDeploymentPostprocessing = 0; 286 | }; 287 | /* End PBXResourcesBuildPhase section */ 288 | 289 | /* Begin PBXSourcesBuildPhase section */ 290 | 5291A4D41E0539E800E8C03A /* Sources */ = { 291 | isa = PBXSourcesBuildPhase; 292 | buildActionMask = 2147483647; 293 | files = ( 294 | 5291A5071E053AA000E8C03A /* LemonBubbleView.m in Sources */, 295 | 5291A5061E053AA000E8C03A /* LemonBubbleInfo.m in Sources */, 296 | 5291A5081E053AA000E8C03A /* UIResponder+LemonBubble.m in Sources */, 297 | ); 298 | runOnlyForDeploymentPostprocessing = 0; 299 | }; 300 | 5291A4E41E053A1900E8C03A /* Sources */ = { 301 | isa = PBXSourcesBuildPhase; 302 | buildActionMask = 2147483647; 303 | files = ( 304 | 5291A4F21E053A1900E8C03A /* ViewController.m in Sources */, 305 | 5291A4EF1E053A1900E8C03A /* AppDelegate.m in Sources */, 306 | 52D26E811E06B5CE008ABC1F /* RoundFunctionButton.m in Sources */, 307 | 5291A4EC1E053A1900E8C03A /* main.m in Sources */, 308 | ); 309 | runOnlyForDeploymentPostprocessing = 0; 310 | }; 311 | /* End PBXSourcesBuildPhase section */ 312 | 313 | /* Begin PBXVariantGroup section */ 314 | 5291A4F31E053A1900E8C03A /* Main.storyboard */ = { 315 | isa = PBXVariantGroup; 316 | children = ( 317 | 5291A4F41E053A1900E8C03A /* Base */, 318 | ); 319 | name = Main.storyboard; 320 | sourceTree = ""; 321 | }; 322 | 5291A4F81E053A1900E8C03A /* LaunchScreen.storyboard */ = { 323 | isa = PBXVariantGroup; 324 | children = ( 325 | 5291A4F91E053A1900E8C03A /* Base */, 326 | ); 327 | name = LaunchScreen.storyboard; 328 | sourceTree = ""; 329 | }; 330 | /* End PBXVariantGroup section */ 331 | 332 | /* Begin XCBuildConfiguration section */ 333 | 5291A4DF1E0539E800E8C03A /* Debug */ = { 334 | isa = XCBuildConfiguration; 335 | buildSettings = { 336 | ALWAYS_SEARCH_USER_PATHS = NO; 337 | CLANG_ANALYZER_NONNULL = YES; 338 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 339 | CLANG_CXX_LIBRARY = "libc++"; 340 | CLANG_ENABLE_MODULES = YES; 341 | CLANG_ENABLE_OBJC_ARC = YES; 342 | CLANG_WARN_BOOL_CONVERSION = YES; 343 | CLANG_WARN_CONSTANT_CONVERSION = YES; 344 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 345 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 346 | CLANG_WARN_EMPTY_BODY = YES; 347 | CLANG_WARN_ENUM_CONVERSION = YES; 348 | CLANG_WARN_INFINITE_RECURSION = YES; 349 | CLANG_WARN_INT_CONVERSION = YES; 350 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 351 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 352 | CLANG_WARN_UNREACHABLE_CODE = YES; 353 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 354 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 355 | COPY_PHASE_STRIP = NO; 356 | DEBUG_INFORMATION_FORMAT = dwarf; 357 | ENABLE_STRICT_OBJC_MSGSEND = YES; 358 | ENABLE_TESTABILITY = YES; 359 | GCC_C_LANGUAGE_STANDARD = gnu99; 360 | GCC_DYNAMIC_NO_PIC = NO; 361 | GCC_NO_COMMON_BLOCKS = YES; 362 | GCC_OPTIMIZATION_LEVEL = 0; 363 | GCC_PREPROCESSOR_DEFINITIONS = ( 364 | "DEBUG=1", 365 | "$(inherited)", 366 | ); 367 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 368 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 369 | GCC_WARN_UNDECLARED_SELECTOR = YES; 370 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 371 | GCC_WARN_UNUSED_FUNCTION = YES; 372 | GCC_WARN_UNUSED_VARIABLE = YES; 373 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 374 | MTL_ENABLE_DEBUG_INFO = YES; 375 | ONLY_ACTIVE_ARCH = YES; 376 | SDKROOT = iphoneos; 377 | }; 378 | name = Debug; 379 | }; 380 | 5291A4E01E0539E800E8C03A /* Release */ = { 381 | isa = XCBuildConfiguration; 382 | buildSettings = { 383 | ALWAYS_SEARCH_USER_PATHS = NO; 384 | CLANG_ANALYZER_NONNULL = YES; 385 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 386 | CLANG_CXX_LIBRARY = "libc++"; 387 | CLANG_ENABLE_MODULES = YES; 388 | CLANG_ENABLE_OBJC_ARC = YES; 389 | CLANG_WARN_BOOL_CONVERSION = YES; 390 | CLANG_WARN_CONSTANT_CONVERSION = YES; 391 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 392 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 393 | CLANG_WARN_EMPTY_BODY = YES; 394 | CLANG_WARN_ENUM_CONVERSION = YES; 395 | CLANG_WARN_INFINITE_RECURSION = YES; 396 | CLANG_WARN_INT_CONVERSION = YES; 397 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 398 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 399 | CLANG_WARN_UNREACHABLE_CODE = YES; 400 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 401 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 402 | COPY_PHASE_STRIP = NO; 403 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 404 | ENABLE_NS_ASSERTIONS = NO; 405 | ENABLE_STRICT_OBJC_MSGSEND = YES; 406 | GCC_C_LANGUAGE_STANDARD = gnu99; 407 | GCC_NO_COMMON_BLOCKS = YES; 408 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 409 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 410 | GCC_WARN_UNDECLARED_SELECTOR = YES; 411 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 412 | GCC_WARN_UNUSED_FUNCTION = YES; 413 | GCC_WARN_UNUSED_VARIABLE = YES; 414 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 415 | MTL_ENABLE_DEBUG_INFO = NO; 416 | SDKROOT = iphoneos; 417 | VALIDATE_PRODUCT = YES; 418 | }; 419 | name = Release; 420 | }; 421 | 5291A4E21E0539E800E8C03A /* Debug */ = { 422 | isa = XCBuildConfiguration; 423 | buildSettings = { 424 | DEVELOPMENT_TEAM = 2RD6E8WKY9; 425 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 426 | ONLY_ACTIVE_ARCH = YES; 427 | OTHER_LDFLAGS = "-ObjC"; 428 | PRODUCT_NAME = "$(TARGET_NAME)"; 429 | SKIP_INSTALL = YES; 430 | }; 431 | name = Debug; 432 | }; 433 | 5291A4E31E0539E800E8C03A /* Release */ = { 434 | isa = XCBuildConfiguration; 435 | buildSettings = { 436 | DEVELOPMENT_TEAM = 2RD6E8WKY9; 437 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 438 | ONLY_ACTIVE_ARCH = NO; 439 | OTHER_LDFLAGS = "-ObjC"; 440 | PRODUCT_NAME = "$(TARGET_NAME)"; 441 | SKIP_INSTALL = YES; 442 | }; 443 | name = Release; 444 | }; 445 | 5291A4FD1E053A1900E8C03A /* Debug */ = { 446 | isa = XCBuildConfiguration; 447 | buildSettings = { 448 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 449 | DEVELOPMENT_TEAM = E9Z57RBU72; 450 | INFOPLIST_FILE = "LemonBubble-samples/Info.plist"; 451 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 452 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 453 | OTHER_LDFLAGS = "-all_load"; 454 | PRODUCT_BUNDLE_IDENTIFIER = "net.lemonsoft.LemonBubble-samples"; 455 | PRODUCT_NAME = "$(TARGET_NAME)"; 456 | }; 457 | name = Debug; 458 | }; 459 | 5291A4FE1E053A1900E8C03A /* Release */ = { 460 | isa = XCBuildConfiguration; 461 | buildSettings = { 462 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 463 | DEVELOPMENT_TEAM = E9Z57RBU72; 464 | INFOPLIST_FILE = "LemonBubble-samples/Info.plist"; 465 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 466 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 467 | OTHER_LDFLAGS = "-all_load"; 468 | PRODUCT_BUNDLE_IDENTIFIER = "net.lemonsoft.LemonBubble-samples"; 469 | PRODUCT_NAME = "$(TARGET_NAME)"; 470 | }; 471 | name = Release; 472 | }; 473 | /* End XCBuildConfiguration section */ 474 | 475 | /* Begin XCConfigurationList section */ 476 | 5291A4D31E0539E800E8C03A /* Build configuration list for PBXProject "LemonBubble" */ = { 477 | isa = XCConfigurationList; 478 | buildConfigurations = ( 479 | 5291A4DF1E0539E800E8C03A /* Debug */, 480 | 5291A4E01E0539E800E8C03A /* Release */, 481 | ); 482 | defaultConfigurationIsVisible = 0; 483 | defaultConfigurationName = Release; 484 | }; 485 | 5291A4E11E0539E800E8C03A /* Build configuration list for PBXNativeTarget "LemonBubble" */ = { 486 | isa = XCConfigurationList; 487 | buildConfigurations = ( 488 | 5291A4E21E0539E800E8C03A /* Debug */, 489 | 5291A4E31E0539E800E8C03A /* Release */, 490 | ); 491 | defaultConfigurationIsVisible = 0; 492 | defaultConfigurationName = Release; 493 | }; 494 | 5291A4FC1E053A1900E8C03A /* Build configuration list for PBXNativeTarget "LemonBubble-samples" */ = { 495 | isa = XCConfigurationList; 496 | buildConfigurations = ( 497 | 5291A4FD1E053A1900E8C03A /* Debug */, 498 | 5291A4FE1E053A1900E8C03A /* Release */, 499 | ); 500 | defaultConfigurationIsVisible = 0; 501 | defaultConfigurationName = Release; 502 | }; 503 | /* End XCConfigurationList section */ 504 | }; 505 | rootObject = 5291A4D01E0539E800E8C03A /* Project object */; 506 | } 507 | --------------------------------------------------------------------------------