├── .gitignore ├── LICENSE ├── README.md ├── WZLBadge.podspec ├── WZLBadge ├── BarItem │ ├── UIBarButtonItem+WZLBadge.h │ ├── UIBarButtonItem+WZLBadge.m │ ├── UITabBarItem+WZLBadge.h │ └── UITabBarItem+WZLBadge.m ├── CategorySupport │ ├── CAAnimation+WAnimation.h │ └── CAAnimation+WAnimation.m ├── Protocol │ └── WZLBadgeProtocol.h ├── View │ ├── UIView+WZLBadge.h │ └── UIView+WZLBadge.m └── WZLBadgeImport.h ├── WZLBadgeDemo.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── WZLBadgeDemo.xccheckout │ └── xcuserdata │ │ └── wzl.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── wzl.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── WZLBadgeDemo.xcscheme │ └── xcschememanagement.plist ├── WZLBadgeDemo ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── Default-568h@2x.png ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── RootTabBarController.h ├── RootTabBarController.m ├── TableViewDataSource.h ├── TableViewDataSource.m ├── Tool │ └── Category │ │ ├── UIView+Frame.h │ │ └── UIView+Frame.m ├── ViewController.h ├── ViewController.m ├── example_prot.gif ├── examples │ ├── TableViewCollectionViewController.h │ └── TableViewCollectionViewController.m ├── logo@2x.jpg ├── main.m ├── nav_list@2x.png └── snapshot.png └── WZLBadgeDemoTests ├── Info.plist └── WZLBadgeDemoTests.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | *.xcbkptlist 25 | *.xcuserstate 26 | 27 | 28 | ## Obj-C/Swift specific 29 | *.hmap 30 | *.ipa 31 | *.dSYM.zip 32 | *.dSYM 33 | 34 | # CocoaPods 35 | # 36 | # We recommend against adding the Pods directory to your .gitignore. However 37 | # you should judge for yourself, the pros and cons are mentioned at: 38 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 39 | # 40 | # Pods/ 41 | 42 | # Carthage 43 | # 44 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 45 | # Carthage/Checkouts 46 | 47 | Carthage/Build 48 | 49 | # fastlane 50 | # 51 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 52 | # screenshots whenever they are needed. 53 | # For more information about the recommended setup visit: 54 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 55 | 56 | fastlane/report.xml 57 | fastlane/Preview.html 58 | fastlane/screenshots 59 | fastlane/test_output 60 | 61 | # Code Injection 62 | # 63 | # After new code Injection tools there's a generated folder /iOSInjectionProject 64 | # https://github.com/johnno1962/injectionforxcode 65 | 66 | iOSInjectionProject/ 67 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Zilin Weng 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 | 一行代码实现Badge效果(iOS) 2 | BADGE IN ONE LINE(iOS) 3 | =================== 4 | OVERVIEW 5 | =================== 6 | WZLBadge is a tool to add or clear badge for **any UIViews**, which is written in Objective-C, **supporting iOS5 or above**, supporting **portrait and landscape device orientation**. 7 | 8 | > The code is implemented by the way of category for UIView, thus, 9 | it is **very easy to use**. 10 | 11 | At this version, three badge style are supported: 12 | 13 | - WBadgeStyleRedDot 14 | - WBadgeStyleNumber 15 | - WBadgeStyleNew 16 | 17 | Three animation types are supported: 18 | 19 | - WBadgeAnimTypeNone(by default) 20 | - WBadgeAnimTypeScale 21 | - WBadgeAnimTypeShake 22 | - WBadgeAnimTypeBreathe 23 | - WBadgeAnimTypeBounce 24 | 25 | 26 | Here are examples for WZLBadge(just show static picture without gif here): 27 | ![](https://ww2.sinaimg.cn/large/006tKfTcgy1fevi5smct4j30yi1pcn52.jpg) 28 | 29 | 30 | ![](https://ww3.sinaimg.cn/large/006tKfTcgy1fevi5x1h2cj31kw0w0tdc.jpg) 31 | 32 | 33 | ---------- 34 | 35 | 36 | INSTALLTATION 37 | ------------- 38 | Method1: 39 | Drag the 40 | > WZLBadge 41 | 42 | folder into your project. 43 | 44 | Method2: 45 | Use CocoaPods to install automaticlly: 46 | 47 | pod 'WZLBadge' 48 | 49 | ---------- 50 | 51 | REQUIREMENTS 52 | ------------------- 53 | 54 | - Xcode 6 55 | - iOS5 or above 56 | - ARC (or MRC, but project setting is necessary) 57 | 58 | ---------- 59 | 60 | 61 | USAGE 62 | ------------- 63 | 64 | 1. Add the following import to the top of the file: 65 | > import "WZLBadgeImport.h" 66 | 67 | 2. Use the following to display badge easily: 68 | 69 | > [someView showBadgeWithStyle:**WBadgeStyleRedDot** value:0 animationType:**WBadgeAnimTypeShake**]; 70 | > [someView showBadgeWithStyle:**WBadgeStyleNumber** value:99 animationType:**WBadgeAnimTypeShake**]; 71 | 72 | or simply call interface:[- showBadge] 73 | 74 | 3. Use the following to hide badge easily: 75 | 76 | 77 | > [someView clearBadge]; 78 | 79 | 4.Use the following to resume badge when it has been hidden: 80 | 81 | > [someView resumeBadge]; 82 | 83 | ---------- 84 | 85 | 86 | BADGE CUSTOMIZATION 87 | -------------------- 88 | Feel free to customize badge size, position, animation style or anything else. 89 | 90 | WZLBadge provides easy way to customize its style.: 91 | 92 | //set background color. red color by default 93 | view.badgeBgColor = [UIColor purpleColor]; 94 | 95 | //set badge position. right-top corner of view by default 96 | view.badgeCenterOffset = CGPointMake(-8, 0); 97 | 98 | //set badge foreground color. white color by default 99 | view.badgeTextColor = [UIColor whiteColor]; 100 | 101 | //... 102 | 103 | ---------- 104 | CONTACT 105 | -------------------- 106 | Do you have any questions or idea? My email is: 107 | 108 | > zilin_weng@163.com 109 | 110 | Or you can find some more info at my blog in cnblogs.com: 111 | 112 | > http://www.cnblogs.com/wengzilin/ 113 | 114 | 如果你在天朝,可以查看中文博客地址: 115 | http://www.cnblogs.com/wengzilin/p/4633937.html 116 | 117 | ---------- 118 | NOTE 119 | -------------------- 120 | This project will be update continually. Therefore, **fork** or **star** would be suggested. 121 | 122 | I wish it to be an ultimat solution for UIView badge in iOS. 123 | 124 | ---------- 125 | AUTHOR 126 | -------------------- 127 | Zilin Weng(翁子林) https://github.com/weng1250 128 | 129 | 130 | ---------- 131 | CONTRIBUTE 132 | -------------------- 133 | - jfuellert https://github.com/jfuellert 134 | - zhangao0086 https://github.com/zhangao0086 135 | 136 | Feel free to open an issue or pull request, if you need help or there is a bug. 137 | 138 | ---------- 139 | CHANGE LOG 140 | -------------------- 141 | v1.2.6 2017.4.20 142 | Bugs were fixed. 143 | Enable setting badge properties before bage initialization. 144 | 145 | v.1.2.5 2017.3.1 146 | fix bug 'when showing TabbarItem bage, badge is covered by tabbarItem icon' 147 | 148 | v1.2.3 2016.2.15 149 | 1.Enable resume badge when badge has been cleard(removed) 150 | 151 | V1.2.2 2015.12.18 152 | 1.Enable badge font customization 153 | 2.code warning removed 154 | 155 | V1.2 2015.09.25 156 | 1.UITabBarItem badge is supproted; 157 | 2.Enable change badge properties when badge is showing; 158 | 3.Other code optimization. 159 | 160 | V1.1 2015.08.12 161 | 162 | 1. UIBarButtonItem badge is supported. UIBarButtonItem is kind of NSObject and its displayed view is invisiable. This version makes usage of UIBarButtonItem badge as to UIView. 163 | 2. Slight adjustment for code structure to fit future extension. 164 | 3. Other code optimization. 165 | 166 | 167 | 168 | V1.0 at 2015.06.16 169 | 170 | Base functions are completed, which is able to meet most of requirements. 171 | 172 | ---------- 173 | ---------- 174 | LICENSE 175 | -------------------- 176 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 177 | -------------------------------------------------------------------------------- /WZLBadge.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'WZLBadge' 3 | s.version = '1.2.6' 4 | s.summary = 'An one-line tool to show styles of badge for UIView' 5 | s.description = <<-DESC 6 | An easy tool to show different styles of UIView objects without the need for subclassing. 7 | DESC 8 | s.homepage = 'https://github.com/weng1250/WZLBadge' 9 | s.license = { :type => 'None', :file => 'LICENSE' } 10 | s.author = { 'Zilin Weng翁子林' => "719113951@qq.com" } 11 | s.source = { :git => 'https://github.com/weng1250/WZLBadge.git', :tag => s.version } 12 | s.platform = :ios, '5.0' 13 | s.requires_arc = true 14 | 15 | s.source_files = 'WZLBadge/BarItem/*.{h,m}', 'WZLBadge/CategorySupport/*.{h,m}', 'WZLBadge/Protocol/*.{h,m}', 'WZLBadge/View/*.{h,m}', 'WZLBadge/WZLBadgeImport.h' 16 | s.public_header_files = 'WZLBadge/**/*.{h}' 17 | 18 | s.frameworks = 'UIKit' 19 | end 20 | -------------------------------------------------------------------------------- /WZLBadge/BarItem/UIBarButtonItem+WZLBadge.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIBarButtonItem+WZLBadge.h 3 | // WZLBadgeDemo 4 | // 5 | // Created by zilin_weng on 15/8/10. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIView+WZLBadge.h" 11 | #import "WZLBadgeProtocol.h" 12 | 13 | @interface UIBarButtonItem (WZLBadge) 14 | 15 | /** 16 | * show badge with red dot style and WBadgeAnimTypeNone by default. 17 | */ 18 | - (void)showBadge; 19 | 20 | /** 21 | * showBadge 22 | * 23 | * @param style WBadgeStyle type 24 | * @param value (if 'style' is WBadgeStyleRedDot or WBadgeStyleNew, 25 | this value will be ignored. In this case, any value will be ok.) 26 | * @param aniType 27 | */ 28 | - (void)showBadgeWithStyle:(WBadgeStyle)style 29 | value:(NSInteger)value 30 | animationType:(WBadgeAnimType)aniType; 31 | 32 | 33 | /** 34 | * clear badge(hide badge) 35 | */ 36 | - (void)clearBadge; 37 | 38 | /** 39 | * make bage(if existing) not hiden 40 | */ 41 | - (void)resumeBadge; 42 | 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /WZLBadge/BarItem/UIBarButtonItem+WZLBadge.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIBarButtonItem+WZLBadge.m 3 | // WZLBadgeDemo 4 | // 5 | // Created by zilin_weng on 15/8/10. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import "UIBarButtonItem+WZLBadge.h" 10 | #import 11 | 12 | #define kActualView [self getActualBadgeSuperView] 13 | 14 | 15 | @implementation UIBarButtonItem (WZLBadge) 16 | 17 | #pragma mark -- public methods 18 | 19 | /** 20 | * show badge with red dot style and WBadgeAnimTypeNone by default. 21 | */ 22 | - (void)showBadge 23 | { 24 | [kActualView showBadge]; 25 | } 26 | 27 | /** 28 | * showBadge 29 | * 30 | * @param style WBadgeStyle type 31 | * @param value (if 'style' is WBadgeStyleRedDot or WBadgeStyleNew, 32 | this value will be ignored. In this case, any value will be ok.) 33 | * @param aniType 34 | */ 35 | - (void)showBadgeWithStyle:(WBadgeStyle)style 36 | value:(NSInteger)value 37 | animationType:(WBadgeAnimType)aniType 38 | { 39 | [kActualView showBadgeWithStyle:style value:value animationType:aniType]; 40 | } 41 | 42 | 43 | /** 44 | * clear badge 45 | */ 46 | - (void)clearBadge 47 | { 48 | [kActualView clearBadge]; 49 | } 50 | 51 | - (void)resumeBadge 52 | { 53 | [kActualView resumeBadge]; 54 | } 55 | 56 | #pragma mark -- private method 57 | 58 | /** 59 | * Because UIBarButtonItem is kind of NSObject, it is not able to directly attach badge. 60 | This method is used to find actual view (non-nil) inside UIBarButtonItem instance. 61 | * 62 | * @return view 63 | */ 64 | - (UIView *)getActualBadgeSuperView 65 | { 66 | return [self valueForKeyPath:@"_view"];//use KVC to hack actual view 67 | } 68 | 69 | #pragma mark -- setter/getter 70 | - (UILabel *)badge 71 | { 72 | return kActualView.badge; 73 | } 74 | 75 | - (void)setBadge:(UILabel *)label 76 | { 77 | [kActualView setBadge:label]; 78 | } 79 | 80 | - (UIFont *)badgeFont 81 | { 82 | return kActualView.badgeFont; 83 | } 84 | 85 | - (void)setBadgeFont:(UIFont *)badgeFont 86 | { 87 | [kActualView setBadgeFont:badgeFont]; 88 | } 89 | 90 | - (UIColor *)badgeBgColor 91 | { 92 | return [kActualView badgeBgColor]; 93 | } 94 | 95 | - (void)setBadgeBgColor:(UIColor *)badgeBgColor 96 | { 97 | [kActualView setBadgeBgColor:badgeBgColor]; 98 | } 99 | 100 | - (UIColor *)badgeTextColor 101 | { 102 | return [kActualView badgeTextColor]; 103 | } 104 | 105 | - (void)setBadgeTextColor:(UIColor *)badgeTextColor 106 | { 107 | [kActualView setBadgeTextColor:badgeTextColor]; 108 | } 109 | 110 | - (WBadgeAnimType)aniType 111 | { 112 | return [kActualView aniType]; 113 | } 114 | 115 | - (void)setAniType:(WBadgeAnimType)aniType 116 | { 117 | [kActualView setAniType:aniType]; 118 | } 119 | 120 | - (CGRect)badgeFrame 121 | { 122 | return [kActualView badgeFrame]; 123 | } 124 | 125 | - (void)setBadgeFrame:(CGRect)badgeFrame 126 | { 127 | [kActualView setBadgeFrame:badgeFrame]; 128 | } 129 | 130 | - (CGPoint)badgeCenterOffset 131 | { 132 | return [kActualView badgeCenterOffset]; 133 | } 134 | 135 | - (void)setBadgeCenterOffset:(CGPoint)badgeCenterOffset 136 | { 137 | [kActualView setBadgeCenterOffset:badgeCenterOffset]; 138 | } 139 | 140 | - (NSInteger)badgeMaximumBadgeNumber 141 | { 142 | return [kActualView badgeMaximumBadgeNumber]; 143 | } 144 | 145 | - (void)setBadgeMaximumBadgeNumber:(NSInteger)badgeMaximumBadgeNumber 146 | { 147 | [kActualView setBadgeMaximumBadgeNumber:badgeMaximumBadgeNumber]; 148 | } 149 | 150 | @end 151 | -------------------------------------------------------------------------------- /WZLBadge/BarItem/UITabBarItem+WZLBadge.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITabBarItem+WZLBadge.h 3 | // WZLBadgeDemo 4 | // 5 | // Created by zilin_weng on 15/9/24. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIView+WZLBadge.h" 11 | #import "WZLBadgeProtocol.h" 12 | 13 | @interface UITabBarItem (WZLBadge) 14 | 15 | /** 16 | * show badge with red dot style and WBadgeAnimTypeNone by default. 17 | */ 18 | - (void)showBadge; 19 | 20 | /** 21 | * showBadge 22 | * 23 | * @param style WBadgeStyle type 24 | * @param value (if 'style' is WBadgeStyleRedDot or WBadgeStyleNew, 25 | this value will be ignored. In this case, any value will be ok.) 26 | * @param aniType 27 | */ 28 | - (void)showBadgeWithStyle:(WBadgeStyle)style 29 | value:(NSInteger)value 30 | animationType:(WBadgeAnimType)aniType; 31 | 32 | 33 | /** 34 | * clear badge(hide badge) 35 | */ 36 | - (void)clearBadge; 37 | 38 | /** 39 | * make bage(if existing) not hiden 40 | */ 41 | - (void)resumeBadge; 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /WZLBadge/BarItem/UITabBarItem+WZLBadge.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITabBarItem+WZLBadge.m 3 | // WZLBadgeDemo 4 | // 5 | // Created by zilin_weng on 15/9/24. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import "UITabBarItem+WZLBadge.h" 10 | 11 | #define kActualView [self getActualBadgeSuperView] 12 | 13 | @implementation UITabBarItem (WZLBadge) 14 | 15 | #pragma mark -- public methods 16 | 17 | /** 18 | * show badge with red dot style and WBadgeAnimTypeNone by default. 19 | */ 20 | - (void)showBadge 21 | { 22 | [kActualView showBadge]; 23 | } 24 | 25 | /** 26 | * showBadge 27 | * 28 | * @param style WBadgeStyle type 29 | * @param value (if 'style' is WBadgeStyleRedDot or WBadgeStyleNew, 30 | this value will be ignored. In this case, any value will be ok.) 31 | * @param aniType 32 | */ 33 | - (void)showBadgeWithStyle:(WBadgeStyle)style 34 | value:(NSInteger)value 35 | animationType:(WBadgeAnimType)aniType 36 | { 37 | [kActualView showBadgeWithStyle:style value:value animationType:aniType]; 38 | } 39 | 40 | /** 41 | * clear badge 42 | */ 43 | - (void)clearBadge 44 | { 45 | [kActualView clearBadge]; 46 | } 47 | 48 | - (void)resumeBadge 49 | { 50 | [kActualView resumeBadge]; 51 | } 52 | 53 | #pragma mark -- private method 54 | 55 | /** 56 | * Because UIBarButtonItem is kind of NSObject, it is not able to directly attach badge. 57 | This method is used to find actual view (non-nil) inside UIBarButtonItem instance. 58 | * 59 | * @return view 60 | */ 61 | - (UIView *)getActualBadgeSuperView 62 | { 63 | // 1.get UITabbarButtion 64 | UIView *bottomView = [self valueForKeyPath:@"_view"]; 65 | 66 | // 2.get imageView, to make sure badge front at anytime. 67 | UIView *actualSuperView = nil; 68 | if (bottomView) { 69 | actualSuperView = [self find:bottomView firstSubviewWithClass:NSClassFromString(@"UITabBarSwappableImageView")]; 70 | } 71 | 72 | // badge label will be added onto imageView 73 | return actualSuperView; 74 | } 75 | 76 | - (UIView *)find:(UIView *)view firstSubviewWithClass:(Class)cls 77 | { 78 | __block UIView *targetView = nil; 79 | [view.subviews enumerateObjectsUsingBlock:^(UIView *subview, NSUInteger idx, BOOL * _Nonnull stop) { 80 | if ([subview isKindOfClass:cls]) { 81 | targetView = subview; 82 | *stop = YES; 83 | } 84 | }]; 85 | return targetView; 86 | } 87 | 88 | #pragma mark -- setter/getter 89 | - (UILabel *)badge 90 | { 91 | return kActualView.badge; 92 | } 93 | 94 | - (void)setBadge:(UILabel *)label 95 | { 96 | [kActualView setBadge:label]; 97 | } 98 | 99 | - (UIFont *)badgeFont 100 | { 101 | return kActualView.badgeFont; 102 | } 103 | 104 | - (void)setBadgeFont:(UIFont *)badgeFont 105 | { 106 | [kActualView setBadgeFont:badgeFont]; 107 | } 108 | 109 | - (UIColor *)badgeBgColor 110 | { 111 | return [kActualView badgeBgColor]; 112 | } 113 | 114 | - (void)setBadgeBgColor:(UIColor *)badgeBgColor 115 | { 116 | [kActualView setBadgeBgColor:badgeBgColor]; 117 | } 118 | 119 | - (UIColor *)badgeTextColor 120 | { 121 | return [kActualView badgeTextColor]; 122 | } 123 | 124 | - (void)setBadgeTextColor:(UIColor *)badgeTextColor 125 | { 126 | [kActualView setBadgeTextColor:badgeTextColor]; 127 | } 128 | 129 | - (WBadgeAnimType)aniType 130 | { 131 | return [kActualView aniType]; 132 | } 133 | 134 | - (void)setAniType:(WBadgeAnimType)aniType 135 | { 136 | [kActualView setAniType:aniType]; 137 | } 138 | 139 | - (CGRect)badgeFrame 140 | { 141 | return [kActualView badgeFrame]; 142 | } 143 | 144 | - (void)setBadgeFrame:(CGRect)badgeFrame 145 | { 146 | [kActualView setBadgeFrame:badgeFrame]; 147 | } 148 | 149 | - (CGPoint)badgeCenterOffset 150 | { 151 | return [kActualView badgeCenterOffset]; 152 | } 153 | 154 | - (void)setBadgeCenterOffset:(CGPoint)badgeCenterOffset 155 | { 156 | [kActualView setBadgeCenterOffset:badgeCenterOffset]; 157 | } 158 | 159 | - (NSInteger)badgeMaximumBadgeNumber 160 | { 161 | return [kActualView badgeMaximumBadgeNumber]; 162 | } 163 | 164 | - (void)setBadgeMaximumBadgeNumber:(NSInteger)badgeMaximumBadgeNumber 165 | { 166 | [kActualView setBadgeMaximumBadgeNumber:badgeMaximumBadgeNumber]; 167 | } 168 | 169 | @end 170 | -------------------------------------------------------------------------------- /WZLBadge/CategorySupport/CAAnimation+WAnimation.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+WAnimation.h 3 | // WZLBadgeDemo 4 | // 5 | // Created by zilin_weng on 15/6/26. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | typedef NS_ENUM(NSUInteger, WAxis) 13 | { 14 | WAxisX = 0, 15 | WAxisY, 16 | WAxisZ 17 | }; 18 | 19 | // Degrees to radians 20 | #define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI) 21 | #define RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / M_PI)) 22 | 23 | @interface CAAnimation (WAnimation) 24 | 25 | /** 26 | * breathing forever 27 | * 28 | * @param time duritaion, from clear to fully seen 29 | * 30 | * @return animation obj 31 | */ 32 | +(CABasicAnimation *)opacityForever_Animation:(float)time; 33 | 34 | /** 35 | * breathing with fixed repeated times 36 | * 37 | * @param repeatTimes times 38 | * @param time duritaion, from clear to fully seen 39 | * 40 | * @return animation obj 41 | */ 42 | +(CABasicAnimation *)opacityTimes_Animation:(float)repeatTimes durTimes:(float)time; 43 | 44 | /** 45 | * //rotate 46 | * 47 | * @param dur duration 48 | * @param degree rotate degree in radian(弧度) 49 | * @param axis axis 50 | * @param repeatCount repeat count 51 | * 52 | * @return animation obj 53 | */ 54 | +(CABasicAnimation *)rotation:(float)dur degree:(float)degree direction:(WAxis)axis repeatCount:(int)repeatCount; 55 | 56 | 57 | /** 58 | * scale animation 59 | * 60 | * @param fromScale the original scale value, 1.0 by default 61 | * @param toScale target scale 62 | * @param time duration 63 | * @param repeatTimes repeat counts 64 | * 65 | * @return animaiton obj 66 | */ 67 | +(CABasicAnimation *)scaleFrom:(CGFloat)fromScale toScale:(CGFloat)toScale durTimes:(float)time rep:(float)repeatTimes; 68 | /** 69 | * shake 70 | * 71 | * @param repeatTimes time 72 | * @param time duration 73 | * @param obj always be CALayer at present 74 | * @return aniamtion obj 75 | */ 76 | +(CAKeyframeAnimation *)shake_AnimationRepeatTimes:(float)repeatTimes durTimes:(float)time forObj:(id)obj; 77 | 78 | /** 79 | * bounce 80 | * 81 | * @param repeatTimes time 82 | * @param time duration 83 | * @param obj always be CALayer at present 84 | * @return aniamtion obj 85 | */ 86 | +(CAKeyframeAnimation *)bounce_AnimationRepeatTimes:(float)repeatTimes durTimes:(float)time forObj:(id)obj; 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /WZLBadge/CategorySupport/CAAnimation+WAnimation.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+WAnimation.m 3 | // WZLBadgeDemo 4 | // 5 | // Created by zilin_weng on 15/6/26. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import "CAAnimation+WAnimation.h" 10 | #import 11 | 12 | @implementation CAAnimation (WAnimation) 13 | /** 14 | * breathing forever 15 | * 16 | * @param time duritaion, from clear to fully seen 17 | * 18 | * @return animation obj 19 | */ 20 | +(CABasicAnimation *)opacityForever_Animation:(float)time 21 | { 22 | CABasicAnimation *animation=[CABasicAnimation animationWithKeyPath:@"opacity"]; 23 | animation.fromValue=[NSNumber numberWithFloat:1.0]; 24 | animation.toValue=[NSNumber numberWithFloat:0.1]; 25 | animation.autoreverses=YES; 26 | animation.duration=time; 27 | animation.repeatCount=FLT_MAX; 28 | animation.removedOnCompletion=NO; 29 | animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 30 | animation.fillMode=kCAFillModeForwards; 31 | return animation; 32 | } 33 | 34 | /** 35 | * breathing with fixed repeated times 36 | * 37 | * @param repeatTimes times 38 | * @param time duritaion, from clear to fully seen 39 | * 40 | * @return animation obj 41 | */ 42 | +(CABasicAnimation *)opacityTimes_Animation:(float)repeatTimes durTimes:(float)time 43 | { 44 | CABasicAnimation *animation=[CABasicAnimation animationWithKeyPath:@"opacity"]; 45 | animation.fromValue=[NSNumber numberWithFloat:1.0]; 46 | animation.toValue=[NSNumber numberWithFloat:0.4]; 47 | animation.repeatCount=repeatTimes; 48 | animation.duration=time; 49 | animation.removedOnCompletion=NO; 50 | animation.fillMode=kCAFillModeForwards; 51 | animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 52 | animation.autoreverses=YES; 53 | return animation; 54 | } 55 | 56 | /** 57 | * //rotate 58 | * 59 | * @param dur duration 60 | * @param degree rotate degree in radian(弧度) 61 | * @param axis axis 62 | * @param repeatCount repeat count 63 | * 64 | * @return animation obj 65 | */ 66 | +(CABasicAnimation *)rotation:(float)dur degree:(float)degree direction:(WAxis)axis repeatCount:(int)repeatCount 67 | { 68 | CABasicAnimation* animation; 69 | NSArray *axisArr = @[@"transform.rotation.x", @"transform.rotation.y", @"transform.rotation.z"]; 70 | animation = [CABasicAnimation animationWithKeyPath:axisArr[axis]]; 71 | animation.fromValue = [NSNumber numberWithFloat:0]; 72 | animation.toValue= [NSNumber numberWithFloat:degree]; 73 | animation.duration= dur; 74 | animation.autoreverses= NO; 75 | animation.cumulative= YES; 76 | animation.removedOnCompletion=NO; 77 | animation.fillMode=kCAFillModeForwards; 78 | animation.repeatCount= repeatCount; 79 | 80 | return animation; 81 | } 82 | 83 | /** 84 | * scale animation 85 | * 86 | * @param fromScale the original scale value, 1.0 by default 87 | * @param toScale target scale 88 | * @param time duration 89 | * @param repeatTimes repeat counts 90 | * 91 | * @return animaiton obj 92 | */ 93 | +(CABasicAnimation *)scaleFrom:(CGFloat)fromScale toScale:(CGFloat)toScale durTimes:(float)time rep:(float)repeatTimes 94 | { 95 | CABasicAnimation *animation=[CABasicAnimation animationWithKeyPath:@"transform.scale"]; 96 | animation.fromValue = @(fromScale); 97 | animation.toValue = @(toScale); 98 | animation.duration = time; 99 | animation.autoreverses = YES; 100 | animation.repeatCount = repeatTimes; 101 | animation.removedOnCompletion = NO; 102 | animation.fillMode = kCAFillModeForwards; 103 | return animation; 104 | } 105 | 106 | /** 107 | * shake 108 | * 109 | * @param repeatTimes time 110 | * @param time duration 111 | * @param obj always be CALayer 112 | * @return aniamtion obj 113 | */ 114 | +(CAKeyframeAnimation *)shake_AnimationRepeatTimes:(float)repeatTimes durTimes:(float)time forObj:(id)obj 115 | { 116 | NSAssert([obj isKindOfClass:[CALayer class]] , @"invalid target"); 117 | CGPoint originPos = CGPointZero; 118 | CGSize originSize = CGSizeZero; 119 | if ([obj isKindOfClass:[CALayer class]]) { 120 | originPos = [(CALayer *)obj position]; 121 | originSize = [(CALayer *)obj bounds].size; 122 | } 123 | CGFloat hOffset = originSize.width / 4; 124 | CAKeyframeAnimation* anim=[CAKeyframeAnimation animation]; 125 | anim.keyPath=@"position"; 126 | anim.values=@[ 127 | [NSValue valueWithCGPoint:CGPointMake(originPos.x, originPos.y)], 128 | [NSValue valueWithCGPoint:CGPointMake(originPos.x-hOffset, originPos.y)], 129 | [NSValue valueWithCGPoint:CGPointMake(originPos.x, originPos.y)], 130 | [NSValue valueWithCGPoint:CGPointMake(originPos.x+hOffset, originPos.y)], 131 | [NSValue valueWithCGPoint:CGPointMake(originPos.x, originPos.y)] 132 | ]; 133 | anim.repeatCount = repeatTimes; 134 | anim.duration = time; 135 | anim.fillMode = kCAFillModeForwards; 136 | return anim; 137 | } 138 | 139 | /** 140 | * bounce 141 | * 142 | * @param repeatTimes time 143 | * @param time duration 144 | * @param obj always be CALayer 145 | * @return aniamtion obj 146 | */ 147 | +(CAKeyframeAnimation *)bounce_AnimationRepeatTimes:(float)repeatTimes durTimes:(float)time forObj:(id)obj 148 | { 149 | NSAssert([obj isKindOfClass:[CALayer class]] , @"invalid target"); 150 | CGPoint originPos = CGPointZero; 151 | CGSize originSize = CGSizeZero; 152 | if ([obj isKindOfClass:[CALayer class]]) { 153 | originPos = [(CALayer *)obj position]; 154 | originSize = [(CALayer *)obj bounds].size; 155 | } 156 | CGFloat hOffset = originSize.height / 4; 157 | CAKeyframeAnimation* anim=[CAKeyframeAnimation animation]; 158 | anim.keyPath=@"position"; 159 | anim.values=@[ 160 | [NSValue valueWithCGPoint:CGPointMake(originPos.x, originPos.y)], 161 | [NSValue valueWithCGPoint:CGPointMake(originPos.x, originPos.y-hOffset)], 162 | [NSValue valueWithCGPoint:CGPointMake(originPos.x, originPos.y)], 163 | [NSValue valueWithCGPoint:CGPointMake(originPos.x, originPos.y+hOffset)], 164 | [NSValue valueWithCGPoint:CGPointMake(originPos.x, originPos.y)] 165 | ]; 166 | anim.repeatCount=repeatTimes; 167 | anim.duration=time; 168 | anim.fillMode = kCAFillModeForwards; 169 | return anim; 170 | } 171 | 172 | @end 173 | -------------------------------------------------------------------------------- /WZLBadge/Protocol/WZLBadgeProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // WZLBadgeProtocol.h 3 | // WZLBadgeDemo 4 | // 5 | // Created by zilin_weng on 15/8/12. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | //WZLBadgeProtocol is a protocol which any Class supported (such UIView and UIBarButtonItem) should confirm 10 | //At present, there are two classes support WZLBadge(UIView and UIBarButtonItem). However, there may be more classes to support. Thus, it is necessary to abstract a protocol. 20150812. 11 | 12 | 13 | #ifndef WZLBadgeDemo_WZLBadgeProtocol_h 14 | #define WZLBadgeDemo_WZLBadgeProtocol_h 15 | 16 | #pragma mark -- types definition 17 | 18 | #define kBadgeBreatheAniKey @"breathe" 19 | #define kBadgeRotateAniKey @"rotate" 20 | #define kBadgeShakeAniKey @"shake" 21 | #define kBadgeScaleAniKey @"scale" 22 | #define kBadgeBounceAniKey @"bounce" 23 | 24 | //key for associative methods during runtime 25 | static char badgeLabelKey; 26 | static char badgeBgColorKey; 27 | static char badgeFontKey; 28 | static char badgeTextColorKey; 29 | static char badgeAniTypeKey; 30 | static char badgeFrameKey; 31 | static char badgeCenterOffsetKey; 32 | static char badgeMaximumBadgeNumberKey; 33 | static char badgeRadiusKey; 34 | 35 | typedef NS_ENUM(NSUInteger, WBadgeStyle) 36 | { 37 | WBadgeStyleRedDot = 0, /* red dot style */ 38 | WBadgeStyleNumber, /* badge with number */ 39 | WBadgeStyleNew /* badge with a fixed text "new" */ 40 | }; 41 | 42 | typedef NS_ENUM(NSUInteger, WBadgeAnimType) 43 | { 44 | WBadgeAnimTypeNone = 0, /* without animation, badge stays still */ 45 | WBadgeAnimTypeScale, /* scale effect */ 46 | WBadgeAnimTypeShake, /* shaking effect */ 47 | WBadgeAnimTypeBounce, /* bouncing effect */ 48 | WBadgeAnimTypeBreathe /* breathing light effect, which makes badge more attractive */ 49 | }; 50 | 51 | 52 | #pragma mark -- protocol definition 53 | 54 | @protocol WZLBadgeProtocol 55 | 56 | @required 57 | 58 | @property (nonatomic, strong) UILabel *badge; /* badge entity, which is adviced not to set manually */ 59 | @property (nonatomic, strong) UIFont *badgeFont; /* [UIFont boldSystemFontOfSize:9] by default if not set */ 60 | @property (nonatomic, strong) UIColor *badgeBgColor; /* red color by default if not set */ 61 | @property (nonatomic, strong) UIColor *badgeTextColor; /* white color by default if not set */ 62 | @property (nonatomic, assign) CGRect badgeFrame; /* we have optimized the badge frame and center. 63 | This property is adviced not to set manually */ 64 | 65 | @property (nonatomic, assign) CGPoint badgeCenterOffset; /* offset from right-top corner. {0,0} by default */ 66 | /* For x, negative number means left offset 67 | For y, negative number means bottom offset */ 68 | 69 | @property (nonatomic, assign) WBadgeAnimType aniType; /* NOTE that this is not animation type of badge's 70 | appearing, nor hidding*/ 71 | 72 | @property (nonatomic, assign) NSInteger badgeMaximumBadgeNumber; /*for WBadgeStyleNumber style badge, 73 | if badge value is above badgeMaximumBadgeNumber, 74 | "badgeMaximumBadgeNumber+" will be printed. */ 75 | 76 | @property (nonatomic, assign) CGFloat badgeRadius; 77 | // nomal use for red dot style of badge 78 | 79 | /** 80 | * show badge with red dot style and WBadgeAnimTypeNone by default. 81 | */ 82 | - (void)showBadge; 83 | 84 | /** 85 | * showBadge 86 | * 87 | * @param style WBadgeStyle type 88 | * @param value (if 'style' is WBadgeStyleRedDot or WBadgeStyleNew, 89 | this value will be ignored. In this case, any value will be ok.) 90 | * @param aniType 91 | */ 92 | - (void)showBadgeWithStyle:(WBadgeStyle)style 93 | value:(NSInteger)value 94 | animationType:(WBadgeAnimType)aniType; 95 | 96 | 97 | /** 98 | * clear badge 99 | */ 100 | - (void)clearBadge; 101 | 102 | 103 | @end 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /WZLBadge/View/UIView+WZLBadge.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+WZLBadge.h 3 | // WZLBadgeDemo 4 | // 5 | // Created by zilin_weng on 15/6/24. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // Project description: this is a solution to enable any UIView to display badge 8 | 9 | #import 10 | #import "WZLBadgeProtocol.h" 11 | 12 | #pragma mark -- badge apis 13 | 14 | @interface UIView (WZLBadge) 15 | 16 | 17 | /** 18 | * show badge with red dot style and WBadgeAnimTypeNone by default. 19 | */ 20 | - (void)showBadge; 21 | 22 | /** 23 | * showBadge 24 | * 25 | * @param style WBadgeStyle type 26 | * @param value (if 'style' is WBadgeStyleRedDot or WBadgeStyleNew, 27 | this value will be ignored. In this case, any value will be ok.) 28 | * @param aniType 29 | */ 30 | - (void)showBadgeWithStyle:(WBadgeStyle)style 31 | value:(NSInteger)value 32 | animationType:(WBadgeAnimType)aniType; 33 | 34 | /* 35 | wBadgeStyle default is WBadgeStyleNumber 36 | */ 37 | - (void)showNumberBadgeWithValue:(NSInteger)value 38 | animationType:(WBadgeAnimType)aniType; 39 | 40 | // wBadgeStyle default is WBadgeStyleNumber ; 41 | // WBadgeAnimType defualt is WBadgeAnimTypeNone 42 | - (void)showNumberBadgeWithValue:(NSInteger)value; 43 | 44 | /** 45 | * clear badge(hide badge) 46 | */ 47 | - (void)clearBadge; 48 | 49 | /** 50 | * make bage(if existing) not hiden 51 | */ 52 | - (void)resumeBadge; 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /WZLBadge/View/UIView+WZLBadge.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+WZLBadge.m 3 | // WZLBadgeDemo 4 | // 5 | // Created by zilin_weng on 15/6/24. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import "UIView+WZLBadge.h" 10 | #import 11 | #import "CAAnimation+WAnimation.h" 12 | 13 | #define kWZLBadgeDefaultFont ([UIFont boldSystemFontOfSize:9]) 14 | 15 | #define kWZLBadgeDefaultMaximumBadgeNumber 99 16 | 17 | 18 | static const CGFloat kWZLBadgeDefaultRedDotRadius = 4.f; 19 | 20 | @implementation UIView (WZLBadge) 21 | 22 | #pragma mark -- public methods 23 | /** 24 | * show badge with red dot style and WBadgeAnimTypeNone by default. 25 | */ 26 | - (void)showBadge 27 | { 28 | [self showBadgeWithStyle:WBadgeStyleRedDot value:0 animationType:WBadgeAnimTypeNone]; 29 | } 30 | 31 | /** 32 | * showBadge 33 | * 34 | * @param style WBadgeStyle type 35 | * @param value (if 'style' is WBadgeStyleRedDot or WBadgeStyleNew, 36 | * this value will be ignored. In this case, any value will be ok.) 37 | */ 38 | - (void)showBadgeWithStyle:(WBadgeStyle)style value:(NSInteger)value animationType:(WBadgeAnimType)aniType 39 | { 40 | self.aniType = aniType; 41 | switch (style) { 42 | case WBadgeStyleRedDot: 43 | [self showRedDotBadge]; 44 | break; 45 | case WBadgeStyleNumber: 46 | [self showNumberBadgeWithValue:value]; 47 | break; 48 | case WBadgeStyleNew: 49 | [self showNewBadge]; 50 | break; 51 | default: 52 | break; 53 | } 54 | if (aniType != WBadgeAnimTypeNone) { 55 | [self beginAnimation]; 56 | } 57 | } 58 | 59 | - (void)showNumberBadgeWithValue:(NSInteger)value animationType:(WBadgeAnimType)aniType { 60 | self.aniType = aniType; 61 | [self showNumberBadgeWithValue:value]; 62 | 63 | if (aniType != WBadgeAnimTypeNone) { 64 | [self beginAnimation]; 65 | } 66 | } 67 | 68 | /** 69 | * clear badge 70 | */ 71 | - (void)clearBadge 72 | { 73 | self.badge.hidden = YES; 74 | } 75 | 76 | /** 77 | * make bage(if existing) not hiden 78 | */ 79 | - (void)resumeBadge 80 | { 81 | if (self.badge && self.badge.hidden == YES) { 82 | self.badge.hidden = NO; 83 | } 84 | } 85 | 86 | #pragma mark -- private methods 87 | - (void)showRedDotBadge 88 | { 89 | [self badgeInit]; 90 | //if badge has been displayed and, in addition, is was not red dot style, we must update UI. 91 | if (self.badge.tag != WBadgeStyleRedDot) { 92 | self.badge.text = @""; 93 | self.badge.tag = WBadgeStyleRedDot; 94 | [self resetBadgeForRedDot]; 95 | self.badge.layer.cornerRadius = CGRectGetWidth(self.badge.frame) / 2; 96 | } 97 | self.badge.hidden = NO; 98 | } 99 | 100 | - (void)resetBadgeForRedDot { 101 | if (self.badgeRadius > 0) { 102 | self.badge.frame = CGRectMake(self.badge.center.x - self.badgeRadius, self.badge.center.y + self.badgeRadius , self.badgeRadius * 2, self.badgeRadius *2); 103 | } 104 | } 105 | 106 | - (void)showNewBadge 107 | { 108 | [self badgeInit]; 109 | //if badge has been displayed and, in addition, is not red dot style, we must update UI. 110 | if (self.badge.tag != WBadgeStyleNew) { 111 | self.badge.text = @"new"; 112 | self.badge.tag = WBadgeStyleNew; 113 | 114 | CGRect frame = self.badge.frame; 115 | frame.size.width = 22; 116 | frame.size.height = 13; 117 | self.badge.frame = frame; 118 | 119 | self.badge.center = CGPointMake(CGRectGetWidth(self.frame) + 2 + self.badgeCenterOffset.x, self.badgeCenterOffset.y); 120 | self.badge.font = kWZLBadgeDefaultFont; 121 | self.badge.layer.cornerRadius = CGRectGetHeight(self.badge.frame) / 3; 122 | } 123 | self.badge.hidden = NO; 124 | } 125 | 126 | - (void)showNumberBadgeWithValue:(NSInteger)value 127 | { 128 | if (value < 0) { 129 | return; 130 | } 131 | [self badgeInit]; 132 | self.badge.hidden = (value == 0); 133 | self.badge.tag = WBadgeStyleNumber; 134 | self.badge.font = self.badgeFont; 135 | self.badge.text = (value > self.badgeMaximumBadgeNumber ? 136 | [NSString stringWithFormat:@"%@+", @(self.badgeMaximumBadgeNumber)] : 137 | [NSString stringWithFormat:@"%@", @(value)]); 138 | [self adjustLabelWidth:self.badge]; 139 | CGRect frame = self.badge.frame; 140 | frame.size.width += 4; 141 | frame.size.height += 4; 142 | if(CGRectGetWidth(frame) < CGRectGetHeight(frame)) { 143 | frame.size.width = CGRectGetHeight(frame); 144 | } 145 | self.badge.frame = frame; 146 | self.badge.center = CGPointMake(CGRectGetWidth(self.frame) + 2 + self.badgeCenterOffset.x, self.badgeCenterOffset.y); 147 | self.badge.layer.cornerRadius = CGRectGetHeight(self.badge.frame) / 2; 148 | } 149 | 150 | //lazy loading 151 | - (void)badgeInit 152 | { 153 | if (self.badgeBgColor == nil) { 154 | self.badgeBgColor = [UIColor redColor]; 155 | } 156 | if (self.badgeTextColor == nil) { 157 | self.badgeTextColor = [UIColor whiteColor]; 158 | } 159 | 160 | if (nil == self.badge) { 161 | CGFloat redotWidth = kWZLBadgeDefaultRedDotRadius *2; 162 | CGRect frm = CGRectMake(CGRectGetWidth(self.frame), -redotWidth, redotWidth, redotWidth); 163 | self.badge = [[UILabel alloc] initWithFrame:frm]; 164 | self.badge.textAlignment = NSTextAlignmentCenter; 165 | self.badge.center = CGPointMake(CGRectGetWidth(self.frame) + 2 + self.badgeCenterOffset.x, self.badgeCenterOffset.y); 166 | self.badge.backgroundColor = self.badgeBgColor; 167 | self.badge.textColor = self.badgeTextColor; 168 | self.badge.text = @""; 169 | self.badge.tag = WBadgeStyleRedDot;//red dot by default 170 | self.badge.layer.cornerRadius = CGRectGetWidth(self.badge.frame) / 2; 171 | self.badge.layer.masksToBounds = YES;//very important 172 | self.badge.hidden = NO; 173 | [self addSubview:self.badge]; 174 | [self bringSubviewToFront:self.badge]; 175 | } 176 | } 177 | 178 | #pragma mark -- other private methods 179 | - (void)adjustLabelWidth:(UILabel *)label 180 | { 181 | [label setNumberOfLines:0]; 182 | NSString *s = label.text; 183 | UIFont *font = [label font]; 184 | CGSize size = CGSizeMake(320,2000); 185 | CGSize labelsize; 186 | 187 | if (![s respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) { 188 | #pragma clang diagnostic push 189 | #pragma clang diagnostic ignored "-Wdeprecated-declarations" 190 | labelsize = [s sizeWithFont:font constrainedToSize:size lineBreakMode:NSLineBreakByWordWrapping]; 191 | #pragma clang diagnostic pop 192 | 193 | } else { 194 | NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 195 | [style setLineBreakMode:NSLineBreakByWordWrapping]; 196 | 197 | labelsize = [s boundingRectWithSize:size 198 | options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) 199 | attributes:@{ NSFontAttributeName:font, NSParagraphStyleAttributeName : style} 200 | context:nil].size; 201 | } 202 | CGRect frame = label.frame; 203 | frame.size = CGSizeMake(ceilf(labelsize.width), ceilf(labelsize.height)); 204 | [label setFrame:frame]; 205 | } 206 | 207 | #pragma mark -- animation 208 | 209 | //if u want to add badge animation type, follow steps bellow: 210 | //1. go to definition of WBadgeAnimType and add new type 211 | //2. go to category of CAAnimation+WAnimation to add new animation interface 212 | //3. call that new interface here 213 | - (void)beginAnimation 214 | { 215 | switch(self.aniType) { 216 | case WBadgeAnimTypeBreathe: 217 | [self.badge.layer addAnimation:[CAAnimation opacityForever_Animation:1.4] 218 | forKey:kBadgeBreatheAniKey]; 219 | break; 220 | case WBadgeAnimTypeShake: 221 | [self.badge.layer addAnimation:[CAAnimation shake_AnimationRepeatTimes:CGFLOAT_MAX 222 | durTimes:1 223 | forObj:self.badge.layer] 224 | forKey:kBadgeShakeAniKey]; 225 | break; 226 | case WBadgeAnimTypeScale: 227 | [self.badge.layer addAnimation:[CAAnimation scaleFrom:1.4 228 | toScale:0.6 229 | durTimes:1 230 | rep:MAXFLOAT] 231 | forKey:kBadgeScaleAniKey]; 232 | break; 233 | case WBadgeAnimTypeBounce: 234 | [self.badge.layer addAnimation:[CAAnimation bounce_AnimationRepeatTimes:CGFLOAT_MAX 235 | durTimes:1 236 | forObj:self.badge.layer] 237 | forKey:kBadgeBounceAniKey]; 238 | break; 239 | case WBadgeAnimTypeNone: 240 | default: 241 | break; 242 | } 243 | } 244 | 245 | 246 | - (void)removeAnimation 247 | { 248 | if (self.badge) { 249 | [self.badge.layer removeAllAnimations]; 250 | } 251 | } 252 | 253 | 254 | #pragma mark -- setter/getter 255 | - (UILabel *)badge 256 | { 257 | return objc_getAssociatedObject(self, &badgeLabelKey); 258 | } 259 | 260 | - (void)setBadge:(UILabel *)label 261 | { 262 | objc_setAssociatedObject(self, &badgeLabelKey, label, OBJC_ASSOCIATION_RETAIN); 263 | } 264 | 265 | - (UIFont *)badgeFont 266 | { 267 | id font = objc_getAssociatedObject(self, &badgeFontKey); 268 | return font == nil ? kWZLBadgeDefaultFont : font; 269 | } 270 | 271 | - (void)setBadgeFont:(UIFont *)badgeFont 272 | { 273 | objc_setAssociatedObject(self, &badgeFontKey, badgeFont, OBJC_ASSOCIATION_RETAIN); 274 | if (!self.badge) { 275 | [self badgeInit]; 276 | } 277 | self.badge.font = badgeFont; 278 | } 279 | 280 | - (UIColor *)badgeBgColor 281 | { 282 | return objc_getAssociatedObject(self, &badgeBgColorKey); 283 | } 284 | 285 | - (void)setBadgeBgColor:(UIColor *)badgeBgColor 286 | { 287 | objc_setAssociatedObject(self, &badgeBgColorKey, badgeBgColor, OBJC_ASSOCIATION_RETAIN); 288 | if (!self.badge) { 289 | [self badgeInit]; 290 | } 291 | self.badge.backgroundColor = badgeBgColor; 292 | } 293 | 294 | - (UIColor *)badgeTextColor 295 | { 296 | return objc_getAssociatedObject(self, &badgeTextColorKey); 297 | } 298 | 299 | - (void)setBadgeTextColor:(UIColor *)badgeTextColor 300 | { 301 | objc_setAssociatedObject(self, &badgeTextColorKey, badgeTextColor, OBJC_ASSOCIATION_RETAIN); 302 | if (!self.badge) { 303 | [self badgeInit]; 304 | } 305 | self.badge.textColor = badgeTextColor; 306 | } 307 | 308 | - (WBadgeAnimType)aniType 309 | { 310 | id obj = objc_getAssociatedObject(self, &badgeAniTypeKey); 311 | if(obj != nil && [obj isKindOfClass:[NSNumber class]]) 312 | { 313 | return [obj integerValue]; 314 | } 315 | else 316 | return WBadgeAnimTypeNone; 317 | } 318 | 319 | - (void)setAniType:(WBadgeAnimType)aniType 320 | { 321 | NSNumber *numObj = @(aniType); 322 | objc_setAssociatedObject(self, &badgeAniTypeKey, numObj, OBJC_ASSOCIATION_RETAIN); 323 | if (!self.badge) { 324 | [self badgeInit]; 325 | } 326 | [self removeAnimation]; 327 | [self beginAnimation]; 328 | } 329 | 330 | - (CGRect)badgeFrame 331 | { 332 | id obj = objc_getAssociatedObject(self, &badgeFrameKey); 333 | if (obj != nil && [obj isKindOfClass:[NSDictionary class]] && [obj count] == 4) { 334 | CGFloat x = [obj[@"x"] floatValue]; 335 | CGFloat y = [obj[@"y"] floatValue]; 336 | CGFloat width = [obj[@"width"] floatValue]; 337 | CGFloat height = [obj[@"height"] floatValue]; 338 | return CGRectMake(x, y, width, height); 339 | } else 340 | return CGRectZero; 341 | } 342 | 343 | - (void)setBadgeFrame:(CGRect)badgeFrame 344 | { 345 | NSDictionary *frameInfo = @{@"x" : @(badgeFrame.origin.x), @"y" : @(badgeFrame.origin.y), 346 | @"width" : @(badgeFrame.size.width), @"height" : @(badgeFrame.size.height)}; 347 | objc_setAssociatedObject(self, &badgeFrameKey, frameInfo, OBJC_ASSOCIATION_RETAIN); 348 | if (!self.badge) { 349 | [self badgeInit]; 350 | } 351 | self.badge.frame = badgeFrame; 352 | } 353 | 354 | - (CGPoint)badgeCenterOffset 355 | { 356 | id obj = objc_getAssociatedObject(self, &badgeCenterOffsetKey); 357 | if (obj != nil && [obj isKindOfClass:[NSDictionary class]] && [obj count] == 2) { 358 | CGFloat x = [obj[@"x"] floatValue]; 359 | CGFloat y = [obj[@"y"] floatValue]; 360 | return CGPointMake(x, y); 361 | } else 362 | return CGPointZero; 363 | } 364 | 365 | - (void)setBadgeCenterOffset:(CGPoint)badgeCenterOff 366 | { 367 | NSDictionary *cenerInfo = @{@"x" : @(badgeCenterOff.x), @"y" : @(badgeCenterOff.y)}; 368 | objc_setAssociatedObject(self, &badgeCenterOffsetKey, cenerInfo, OBJC_ASSOCIATION_RETAIN); 369 | if (!self.badge) { 370 | [self badgeInit]; 371 | } 372 | self.badge.center = CGPointMake(CGRectGetWidth(self.frame) + 2 + badgeCenterOff.x, badgeCenterOff.y); 373 | } 374 | 375 | //badgeRadiusKey 376 | 377 | - (void)setBadgeRadius:(CGFloat)badgeRadius { 378 | objc_setAssociatedObject(self, &badgeRadiusKey, [NSNumber numberWithFloat:badgeRadius], OBJC_ASSOCIATION_RETAIN); 379 | if (!self.badge) { 380 | [self badgeInit]; 381 | } 382 | } 383 | 384 | - (CGFloat)badgeRadius { 385 | return [objc_getAssociatedObject(self, &badgeRadiusKey) floatValue]; 386 | } 387 | 388 | - (NSInteger)badgeMaximumBadgeNumber { 389 | id obj = objc_getAssociatedObject(self, &badgeMaximumBadgeNumberKey); 390 | if(obj != nil && [obj isKindOfClass:[NSNumber class]]) 391 | { 392 | return [obj integerValue]; 393 | } 394 | else 395 | return kWZLBadgeDefaultMaximumBadgeNumber; 396 | } 397 | 398 | - (void)setBadgeMaximumBadgeNumber:(NSInteger)badgeMaximumBadgeNumber { 399 | NSNumber *numObj = @(badgeMaximumBadgeNumber); 400 | objc_setAssociatedObject(self, &badgeMaximumBadgeNumberKey, numObj, OBJC_ASSOCIATION_RETAIN); 401 | if (!self.badge) { 402 | [self badgeInit]; 403 | } 404 | } 405 | 406 | @end 407 | -------------------------------------------------------------------------------- /WZLBadge/WZLBadgeImport.h: -------------------------------------------------------------------------------- 1 | // 2 | // WZLBadgeImport.h 3 | // WZLBadgeDemo 4 | // 5 | // Created by zilin_weng on 15/8/10. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | 10 | // Only import this header file for your project is enough. 11 | // WZLBadge now supports badge for UIView, all subclasses of UIView and UIBarButtonItem Class. 12 | 13 | #ifndef WZLBadgeDemo_WZLBadgeImport_h 14 | #define WZLBadgeDemo_WZLBadgeImport_h 15 | 16 | #import "UIView+WZLBadge.h" 17 | #import "UIBarButtonItem+WZLBadge.h" 18 | #import "UITabBarItem+WZLBadge.h" 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /WZLBadgeDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 19133FAC1C9663B7002D4FB4 /* TableViewDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 19133FAB1C9663B7002D4FB4 /* TableViewDataSource.m */; }; 11 | 19685FF71B7898E600AD10C2 /* nav_list@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 19685FF61B7898E600AD10C2 /* nav_list@2x.png */; }; 12 | 196860021B78A6F500AD10C2 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 196860011B78A6F500AD10C2 /* libz.dylib */; }; 13 | 1968600F1B78AB4A00AD10C2 /* UIView+WZLBadge.m in Sources */ = {isa = PBXBuildFile; fileRef = 1968600C1B78AB4A00AD10C2 /* UIView+WZLBadge.m */; }; 14 | 1968601F1B7AD02E00AD10C2 /* CAAnimation+WAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 1968601C1B7AD02E00AD10C2 /* CAAnimation+WAnimation.m */; }; 15 | 19784AF11B4BC59C00FEA91C /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 19784AF01B4BC59C00FEA91C /* Default-568h@2x.png */; }; 16 | 19AD4E7F1BB3D0610059AA66 /* RootTabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 19AD4E7E1BB3D0610059AA66 /* RootTabBarController.m */; }; 17 | 19AD4E8A1BB3D4600059AA66 /* UIBarButtonItem+WZLBadge.m in Sources */ = {isa = PBXBuildFile; fileRef = 19AD4E871BB3D4600059AA66 /* UIBarButtonItem+WZLBadge.m */; }; 18 | 19AD4E8B1BB3D4600059AA66 /* UITabBarItem+WZLBadge.m in Sources */ = {isa = PBXBuildFile; fileRef = 19AD4E891BB3D4600059AA66 /* UITabBarItem+WZLBadge.m */; }; 19 | 19AD4E901BB3D4D80059AA66 /* UIView+Frame.m in Sources */ = {isa = PBXBuildFile; fileRef = 19AD4E8F1BB3D4D80059AA66 /* UIView+Frame.m */; }; 20 | 19C18C461B3AAEBA00BD63D2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 19C18C451B3AAEBA00BD63D2 /* main.m */; }; 21 | 19C18C491B3AAEBA00BD63D2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 19C18C481B3AAEBA00BD63D2 /* AppDelegate.m */; }; 22 | 19C18C4C1B3AAEBA00BD63D2 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 19C18C4B1B3AAEBA00BD63D2 /* ViewController.m */; }; 23 | 19C18C511B3AAEBA00BD63D2 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 19C18C501B3AAEBA00BD63D2 /* Images.xcassets */; }; 24 | 19C18C601B3AAEBA00BD63D2 /* WZLBadgeDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 19C18C5F1B3AAEBA00BD63D2 /* WZLBadgeDemoTests.m */; }; 25 | 19C18C7B1B42496700BD63D2 /* logo@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 19C18C7A1B42496700BD63D2 /* logo@2x.jpg */; }; 26 | A2BB80901B7BA5FA00373C78 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 19C18C4D1B3AAEBA00BD63D2 /* Main.storyboard */; }; 27 | A2BB80911B7BA5FA00373C78 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 19C18C521B3AAEBA00BD63D2 /* LaunchScreen.xib */; }; 28 | DC040FB11EF7CB0B000B69A3 /* TableViewCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DC040FB01EF7CB0B000B69A3 /* TableViewCollectionViewController.m */; }; 29 | /* End PBXBuildFile section */ 30 | 31 | /* Begin PBXContainerItemProxy section */ 32 | 19C18C5A1B3AAEBA00BD63D2 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = 19C18C381B3AAEBA00BD63D2 /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = 19C18C3F1B3AAEBA00BD63D2; 37 | remoteInfo = WZLBadgeDemo; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXFileReference section */ 42 | 19133FAA1C9663B7002D4FB4 /* TableViewDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableViewDataSource.h; sourceTree = ""; }; 43 | 19133FAB1C9663B7002D4FB4 /* TableViewDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TableViewDataSource.m; sourceTree = ""; }; 44 | 19685FF61B7898E600AD10C2 /* nav_list@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "nav_list@2x.png"; sourceTree = ""; }; 45 | 196860011B78A6F500AD10C2 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; 46 | 1968600B1B78AB4A00AD10C2 /* UIView+WZLBadge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+WZLBadge.h"; sourceTree = ""; }; 47 | 1968600C1B78AB4A00AD10C2 /* UIView+WZLBadge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+WZLBadge.m"; sourceTree = ""; }; 48 | 196860101B78AB8200AD10C2 /* WZLBadgeImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WZLBadgeImport.h; sourceTree = ""; }; 49 | 1968601B1B7AD02E00AD10C2 /* CAAnimation+WAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CAAnimation+WAnimation.h"; sourceTree = ""; }; 50 | 1968601C1B7AD02E00AD10C2 /* CAAnimation+WAnimation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CAAnimation+WAnimation.m"; sourceTree = ""; }; 51 | 196860221B7AD96D00AD10C2 /* WZLBadgeProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WZLBadgeProtocol.h; sourceTree = ""; }; 52 | 19784AF01B4BC59C00FEA91C /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 53 | 19AD4E7D1BB3D0610059AA66 /* RootTabBarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootTabBarController.h; sourceTree = ""; }; 54 | 19AD4E7E1BB3D0610059AA66 /* RootTabBarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootTabBarController.m; sourceTree = ""; }; 55 | 19AD4E861BB3D4600059AA66 /* UIBarButtonItem+WZLBadge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIBarButtonItem+WZLBadge.h"; path = "WZLBadge/BarItem/UIBarButtonItem+WZLBadge.h"; sourceTree = SOURCE_ROOT; }; 56 | 19AD4E871BB3D4600059AA66 /* UIBarButtonItem+WZLBadge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIBarButtonItem+WZLBadge.m"; path = "WZLBadge/BarItem/UIBarButtonItem+WZLBadge.m"; sourceTree = SOURCE_ROOT; }; 57 | 19AD4E881BB3D4600059AA66 /* UITabBarItem+WZLBadge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UITabBarItem+WZLBadge.h"; path = "WZLBadge/BarItem/UITabBarItem+WZLBadge.h"; sourceTree = SOURCE_ROOT; }; 58 | 19AD4E891BB3D4600059AA66 /* UITabBarItem+WZLBadge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UITabBarItem+WZLBadge.m"; path = "WZLBadge/BarItem/UITabBarItem+WZLBadge.m"; sourceTree = SOURCE_ROOT; }; 59 | 19AD4E8E1BB3D4D80059AA66 /* UIView+Frame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+Frame.h"; sourceTree = ""; }; 60 | 19AD4E8F1BB3D4D80059AA66 /* UIView+Frame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+Frame.m"; sourceTree = ""; }; 61 | 19C18C401B3AAEBA00BD63D2 /* WZLBadgeDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WZLBadgeDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 62 | 19C18C441B3AAEBA00BD63D2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 63 | 19C18C451B3AAEBA00BD63D2 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 64 | 19C18C471B3AAEBA00BD63D2 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 65 | 19C18C481B3AAEBA00BD63D2 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 66 | 19C18C4A1B3AAEBA00BD63D2 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 67 | 19C18C4B1B3AAEBA00BD63D2 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 68 | 19C18C4E1B3AAEBA00BD63D2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 69 | 19C18C501B3AAEBA00BD63D2 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 70 | 19C18C531B3AAEBA00BD63D2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 71 | 19C18C591B3AAEBA00BD63D2 /* WZLBadgeDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WZLBadgeDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 72 | 19C18C5E1B3AAEBA00BD63D2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 73 | 19C18C5F1B3AAEBA00BD63D2 /* WZLBadgeDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WZLBadgeDemoTests.m; sourceTree = ""; }; 74 | 19C18C7A1B42496700BD63D2 /* logo@2x.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "logo@2x.jpg"; sourceTree = ""; }; 75 | DC040FAF1EF7CB0B000B69A3 /* TableViewCollectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableViewCollectionViewController.h; sourceTree = ""; }; 76 | DC040FB01EF7CB0B000B69A3 /* TableViewCollectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TableViewCollectionViewController.m; sourceTree = ""; }; 77 | /* End PBXFileReference section */ 78 | 79 | /* Begin PBXFrameworksBuildPhase section */ 80 | 19C18C3D1B3AAEBA00BD63D2 /* Frameworks */ = { 81 | isa = PBXFrameworksBuildPhase; 82 | buildActionMask = 2147483647; 83 | files = ( 84 | 196860021B78A6F500AD10C2 /* libz.dylib in Frameworks */, 85 | ); 86 | runOnlyForDeploymentPostprocessing = 0; 87 | }; 88 | 19C18C561B3AAEBA00BD63D2 /* Frameworks */ = { 89 | isa = PBXFrameworksBuildPhase; 90 | buildActionMask = 2147483647; 91 | files = ( 92 | ); 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | /* End PBXFrameworksBuildPhase section */ 96 | 97 | /* Begin PBXGroup section */ 98 | 196860031B78AB4A00AD10C2 /* WZLBadge */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 196860211B7AD91100AD10C2 /* Protocol */, 102 | 1968601A1B7AD02E00AD10C2 /* CategorySupport */, 103 | 196860041B78AB4A00AD10C2 /* BarItem */, 104 | 1968600A1B78AB4A00AD10C2 /* View */, 105 | 196860101B78AB8200AD10C2 /* WZLBadgeImport.h */, 106 | ); 107 | path = WZLBadge; 108 | sourceTree = SOURCE_ROOT; 109 | }; 110 | 196860041B78AB4A00AD10C2 /* BarItem */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | 19AD4E861BB3D4600059AA66 /* UIBarButtonItem+WZLBadge.h */, 114 | 19AD4E871BB3D4600059AA66 /* UIBarButtonItem+WZLBadge.m */, 115 | 19AD4E881BB3D4600059AA66 /* UITabBarItem+WZLBadge.h */, 116 | 19AD4E891BB3D4600059AA66 /* UITabBarItem+WZLBadge.m */, 117 | ); 118 | name = BarItem; 119 | path = BarButtonItem; 120 | sourceTree = ""; 121 | }; 122 | 1968600A1B78AB4A00AD10C2 /* View */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | 1968600B1B78AB4A00AD10C2 /* UIView+WZLBadge.h */, 126 | 1968600C1B78AB4A00AD10C2 /* UIView+WZLBadge.m */, 127 | ); 128 | path = View; 129 | sourceTree = ""; 130 | }; 131 | 1968601A1B7AD02E00AD10C2 /* CategorySupport */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 1968601B1B7AD02E00AD10C2 /* CAAnimation+WAnimation.h */, 135 | 1968601C1B7AD02E00AD10C2 /* CAAnimation+WAnimation.m */, 136 | ); 137 | path = CategorySupport; 138 | sourceTree = ""; 139 | }; 140 | 196860211B7AD91100AD10C2 /* Protocol */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | 196860221B7AD96D00AD10C2 /* WZLBadgeProtocol.h */, 144 | ); 145 | path = Protocol; 146 | sourceTree = ""; 147 | }; 148 | 19AD4E8C1BB3D4D80059AA66 /* Tool */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | 19AD4E8D1BB3D4D80059AA66 /* Category */, 152 | ); 153 | path = Tool; 154 | sourceTree = ""; 155 | }; 156 | 19AD4E8D1BB3D4D80059AA66 /* Category */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 19AD4E8E1BB3D4D80059AA66 /* UIView+Frame.h */, 160 | 19AD4E8F1BB3D4D80059AA66 /* UIView+Frame.m */, 161 | ); 162 | path = Category; 163 | sourceTree = ""; 164 | }; 165 | 19C18C371B3AAEBA00BD63D2 = { 166 | isa = PBXGroup; 167 | children = ( 168 | 19C18C421B3AAEBA00BD63D2 /* WZLBadgeDemo */, 169 | 19C18C5C1B3AAEBA00BD63D2 /* WZLBadgeDemoTests */, 170 | 19C18C411B3AAEBA00BD63D2 /* Products */, 171 | ); 172 | sourceTree = ""; 173 | }; 174 | 19C18C411B3AAEBA00BD63D2 /* Products */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | 19C18C401B3AAEBA00BD63D2 /* WZLBadgeDemo.app */, 178 | 19C18C591B3AAEBA00BD63D2 /* WZLBadgeDemoTests.xctest */, 179 | ); 180 | name = Products; 181 | sourceTree = ""; 182 | }; 183 | 19C18C421B3AAEBA00BD63D2 /* WZLBadgeDemo */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | DC040FAE1EF7CADF000B69A3 /* examples */, 187 | 19AD4E8C1BB3D4D80059AA66 /* Tool */, 188 | 196860031B78AB4A00AD10C2 /* WZLBadge */, 189 | 19C18C471B3AAEBA00BD63D2 /* AppDelegate.h */, 190 | 19C18C481B3AAEBA00BD63D2 /* AppDelegate.m */, 191 | 19C18C4D1B3AAEBA00BD63D2 /* Main.storyboard */, 192 | 19AD4E7D1BB3D0610059AA66 /* RootTabBarController.h */, 193 | 19AD4E7E1BB3D0610059AA66 /* RootTabBarController.m */, 194 | 19C18C4A1B3AAEBA00BD63D2 /* ViewController.h */, 195 | 19C18C4B1B3AAEBA00BD63D2 /* ViewController.m */, 196 | 19133FAA1C9663B7002D4FB4 /* TableViewDataSource.h */, 197 | 19133FAB1C9663B7002D4FB4 /* TableViewDataSource.m */, 198 | 19C18C431B3AAEBA00BD63D2 /* Supporting Files */, 199 | ); 200 | path = WZLBadgeDemo; 201 | sourceTree = ""; 202 | }; 203 | 19C18C431B3AAEBA00BD63D2 /* Supporting Files */ = { 204 | isa = PBXGroup; 205 | children = ( 206 | 19C18C501B3AAEBA00BD63D2 /* Images.xcassets */, 207 | 19C18C521B3AAEBA00BD63D2 /* LaunchScreen.xib */, 208 | 19C18C7A1B42496700BD63D2 /* logo@2x.jpg */, 209 | 19685FF61B7898E600AD10C2 /* nav_list@2x.png */, 210 | 196860011B78A6F500AD10C2 /* libz.dylib */, 211 | 19784AF01B4BC59C00FEA91C /* Default-568h@2x.png */, 212 | 19C18C441B3AAEBA00BD63D2 /* Info.plist */, 213 | 19C18C451B3AAEBA00BD63D2 /* main.m */, 214 | ); 215 | name = "Supporting Files"; 216 | sourceTree = ""; 217 | }; 218 | 19C18C5C1B3AAEBA00BD63D2 /* WZLBadgeDemoTests */ = { 219 | isa = PBXGroup; 220 | children = ( 221 | 19C18C5F1B3AAEBA00BD63D2 /* WZLBadgeDemoTests.m */, 222 | 19C18C5D1B3AAEBA00BD63D2 /* Supporting Files */, 223 | ); 224 | path = WZLBadgeDemoTests; 225 | sourceTree = ""; 226 | }; 227 | 19C18C5D1B3AAEBA00BD63D2 /* Supporting Files */ = { 228 | isa = PBXGroup; 229 | children = ( 230 | 19C18C5E1B3AAEBA00BD63D2 /* Info.plist */, 231 | ); 232 | name = "Supporting Files"; 233 | sourceTree = ""; 234 | }; 235 | DC040FAE1EF7CADF000B69A3 /* examples */ = { 236 | isa = PBXGroup; 237 | children = ( 238 | DC040FAF1EF7CB0B000B69A3 /* TableViewCollectionViewController.h */, 239 | DC040FB01EF7CB0B000B69A3 /* TableViewCollectionViewController.m */, 240 | ); 241 | path = examples; 242 | sourceTree = ""; 243 | }; 244 | /* End PBXGroup section */ 245 | 246 | /* Begin PBXNativeTarget section */ 247 | 19C18C3F1B3AAEBA00BD63D2 /* WZLBadgeDemo */ = { 248 | isa = PBXNativeTarget; 249 | buildConfigurationList = 19C18C631B3AAEBA00BD63D2 /* Build configuration list for PBXNativeTarget "WZLBadgeDemo" */; 250 | buildPhases = ( 251 | 19C18C3C1B3AAEBA00BD63D2 /* Sources */, 252 | 19C18C3D1B3AAEBA00BD63D2 /* Frameworks */, 253 | 19C18C3E1B3AAEBA00BD63D2 /* Resources */, 254 | ); 255 | buildRules = ( 256 | ); 257 | dependencies = ( 258 | ); 259 | name = WZLBadgeDemo; 260 | productName = WZLBadgeDemo; 261 | productReference = 19C18C401B3AAEBA00BD63D2 /* WZLBadgeDemo.app */; 262 | productType = "com.apple.product-type.application"; 263 | }; 264 | 19C18C581B3AAEBA00BD63D2 /* WZLBadgeDemoTests */ = { 265 | isa = PBXNativeTarget; 266 | buildConfigurationList = 19C18C661B3AAEBA00BD63D2 /* Build configuration list for PBXNativeTarget "WZLBadgeDemoTests" */; 267 | buildPhases = ( 268 | 19C18C551B3AAEBA00BD63D2 /* Sources */, 269 | 19C18C561B3AAEBA00BD63D2 /* Frameworks */, 270 | 19C18C571B3AAEBA00BD63D2 /* Resources */, 271 | ); 272 | buildRules = ( 273 | ); 274 | dependencies = ( 275 | 19C18C5B1B3AAEBA00BD63D2 /* PBXTargetDependency */, 276 | ); 277 | name = WZLBadgeDemoTests; 278 | productName = WZLBadgeDemoTests; 279 | productReference = 19C18C591B3AAEBA00BD63D2 /* WZLBadgeDemoTests.xctest */; 280 | productType = "com.apple.product-type.bundle.unit-test"; 281 | }; 282 | /* End PBXNativeTarget section */ 283 | 284 | /* Begin PBXProject section */ 285 | 19C18C381B3AAEBA00BD63D2 /* Project object */ = { 286 | isa = PBXProject; 287 | attributes = { 288 | LastUpgradeCheck = 0630; 289 | ORGANIZATIONNAME = "Weng-Zilin"; 290 | TargetAttributes = { 291 | 19C18C3F1B3AAEBA00BD63D2 = { 292 | CreatedOnToolsVersion = 6.3; 293 | DevelopmentTeam = 99R47P69W5; 294 | }; 295 | 19C18C581B3AAEBA00BD63D2 = { 296 | CreatedOnToolsVersion = 6.3; 297 | TestTargetID = 19C18C3F1B3AAEBA00BD63D2; 298 | }; 299 | }; 300 | }; 301 | buildConfigurationList = 19C18C3B1B3AAEBA00BD63D2 /* Build configuration list for PBXProject "WZLBadgeDemo" */; 302 | compatibilityVersion = "Xcode 3.2"; 303 | developmentRegion = English; 304 | hasScannedForEncodings = 0; 305 | knownRegions = ( 306 | en, 307 | Base, 308 | "zh-Hans", 309 | ); 310 | mainGroup = 19C18C371B3AAEBA00BD63D2; 311 | productRefGroup = 19C18C411B3AAEBA00BD63D2 /* Products */; 312 | projectDirPath = ""; 313 | projectRoot = ""; 314 | targets = ( 315 | 19C18C3F1B3AAEBA00BD63D2 /* WZLBadgeDemo */, 316 | 19C18C581B3AAEBA00BD63D2 /* WZLBadgeDemoTests */, 317 | ); 318 | }; 319 | /* End PBXProject section */ 320 | 321 | /* Begin PBXResourcesBuildPhase section */ 322 | 19C18C3E1B3AAEBA00BD63D2 /* Resources */ = { 323 | isa = PBXResourcesBuildPhase; 324 | buildActionMask = 2147483647; 325 | files = ( 326 | A2BB80901B7BA5FA00373C78 /* Main.storyboard in Resources */, 327 | A2BB80911B7BA5FA00373C78 /* LaunchScreen.xib in Resources */, 328 | 19C18C7B1B42496700BD63D2 /* logo@2x.jpg in Resources */, 329 | 19784AF11B4BC59C00FEA91C /* Default-568h@2x.png in Resources */, 330 | 19685FF71B7898E600AD10C2 /* nav_list@2x.png in Resources */, 331 | 19C18C511B3AAEBA00BD63D2 /* Images.xcassets in Resources */, 332 | ); 333 | runOnlyForDeploymentPostprocessing = 0; 334 | }; 335 | 19C18C571B3AAEBA00BD63D2 /* Resources */ = { 336 | isa = PBXResourcesBuildPhase; 337 | buildActionMask = 2147483647; 338 | files = ( 339 | ); 340 | runOnlyForDeploymentPostprocessing = 0; 341 | }; 342 | /* End PBXResourcesBuildPhase section */ 343 | 344 | /* Begin PBXSourcesBuildPhase section */ 345 | 19C18C3C1B3AAEBA00BD63D2 /* Sources */ = { 346 | isa = PBXSourcesBuildPhase; 347 | buildActionMask = 2147483647; 348 | files = ( 349 | 19C18C4C1B3AAEBA00BD63D2 /* ViewController.m in Sources */, 350 | 1968601F1B7AD02E00AD10C2 /* CAAnimation+WAnimation.m in Sources */, 351 | 19AD4E7F1BB3D0610059AA66 /* RootTabBarController.m in Sources */, 352 | 19AD4E901BB3D4D80059AA66 /* UIView+Frame.m in Sources */, 353 | DC040FB11EF7CB0B000B69A3 /* TableViewCollectionViewController.m in Sources */, 354 | 19133FAC1C9663B7002D4FB4 /* TableViewDataSource.m in Sources */, 355 | 19C18C491B3AAEBA00BD63D2 /* AppDelegate.m in Sources */, 356 | 1968600F1B78AB4A00AD10C2 /* UIView+WZLBadge.m in Sources */, 357 | 19AD4E8B1BB3D4600059AA66 /* UITabBarItem+WZLBadge.m in Sources */, 358 | 19AD4E8A1BB3D4600059AA66 /* UIBarButtonItem+WZLBadge.m in Sources */, 359 | 19C18C461B3AAEBA00BD63D2 /* main.m in Sources */, 360 | ); 361 | runOnlyForDeploymentPostprocessing = 0; 362 | }; 363 | 19C18C551B3AAEBA00BD63D2 /* Sources */ = { 364 | isa = PBXSourcesBuildPhase; 365 | buildActionMask = 2147483647; 366 | files = ( 367 | 19C18C601B3AAEBA00BD63D2 /* WZLBadgeDemoTests.m in Sources */, 368 | ); 369 | runOnlyForDeploymentPostprocessing = 0; 370 | }; 371 | /* End PBXSourcesBuildPhase section */ 372 | 373 | /* Begin PBXTargetDependency section */ 374 | 19C18C5B1B3AAEBA00BD63D2 /* PBXTargetDependency */ = { 375 | isa = PBXTargetDependency; 376 | target = 19C18C3F1B3AAEBA00BD63D2 /* WZLBadgeDemo */; 377 | targetProxy = 19C18C5A1B3AAEBA00BD63D2 /* PBXContainerItemProxy */; 378 | }; 379 | /* End PBXTargetDependency section */ 380 | 381 | /* Begin PBXVariantGroup section */ 382 | 19C18C4D1B3AAEBA00BD63D2 /* Main.storyboard */ = { 383 | isa = PBXVariantGroup; 384 | children = ( 385 | 19C18C4E1B3AAEBA00BD63D2 /* Base */, 386 | ); 387 | name = Main.storyboard; 388 | sourceTree = ""; 389 | }; 390 | 19C18C521B3AAEBA00BD63D2 /* LaunchScreen.xib */ = { 391 | isa = PBXVariantGroup; 392 | children = ( 393 | 19C18C531B3AAEBA00BD63D2 /* Base */, 394 | ); 395 | name = LaunchScreen.xib; 396 | sourceTree = ""; 397 | }; 398 | /* End PBXVariantGroup section */ 399 | 400 | /* Begin XCBuildConfiguration section */ 401 | 19C18C611B3AAEBA00BD63D2 /* Debug */ = { 402 | isa = XCBuildConfiguration; 403 | buildSettings = { 404 | ALWAYS_SEARCH_USER_PATHS = NO; 405 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 406 | CLANG_CXX_LIBRARY = "libc++"; 407 | CLANG_ENABLE_MODULES = YES; 408 | CLANG_ENABLE_OBJC_ARC = YES; 409 | CLANG_WARN_BOOL_CONVERSION = YES; 410 | CLANG_WARN_CONSTANT_CONVERSION = YES; 411 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 412 | CLANG_WARN_EMPTY_BODY = YES; 413 | CLANG_WARN_ENUM_CONVERSION = YES; 414 | CLANG_WARN_INT_CONVERSION = YES; 415 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 416 | CLANG_WARN_UNREACHABLE_CODE = YES; 417 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 418 | CODE_SIGN_IDENTITY = "iPhone Developer"; 419 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 420 | COPY_PHASE_STRIP = NO; 421 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 422 | ENABLE_STRICT_OBJC_MSGSEND = YES; 423 | GCC_C_LANGUAGE_STANDARD = gnu99; 424 | GCC_DYNAMIC_NO_PIC = NO; 425 | GCC_NO_COMMON_BLOCKS = YES; 426 | GCC_OPTIMIZATION_LEVEL = 0; 427 | GCC_PREPROCESSOR_DEFINITIONS = ( 428 | "DEBUG=1", 429 | "$(inherited)", 430 | ); 431 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 432 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 433 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 434 | GCC_WARN_UNDECLARED_SELECTOR = YES; 435 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 436 | GCC_WARN_UNUSED_FUNCTION = YES; 437 | GCC_WARN_UNUSED_VARIABLE = YES; 438 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 439 | MTL_ENABLE_DEBUG_INFO = YES; 440 | ONLY_ACTIVE_ARCH = YES; 441 | SDKROOT = iphoneos; 442 | }; 443 | name = Debug; 444 | }; 445 | 19C18C621B3AAEBA00BD63D2 /* Release */ = { 446 | isa = XCBuildConfiguration; 447 | buildSettings = { 448 | ALWAYS_SEARCH_USER_PATHS = NO; 449 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 450 | CLANG_CXX_LIBRARY = "libc++"; 451 | CLANG_ENABLE_MODULES = YES; 452 | CLANG_ENABLE_OBJC_ARC = YES; 453 | CLANG_WARN_BOOL_CONVERSION = YES; 454 | CLANG_WARN_CONSTANT_CONVERSION = YES; 455 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 456 | CLANG_WARN_EMPTY_BODY = YES; 457 | CLANG_WARN_ENUM_CONVERSION = YES; 458 | CLANG_WARN_INT_CONVERSION = YES; 459 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 460 | CLANG_WARN_UNREACHABLE_CODE = YES; 461 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 462 | CODE_SIGN_IDENTITY = "iPhone Distribution"; 463 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; 464 | COPY_PHASE_STRIP = NO; 465 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 466 | ENABLE_NS_ASSERTIONS = NO; 467 | ENABLE_STRICT_OBJC_MSGSEND = YES; 468 | GCC_C_LANGUAGE_STANDARD = gnu99; 469 | GCC_NO_COMMON_BLOCKS = YES; 470 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 471 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 472 | GCC_WARN_UNDECLARED_SELECTOR = YES; 473 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 474 | GCC_WARN_UNUSED_FUNCTION = YES; 475 | GCC_WARN_UNUSED_VARIABLE = YES; 476 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 477 | MTL_ENABLE_DEBUG_INFO = NO; 478 | SDKROOT = iphoneos; 479 | VALIDATE_PRODUCT = YES; 480 | }; 481 | name = Release; 482 | }; 483 | 19C18C641B3AAEBA00BD63D2 /* Debug */ = { 484 | isa = XCBuildConfiguration; 485 | buildSettings = { 486 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 487 | CODE_SIGN_IDENTITY = "iPhone Developer"; 488 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 489 | FRAMEWORK_SEARCH_PATHS = ( 490 | "$(inherited)", 491 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/umeng_ios_social_sdk_4.2.3_arm64_custom/UMSocial_Sdk_Extra_Frameworks/TencentOpenAPI, 492 | ); 493 | INFOPLIST_FILE = WZLBadgeDemo/Info.plist; 494 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 495 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 496 | LIBRARY_SEARCH_PATHS = ( 497 | "$(inherited)", 498 | "/Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/AdsMoGo/AdsMoGoNetworks/Baidu_3.6.2(2.8)_SDK/lib", 499 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/AdsMoGo/AdsMoGoNetworks/GDTMob_SDK_350/libs, 500 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/AdsMoGo/AdsMoGoSDK, 501 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/UMAnalytics_Sdk_3.5.8, 502 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/umeng_ios_social_sdk_4.2.3_arm64_custom/UMSocial_Sdk_4.2.3, 503 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/umeng_ios_social_sdk_4.2.3_arm64_custom/UMSocial_Sdk_Extra_Frameworks/Sina, 504 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/umeng_ios_social_sdk_4.2.3_arm64_custom/UMSocial_Sdk_Extra_Frameworks/SinaSSO, 505 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/umeng_ios_social_sdk_4.2.3_arm64_custom/UMSocial_Sdk_Extra_Frameworks/TencentOpenAPI, 506 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/umeng_ios_social_sdk_4.2.3_arm64_custom/UMSocial_Sdk_Extra_Frameworks/UMSocial_ScreenShot_Sdk, 507 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/umeng_ios_social_sdk_4.2.3_arm64_custom/UMSocial_Sdk_Extra_Frameworks/UMSocial_Shake_Sdk, 508 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/umeng_ios_social_sdk_4.2.3_arm64_custom/UMSocial_Sdk_Extra_Frameworks/Wechat, 509 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/UMengFeedback_SDK, 510 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/UMengFeedback_SDK/UMOpus, 511 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/UMessage_Sdk_1.1.0, 512 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/YouMi/lib, 513 | ); 514 | OTHER_LDFLAGS = ""; 515 | PRODUCT_NAME = "$(TARGET_NAME)"; 516 | PROVISIONING_PROFILE = ""; 517 | TARGETED_DEVICE_FAMILY = "1,2"; 518 | }; 519 | name = Debug; 520 | }; 521 | 19C18C651B3AAEBA00BD63D2 /* Release */ = { 522 | isa = XCBuildConfiguration; 523 | buildSettings = { 524 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 525 | CODE_SIGN_IDENTITY = "iPhone Developer"; 526 | FRAMEWORK_SEARCH_PATHS = ( 527 | "$(inherited)", 528 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/umeng_ios_social_sdk_4.2.3_arm64_custom/UMSocial_Sdk_Extra_Frameworks/TencentOpenAPI, 529 | ); 530 | INFOPLIST_FILE = WZLBadgeDemo/Info.plist; 531 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 532 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 533 | LIBRARY_SEARCH_PATHS = ( 534 | "$(inherited)", 535 | "/Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/AdsMoGo/AdsMoGoNetworks/Baidu_3.6.2(2.8)_SDK/lib", 536 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/AdsMoGo/AdsMoGoNetworks/GDTMob_SDK_350/libs, 537 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/AdsMoGo/AdsMoGoSDK, 538 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/UMAnalytics_Sdk_3.5.8, 539 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/umeng_ios_social_sdk_4.2.3_arm64_custom/UMSocial_Sdk_4.2.3, 540 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/umeng_ios_social_sdk_4.2.3_arm64_custom/UMSocial_Sdk_Extra_Frameworks/Sina, 541 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/umeng_ios_social_sdk_4.2.3_arm64_custom/UMSocial_Sdk_Extra_Frameworks/SinaSSO, 542 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/umeng_ios_social_sdk_4.2.3_arm64_custom/UMSocial_Sdk_Extra_Frameworks/TencentOpenAPI, 543 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/umeng_ios_social_sdk_4.2.3_arm64_custom/UMSocial_Sdk_Extra_Frameworks/UMSocial_ScreenShot_Sdk, 544 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/umeng_ios_social_sdk_4.2.3_arm64_custom/UMSocial_Sdk_Extra_Frameworks/UMSocial_Shake_Sdk, 545 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/umeng_ios_social_sdk_4.2.3_arm64_custom/UMSocial_Sdk_Extra_Frameworks/Wechat, 546 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/UMengFeedback_SDK, 547 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/UMengFeedback_SDK/UMOpus, 548 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/UMeng/UMessage_Sdk_1.1.0, 549 | /Users/user/Desktop/Git/WuJieCaoJoke/WuJieCaoJoke/ThirdPart/ThirdPlatform/YouMi/lib, 550 | ); 551 | OTHER_LDFLAGS = ""; 552 | PRODUCT_NAME = "$(TARGET_NAME)"; 553 | PROVISIONING_PROFILE = ""; 554 | TARGETED_DEVICE_FAMILY = "1,2"; 555 | }; 556 | name = Release; 557 | }; 558 | 19C18C671B3AAEBA00BD63D2 /* Debug */ = { 559 | isa = XCBuildConfiguration; 560 | buildSettings = { 561 | BUNDLE_LOADER = "$(TEST_HOST)"; 562 | FRAMEWORK_SEARCH_PATHS = ( 563 | "$(SDKROOT)/Developer/Library/Frameworks", 564 | "$(inherited)", 565 | ); 566 | GCC_PREPROCESSOR_DEFINITIONS = ( 567 | "DEBUG=1", 568 | "$(inherited)", 569 | ); 570 | INFOPLIST_FILE = WZLBadgeDemoTests/Info.plist; 571 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 572 | PRODUCT_NAME = "$(TARGET_NAME)"; 573 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WZLBadgeDemo.app/WZLBadgeDemo"; 574 | }; 575 | name = Debug; 576 | }; 577 | 19C18C681B3AAEBA00BD63D2 /* Release */ = { 578 | isa = XCBuildConfiguration; 579 | buildSettings = { 580 | BUNDLE_LOADER = "$(TEST_HOST)"; 581 | FRAMEWORK_SEARCH_PATHS = ( 582 | "$(SDKROOT)/Developer/Library/Frameworks", 583 | "$(inherited)", 584 | ); 585 | INFOPLIST_FILE = WZLBadgeDemoTests/Info.plist; 586 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 587 | PRODUCT_NAME = "$(TARGET_NAME)"; 588 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WZLBadgeDemo.app/WZLBadgeDemo"; 589 | }; 590 | name = Release; 591 | }; 592 | /* End XCBuildConfiguration section */ 593 | 594 | /* Begin XCConfigurationList section */ 595 | 19C18C3B1B3AAEBA00BD63D2 /* Build configuration list for PBXProject "WZLBadgeDemo" */ = { 596 | isa = XCConfigurationList; 597 | buildConfigurations = ( 598 | 19C18C611B3AAEBA00BD63D2 /* Debug */, 599 | 19C18C621B3AAEBA00BD63D2 /* Release */, 600 | ); 601 | defaultConfigurationIsVisible = 0; 602 | defaultConfigurationName = Release; 603 | }; 604 | 19C18C631B3AAEBA00BD63D2 /* Build configuration list for PBXNativeTarget "WZLBadgeDemo" */ = { 605 | isa = XCConfigurationList; 606 | buildConfigurations = ( 607 | 19C18C641B3AAEBA00BD63D2 /* Debug */, 608 | 19C18C651B3AAEBA00BD63D2 /* Release */, 609 | ); 610 | defaultConfigurationIsVisible = 0; 611 | defaultConfigurationName = Release; 612 | }; 613 | 19C18C661B3AAEBA00BD63D2 /* Build configuration list for PBXNativeTarget "WZLBadgeDemoTests" */ = { 614 | isa = XCConfigurationList; 615 | buildConfigurations = ( 616 | 19C18C671B3AAEBA00BD63D2 /* Debug */, 617 | 19C18C681B3AAEBA00BD63D2 /* Release */, 618 | ); 619 | defaultConfigurationIsVisible = 0; 620 | defaultConfigurationName = Release; 621 | }; 622 | /* End XCConfigurationList section */ 623 | }; 624 | rootObject = 19C18C381B3AAEBA00BD63D2 /* Project object */; 625 | } 626 | -------------------------------------------------------------------------------- /WZLBadgeDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WZLBadgeDemo.xcodeproj/project.xcworkspace/xcshareddata/WZLBadgeDemo.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | A3BE51FF-D735-42B4-8D65-BDE1B81D8FD9 9 | IDESourceControlProjectName 10 | WZLBadgeDemo 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 3BF1779AF4FFF0FD58C1CC3AF3C4EB46ABB0E373 14 | https://github.com/weng1250/WZLBadge.git 15 | AAB138F125F5B37A68BC23E8221CF7BBF607AC69 16 | https://git.oschina.net/zilin_weng/WuJieCaoJoke.git 17 | 18 | IDESourceControlProjectPath 19 | WZLBadgeDemo.xcodeproj 20 | IDESourceControlProjectRelativeInstallPathDictionary 21 | 22 | 3BF1779AF4FFF0FD58C1CC3AF3C4EB46ABB0E373 23 | ../.. 24 | AAB138F125F5B37A68BC23E8221CF7BBF607AC69 25 | ../../../WuJieCaoJoke 26 | 27 | IDESourceControlProjectURL 28 | https://github.com/weng1250/WZLBadge.git 29 | IDESourceControlProjectVersion 30 | 111 31 | IDESourceControlProjectWCCIdentifier 32 | 3BF1779AF4FFF0FD58C1CC3AF3C4EB46ABB0E373 33 | IDESourceControlProjectWCConfigurations 34 | 35 | 36 | IDESourceControlRepositoryExtensionIdentifierKey 37 | public.vcs.git 38 | IDESourceControlWCCIdentifierKey 39 | AAB138F125F5B37A68BC23E8221CF7BBF607AC69 40 | IDESourceControlWCCName 41 | WuJieCaoJoke 42 | 43 | 44 | IDESourceControlRepositoryExtensionIdentifierKey 45 | public.vcs.git 46 | IDESourceControlWCCIdentifierKey 47 | 3BF1779AF4FFF0FD58C1CC3AF3C4EB46ABB0E373 48 | IDESourceControlWCCName 49 | WZLBadgeDemo 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /WZLBadgeDemo.xcodeproj/project.xcworkspace/xcuserdata/wzl.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weng1250/WZLBadge/e4ff607d4908f82b09ac2a868c40aeec9c360cb1/WZLBadgeDemo.xcodeproj/project.xcworkspace/xcuserdata/wzl.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WZLBadgeDemo.xcodeproj/xcuserdata/wzl.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /WZLBadgeDemo.xcodeproj/xcuserdata/wzl.xcuserdatad/xcschemes/WZLBadgeDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /WZLBadgeDemo.xcodeproj/xcuserdata/wzl.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WZLBadgeDemo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 19C18C3F1B3AAEBA00BD63D2 16 | 17 | primary 18 | 19 | 20 | 19C18C581B3AAEBA00BD63D2 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /WZLBadgeDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // WZLBadgeDemo 4 | // 5 | // Created by zilin_weng on 15/6/24. 6 | // Copyright (c) 2015年 Weng-Zilin. 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 | -------------------------------------------------------------------------------- /WZLBadgeDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // WZLBadgeDemo 4 | // 5 | // Created by zilin_weng on 15/6/24. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /WZLBadgeDemo/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /WZLBadgeDemo/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 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /WZLBadgeDemo/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weng1250/WZLBadge/e4ff607d4908f82b09ac2a868c40aeec9c360cb1/WZLBadgeDemo/Default-568h@2x.png -------------------------------------------------------------------------------- /WZLBadgeDemo/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /WZLBadgeDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.Weng-Zilin.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.2.5 19 | CFBundleSignature 20 | ???? 21 | CFBundleURLTypes 22 | 23 | 24 | CFBundleURLName 25 | test 26 | CFBundleURLSchemes 27 | 28 | myTest 29 | 30 | 31 | 32 | CFBundleURLName 33 | Weng-Zilin.WZLBadgeDemo 34 | CFBundleURLSchemes 35 | 36 | WBadge 37 | 38 | 39 | 40 | CFBundleVersion 41 | 2016073115 42 | LSRequiresIPhoneOS 43 | 44 | UILaunchStoryboardName 45 | LaunchScreen 46 | UIMainStoryboardFile 47 | Main 48 | UIRequiredDeviceCapabilities 49 | 50 | armv7 51 | 52 | UISupportedInterfaceOrientations 53 | 54 | UIInterfaceOrientationPortrait 55 | UIInterfaceOrientationLandscapeLeft 56 | UIInterfaceOrientationLandscapeRight 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /WZLBadgeDemo/RootTabBarController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RootTabBarController.h 3 | // WZLBadgeDemo 4 | // 5 | // Created by zilin_weng on 15/9/24. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface RootTabBarController : UITabBarController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WZLBadgeDemo/RootTabBarController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RootTabBarController.m 3 | // WZLBadgeDemo 4 | // 5 | // Created by zilin_weng on 15/9/24. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import "RootTabBarController.h" 10 | #import "WZLBadgeImport.h" 11 | #import "ViewController.h" 12 | 13 | @interface RootTabBarController () 14 | 15 | @end 16 | 17 | @implementation RootTabBarController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | // Do any additional setup after loading the view. 22 | [self listenDeviceRotation]; 23 | [self setupTabbar]; 24 | [self setupTabbarBadge]; 25 | [self setupNaviBarItems]; 26 | } 27 | 28 | - (void)dealloc 29 | { 30 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 31 | } 32 | 33 | - (void)setupTabbar 34 | { 35 | UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; 36 | UIViewController *leftVC = [sb instantiateViewControllerWithIdentifier:NSStringFromClass([ViewController class])]; 37 | UIViewController *rightVC = [sb instantiateViewControllerWithIdentifier:NSStringFromClass([ViewController class])]; 38 | self.viewControllers = @[leftVC, rightVC]; 39 | 40 | UITabBarItem *leftItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemContacts tag:0]; 41 | leftVC.tabBarItem = leftItem; 42 | UITabBarItem *rightItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemHistory tag:1]; 43 | rightVC.tabBarItem = rightItem; 44 | } 45 | 46 | - (void)setupTabbarBadge 47 | { 48 | UITabBarItem *firstItem = self.tabBar.items.firstObject; 49 | //it is necessary to adjust badge position 50 | firstItem.badgeCenterOffset = CGPointMake(0, 0); 51 | [firstItem showBadgeWithStyle:WBadgeStyleNew value:0 animationType:WBadgeAnimTypeShake]; 52 | } 53 | 54 | - (void)setupNaviBarItems 55 | { 56 | //configure navi item 57 | UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"nav_list.png"] 58 | style:UIBarButtonItemStylePlain 59 | target:self 60 | action:@selector(onBarItemClicked:)]; 61 | self.navigationItem.leftBarButtonItem = leftItem; 62 | 63 | //show example of customize badge`s centerOffset property 64 | leftItem.badgeCenterOffset = CGPointMake(-8, 0); 65 | [leftItem showBadge]; 66 | } 67 | 68 | 69 | - (void)listenDeviceRotation 70 | { 71 | [[NSNotificationCenter defaultCenter] addObserver:self 72 | selector:@selector(handleDeviceRotation:) 73 | name:UIDeviceOrientationDidChangeNotification 74 | object:nil]; 75 | } 76 | 77 | #pragma mark -- handle action 78 | - (void)handleDeviceRotation:(id)obj 79 | { 80 | //do nothing 81 | } 82 | 83 | - (void)onBarItemClicked:(UIBarButtonItem *)sender 84 | { 85 | [sender clearBadge]; 86 | } 87 | 88 | 89 | - (void)didReceiveMemoryWarning { 90 | [super didReceiveMemoryWarning]; 91 | // Dispose of any resources that can be recreated. 92 | } 93 | 94 | 95 | 96 | @end 97 | -------------------------------------------------------------------------------- /WZLBadgeDemo/TableViewDataSource.h: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewDataSource.h 3 | // WZLBadgeDemo 4 | // 5 | // Created by wengzilin on 16/3/14. 6 | // Copyright © 2016年 Weng-Zilin. All rights reserved. 7 | // 8 | // This class provides datasource for tableView in ViewController 9 | 10 | #import 11 | #import 12 | 13 | @interface TableViewDataSource : NSObject 14 | 15 | - (instancetype)initWithDataItems:(NSMutableArray *)items; 16 | 17 | @end 18 | 19 | 20 | @interface UITableViewCell (cellConfiguration) 21 | 22 | - (void)configCellWithItem:(id)item indexPath:(NSIndexPath *)indexPath; 23 | 24 | @end -------------------------------------------------------------------------------- /WZLBadgeDemo/TableViewDataSource.m: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewDataSource.m 3 | // WZLBadgeDemo 4 | // 5 | // Created by wengzilin on 16/3/14. 6 | // Copyright © 2016年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import "TableViewDataSource.h" 10 | #import 11 | #import "WZLBadgeImport.h" 12 | #import "UIView+Frame.h" 13 | 14 | @interface TableViewDataSource () 15 | 16 | @property (nonatomic, strong) NSMutableArray *dataItems; 17 | 18 | @end 19 | 20 | @implementation TableViewDataSource 21 | 22 | - (instancetype)initWithDataItems:(NSMutableArray *)items 23 | { 24 | if (self = [super init]) { 25 | self.dataItems = [NSMutableArray arrayWithArray:items]; 26 | } 27 | return self; 28 | } 29 | 30 | #pragma mark - private 31 | 32 | #pragma mark - datasource of UITableView 33 | 34 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 35 | { 36 | NSAssert(self.dataItems && [self.dataItems count] > 0, @"dataItems should not be empty"); 37 | return [self.dataItems count]; 38 | } 39 | 40 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 41 | { 42 | return [[self.dataItems objectAtIndex:section] count]; 43 | } 44 | 45 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 46 | { 47 | static NSString *cellID = @"cell"; 48 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; 49 | if (cell == nil) { 50 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:cellID]; 51 | } 52 | NSInteger section = indexPath.section; 53 | NSInteger row = indexPath.row; 54 | UIView *view = (UIView *)self.dataItems[section][row]; 55 | [cell configCellWithItem:view indexPath:indexPath]; 56 | return cell; 57 | } 58 | 59 | - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 60 | { 61 | NSArray *headTitles = @[@"badge with not any animation", @"badge with animations",@"extension"]; 62 | return headTitles[section]; 63 | } 64 | 65 | #pragma mark - delegate of UITableView 66 | //to be simple, I also add delegate into datasource. 67 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 68 | { 69 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 70 | 71 | UIView *view = (UIView *)self.dataItems[indexPath.section][indexPath.row]; 72 | [view clearBadge]; 73 | } 74 | 75 | @end 76 | 77 | @implementation UITableViewCell (cellConfiguration) 78 | 79 | - (void)configCellWithItem:(id)item indexPath:(NSIndexPath *)indexPath 80 | { 81 | if (item && [item isKindOfClass:[UIButton class]]) { 82 | [self resetCell]; 83 | UIView *view = (UIView *)item; 84 | view.y = 10; 85 | view.x = 160; 86 | [self.contentView addSubview:view]; 87 | //configure cell title 88 | NSArray *subtitles = @[@"red dot style:", @"new style:", @"number style:", @"number style:"]; 89 | self.detailTextLabel.text = subtitles[indexPath.row]; 90 | } 91 | } 92 | 93 | - (void)resetCell 94 | { 95 | UIView *view = [self getExistingBadgeParentView]; 96 | if (view) { 97 | [view removeFromSuperview]; 98 | } 99 | } 100 | 101 | - (UIView *)getExistingBadgeParentView 102 | { 103 | for (UIView *subview in self.contentView.subviews) { 104 | if (subview.tag == 1000) { 105 | return subview; 106 | } 107 | } 108 | return nil; 109 | } 110 | 111 | @end 112 | -------------------------------------------------------------------------------- /WZLBadgeDemo/Tool/Category/UIView+Frame.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Frame.h 3 | // WZLCodeLibrary 4 | // 5 | // Created by wzl on 15/3/23. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (Frame) 12 | 13 | @property (nonatomic, assign) CGFloat x; 14 | @property (nonatomic, assign) CGFloat y; 15 | @property (nonatomic, assign) CGFloat width; 16 | @property (nonatomic, assign) CGFloat height; 17 | @property (nonatomic, assign) CGPoint origin; 18 | @property (nonatomic, assign) CGSize size; 19 | @property (nonatomic, assign) CGFloat bottom; 20 | @property (nonatomic, assign) CGFloat tail; 21 | @property (nonatomic, assign) CGFloat middleX; 22 | @property (nonatomic, assign) CGFloat middleY; 23 | 24 | @end -------------------------------------------------------------------------------- /WZLBadgeDemo/Tool/Category/UIView+Frame.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Frame.m 3 | // WZLCodeLibrary 4 | // 5 | // Created by wzl on 15/3/23. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import "UIView+Frame.h" 10 | 11 | @implementation UIView (Frame) 12 | 13 | - (void)setX:(CGFloat)x 14 | { 15 | CGRect frame = self.frame; 16 | frame.origin.x = x; 17 | self.frame = frame; 18 | } 19 | 20 | - (CGFloat)x 21 | { 22 | return self.frame.origin.x; 23 | } 24 | 25 | - (void)setY:(CGFloat)y 26 | { 27 | CGRect frame = self.frame; 28 | frame.origin.y = y; 29 | self.frame = frame; 30 | } 31 | 32 | - (CGFloat)y 33 | { 34 | return self.frame.origin.y; 35 | } 36 | 37 | - (void)setOrigin:(CGPoint)origin 38 | { 39 | CGRect frame = self.frame; 40 | frame.origin = origin; 41 | self.frame = frame; 42 | } 43 | 44 | - (CGPoint)origin 45 | { 46 | return self.frame.origin; 47 | } 48 | 49 | - (void)setWidth:(CGFloat)width 50 | { 51 | CGRect frame = self.frame; 52 | frame.size.width = width; 53 | self.frame = frame; 54 | } 55 | 56 | - (CGFloat)width 57 | { 58 | return self.frame.size.width; 59 | } 60 | 61 | - (void)setHeight:(CGFloat)height 62 | { 63 | CGRect frame = self.frame; 64 | frame.size.height = height; 65 | self.frame = frame; 66 | } 67 | 68 | - (CGFloat)height 69 | { 70 | return self.frame.size.height; 71 | } 72 | 73 | - (void)setSize:(CGSize)size 74 | { 75 | CGRect frame = self.frame; 76 | frame.size = size; 77 | self.frame = frame; 78 | } 79 | 80 | - (CGSize)size 81 | { 82 | return self.frame.size; 83 | } 84 | 85 | - (void)setBottom:(CGFloat)bottom 86 | { 87 | CGRect frame = self.frame; 88 | frame.origin.y = bottom - frame.size.height; 89 | self.frame = frame; 90 | } 91 | 92 | - (CGFloat)bottom 93 | { 94 | return CGRectGetMaxY(self.frame); 95 | } 96 | 97 | - (CGFloat)tail 98 | { 99 | return CGRectGetMaxX(self.frame); 100 | } 101 | 102 | - (void)setTail:(CGFloat)tail 103 | { 104 | CGRect frame = self.frame; 105 | frame.origin.x = tail - frame.size.width; 106 | self.frame = frame; 107 | } 108 | 109 | - (void)setMiddleX:(CGFloat)middleX 110 | { 111 | CGRect frame = self.frame; 112 | frame.origin.x = middleX - frame.size.width / 2; 113 | self.frame = frame; 114 | } 115 | 116 | - (CGFloat)middleX 117 | { 118 | return CGRectGetMidX(self.frame); 119 | } 120 | 121 | - (void)setMiddleY:(CGFloat)middleY 122 | { 123 | CGRect frame = self.frame; 124 | frame.origin.y = middleY - frame.size.height / 2 ; 125 | self.frame = frame; 126 | } 127 | 128 | - (CGFloat)middleY 129 | { 130 | return CGRectGetMidY(self.frame); 131 | } 132 | 133 | 134 | @end -------------------------------------------------------------------------------- /WZLBadgeDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // WZLBadgeDemo 4 | // 5 | // Created by zilin_weng on 15/6/24. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /WZLBadgeDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // WZLBadgeDemo 4 | // 5 | // Created by zilin_weng on 15/6/24. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "TableViewDataSource.h" 11 | #import "UIView+Frame.h" 12 | #import "WZLBadgeImport.h" 13 | #import "TableViewCollectionViewController.h" 14 | 15 | @interface ViewController () 16 | 17 | @property (nonatomic, strong) UITableView *tableView; 18 | @property (nonatomic, strong) TableViewDataSource *tabDataSource; 19 | 20 | @end 21 | 22 | @implementation ViewController 23 | 24 | - (void)viewDidLoad { 25 | [super viewDidLoad]; 26 | self.title = @"WZLBadge Examples"; 27 | [self setup]; 28 | [self loadTableViewDataSource]; 29 | } 30 | 31 | #pragma mark -- private methods 32 | - (void)setup 33 | { 34 | //configure table view 35 | CGFloat y = NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_7_0 ? 64 : 44; 36 | CGRect frame = CGRectMake(0, y, self.view.width, self.view.height - y - 44); 37 | self.tableView = [[UITableView alloc] initWithFrame:frame style:UITableViewStyleGrouped]; 38 | self.tableView.delegate = self; 39 | self.tableView.userInteractionEnabled = YES; 40 | self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 41 | self.tableView.rowHeight = 60; 42 | [self.view addSubview:self.tableView]; 43 | } 44 | 45 | - (void)loadTableViewDataSource 46 | { 47 | self.tabDataSource = [[TableViewDataSource alloc] initWithDataItems:[self prepareDataItems]]; 48 | self.tableView.dataSource = self.tabDataSource; 49 | } 50 | 51 | - (NSMutableArray *)prepareDataItems 52 | { 53 | NSMutableArray *dataItems = [[NSMutableArray alloc] initWithCapacity:0]; 54 | 55 | NSMutableArray *staticBadges = [NSMutableArray array]; 56 | NSMutableArray *dynamicBadges = [NSMutableArray array]; 57 | 58 | // static badge configure 59 | WBadgeStyle styles[] = {WBadgeStyleRedDot, WBadgeStyleNew, WBadgeStyleNumber, WBadgeStyleNumber}; 60 | for (NSInteger i = 0; i < sizeof(styles) / sizeof(styles[0]); i++) { 61 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 62 | btn.frame = CGRectMake(0, 0, 40, 40); 63 | btn.tag = 1000; 64 | [btn setImage:[UIImage imageNamed:@"logo.jpg"] forState:UIControlStateNormal]; 65 | btn.layer.cornerRadius = btn.width / 2; 66 | if (i == 1) { 67 | btn.badgeBgColor = [UIColor purpleColor]; 68 | btn.badgeCenterOffset = CGPointMake(-btn.width, 0); 69 | } else 70 | if (i == 2) { 71 | btn.badgeBgColor = [UIColor blueColor]; 72 | } 73 | [btn showBadgeWithStyle:styles[i] value:100 animationType:WBadgeAnimTypeNone];//actual badge call comes here. 74 | [staticBadges addObject:btn]; 75 | } 76 | 77 | // animating badge config 78 | WBadgeAnimType animations[] = {WBadgeAnimTypeShake, WBadgeAnimTypeBounce, WBadgeAnimTypeBreathe, WBadgeAnimTypeScale}; 79 | for (NSInteger i = 0; i < sizeof(animations) / sizeof(animations[0]); i++) { 80 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 81 | btn.frame = CGRectMake(0, 0, 40, 40); 82 | btn.tag = 1000; 83 | [btn setImage:[UIImage imageNamed:@"logo.jpg"] forState:UIControlStateNormal]; 84 | btn.layer.cornerRadius= btn.width / 2; 85 | [btn showBadgeWithStyle:styles[i] value:100 animationType:animations[i]]; 86 | [dynamicBadges addObject:btn]; 87 | } 88 | 89 | NSMutableArray *extensions = [NSMutableArray array]; 90 | 91 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 92 | btn.frame = CGRectMake(0, 0, 40, 40); 93 | btn.tag = 1000; 94 | [btn setImage:[UIImage imageNamed:@"logo.jpg"] forState:UIControlStateNormal]; 95 | btn.layer.cornerRadius = btn.width / 2; 96 | [btn showBadgeWithStyle:WBadgeStyleRedDot value:100 animationType:WBadgeAnimTypeShake]; 97 | [extensions addObject:btn]; 98 | 99 | [dataItems addObject:staticBadges]; 100 | [dataItems addObject:dynamicBadges]; 101 | [dataItems addObject:extensions]; 102 | 103 | return dataItems; 104 | } 105 | 106 | #pragma mark - tableView delegate 107 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 108 | if ([indexPath isEqual:[NSIndexPath indexPathForRow:0 inSection:2]]) { 109 | [self.navigationController pushViewController:[TableViewCollectionViewController new] animated:YES]; 110 | 111 | } 112 | 113 | } 114 | 115 | @end 116 | -------------------------------------------------------------------------------- /WZLBadgeDemo/example_prot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weng1250/WZLBadge/e4ff607d4908f82b09ac2a868c40aeec9c360cb1/WZLBadgeDemo/example_prot.gif -------------------------------------------------------------------------------- /WZLBadgeDemo/examples/TableViewCollectionViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CollectionViewEmbedTableViewController.h 3 | // WZLBadgeDemo 4 | // 5 | // Created by felix on 2017/6/19. 6 | // Copyright © 2017年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TableViewCollectionViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WZLBadgeDemo/examples/TableViewCollectionViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CollectionViewEmbedTableViewController.m 3 | // WZLBadgeDemo 4 | // 5 | // Created by felix on 2017/6/19. 6 | // Copyright © 2017年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import "TableViewCollectionViewController.h" 10 | #import "WZLBadgeImport.h" 11 | 12 | @interface TableViewCollectionViewController () 13 | 14 | @property (nonatomic, strong) UITableView *tableView; 15 | 16 | @end 17 | 18 | static NSInteger const cellNum = 120; 19 | static NSInteger const numberOfAStyle = 3; 20 | 21 | @implementation TableViewCollectionViewController 22 | 23 | - (void)viewDidLoad { 24 | [super viewDidLoad]; 25 | 26 | self.title = @"test cell reuse"; 27 | self.view.backgroundColor = [UIColor whiteColor]; 28 | 29 | self.tableView = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStylePlain]; 30 | [self.view addSubview:self.tableView]; 31 | 32 | self.tableView.backgroundColor = [UIColor grayColor]; 33 | [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:NSStringFromClass([UITableViewCell class])]; 34 | self.tableView.dataSource = self; 35 | self.tableView.delegate = self; 36 | self.tableView.allowsSelection = NO; 37 | } 38 | 39 | - (void)didReceiveMemoryWarning { 40 | [super didReceiveMemoryWarning]; 41 | } 42 | 43 | 44 | #pragma mark -- tableView delegate and datasource 45 | 46 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 47 | return cellNum; 48 | } 49 | 50 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 51 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([UITableViewCell class]) forIndexPath:indexPath]; 52 | cell.textLabel.text = @"hello words"; 53 | cell.textLabel.backgroundColor = [UIColor whiteColor]; 54 | cell.detailTextLabel.text = @"description text"; 55 | cell.detailTextLabel.backgroundColor = [UIColor greenColor]; 56 | 57 | switch (indexPath.row%numberOfAStyle) { 58 | case WBadgeStyleRedDot: 59 | { 60 | cell.contentView.badgeRadius = 4.f; 61 | cell.contentView.badgeCenterOffset = CGPointMake(-100, 30); 62 | [cell.contentView showBadge]; 63 | } 64 | break; 65 | case WBadgeStyleNumber: 66 | { 67 | [cell.contentView showNumberBadgeWithValue:indexPath.row]; 68 | cell.contentView.badgeCenterOffset = CGPointMake(-100, 30); 69 | } 70 | break; 71 | case WBadgeStyleNew: 72 | { 73 | [cell.contentView showBadgeWithStyle:WBadgeStyleNew value:0 animationType:WBadgeAnimTypeNone]; 74 | cell.contentView.badgeCenterOffset = CGPointMake(-100, 30); 75 | } 76 | break; 77 | default: 78 | break; 79 | } 80 | return cell; 81 | } 82 | 83 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 84 | return 60.f; 85 | } 86 | 87 | @end 88 | -------------------------------------------------------------------------------- /WZLBadgeDemo/logo@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weng1250/WZLBadge/e4ff607d4908f82b09ac2a868c40aeec9c360cb1/WZLBadgeDemo/logo@2x.jpg -------------------------------------------------------------------------------- /WZLBadgeDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WZLBadgeDemo 4 | // 5 | // Created by zilin_weng on 15/6/24. 6 | // Copyright (c) 2015年 Weng-Zilin. 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 | -------------------------------------------------------------------------------- /WZLBadgeDemo/nav_list@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weng1250/WZLBadge/e4ff607d4908f82b09ac2a868c40aeec9c360cb1/WZLBadgeDemo/nav_list@2x.png -------------------------------------------------------------------------------- /WZLBadgeDemo/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weng1250/WZLBadge/e4ff607d4908f82b09ac2a868c40aeec9c360cb1/WZLBadgeDemo/snapshot.png -------------------------------------------------------------------------------- /WZLBadgeDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | Weng-Zilin.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /WZLBadgeDemoTests/WZLBadgeDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // WZLBadgeDemoTests.m 3 | // WZLBadgeDemoTests 4 | // 5 | // Created by zilin_weng on 15/6/24. 6 | // Copyright (c) 2015年 Weng-Zilin. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface WZLBadgeDemoTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation WZLBadgeDemoTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | --------------------------------------------------------------------------------