├── README.md ├── TaobaoTabBarDemo.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ └── climbwang.xcuserdatad │ └── UserInterfaceState.xcuserstate ├── TaobaoTabBarDemo ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── tabbar_find_normal.imageset │ │ ├── Contents.json │ │ ├── tabbar_find_normal@2x.png │ │ └── tabbar_find_normal@3x.png │ ├── tabbar_find_selected.imageset │ │ ├── Contents.json │ │ ├── tabbar_find_selected@2x.png │ │ └── tabbar_find_selected@3x.png │ ├── tabbar_home_launch.imageset │ │ ├── Contents.json │ │ ├── tabbar_home_launch@2x.png │ │ └── tabbar_home_launch@3x.png │ ├── tabbar_home_normal.imageset │ │ ├── Contents.json │ │ ├── tabbar_home_normal@2x.png │ │ └── tabbar_home_normal@3x.png │ ├── tabbar_home_selecetedBg.imageset │ │ ├── Contents.json │ │ ├── tabbar_home_selecetedBg@2x.png │ │ └── tabbar_home_selecetedBg@3x.png │ ├── tabbar_home_selecetedLogo.imageset │ │ ├── Contents.json │ │ ├── tabbar_home_selecetedLogo@2x.png │ │ └── tabbar_home_selecetedLogo@3x.png │ ├── tabbar_home_selecetedPush.imageset │ │ ├── Contents.json │ │ ├── tabbar_home_selecetedPush@2x.png │ │ └── tabbar_home_selecetedPush@3x.png │ ├── tabbar_home_selected.imageset │ │ ├── Contents.json │ │ ├── tabbar_home_selected@2x.png │ │ └── tabbar_home_selected@3x.png │ ├── tabbar_knowledge_normal.imageset │ │ ├── Contents.json │ │ ├── tabbar_knowledge_normal@2x.png │ │ └── tabbar_knowledge_normal@3x.png │ ├── tabbar_knowledge_selected.imageset │ │ ├── Contents.json │ │ ├── tabbar_knowledge_selected@2x.png │ │ └── tabbar_knowledge_selected@3x.png │ ├── tabbar_mall_normal.imageset │ │ ├── Contents.json │ │ ├── tabbar_mall_normal@2x.png │ │ └── tabbar_mall_normal@3x.png │ ├── tabbar_mall_selected.imageset │ │ ├── Contents.json │ │ ├── tabbar_mall_selected@2x.png │ │ └── tabbar_mall_selected@3x.png │ ├── tabbar_mine_normal.imageset │ │ ├── Contents.json │ │ ├── tabbar_mine_normal@2x.png │ │ └── tabbar_mine_normal@3x.png │ └── tabbar_mine_selected.imageset │ │ ├── Contents.json │ │ ├── tabbar_mine_selected@2x.png │ │ └── tabbar_mine_selected@3x.png ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── FifthViewController.h ├── FifthViewController.m ├── FirstViewController.h ├── FirstViewController.m ├── FourViewController.h ├── FourViewController.m ├── Info.plist ├── SecondViewController.h ├── SecondViewController.m ├── TabBar │ ├── WMTabBar.h │ ├── WMTabBar.m │ ├── WMTabBarController.h │ ├── WMTabBarController.m │ ├── WMTabBarItem.h │ ├── WMTabBarItem.m │ ├── WMTabBarItemCell.h │ └── WMTabBarItemCell.m ├── ThirdViewController.h ├── ThirdViewController.m └── main.m ├── TaobaoTabBarDemoTests ├── Info.plist └── TaobaoTabBarDemoTests.m └── TaobaoTabBarDemoUITests ├── Info.plist └── TaobaoTabBarDemoUITests.m /README.md: -------------------------------------------------------------------------------- 1 | # 仿淘宝tabBar点击及滑动时logo和火箭🚀切换动画 2 | 3 | ## 仿淘宝tabBar点击及滑动时logo和火箭🚀切换动画 4 | 5 | 6 | 最近项目改版里,产品设计重新设计了tabbar动画,旨在提升app的逼格。。。 7 | 设计图是借鉴淘宝的tabBar: 8 | 9 | ![](https://wx1.sinaimg.cn/large/006tNc79ly1g2v2ucnju7g30bi0owhe7.gif) 10 | 11 | 12 | 13 | 找资料查找下,还没有相关开源的代码,好吧,那就自己开干吧。 14 | 15 | ## 先拆解功能点: 16 | - 自定义tabBar,高度56 17 | - tab显示:首页tab在选中时是大logo 无文字,未选中时是图片文字 ;其他tab未选中和选中都是图片文字 18 | - tab切换:tab之间相互点击切换选中时的缩小放大的动画 19 | - 当首页滑动到一定距离时,首页tab的大logo和小火箭执行切换动画:`手势上滑 - logo向下切换到小火箭; 手势下滑 - 小火箭向上切换到logo;` 20 | 21 | ## 开始各个击破吧 22 | ### 1. 自定义tabBar,高度56 23 | 删除系统tabBar,创建自定义tabBar, 24 | ``` 25 | @implementation WMTabBar 26 | 27 | // 删除系统tabbar的UITabBarButton 28 | - (void)layoutSubviews { 29 | [super layoutSubviews]; 30 | 31 | for (UIView *view in self.subviews) { 32 | if ([view isKindOfClass:NSClassFromString(@"UITabBarButton")]) { 33 | [view removeFromSuperview]; 34 | } 35 | } 36 | } 37 | 38 | // 根据配置信息创建自定义tabBar 39 | + (instancetype)tabBarWithTitleArray:(NSArray *)titleArray imageArray:(NSArray *)imageArray selectedImageArray:(NSArray *)selectedImageArray { 40 | WMTabBar *tabBar = [[WMTabBar alloc] init]; 41 | tabBar.titleArray = titleArray; 42 | tabBar.imageArray = imageArray; 43 | tabBar.selectedImageArray = selectedImageArray; 44 | [tabBar setupUI]; 45 | return tabBar; 46 | } 47 | 48 | - (void)setupUI { 49 | self.lastSelectIndex = 100;//默认为100 50 | self.backgroundColor = [UIColor whiteColor]; 51 | for (int i = 0; i < self.titleArray.count; i++) { 52 | CGFloat itemWidth = (kScreen_width/self.titleArray.count); 53 | CGRect frame = CGRectMake(i*itemWidth, 0, itemWidth, 56); 54 | WMTabBarItem *tabBarItem = [[WMTabBarItem alloc] initWithFrame:frame index:i]; 55 | tabBarItem.tag = i ; 56 | UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tabBarItemClickAction:)]; 57 | [tabBarItem addGestureRecognizer:tap]; 58 | [self addSubview:tabBarItem]; 59 | [self.itemArray addObject:tabBarItem]; 60 | } 61 | // 记录选中index, 在其setter方法里重写逻辑 62 | self.selectedIndex = 0; 63 | } 64 | 65 | 66 | - (void)setSelectedIndex:(NSInteger )selectedIndex { 67 | _selectedIndex = selectedIndex; 68 | [self.itemArray enumerateObjectsUsingBlock:^(WMTabBarItem *tabBarItem, NSUInteger idx, BOOL * _Nonnull stop) { 69 | // 当遍历的idx=selectedIndex时,记录选中状态 70 | BOOL selected = (idx == selectedIndex); 71 | // 配置tabBarItem的内容信息 72 | [tabBarItem configTitle:self.titleArray[idx] normalImage:self.imageArray[idx] selectedImage:self.selectedImageArray[idx] index:idx selected:selected lastSelectIndex:self.lastSelectIndex]; 73 | // 当遍历到最后一个时,赋值lastSelectIndex 74 | if (idx == (self.itemArray.count-1)) { 75 | self.lastSelectIndex = selectedIndex; 76 | } 77 | }]; 78 | } 79 | ``` 80 | 在WMTabBar里仿照系统tabBar的点击方法,添加两个wmTabBar代理方法,以满足项目里tabBar点击选中或点击tabBar时根据登录状态进行是否选中等操作: 81 | ``` 82 | @protocol WMTabBarDelegate 83 | 84 | /** 选中tabbar */ 85 | - (void)wmtabBar:(WMTabBar *)wmTabBar selectedWMTabBarItemAtIndex:(NSInteger)index; 86 | /** 是否可选tabbar */ 87 | - (BOOL)wmtabBar:(WMTabBar *)wmTabBar shouldSelectedWMTabBarItemAtIndex:(NSInteger)index; 88 | 89 | @end 90 | ``` 91 | 在WMTabBarController里设置tabBar 92 | ``` 93 | // 重写tabbar的frame,改变tabbar高度 94 | - (void)viewDidLayoutSubviews { 95 | [super viewDidLayoutSubviews]; 96 | 97 | CGRect frame = self.tabBar.frame; 98 | if (frame.size.height != kTABBARHEIGHT) { 99 | frame.size.height = kTABBARHEIGHT; 100 | frame.origin.y = self.view.frame.size.height - frame.size.height; 101 | self.tabBar.frame = frame; 102 | } 103 | } 104 | 105 | //添加子模块 106 | - (void)creatTabBarWithChildVCArray:(NSArray *)childVCArray 107 | titleArray:(NSArray *)titleArray 108 | imageArray:(NSArray *)imageArray 109 | selectedImageArray:(NSArray *)selectedImageArray { 110 | 111 | for (UIViewController *viewController in childVCArray) { 112 | MPNavigationController *navigationController = [[MPNavigationController alloc] initWithRootViewController:viewController]; 113 | [self.controllersArray addObject:navigationController]; 114 | } 115 | 116 | self.wmTabBar = [WMTabBar tabBarWithTitleArray:titleArray 117 | imageArray:imageArray 118 | selectedImageArray:selectedImageArray]; 119 | self.wmTabBar.tabBarDelegate = self; 120 | [self setValue:self.wmTabBar forKeyPath:@"tabBar"]; 121 | self.viewControllers = self.controllersArray; 122 | } 123 | ``` 124 | 125 | ### 2. tab显示:首页tab在选中时是大logo 无文字,未选中时是图片文字 ;其他tab未选中和选中都是图片文字 126 | 127 | ##### 在tabBarItem里创建显示UI 128 | 129 | ``` 130 | @implementation WMTabBarItem 131 | 132 | - (instancetype)initWithFrame:(CGRect)frame index:(NSInteger )index { 133 | self = [super initWithFrame:frame]; 134 | if (self) { 135 | 136 | [self addSubview:self.titleLabel]; 137 | [self addSubview:self.imageView]; 138 | [self addSubview:self.homeTabSelectedBgView]; 139 | 140 | self.imageView.frame = CGRectMake(self.bounds.size.width/2-14, 7, 28, 28); 141 | self.titleLabel.frame = CGRectMake(0, CGRectGetMaxY(self.imageView.frame)+2, self.bounds.size.width, 14); 142 | self.homeTabSelectedBgView.frame = CGRectMake(self.bounds.size.width/2-21, 7, 42, 42); 143 | 144 | if (index == 0) { 145 | // 当为首页tab时,加上以下内容 146 | [self addSubview:self.homeTabSelectedBgView]; 147 | 148 | // /** 第一种方案 */ 149 | // [self.homeTabSelectedBgView addSubview:self.homeTabAnimateImageView]; 150 | // self.homeTabAnimateImageView.frame = CGRectMake(0, 0, 32, 32); 151 | // self.homeTabAnimateImageView.center = CGPointMake(self.homeTabSelectedBgView.frame.size.width/2, self.homeTabSelectedBgView.frame.size.height/2); 152 | 153 | /** 第二种方案 */ 154 | [self.homeTabSelectedBgView addSubview:self.collectionView]; 155 | self.homeTabSelectedBgView.frame = CGRectMake(self.bounds.size.width/2-21, 7, 42, 42); 156 | self.collectionView.frame = CGRectMake(0, 0, 42, 42); 157 | self.collectionView.center = CGPointMake(self.homeTabSelectedBgView.frame.size.width/2, self.homeTabSelectedBgView.frame.size.height/2); 158 | 159 | [self.collectionView registerClass:[WMTabBarItemCell class] 160 | forCellWithReuseIdentifier:NSStringFromClass([WMTabBarItemCell class])]; 161 | } 162 | } 163 | return self; 164 | } 165 | ``` 166 | ##### 在tab点击事件里处理: 167 | 168 | ``` 169 | 170 | // 当点击tab的item时,执行 171 | - (void)configTitle:(NSString *)title normalImage:(NSString *)normalImage selectedImage:(NSString *)selectedImage index:(NSInteger)index selected:(BOOL)selected lastSelectIndex:(NSInteger )lastSelectIndex { 172 | self.titleLabel.text = title; 173 | // 当index == 0, 即首页tab 174 | if (index == 0) { 175 | if (selected) { 176 | [self.homeTabSelectedBgView setImage:[UIImage imageNamed:@"tabbar_home_selecetedBg"]]; 177 | self.homeTabSelectedBgView.hidden = NO; 178 | YES;self.imageView.hidden = self.titleLabel.hidden = YES; 179 | 180 | // /** 第一种方案 */ 181 | // [self.homeTabAnimateImageView setImage:[UIImage imageNamed:@"tabbar_home_selecetedLogo"]]; 182 | // /** 第二种方案 默认显示第一个cell 所以不用在这里设置图片 */ 183 | 184 | // 如果本次点击和上次是同一个tab 都是第0个,则执行push动画,否则执行放大缩小动画 185 | if (lastSelectIndex == index) { 186 | if (self.flag) { 187 | // 如果已经是火箭状态,则点击切换logo,且发通知 让首页滑到顶部 188 | [self pushHomeTabAnimationDown]; 189 | [[NSNotificationCenter defaultCenter] postNotificationName:@"kPushDownAnimationScrollTopNotification" object:nil]; 190 | } 191 | }else { 192 | [self animationWithHomeTab]; 193 | } 194 | }else { 195 | [self.imageView setImage:[UIImage imageNamed:normalImage]]; 196 | self.homeTabSelectedBgView.hidden = YES; 197 | self.imageView.hidden = self.titleLabel.hidden = NO; 198 | } 199 | }else { 200 | // 其他tab 201 | self.homeTabSelectedBgView.hidden = YES; 202 | self.imageView.hidden = self.titleLabel.hidden = NO; 203 | if (selected) { 204 | [self.imageView setImage:[UIImage imageNamed:selectedImage]]; 205 | self.titleLabel.textColor = [self colorFromHexRGB:@"18A2FF"]; 206 | // 如果本次点击和上次是同一个tab 则无反应,否则执行放大缩小动画 207 | if (lastSelectIndex != index) { 208 | [self animationWithNormalTab]; 209 | } 210 | }else { 211 | [self.imageView setImage:[UIImage imageNamed:normalImage]]; 212 | self.titleLabel.textColor = [self colorFromHexRGB:@"575D66"]; 213 | } 214 | } 215 | } 216 | ``` 217 | 就是在tab点击事件里做处理: 218 | - 当index==0 即首页tab时,根据是否是seleted状态 来判断显示是大logo控件还是正常文字图片控件。 219 | - 其他tab时,隐藏大logo控件,只显示图片文字控件,再根据是否是seleted状态 来判断选中和未选中时的图片及文字颜色配置。 220 | 221 | 222 | ### 3.tab切换:tab之间相互点击切换选中时的缩小放大的动画 223 | 224 | tab在相互点击切换选中时的缩小放大动画,通过CABasicAnimation来实现: 225 | 226 | ``` 227 | /** 228 | * tab之间切换动画 229 | */ 230 | // 首页tab缩小放大动画 231 | - (void)animationForHomeTab { 232 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 233 | animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 234 | animation.duration = 0.2f; 235 | animation.fromValue = [NSNumber numberWithFloat:0.5f]; 236 | animation.toValue = [NSNumber numberWithFloat:1.f]; 237 | [self.homeTabSelectedBgView.layer addAnimation:animation forKey:nil]; 238 | } 239 | 240 | // 其他tab缩小放大动画 241 | - (void)animationForNormalTab { 242 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 243 | animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 244 | animation.duration = 0.25f; 245 | animation.fromValue = [NSNumber numberWithFloat:0.5f]; 246 | animation.toValue = [NSNumber numberWithFloat:1.f]; 247 | [self.imageView.layer addAnimation:animation forKey:nil]; 248 | [self.titleLabel.layer addAnimation:animation forKey:nil]; 249 | } 250 | 251 | ``` 252 | 效果如下: 253 | ![](https://wx1.sinaimg.cn/large/006tNc79ly1g2uuor58sbg30c80lrqv5.gif) 254 | 255 | ### 4.当首页滑动到一定距离时,首页tab的大logo和小火箭执行切换动画 256 | 257 | 258 | ##### 观察设计图,可以得出根据首页的滑动偏移量及滑动手势,来确定滑动动画方案: 259 | 260 | `在一次滑动行为中:当偏移量>阈值,且手势上滑 - logo向下切换到小火箭;当偏移量<阈值,且手势下滑 - 小火箭向上切换到logo;` 261 | 262 | ##### 首页里滑动代理实现: 263 | ``` 264 | // tabBar动画 - 判断滑动手势,再根据手势,偏移量 判断动画类型 265 | - (void)tabBarAnimateWithScrollView:(UIScrollView *)scrollView { 266 | CGFloat currentPostionOffsetY = scrollView.contentOffset.y; 267 | if (currentPostionOffsetY > self.lastPositionOffestY) { 268 | NSLog(@"手势上滑"); 269 | // tabBar动画 270 | if (self.tabAnimateOnceScrollFlag) { 271 | // 在一次滑动中,且currentPostionOffsetY>456,执行logo切换火箭🚀动画 272 | if ((currentPostionOffsetY > 456.f)) { 273 | NSLog(@"执行-切换火箭"); 274 | [[AppLoginHandle sharedInstance].tabBarController pushHomeTabBarAnimationType:anmationDirectionUp]; 275 | self.tabAnimateOnceScrollFlag = NO; 276 | } 277 | } 278 | }else { 279 | NSLog(@"手势下滑"); 280 | // tabBar动画 281 | if (self.tabAnimateOnceScrollFlag) { 282 | // 在一次滑动中,下滑手势, 且currentPostionOffsetY<456,执行火箭🚀切换logo动画 283 | if ((currentPostionOffsetY < 456.f)) { 284 | NSLog(@"触发-切换logo"); 285 | [[AppLoginHandle sharedInstance].tabBarController pushHomeTabBarAnimationType:anmationDirectionDown]; 286 | self.tabAnimateOnceScrollFlag = NO; 287 | } 288 | } 289 | } 290 | } 291 | 292 | // 当开始滚动视图时,执行该方法。一次有效滑动(开始滑动,滑动一小段距离,只要手指不松开,只算一次滑动),只执行一次。 293 | - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { 294 | if ([scrollView isEqual:self.collectionView]) { 295 | self.tabAnimateOnceScrollFlag = YES; 296 | self.lastPositionOffestY = scrollView.contentOffset.y; 297 | } 298 | } 299 | 300 | ``` 301 | ##### WMTabBar里暴露出外部调用切换动画的方法如下: 302 | ``` 303 | // logo和火箭切换动画的枚举anmationDirection 304 | typedef NS_ENUM(NSUInteger, anmationDirection) { 305 | anmationDirectionUp,//push动画,火箭头出来,logo下去 306 | anmationDirectionDown,//push动画,火箭头下去,logo出来 307 | }; 308 | @class WMTabBar; 309 | @protocol WMTabBarDelegate 310 | 311 | /** 选中tabbar */ 312 | - (void)wmtabBar:(WMTabBar *)wmTabBar didSelectWMTabBarItemAtIndex:(NSInteger)index; 313 | /** 是否可选tabbar */ 314 | - (BOOL)wmtabBar:(WMTabBar *)wmTabBar shouldSelectWMTabBarItemAtIndex:(NSInteger)index; 315 | 316 | @end 317 | 318 | @interface WMTabBar : UITabBar 319 | 320 | @property (nonatomic, weak) id tabBarDelegate; 321 | @property (nonatomic, assign) anmationDirection anmationDirection; 322 | /** 实例化 */ 323 | + (instancetype)tabBarWithTitleArray:(NSArray *)titleArray imageArray:(NSArray *)imageArray selectedImageArray:(NSArray *)selectedImageArray; 324 | 325 | // 外部指定跳转到某个tab时调用 326 | - (void)selectedTabbarAtIndex:(NSNumber *)index; 327 | // 暴露外部的切换动画logo和火箭的方法 328 | - (void)pushHomeTabBarAnimationType:(anmationDirection )anmationDirection; 329 | 330 | @end 331 | ``` 332 | ##### WMTabBarItem里实现首页tab的小火箭和logo之间切换动画 333 | ###### 这里写了两种方法,第一种是最开始尝试的,通过CATransition的push动画,来达到一个imageView控件的两个图片切换,如下: 334 | 335 | - 第一种方案 push动画方案: 336 | ``` 337 | // push动画,火箭头出来 338 | -(void)pushHomeTabAnimationUp { 339 | self.flag = YES; 340 | // /** 第一种方案 */ 341 | // [self.homeTabAnimateImageView setImage:[UIImage imageNamed:@"tabbar_home_selecetedPush"]]; 342 | // CATransition *animation = [CATransition animation]; 343 | // animation.type = kCATransitionPush;//设置动画的类型 344 | // animation.subtype = kCATransitionFromTop; //设置动画的方向 345 | // animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 346 | // animation.duration = 0.25f; 347 | // [self.homeTabAnimateImageView.layer addAnimation:animation forKey:@"pushAnimation"]; 348 | } 349 | 350 | // push动画,火箭头落下 351 | -(void)pushHomeTabAnimationDown { 352 | self.flag = NO; 353 | // /** 第一种方案 */ 354 | // [self.homeTabAnimateImageView setImage:[UIImage imageNamed:@"tabbar_home_selecetedLogo"]]; 355 | // CATransition *animation = [CATransition animation]; 356 | // animation.type = kCATransitionPush;//设置动画的类型 357 | // animation.subtype = kCATransitionFromBottom; //设置动画的方向 358 | // animation.duration = 0.25f; 359 | // [self.homeTabAnimateImageView.layer addAnimation:animation forKey:@"pushAnimation"]; 360 | } 361 | ``` 362 | 效果如下: 363 | 364 | ![](https://wx1.sinaimg.cn/large/006tNc79ly1g2uuq8uf8rg30hs0vmu0z.gif) 365 | 366 | 367 | 虽然能实现功能,但在切换过程中,会有残留效果,这显示是不太美好的,再想想有没有更好的实现方法。 368 | 369 | 370 | 然后就想到了collectionView了。 371 | 372 | - 第二种方案 collection滑动item方案: 373 | 374 | ###### 把collectionView设置成首页tab大小,通过让collection的cell的scrollToItem方法, 即滑动到第n个item来达到切换动画效果,如下: 375 | ``` 376 | // push动画,火箭头出来 377 | -(void)pushHomeTabAnimationUp { 378 | self.flag = YES; 379 | /** 第二种方案 */ 380 | [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:1 inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES]; 381 | } 382 | 383 | // push动画,火箭头落下 384 | -(void)pushHomeTabAnimationDown { 385 | self.flag = NO; 386 | /** 第二种方案 */ 387 | [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES]; 388 | } 389 | ``` 390 | 391 | ![](https://wx1.sinaimg.cn/large/006tNc79ly1g2uv0hs2e9g30hs0vm4qu.gif) 392 | 393 | 漂亮! 394 | 395 | 396 | 到此,新版tabBar实现就完成了! 397 | 398 | 399 | 400 | 401 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 17B506D72244A51B007AE2BC /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 17B506D62244A51B007AE2BC /* AppDelegate.m */; }; 11 | 17B506DD2244A51B007AE2BC /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 17B506DB2244A51B007AE2BC /* Main.storyboard */; }; 12 | 17B506DF2244A51D007AE2BC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 17B506DE2244A51D007AE2BC /* Assets.xcassets */; }; 13 | 17B506E22244A51D007AE2BC /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 17B506E02244A51D007AE2BC /* LaunchScreen.storyboard */; }; 14 | 17B506E52244A51D007AE2BC /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 17B506E42244A51D007AE2BC /* main.m */; }; 15 | 17B506EF2244A51D007AE2BC /* TaobaoTabBarDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 17B506EE2244A51D007AE2BC /* TaobaoTabBarDemoTests.m */; }; 16 | 17B506FA2244A51D007AE2BC /* TaobaoTabBarDemoUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 17B506F92244A51D007AE2BC /* TaobaoTabBarDemoUITests.m */; }; 17 | 17B507092244A613007AE2BC /* FirstViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17B507082244A613007AE2BC /* FirstViewController.m */; }; 18 | 17B5070C2244A61E007AE2BC /* SecondViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17B5070B2244A61E007AE2BC /* SecondViewController.m */; }; 19 | 17B5070F2244A626007AE2BC /* ThirdViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17B5070E2244A626007AE2BC /* ThirdViewController.m */; }; 20 | 17B507122244A634007AE2BC /* FourViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17B507112244A634007AE2BC /* FourViewController.m */; }; 21 | 17B507152244A641007AE2BC /* FifthViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17B507142244A641007AE2BC /* FifthViewController.m */; }; 22 | 17B507222244A7FE007AE2BC /* WMTabBarItemCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 17B5071A2244A7FE007AE2BC /* WMTabBarItemCell.m */; }; 23 | 17B507232244A7FE007AE2BC /* WMTabBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 17B5071D2244A7FE007AE2BC /* WMTabBar.m */; }; 24 | 17B507242244A7FE007AE2BC /* WMTabBarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 17B5071E2244A7FE007AE2BC /* WMTabBarItem.m */; }; 25 | 17B507252244A7FE007AE2BC /* WMTabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17B5071F2244A7FE007AE2BC /* WMTabBarController.m */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXContainerItemProxy section */ 29 | 17B506EB2244A51D007AE2BC /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = 17B506CA2244A51B007AE2BC /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = 17B506D12244A51B007AE2BC; 34 | remoteInfo = TaobaoTabBarDemo; 35 | }; 36 | 17B506F62244A51D007AE2BC /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 17B506CA2244A51B007AE2BC /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = 17B506D12244A51B007AE2BC; 41 | remoteInfo = TaobaoTabBarDemo; 42 | }; 43 | /* End PBXContainerItemProxy section */ 44 | 45 | /* Begin PBXFileReference section */ 46 | 17B506D22244A51B007AE2BC /* TaobaoTabBarDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TaobaoTabBarDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 17B506D52244A51B007AE2BC /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 48 | 17B506D62244A51B007AE2BC /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 49 | 17B506DC2244A51B007AE2BC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 50 | 17B506DE2244A51D007AE2BC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 51 | 17B506E12244A51D007AE2BC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 52 | 17B506E32244A51D007AE2BC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 53 | 17B506E42244A51D007AE2BC /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 54 | 17B506EA2244A51D007AE2BC /* TaobaoTabBarDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TaobaoTabBarDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | 17B506EE2244A51D007AE2BC /* TaobaoTabBarDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TaobaoTabBarDemoTests.m; sourceTree = ""; }; 56 | 17B506F02244A51D007AE2BC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | 17B506F52244A51D007AE2BC /* TaobaoTabBarDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TaobaoTabBarDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | 17B506F92244A51D007AE2BC /* TaobaoTabBarDemoUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TaobaoTabBarDemoUITests.m; sourceTree = ""; }; 59 | 17B506FB2244A51D007AE2BC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 60 | 17B507072244A613007AE2BC /* FirstViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FirstViewController.h; sourceTree = ""; }; 61 | 17B507082244A613007AE2BC /* FirstViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FirstViewController.m; sourceTree = ""; }; 62 | 17B5070A2244A61E007AE2BC /* SecondViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecondViewController.h; sourceTree = ""; }; 63 | 17B5070B2244A61E007AE2BC /* SecondViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecondViewController.m; sourceTree = ""; }; 64 | 17B5070D2244A626007AE2BC /* ThirdViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ThirdViewController.h; sourceTree = ""; }; 65 | 17B5070E2244A626007AE2BC /* ThirdViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ThirdViewController.m; sourceTree = ""; }; 66 | 17B507102244A634007AE2BC /* FourViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FourViewController.h; sourceTree = ""; }; 67 | 17B507112244A634007AE2BC /* FourViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FourViewController.m; sourceTree = ""; }; 68 | 17B507132244A641007AE2BC /* FifthViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FifthViewController.h; sourceTree = ""; }; 69 | 17B507142244A641007AE2BC /* FifthViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FifthViewController.m; sourceTree = ""; }; 70 | 17B5071A2244A7FE007AE2BC /* WMTabBarItemCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WMTabBarItemCell.m; sourceTree = ""; }; 71 | 17B5071B2244A7FE007AE2BC /* WMTabBarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMTabBarController.h; sourceTree = ""; }; 72 | 17B5071C2244A7FE007AE2BC /* WMTabBarItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMTabBarItem.h; sourceTree = ""; }; 73 | 17B5071D2244A7FE007AE2BC /* WMTabBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WMTabBar.m; sourceTree = ""; }; 74 | 17B5071E2244A7FE007AE2BC /* WMTabBarItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WMTabBarItem.m; sourceTree = ""; }; 75 | 17B5071F2244A7FE007AE2BC /* WMTabBarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WMTabBarController.m; sourceTree = ""; }; 76 | 17B507202244A7FE007AE2BC /* WMTabBarItemCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMTabBarItemCell.h; sourceTree = ""; }; 77 | 17B507212244A7FE007AE2BC /* WMTabBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMTabBar.h; sourceTree = ""; }; 78 | /* End PBXFileReference section */ 79 | 80 | /* Begin PBXFrameworksBuildPhase section */ 81 | 17B506CF2244A51B007AE2BC /* Frameworks */ = { 82 | isa = PBXFrameworksBuildPhase; 83 | buildActionMask = 2147483647; 84 | files = ( 85 | ); 86 | runOnlyForDeploymentPostprocessing = 0; 87 | }; 88 | 17B506E72244A51D007AE2BC /* Frameworks */ = { 89 | isa = PBXFrameworksBuildPhase; 90 | buildActionMask = 2147483647; 91 | files = ( 92 | ); 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | 17B506F22244A51D007AE2BC /* Frameworks */ = { 96 | isa = PBXFrameworksBuildPhase; 97 | buildActionMask = 2147483647; 98 | files = ( 99 | ); 100 | runOnlyForDeploymentPostprocessing = 0; 101 | }; 102 | /* End PBXFrameworksBuildPhase section */ 103 | 104 | /* Begin PBXGroup section */ 105 | 17B506C92244A51B007AE2BC = { 106 | isa = PBXGroup; 107 | children = ( 108 | 17B506D42244A51B007AE2BC /* TaobaoTabBarDemo */, 109 | 17B506ED2244A51D007AE2BC /* TaobaoTabBarDemoTests */, 110 | 17B506F82244A51D007AE2BC /* TaobaoTabBarDemoUITests */, 111 | 17B506D32244A51B007AE2BC /* Products */, 112 | ); 113 | sourceTree = ""; 114 | }; 115 | 17B506D32244A51B007AE2BC /* Products */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | 17B506D22244A51B007AE2BC /* TaobaoTabBarDemo.app */, 119 | 17B506EA2244A51D007AE2BC /* TaobaoTabBarDemoTests.xctest */, 120 | 17B506F52244A51D007AE2BC /* TaobaoTabBarDemoUITests.xctest */, 121 | ); 122 | name = Products; 123 | sourceTree = ""; 124 | }; 125 | 17B506D42244A51B007AE2BC /* TaobaoTabBarDemo */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | 17B506D52244A51B007AE2BC /* AppDelegate.h */, 129 | 17B506D62244A51B007AE2BC /* AppDelegate.m */, 130 | 17B507192244A7FE007AE2BC /* TabBar */, 131 | 17B507072244A613007AE2BC /* FirstViewController.h */, 132 | 17B507082244A613007AE2BC /* FirstViewController.m */, 133 | 17B5070A2244A61E007AE2BC /* SecondViewController.h */, 134 | 17B5070B2244A61E007AE2BC /* SecondViewController.m */, 135 | 17B5070D2244A626007AE2BC /* ThirdViewController.h */, 136 | 17B5070E2244A626007AE2BC /* ThirdViewController.m */, 137 | 17B507102244A634007AE2BC /* FourViewController.h */, 138 | 17B507112244A634007AE2BC /* FourViewController.m */, 139 | 17B507132244A641007AE2BC /* FifthViewController.h */, 140 | 17B507142244A641007AE2BC /* FifthViewController.m */, 141 | 17B506DB2244A51B007AE2BC /* Main.storyboard */, 142 | 17B506DE2244A51D007AE2BC /* Assets.xcassets */, 143 | 17B506E02244A51D007AE2BC /* LaunchScreen.storyboard */, 144 | 17B506E32244A51D007AE2BC /* Info.plist */, 145 | 17B506E42244A51D007AE2BC /* main.m */, 146 | ); 147 | path = TaobaoTabBarDemo; 148 | sourceTree = ""; 149 | }; 150 | 17B506ED2244A51D007AE2BC /* TaobaoTabBarDemoTests */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 17B506EE2244A51D007AE2BC /* TaobaoTabBarDemoTests.m */, 154 | 17B506F02244A51D007AE2BC /* Info.plist */, 155 | ); 156 | path = TaobaoTabBarDemoTests; 157 | sourceTree = ""; 158 | }; 159 | 17B506F82244A51D007AE2BC /* TaobaoTabBarDemoUITests */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | 17B506F92244A51D007AE2BC /* TaobaoTabBarDemoUITests.m */, 163 | 17B506FB2244A51D007AE2BC /* Info.plist */, 164 | ); 165 | path = TaobaoTabBarDemoUITests; 166 | sourceTree = ""; 167 | }; 168 | 17B507192244A7FE007AE2BC /* TabBar */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | 17B5071B2244A7FE007AE2BC /* WMTabBarController.h */, 172 | 17B5071F2244A7FE007AE2BC /* WMTabBarController.m */, 173 | 17B507212244A7FE007AE2BC /* WMTabBar.h */, 174 | 17B5071D2244A7FE007AE2BC /* WMTabBar.m */, 175 | 17B5071C2244A7FE007AE2BC /* WMTabBarItem.h */, 176 | 17B5071E2244A7FE007AE2BC /* WMTabBarItem.m */, 177 | 17B507202244A7FE007AE2BC /* WMTabBarItemCell.h */, 178 | 17B5071A2244A7FE007AE2BC /* WMTabBarItemCell.m */, 179 | ); 180 | path = TabBar; 181 | sourceTree = ""; 182 | }; 183 | /* End PBXGroup section */ 184 | 185 | /* Begin PBXNativeTarget section */ 186 | 17B506D12244A51B007AE2BC /* TaobaoTabBarDemo */ = { 187 | isa = PBXNativeTarget; 188 | buildConfigurationList = 17B506FE2244A51D007AE2BC /* Build configuration list for PBXNativeTarget "TaobaoTabBarDemo" */; 189 | buildPhases = ( 190 | 17B506CE2244A51B007AE2BC /* Sources */, 191 | 17B506CF2244A51B007AE2BC /* Frameworks */, 192 | 17B506D02244A51B007AE2BC /* Resources */, 193 | ); 194 | buildRules = ( 195 | ); 196 | dependencies = ( 197 | ); 198 | name = TaobaoTabBarDemo; 199 | productName = TaobaoTabBarDemo; 200 | productReference = 17B506D22244A51B007AE2BC /* TaobaoTabBarDemo.app */; 201 | productType = "com.apple.product-type.application"; 202 | }; 203 | 17B506E92244A51D007AE2BC /* TaobaoTabBarDemoTests */ = { 204 | isa = PBXNativeTarget; 205 | buildConfigurationList = 17B507012244A51D007AE2BC /* Build configuration list for PBXNativeTarget "TaobaoTabBarDemoTests" */; 206 | buildPhases = ( 207 | 17B506E62244A51D007AE2BC /* Sources */, 208 | 17B506E72244A51D007AE2BC /* Frameworks */, 209 | 17B506E82244A51D007AE2BC /* Resources */, 210 | ); 211 | buildRules = ( 212 | ); 213 | dependencies = ( 214 | 17B506EC2244A51D007AE2BC /* PBXTargetDependency */, 215 | ); 216 | name = TaobaoTabBarDemoTests; 217 | productName = TaobaoTabBarDemoTests; 218 | productReference = 17B506EA2244A51D007AE2BC /* TaobaoTabBarDemoTests.xctest */; 219 | productType = "com.apple.product-type.bundle.unit-test"; 220 | }; 221 | 17B506F42244A51D007AE2BC /* TaobaoTabBarDemoUITests */ = { 222 | isa = PBXNativeTarget; 223 | buildConfigurationList = 17B507042244A51D007AE2BC /* Build configuration list for PBXNativeTarget "TaobaoTabBarDemoUITests" */; 224 | buildPhases = ( 225 | 17B506F12244A51D007AE2BC /* Sources */, 226 | 17B506F22244A51D007AE2BC /* Frameworks */, 227 | 17B506F32244A51D007AE2BC /* Resources */, 228 | ); 229 | buildRules = ( 230 | ); 231 | dependencies = ( 232 | 17B506F72244A51D007AE2BC /* PBXTargetDependency */, 233 | ); 234 | name = TaobaoTabBarDemoUITests; 235 | productName = TaobaoTabBarDemoUITests; 236 | productReference = 17B506F52244A51D007AE2BC /* TaobaoTabBarDemoUITests.xctest */; 237 | productType = "com.apple.product-type.bundle.ui-testing"; 238 | }; 239 | /* End PBXNativeTarget section */ 240 | 241 | /* Begin PBXProject section */ 242 | 17B506CA2244A51B007AE2BC /* Project object */ = { 243 | isa = PBXProject; 244 | attributes = { 245 | LastUpgradeCheck = 1010; 246 | ORGANIZATIONNAME = "Climb 王"; 247 | TargetAttributes = { 248 | 17B506D12244A51B007AE2BC = { 249 | CreatedOnToolsVersion = 10.1; 250 | }; 251 | 17B506E92244A51D007AE2BC = { 252 | CreatedOnToolsVersion = 10.1; 253 | TestTargetID = 17B506D12244A51B007AE2BC; 254 | }; 255 | 17B506F42244A51D007AE2BC = { 256 | CreatedOnToolsVersion = 10.1; 257 | TestTargetID = 17B506D12244A51B007AE2BC; 258 | }; 259 | }; 260 | }; 261 | buildConfigurationList = 17B506CD2244A51B007AE2BC /* Build configuration list for PBXProject "TaobaoTabBarDemo" */; 262 | compatibilityVersion = "Xcode 9.3"; 263 | developmentRegion = en; 264 | hasScannedForEncodings = 0; 265 | knownRegions = ( 266 | en, 267 | Base, 268 | ); 269 | mainGroup = 17B506C92244A51B007AE2BC; 270 | productRefGroup = 17B506D32244A51B007AE2BC /* Products */; 271 | projectDirPath = ""; 272 | projectRoot = ""; 273 | targets = ( 274 | 17B506D12244A51B007AE2BC /* TaobaoTabBarDemo */, 275 | 17B506E92244A51D007AE2BC /* TaobaoTabBarDemoTests */, 276 | 17B506F42244A51D007AE2BC /* TaobaoTabBarDemoUITests */, 277 | ); 278 | }; 279 | /* End PBXProject section */ 280 | 281 | /* Begin PBXResourcesBuildPhase section */ 282 | 17B506D02244A51B007AE2BC /* Resources */ = { 283 | isa = PBXResourcesBuildPhase; 284 | buildActionMask = 2147483647; 285 | files = ( 286 | 17B506E22244A51D007AE2BC /* LaunchScreen.storyboard in Resources */, 287 | 17B506DF2244A51D007AE2BC /* Assets.xcassets in Resources */, 288 | 17B506DD2244A51B007AE2BC /* Main.storyboard in Resources */, 289 | ); 290 | runOnlyForDeploymentPostprocessing = 0; 291 | }; 292 | 17B506E82244A51D007AE2BC /* Resources */ = { 293 | isa = PBXResourcesBuildPhase; 294 | buildActionMask = 2147483647; 295 | files = ( 296 | ); 297 | runOnlyForDeploymentPostprocessing = 0; 298 | }; 299 | 17B506F32244A51D007AE2BC /* Resources */ = { 300 | isa = PBXResourcesBuildPhase; 301 | buildActionMask = 2147483647; 302 | files = ( 303 | ); 304 | runOnlyForDeploymentPostprocessing = 0; 305 | }; 306 | /* End PBXResourcesBuildPhase section */ 307 | 308 | /* Begin PBXSourcesBuildPhase section */ 309 | 17B506CE2244A51B007AE2BC /* Sources */ = { 310 | isa = PBXSourcesBuildPhase; 311 | buildActionMask = 2147483647; 312 | files = ( 313 | 17B507122244A634007AE2BC /* FourViewController.m in Sources */, 314 | 17B5070C2244A61E007AE2BC /* SecondViewController.m in Sources */, 315 | 17B5070F2244A626007AE2BC /* ThirdViewController.m in Sources */, 316 | 17B506E52244A51D007AE2BC /* main.m in Sources */, 317 | 17B507242244A7FE007AE2BC /* WMTabBarItem.m in Sources */, 318 | 17B507222244A7FE007AE2BC /* WMTabBarItemCell.m in Sources */, 319 | 17B507092244A613007AE2BC /* FirstViewController.m in Sources */, 320 | 17B507232244A7FE007AE2BC /* WMTabBar.m in Sources */, 321 | 17B507152244A641007AE2BC /* FifthViewController.m in Sources */, 322 | 17B506D72244A51B007AE2BC /* AppDelegate.m in Sources */, 323 | 17B507252244A7FE007AE2BC /* WMTabBarController.m in Sources */, 324 | ); 325 | runOnlyForDeploymentPostprocessing = 0; 326 | }; 327 | 17B506E62244A51D007AE2BC /* Sources */ = { 328 | isa = PBXSourcesBuildPhase; 329 | buildActionMask = 2147483647; 330 | files = ( 331 | 17B506EF2244A51D007AE2BC /* TaobaoTabBarDemoTests.m in Sources */, 332 | ); 333 | runOnlyForDeploymentPostprocessing = 0; 334 | }; 335 | 17B506F12244A51D007AE2BC /* Sources */ = { 336 | isa = PBXSourcesBuildPhase; 337 | buildActionMask = 2147483647; 338 | files = ( 339 | 17B506FA2244A51D007AE2BC /* TaobaoTabBarDemoUITests.m in Sources */, 340 | ); 341 | runOnlyForDeploymentPostprocessing = 0; 342 | }; 343 | /* End PBXSourcesBuildPhase section */ 344 | 345 | /* Begin PBXTargetDependency section */ 346 | 17B506EC2244A51D007AE2BC /* PBXTargetDependency */ = { 347 | isa = PBXTargetDependency; 348 | target = 17B506D12244A51B007AE2BC /* TaobaoTabBarDemo */; 349 | targetProxy = 17B506EB2244A51D007AE2BC /* PBXContainerItemProxy */; 350 | }; 351 | 17B506F72244A51D007AE2BC /* PBXTargetDependency */ = { 352 | isa = PBXTargetDependency; 353 | target = 17B506D12244A51B007AE2BC /* TaobaoTabBarDemo */; 354 | targetProxy = 17B506F62244A51D007AE2BC /* PBXContainerItemProxy */; 355 | }; 356 | /* End PBXTargetDependency section */ 357 | 358 | /* Begin PBXVariantGroup section */ 359 | 17B506DB2244A51B007AE2BC /* Main.storyboard */ = { 360 | isa = PBXVariantGroup; 361 | children = ( 362 | 17B506DC2244A51B007AE2BC /* Base */, 363 | ); 364 | name = Main.storyboard; 365 | sourceTree = ""; 366 | }; 367 | 17B506E02244A51D007AE2BC /* LaunchScreen.storyboard */ = { 368 | isa = PBXVariantGroup; 369 | children = ( 370 | 17B506E12244A51D007AE2BC /* Base */, 371 | ); 372 | name = LaunchScreen.storyboard; 373 | sourceTree = ""; 374 | }; 375 | /* End PBXVariantGroup section */ 376 | 377 | /* Begin XCBuildConfiguration section */ 378 | 17B506FC2244A51D007AE2BC /* Debug */ = { 379 | isa = XCBuildConfiguration; 380 | buildSettings = { 381 | ALWAYS_SEARCH_USER_PATHS = NO; 382 | CLANG_ANALYZER_NONNULL = YES; 383 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 384 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 385 | CLANG_CXX_LIBRARY = "libc++"; 386 | CLANG_ENABLE_MODULES = YES; 387 | CLANG_ENABLE_OBJC_ARC = YES; 388 | CLANG_ENABLE_OBJC_WEAK = YES; 389 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 390 | CLANG_WARN_BOOL_CONVERSION = YES; 391 | CLANG_WARN_COMMA = YES; 392 | CLANG_WARN_CONSTANT_CONVERSION = YES; 393 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 394 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 395 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 396 | CLANG_WARN_EMPTY_BODY = YES; 397 | CLANG_WARN_ENUM_CONVERSION = YES; 398 | CLANG_WARN_INFINITE_RECURSION = YES; 399 | CLANG_WARN_INT_CONVERSION = YES; 400 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 401 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 402 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 403 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 404 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 405 | CLANG_WARN_STRICT_PROTOTYPES = YES; 406 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 407 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 408 | CLANG_WARN_UNREACHABLE_CODE = YES; 409 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 410 | CODE_SIGN_IDENTITY = "iPhone Developer"; 411 | COPY_PHASE_STRIP = NO; 412 | DEBUG_INFORMATION_FORMAT = dwarf; 413 | ENABLE_STRICT_OBJC_MSGSEND = YES; 414 | ENABLE_TESTABILITY = YES; 415 | GCC_C_LANGUAGE_STANDARD = gnu11; 416 | GCC_DYNAMIC_NO_PIC = NO; 417 | GCC_NO_COMMON_BLOCKS = YES; 418 | GCC_OPTIMIZATION_LEVEL = 0; 419 | GCC_PREPROCESSOR_DEFINITIONS = ( 420 | "DEBUG=1", 421 | "$(inherited)", 422 | ); 423 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 424 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 425 | GCC_WARN_UNDECLARED_SELECTOR = YES; 426 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 427 | GCC_WARN_UNUSED_FUNCTION = YES; 428 | GCC_WARN_UNUSED_VARIABLE = YES; 429 | IPHONEOS_DEPLOYMENT_TARGET = 12.1; 430 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 431 | MTL_FAST_MATH = YES; 432 | ONLY_ACTIVE_ARCH = YES; 433 | SDKROOT = iphoneos; 434 | }; 435 | name = Debug; 436 | }; 437 | 17B506FD2244A51D007AE2BC /* Release */ = { 438 | isa = XCBuildConfiguration; 439 | buildSettings = { 440 | ALWAYS_SEARCH_USER_PATHS = NO; 441 | CLANG_ANALYZER_NONNULL = YES; 442 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 443 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 444 | CLANG_CXX_LIBRARY = "libc++"; 445 | CLANG_ENABLE_MODULES = YES; 446 | CLANG_ENABLE_OBJC_ARC = YES; 447 | CLANG_ENABLE_OBJC_WEAK = YES; 448 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 449 | CLANG_WARN_BOOL_CONVERSION = YES; 450 | CLANG_WARN_COMMA = YES; 451 | CLANG_WARN_CONSTANT_CONVERSION = YES; 452 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 453 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 454 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 455 | CLANG_WARN_EMPTY_BODY = YES; 456 | CLANG_WARN_ENUM_CONVERSION = YES; 457 | CLANG_WARN_INFINITE_RECURSION = YES; 458 | CLANG_WARN_INT_CONVERSION = YES; 459 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 460 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 461 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 462 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 463 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 464 | CLANG_WARN_STRICT_PROTOTYPES = YES; 465 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 466 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 467 | CLANG_WARN_UNREACHABLE_CODE = YES; 468 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 469 | CODE_SIGN_IDENTITY = "iPhone Developer"; 470 | COPY_PHASE_STRIP = NO; 471 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 472 | ENABLE_NS_ASSERTIONS = NO; 473 | ENABLE_STRICT_OBJC_MSGSEND = YES; 474 | GCC_C_LANGUAGE_STANDARD = gnu11; 475 | GCC_NO_COMMON_BLOCKS = YES; 476 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 477 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 478 | GCC_WARN_UNDECLARED_SELECTOR = YES; 479 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 480 | GCC_WARN_UNUSED_FUNCTION = YES; 481 | GCC_WARN_UNUSED_VARIABLE = YES; 482 | IPHONEOS_DEPLOYMENT_TARGET = 12.1; 483 | MTL_ENABLE_DEBUG_INFO = NO; 484 | MTL_FAST_MATH = YES; 485 | SDKROOT = iphoneos; 486 | VALIDATE_PRODUCT = YES; 487 | }; 488 | name = Release; 489 | }; 490 | 17B506FF2244A51D007AE2BC /* Debug */ = { 491 | isa = XCBuildConfiguration; 492 | buildSettings = { 493 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 494 | CODE_SIGN_STYLE = Automatic; 495 | DEVELOPMENT_TEAM = 3YA54AB2B7; 496 | INFOPLIST_FILE = TaobaoTabBarDemo/Info.plist; 497 | LD_RUNPATH_SEARCH_PATHS = ( 498 | "$(inherited)", 499 | "@executable_path/Frameworks", 500 | ); 501 | PRODUCT_BUNDLE_IDENTIFIER = Alibaba.TaobaoTabBarDemo; 502 | PRODUCT_NAME = "$(TARGET_NAME)"; 503 | TARGETED_DEVICE_FAMILY = "1,2"; 504 | }; 505 | name = Debug; 506 | }; 507 | 17B507002244A51D007AE2BC /* Release */ = { 508 | isa = XCBuildConfiguration; 509 | buildSettings = { 510 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 511 | CODE_SIGN_STYLE = Automatic; 512 | DEVELOPMENT_TEAM = 3YA54AB2B7; 513 | INFOPLIST_FILE = TaobaoTabBarDemo/Info.plist; 514 | LD_RUNPATH_SEARCH_PATHS = ( 515 | "$(inherited)", 516 | "@executable_path/Frameworks", 517 | ); 518 | PRODUCT_BUNDLE_IDENTIFIER = Alibaba.TaobaoTabBarDemo; 519 | PRODUCT_NAME = "$(TARGET_NAME)"; 520 | TARGETED_DEVICE_FAMILY = "1,2"; 521 | }; 522 | name = Release; 523 | }; 524 | 17B507022244A51D007AE2BC /* Debug */ = { 525 | isa = XCBuildConfiguration; 526 | buildSettings = { 527 | BUNDLE_LOADER = "$(TEST_HOST)"; 528 | CODE_SIGN_STYLE = Automatic; 529 | DEVELOPMENT_TEAM = 3YA54AB2B7; 530 | INFOPLIST_FILE = TaobaoTabBarDemoTests/Info.plist; 531 | LD_RUNPATH_SEARCH_PATHS = ( 532 | "$(inherited)", 533 | "@executable_path/Frameworks", 534 | "@loader_path/Frameworks", 535 | ); 536 | PRODUCT_BUNDLE_IDENTIFIER = Alibaba.TaobaoTabBarDemoTests; 537 | PRODUCT_NAME = "$(TARGET_NAME)"; 538 | TARGETED_DEVICE_FAMILY = "1,2"; 539 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TaobaoTabBarDemo.app/TaobaoTabBarDemo"; 540 | }; 541 | name = Debug; 542 | }; 543 | 17B507032244A51D007AE2BC /* Release */ = { 544 | isa = XCBuildConfiguration; 545 | buildSettings = { 546 | BUNDLE_LOADER = "$(TEST_HOST)"; 547 | CODE_SIGN_STYLE = Automatic; 548 | DEVELOPMENT_TEAM = 3YA54AB2B7; 549 | INFOPLIST_FILE = TaobaoTabBarDemoTests/Info.plist; 550 | LD_RUNPATH_SEARCH_PATHS = ( 551 | "$(inherited)", 552 | "@executable_path/Frameworks", 553 | "@loader_path/Frameworks", 554 | ); 555 | PRODUCT_BUNDLE_IDENTIFIER = Alibaba.TaobaoTabBarDemoTests; 556 | PRODUCT_NAME = "$(TARGET_NAME)"; 557 | TARGETED_DEVICE_FAMILY = "1,2"; 558 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TaobaoTabBarDemo.app/TaobaoTabBarDemo"; 559 | }; 560 | name = Release; 561 | }; 562 | 17B507052244A51D007AE2BC /* Debug */ = { 563 | isa = XCBuildConfiguration; 564 | buildSettings = { 565 | CODE_SIGN_STYLE = Automatic; 566 | DEVELOPMENT_TEAM = 3YA54AB2B7; 567 | INFOPLIST_FILE = TaobaoTabBarDemoUITests/Info.plist; 568 | LD_RUNPATH_SEARCH_PATHS = ( 569 | "$(inherited)", 570 | "@executable_path/Frameworks", 571 | "@loader_path/Frameworks", 572 | ); 573 | PRODUCT_BUNDLE_IDENTIFIER = Alibaba.TaobaoTabBarDemoUITests; 574 | PRODUCT_NAME = "$(TARGET_NAME)"; 575 | TARGETED_DEVICE_FAMILY = "1,2"; 576 | TEST_TARGET_NAME = TaobaoTabBarDemo; 577 | }; 578 | name = Debug; 579 | }; 580 | 17B507062244A51D007AE2BC /* Release */ = { 581 | isa = XCBuildConfiguration; 582 | buildSettings = { 583 | CODE_SIGN_STYLE = Automatic; 584 | DEVELOPMENT_TEAM = 3YA54AB2B7; 585 | INFOPLIST_FILE = TaobaoTabBarDemoUITests/Info.plist; 586 | LD_RUNPATH_SEARCH_PATHS = ( 587 | "$(inherited)", 588 | "@executable_path/Frameworks", 589 | "@loader_path/Frameworks", 590 | ); 591 | PRODUCT_BUNDLE_IDENTIFIER = Alibaba.TaobaoTabBarDemoUITests; 592 | PRODUCT_NAME = "$(TARGET_NAME)"; 593 | TARGETED_DEVICE_FAMILY = "1,2"; 594 | TEST_TARGET_NAME = TaobaoTabBarDemo; 595 | }; 596 | name = Release; 597 | }; 598 | /* End XCBuildConfiguration section */ 599 | 600 | /* Begin XCConfigurationList section */ 601 | 17B506CD2244A51B007AE2BC /* Build configuration list for PBXProject "TaobaoTabBarDemo" */ = { 602 | isa = XCConfigurationList; 603 | buildConfigurations = ( 604 | 17B506FC2244A51D007AE2BC /* Debug */, 605 | 17B506FD2244A51D007AE2BC /* Release */, 606 | ); 607 | defaultConfigurationIsVisible = 0; 608 | defaultConfigurationName = Release; 609 | }; 610 | 17B506FE2244A51D007AE2BC /* Build configuration list for PBXNativeTarget "TaobaoTabBarDemo" */ = { 611 | isa = XCConfigurationList; 612 | buildConfigurations = ( 613 | 17B506FF2244A51D007AE2BC /* Debug */, 614 | 17B507002244A51D007AE2BC /* Release */, 615 | ); 616 | defaultConfigurationIsVisible = 0; 617 | defaultConfigurationName = Release; 618 | }; 619 | 17B507012244A51D007AE2BC /* Build configuration list for PBXNativeTarget "TaobaoTabBarDemoTests" */ = { 620 | isa = XCConfigurationList; 621 | buildConfigurations = ( 622 | 17B507022244A51D007AE2BC /* Debug */, 623 | 17B507032244A51D007AE2BC /* Release */, 624 | ); 625 | defaultConfigurationIsVisible = 0; 626 | defaultConfigurationName = Release; 627 | }; 628 | 17B507042244A51D007AE2BC /* Build configuration list for PBXNativeTarget "TaobaoTabBarDemoUITests" */ = { 629 | isa = XCConfigurationList; 630 | buildConfigurations = ( 631 | 17B507052244A51D007AE2BC /* Debug */, 632 | 17B507062244A51D007AE2BC /* Release */, 633 | ); 634 | defaultConfigurationIsVisible = 0; 635 | defaultConfigurationName = Release; 636 | }; 637 | /* End XCConfigurationList section */ 638 | }; 639 | rootObject = 17B506CA2244A51B007AE2BC /* Project object */; 640 | } 641 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo.xcodeproj/project.xcworkspace/xcuserdata/climbwang.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo.xcodeproj/project.xcworkspace/xcuserdata/climbwang.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /TaobaoTabBarDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // TaobaoTabBarDemo 4 | // 5 | // Created by Climb 王 on 2019/3/22. 6 | // Copyright © 2019 Climb 王. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "WMTabBarController.h" 12 | 13 | @interface AppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | @property (nonatomic, strong) WMTabBarController *wmTabBar; 17 | 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // TaobaoTabBarDemo 4 | // 5 | // Created by Climb 王 on 2019/3/22. 6 | // Copyright © 2019 Climb 王. 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 | 20 | // 设置主窗口,并设置根控制器 21 | self.window = [[UIWindow alloc]init]; 22 | self.window.frame = [UIScreen mainScreen].bounds; 23 | [self.window makeKeyAndVisible]; 24 | 25 | self.wmTabBar= [[WMTabBarController alloc] init]; 26 | [self.window setRootViewController:self.wmTabBar]; 27 | 28 | return YES; 29 | } 30 | 31 | 32 | - (void)applicationWillResignActive:(UIApplication *)application { 33 | // 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. 34 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 35 | } 36 | 37 | 38 | - (void)applicationDidEnterBackground:(UIApplication *)application { 39 | // 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. 40 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 41 | } 42 | 43 | 44 | - (void)applicationWillEnterForeground:(UIApplication *)application { 45 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 46 | } 47 | 48 | 49 | - (void)applicationDidBecomeActive:(UIApplication *)application { 50 | // 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. 51 | } 52 | 53 | 54 | - (void)applicationWillTerminate:(UIApplication *)application { 55 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 56 | } 57 | 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_find_normal.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tabbar_find_normal@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tabbar_find_normal@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_find_normal.imageset/tabbar_find_normal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_find_normal.imageset/tabbar_find_normal@2x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_find_normal.imageset/tabbar_find_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_find_normal.imageset/tabbar_find_normal@3x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_find_selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tabbar_find_selected@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tabbar_find_selected@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_find_selected.imageset/tabbar_find_selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_find_selected.imageset/tabbar_find_selected@2x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_find_selected.imageset/tabbar_find_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_find_selected.imageset/tabbar_find_selected@3x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_launch.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tabbar_home_launch@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tabbar_home_launch@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_launch.imageset/tabbar_home_launch@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_home_launch.imageset/tabbar_home_launch@2x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_launch.imageset/tabbar_home_launch@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_home_launch.imageset/tabbar_home_launch@3x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_normal.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tabbar_home_normal@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tabbar_home_normal@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_normal.imageset/tabbar_home_normal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_home_normal.imageset/tabbar_home_normal@2x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_normal.imageset/tabbar_home_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_home_normal.imageset/tabbar_home_normal@3x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selecetedBg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tabbar_home_selecetedBg@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tabbar_home_selecetedBg@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selecetedBg.imageset/tabbar_home_selecetedBg@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selecetedBg.imageset/tabbar_home_selecetedBg@2x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selecetedBg.imageset/tabbar_home_selecetedBg@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selecetedBg.imageset/tabbar_home_selecetedBg@3x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selecetedLogo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tabbar_home_selecetedLogo@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tabbar_home_selecetedLogo@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selecetedLogo.imageset/tabbar_home_selecetedLogo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selecetedLogo.imageset/tabbar_home_selecetedLogo@2x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selecetedLogo.imageset/tabbar_home_selecetedLogo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selecetedLogo.imageset/tabbar_home_selecetedLogo@3x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selecetedPush.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tabbar_home_selecetedPush@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tabbar_home_selecetedPush@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selecetedPush.imageset/tabbar_home_selecetedPush@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selecetedPush.imageset/tabbar_home_selecetedPush@2x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selecetedPush.imageset/tabbar_home_selecetedPush@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selecetedPush.imageset/tabbar_home_selecetedPush@3x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tabbar_home_selected@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tabbar_home_selected@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selected.imageset/tabbar_home_selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selected.imageset/tabbar_home_selected@2x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selected.imageset/tabbar_home_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_home_selected.imageset/tabbar_home_selected@3x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_knowledge_normal.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tabbar_knowledge_normal@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tabbar_knowledge_normal@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_knowledge_normal.imageset/tabbar_knowledge_normal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_knowledge_normal.imageset/tabbar_knowledge_normal@2x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_knowledge_normal.imageset/tabbar_knowledge_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_knowledge_normal.imageset/tabbar_knowledge_normal@3x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_knowledge_selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tabbar_knowledge_selected@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tabbar_knowledge_selected@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_knowledge_selected.imageset/tabbar_knowledge_selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_knowledge_selected.imageset/tabbar_knowledge_selected@2x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_knowledge_selected.imageset/tabbar_knowledge_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_knowledge_selected.imageset/tabbar_knowledge_selected@3x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_mall_normal.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tabbar_mall_normal@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tabbar_mall_normal@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_mall_normal.imageset/tabbar_mall_normal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_mall_normal.imageset/tabbar_mall_normal@2x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_mall_normal.imageset/tabbar_mall_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_mall_normal.imageset/tabbar_mall_normal@3x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_mall_selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tabbar_mall_selected@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tabbar_mall_selected@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_mall_selected.imageset/tabbar_mall_selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_mall_selected.imageset/tabbar_mall_selected@2x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_mall_selected.imageset/tabbar_mall_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_mall_selected.imageset/tabbar_mall_selected@3x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_mine_normal.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tabbar_mine_normal@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tabbar_mine_normal@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_mine_normal.imageset/tabbar_mine_normal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_mine_normal.imageset/tabbar_mine_normal@2x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_mine_normal.imageset/tabbar_mine_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_mine_normal.imageset/tabbar_mine_normal@3x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_mine_selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tabbar_mine_selected@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "tabbar_mine_selected@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_mine_selected.imageset/tabbar_mine_selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_mine_selected.imageset/tabbar_mine_selected@2x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Assets.xcassets/tabbar_mine_selected.imageset/tabbar_mine_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Climb0516/TaobaoTabBarDemo/f299593016e12a1e9fae051cef9b1f709c1bd05e/TaobaoTabBarDemo/Assets.xcassets/tabbar_mine_selected.imageset/tabbar_mine_selected@3x.png -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/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 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/FifthViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FifthViewController.h 3 | // TaobaoTabBarDemo 4 | // 5 | // Created by Climb 王 on 2019/3/22. 6 | // Copyright © 2019 Climb 王. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface FifthViewController : UIViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/FifthViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FifthViewController.m 3 | // TaobaoTabBarDemo 4 | // 5 | // Created by Climb 王 on 2019/3/22. 6 | // Copyright © 2019 Climb 王. All rights reserved. 7 | // 8 | 9 | #import "FifthViewController.h" 10 | 11 | @interface FifthViewController () 12 | 13 | @end 14 | 15 | @implementation FifthViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | 20 | self.title = @"我的"; 21 | [self.view setBackgroundColor:[UIColor blueColor]]; 22 | } 23 | 24 | /* 25 | #pragma mark - Navigation 26 | 27 | // In a storyboard-based application, you will often want to do a little preparation before navigation 28 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 29 | // Get the new view controller using [segue destinationViewController]. 30 | // Pass the selected object to the new view controller. 31 | } 32 | */ 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/FirstViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FirstViewController.h 3 | // TaobaoTabBarDemo 4 | // 5 | // Created by Climb 王 on 2019/3/22. 6 | // Copyright © 2019 Climb 王. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface FirstViewController : UIViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/FirstViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FirstViewController.m 3 | // TaobaoTabBarDemo 4 | // 5 | // Created by Climb 王 on 2019/3/22. 6 | // Copyright © 2019 Climb 王. All rights reserved. 7 | // 8 | 9 | #import "FirstViewController.h" 10 | 11 | #import "AppDelegate.h" 12 | 13 | @interface FirstViewController () 14 | 15 | @property (nonatomic, strong) UITableView *tableView; 16 | /** 动画相关 */ 17 | @property (nonatomic, assign) BOOL tabAnimateOnceScrollFlag;//tabBar动画实现的一次滑动的标志,用来区分t不松手的一次滑行中调用多次s切换动画问题 18 | @property (nonatomic, assign) CGFloat lastPositionOffestY; //记录上次偏移量,用以比对上滑/下滑/滑动范围等操作 19 | 20 | @end 21 | 22 | @implementation FirstViewController 23 | 24 | - (void)viewDidLoad { 25 | [super viewDidLoad]; 26 | 27 | self.title = @"首页"; 28 | [self.view setBackgroundColor:[UIColor whiteColor]]; 29 | 30 | self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; 31 | self.tableView.delegate = self; 32 | self.tableView.dataSource = self; 33 | [self.view addSubview:self.tableView]; 34 | 35 | // 点击火箭🚀tab执行的滑动到顶部通知 36 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollTopAction) name:@"kPushDownAnimationScrollTopNotification" object:nil]; 37 | } 38 | 39 | 40 | #pragma mark ----------- tableViewDelegate ------------- 41 | 42 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 43 | return 1; 44 | } 45 | 46 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 47 | return 30; 48 | } 49 | 50 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 51 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellId"]; 52 | if (!cell) { 53 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CellId"]; 54 | } 55 | cell.textLabel.text = [NSString stringWithFormat:@"TaoBao淘宝%ld", indexPath.row]; 56 | return cell; 57 | } 58 | 59 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 60 | return 44.f; 61 | } 62 | 63 | 64 | #pragma mark ----------- Action ------------- 65 | 66 | // 点击tab火箭🚀 界面滑到顶部事件 67 | - (void)scrollTopAction { 68 | [self.tableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES]; 69 | } 70 | 71 | 72 | #pragma mark ----------- scrollviewDelegate ------------- 73 | 74 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView { 75 | if ([scrollView isEqual: self.tableView]) { 76 | CGFloat currentPostionOffsetY = scrollView.contentOffset.y; 77 | // // 限制向下偏移量 78 | // if (currentPostionOffsetY < -120) { 79 | // self.tableView.contentOffset = CGPointMake(0, -120.f); 80 | // } 81 | if (currentPostionOffsetY > self.lastPositionOffestY) { 82 | NSLog(@"手势上滑"); 83 | // tabBar动画 84 | if (self.tabAnimateOnceScrollFlag) { 85 | // 上一次lastPositionOffestY<300.f, 且currentPostionOffsetY>300.f 86 | if ((self.lastPositionOffestY < 300.f) && (currentPostionOffsetY > 300.f)) { 87 | NSLog(@"发送通知,切换火箭"); 88 | AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; 89 | [appDelegate.wmTabBar pushHomeTabBarAnimationType:anmationDirectionUp]; 90 | self.tabAnimateOnceScrollFlag = NO; 91 | } 92 | } 93 | }else { 94 | NSLog(@"手势下滑"); 95 | // tabBar动画 96 | if (self.tabAnimateOnceScrollFlag) { 97 | if ((self.lastPositionOffestY >= 300.f) && (currentPostionOffsetY < 300.f)) { 98 | NSLog(@"发送通知,切换logo"); 99 | AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; 100 | [appDelegate.wmTabBar pushHomeTabBarAnimationType:anmationDirectionDown]; 101 | self.tabAnimateOnceScrollFlag = NO; 102 | } 103 | } 104 | 105 | } 106 | } 107 | } 108 | 109 | // 当开始滚动视图时,执行该方法。一次有效滑动(开始滑动,滑动一小段距离,只要手指不松开,只算一次滑动),只执行一次。 110 | - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { 111 | if ([scrollView isEqual:self.tableView]) { 112 | self.tabAnimateOnceScrollFlag = YES; 113 | self.lastPositionOffestY = scrollView.contentOffset.y; 114 | } 115 | } 116 | 117 | @end 118 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/FourViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FourViewController.h 3 | // TaobaoTabBarDemo 4 | // 5 | // Created by Climb 王 on 2019/3/22. 6 | // Copyright © 2019 Climb 王. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface FourViewController : UIViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/FourViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FourViewController.m 3 | // TaobaoTabBarDemo 4 | // 5 | // Created by Climb 王 on 2019/3/22. 6 | // Copyright © 2019 Climb 王. All rights reserved. 7 | // 8 | 9 | #import "FourViewController.h" 10 | 11 | @interface FourViewController () 12 | 13 | @end 14 | 15 | @implementation FourViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | 20 | self.title = @"h商城"; 21 | [self.view setBackgroundColor:[UIColor orangeColor]]; 22 | } 23 | 24 | /* 25 | #pragma mark - Navigation 26 | 27 | // In a storyboard-based application, you will often want to do a little preparation before navigation 28 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 29 | // Get the new view controller using [segue destinationViewController]. 30 | // Pass the selected object to the new view controller. 31 | } 32 | */ 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/SecondViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.h 3 | // TaobaoTabBarDemo 4 | // 5 | // Created by Climb 王 on 2019/3/22. 6 | // Copyright © 2019 Climb 王. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface SecondViewController : UIViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/SecondViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.m 3 | // TaobaoTabBarDemo 4 | // 5 | // Created by Climb 王 on 2019/3/22. 6 | // Copyright © 2019 Climb 王. All rights reserved. 7 | // 8 | 9 | #import "SecondViewController.h" 10 | 11 | @interface SecondViewController () 12 | 13 | @end 14 | 15 | @implementation SecondViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | 20 | self.title = @"发现"; 21 | [self.view setBackgroundColor:[UIColor purpleColor]]; 22 | } 23 | 24 | /* 25 | #pragma mark - Navigation 26 | 27 | // In a storyboard-based application, you will often want to do a little preparation before navigation 28 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 29 | // Get the new view controller using [segue destinationViewController]. 30 | // Pass the selected object to the new view controller. 31 | } 32 | */ 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/TabBar/WMTabBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // WMTabBar.h 3 | // Micropulse 4 | // 5 | // Created by Climb 王 on 2019/3/20. 6 | // Copyright © 2019 iChoice. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | // logo和火箭切换动画的枚举anmationDirection 14 | typedef NS_ENUM(NSUInteger, anmationDirection) { 15 | anmationDirectionUp,//push动画,火箭头出来,logo下去 16 | anmationDirectionDown,//push动画,火箭头下去,logo出来 17 | }; 18 | 19 | @protocol WMTabBarDelegate 20 | 21 | /** 选中tabbar */ 22 | - (void)selectedWMTabBarItemAtIndex:(NSInteger)index; 23 | 24 | @end 25 | 26 | @interface WMTabBar : UITabBar 27 | 28 | @property (nonatomic, strong) NSMutableArray *itemArray; 29 | @property (nonatomic, strong) NSArray *titleArray; 30 | @property (nonatomic, strong) NSArray *imageArray; 31 | @property (nonatomic, strong) NSArray *selectedImageArray; 32 | @property (nonatomic, weak) id tabBarDelegate; 33 | /** 实例化 */ 34 | + (instancetype)tabBarWithTitleArray:(NSArray *)titleArray imageArray:(NSArray *)imageArray selectedImageArray:(NSArray *)selectedImageArray; 35 | 36 | // 外部指定跳转到某个tab时调用 37 | - (void)selectedTabbarAtIndex:(NSNumber *)index; 38 | 39 | // 暴露外部的切换动画logo和火箭的方法 40 | - (void)pushHomeTabBarAnimationType:(anmationDirection )anmationDirection; 41 | 42 | @end 43 | 44 | NS_ASSUME_NONNULL_END 45 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/TabBar/WMTabBar.m: -------------------------------------------------------------------------------- 1 | // 2 | // WMTabBar.m 3 | // Micropulse 4 | // 5 | // Created by Climb 王 on 2019/3/20. 6 | // Copyright © 2019 iChoice. All rights reserved. 7 | // 8 | 9 | #import "WMTabBar.h" 10 | 11 | #import "WMTabBarItem.h" 12 | 13 | #define kScreen_height [[UIScreen mainScreen] bounds].size.height 14 | #define kScreen_width [[UIScreen mainScreen] bounds].size.width 15 | 16 | @interface WMTabBar () 17 | 18 | @property (nonatomic, assign) NSInteger lastSelectIndex;//记录上一次点击index 19 | @property (nonatomic, assign) NSInteger selectedIndex; 20 | 21 | @end 22 | 23 | @implementation WMTabBar 24 | 25 | //删除系统tabbar的UITabBarButton 26 | - (void)layoutSubviews { 27 | [super layoutSubviews]; 28 | 29 | for (UIView *view in self.subviews) { 30 | if ([view isKindOfClass:NSClassFromString(@"UITabBarButton")]) { 31 | [view removeFromSuperview]; 32 | } 33 | } 34 | } 35 | 36 | 37 | + (instancetype)tabBarWithTitleArray:(NSArray *)titleArray imageArray:(NSArray *)imageArray selectedImageArray:(NSArray *)selectedImageArray { 38 | WMTabBar *tabBar = [[WMTabBar alloc] init]; 39 | tabBar.titleArray = titleArray; 40 | tabBar.imageArray = imageArray; 41 | tabBar.selectedImageArray = selectedImageArray; 42 | [tabBar setupUI]; 43 | return tabBar; 44 | } 45 | 46 | - (void)setupUI { 47 | self.lastSelectIndex = 100;//默认为100 48 | self.backgroundColor = [UIColor whiteColor]; 49 | for (int i = 0; i < self.titleArray.count; i++) { 50 | CGFloat itemWidth = (kScreen_width/self.titleArray.count); 51 | CGRect frame = CGRectMake(i*itemWidth, 0, itemWidth, 56); 52 | WMTabBarItem *tabBarItem = [[WMTabBarItem alloc] initWithFrame:frame index:i]; 53 | tabBarItem.tag = i ; 54 | UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(selectTabBarItemAction:)]; 55 | [tabBarItem addGestureRecognizer:tap]; 56 | [self addSubview:tabBarItem]; 57 | [self.itemArray addObject:tabBarItem]; 58 | } 59 | self.selectedIndex = 0; 60 | } 61 | 62 | - (void)selectTabBarItemAction:(UITapGestureRecognizer *)sender { 63 | [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(selectedTabbarAtIndex:) object:@(sender.view.tag)]; 64 | [self performSelector:@selector(selectedTabbarAtIndex:) withObject:@(sender.view.tag) afterDelay:0.15f]; 65 | } 66 | 67 | - (void)selectedTabbarAtIndex:(NSNumber *)index { 68 | self.selectedIndex = [index integerValue]; 69 | if ([self.tabBarDelegate respondsToSelector:@selector(selectedWMTabBarItemAtIndex:)]) { 70 | [self.tabBarDelegate selectedWMTabBarItemAtIndex:[index integerValue]]; 71 | } 72 | } 73 | 74 | - (void)setSelectedIndex:(NSInteger )selectedIndex { 75 | _selectedIndex = selectedIndex; 76 | [self.itemArray enumerateObjectsUsingBlock:^(WMTabBarItem *tabBarItem, NSUInteger idx, BOOL * _Nonnull stop) { 77 | // 当遍历的idx=selectedIndex时,记录选中状态 78 | BOOL selected = (idx == selectedIndex); 79 | // 配置tabBarItem的内容信息 80 | [tabBarItem configTitle:self.titleArray[idx] normalImage:self.imageArray[idx] selectedImage:self.selectedImageArray[idx] index:idx selected:selected lastSelectIndex:self.lastSelectIndex]; 81 | // 当遍历到最后一个时,赋值lastSelectIndex 82 | if (idx == (self.itemArray.count-1)) { 83 | self.lastSelectIndex = selectedIndex; 84 | } 85 | }]; 86 | } 87 | 88 | // 暴露外部的切换动画logo和火箭的方法 89 | - (void)pushHomeTabBarAnimationType:(anmationDirection )anmationDirection { 90 | if (self.itemArray.count > 0) { 91 | WMTabBarItem *tabBarItem = self.itemArray[0]; 92 | if (anmationDirection == anmationDirectionUp) { 93 | [tabBarItem pushHomeTabAnimationUp]; 94 | }else { 95 | [tabBarItem pushHomeTabAnimationDown]; 96 | } 97 | } 98 | } 99 | 100 | #pragma mark - lazy 101 | - (NSMutableArray *)itemArray { 102 | if (!_itemArray) { 103 | _itemArray = [NSMutableArray array]; 104 | } 105 | return _itemArray; 106 | } 107 | 108 | - (NSArray *)titleArray { 109 | if (!_titleArray) { 110 | _titleArray = [NSArray array]; 111 | } 112 | return _titleArray; 113 | } 114 | 115 | - (NSArray *)imageArray { 116 | if (!_imageArray) { 117 | _imageArray = [NSArray array]; 118 | } 119 | return _imageArray; 120 | } 121 | 122 | - (NSArray *)selectedImageArray { 123 | if (!_selectedImageArray) { 124 | _selectedImageArray = [NSArray array]; 125 | } 126 | return _selectedImageArray; 127 | } 128 | 129 | @end 130 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/TabBar/WMTabBarController.h: -------------------------------------------------------------------------------- 1 | // 2 | // WMTabBarController.h 3 | // Micropulse 4 | // 5 | // Created by Climb 王 on 2019/3/20. 6 | // Copyright © 2019 iChoice. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "WMTabBar.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface WMTabBarController : UITabBarController 16 | 17 | // 切换指定index的tabbar,用该方法 18 | - (void)changeTabBarAtIndex:(NSInteger )index; 19 | 20 | // 暴露外部的切换动画logo和火箭的方法 21 | - (void)pushHomeTabBarAnimationType:(anmationDirection )anmationDirection; 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/TabBar/WMTabBarController.m: -------------------------------------------------------------------------------- 1 | // 2 | // WMTabBarController.m 3 | // Micropulse 4 | // 5 | // Created by Climb 王 on 2019/3/20. 6 | // Copyright © 2019 iChoice. All rights reserved. 7 | // 8 | 9 | #import "WMTabBarController.h" 10 | 11 | #import "WMTabBar.h" 12 | #import "FirstViewController.h" 13 | #import "SecondViewController.h" 14 | #import "ThirdViewController.h" 15 | #import "FourViewController.h" 16 | #import "FifthViewController.h" 17 | 18 | @interface WMTabBarController () 19 | 20 | @property (nonatomic, strong) FirstViewController *homePageController; 21 | @property (nonatomic, strong) SecondViewController *seeDoctorController; 22 | @property (nonatomic, strong) ThirdViewController *knowledgeController; 23 | @property (nonatomic, strong) FourViewController *mallController; 24 | @property (nonatomic, strong) FifthViewController *mineController; 25 | @property (nonatomic, strong) NSMutableArray *controllersArray; 26 | @property (nonatomic, strong) WMTabBar *wmTabBar; 27 | 28 | @end 29 | 30 | @implementation WMTabBarController 31 | 32 | - (void)viewDidLoad { 33 | [super viewDidLoad]; 34 | 35 | self.controllersArray = [NSMutableArray new]; 36 | [self createControllers]; 37 | } 38 | 39 | - (void)createControllers { 40 | self.homePageController = [FirstViewController new]; 41 | self.seeDoctorController = [SecondViewController new]; 42 | self.knowledgeController = [ThirdViewController new]; 43 | self.mallController = [FourViewController new]; 44 | self.mineController = [FifthViewController new]; 45 | 46 | NSArray *childVCArray = @[self.homePageController, self.seeDoctorController, self.knowledgeController, self.mallController, self.mineController]; 47 | NSArray *titleArray = @[@"首页", @"发现", @"知识", @"商城", @"我的"]; 48 | NSArray *imageArray = @[@"tabbar_home_normal", @"tabbar_find_normal", @"tabbar_knowledge_normal", @"tabbar_mall_normal", @"tabbar_mine_normal"]; 49 | NSArray *selectedImageArray = @[@"tabbar_home_selectedBg", @"tabbar_find_selected", @"tabbar_knowledge_selected", @"tabbar_mall_selected", @"tabbar_mine_selected"]; 50 | //添加子模块 51 | [self creatTabBarWithChildVCArray: childVCArray 52 | titleArray: titleArray 53 | imageArray: imageArray 54 | selectedImageArray: selectedImageArray]; 55 | } 56 | 57 | //添加子模块 58 | - (void)creatTabBarWithChildVCArray:(NSArray *)childVCArray 59 | titleArray:(NSArray *)titleArray 60 | imageArray:(NSArray *)imageArray 61 | selectedImageArray:(NSArray *)selectedImageArray { 62 | 63 | for (UIViewController *viewController in childVCArray) { 64 | UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController]; 65 | [self.controllersArray addObject:navigationController]; 66 | } 67 | 68 | self.wmTabBar = [WMTabBar tabBarWithTitleArray:titleArray 69 | imageArray:imageArray 70 | selectedImageArray:selectedImageArray]; 71 | self.wmTabBar.tabBarDelegate = self; 72 | [self setValue:self.wmTabBar forKeyPath:@"tabBar"]; 73 | self.viewControllers = self.controllersArray; 74 | } 75 | 76 | // 重写tabbar的frame,改变tabbar高度 77 | - (void)viewDidLayoutSubviews { 78 | [super viewDidLayoutSubviews]; 79 | 80 | CGRect frame = self.tabBar.frame; 81 | if (frame.size.height != 56) { 82 | frame.size.height = 56; 83 | frame.origin.y = self.view.frame.size.height - frame.size.height; 84 | self.tabBar.frame = frame; 85 | } 86 | } 87 | 88 | #pragma mark ----------- tabbarDelegate ------------- 89 | 90 | - (void)selectedWMTabBarItemAtIndex:(NSInteger)index { 91 | self.selectedIndex = index; 92 | } 93 | 94 | 95 | #pragma mark ----------- publick Mothed ------------- 96 | 97 | - (void)changeTabBarAtIndex:(NSInteger)index { 98 | self.selectedIndex = index; 99 | [self.wmTabBar selectedTabbarAtIndex:@(index)]; 100 | } 101 | 102 | // 暴露外部的切换动画logo和火箭的方法 103 | - (void)pushHomeTabBarAnimationType:(anmationDirection)anmationDirection { 104 | [self.wmTabBar pushHomeTabBarAnimationType:anmationDirection]; 105 | } 106 | 107 | @end 108 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/TabBar/WMTabBarItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // WMTabBarItem.h 3 | // Micropulse 4 | // 5 | // Created by Climb 王 on 2019/3/20. 6 | // Copyright © 2019 iChoice. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface WMTabBarItem : UIView 14 | 15 | - (instancetype)initWithFrame:(CGRect)frame index:(NSInteger )index; 16 | 17 | - (void)configTitle:(NSString *)title normalImage:(NSString *)normalImage selectedImage:(NSString *)selectedImage index:(NSInteger)index selected:(BOOL)selected lastSelectIndex:(NSInteger )lastSelectIndex; 18 | 19 | // push动画 - 火箭头上来,logo下来 20 | - (void)pushHomeTabAnimationUp; 21 | // push动画 - 火箭头落下, logo上来 22 | - (void)pushHomeTabAnimationDown; 23 | 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/TabBar/WMTabBarItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // WMTabBarItem.m 3 | // Micropulse 4 | // 5 | // Created by Climb 王 on 2019/3/20. 6 | // Copyright © 2019 iChoice. All rights reserved. 7 | // 8 | 9 | #import "WMTabBarItem.h" 10 | 11 | #import "WMTabBarItemCell.h" 12 | 13 | @interface WMTabBarItem () 14 | 15 | /** tabbar的文字title */ 16 | @property (nonatomic, strong) UILabel *titleLabel; 17 | /** tabbar的图片 */ 18 | @property (nonatomic, strong) UIImageView *imageView; 19 | 20 | /* 21 | * index=0时,即首页tababr 选中时的背景图片 22 | * 效果图细节:背景原图片没有变化,只是背景图片上的火箭🚀和logo 两个切换动画, 23 | * 所以: 隔离开背景部分和动画部分 24 | */ 25 | @property (nonatomic, strong) UIImageView *homeTabSelectedBgView; 26 | /* 27 | * 动画部分 28 | * 第一种方案,用的是ImageView,进行kCATransitionPush向上或向下的动画 29 | * 优点: 布局省事 30 | * 缺点: 当火箭🚀向上动画时,大logo会有残影,且也算明显 31 | */ 32 | @property (nonatomic, strong) UIImageView *homeTabAnimateImageView; 33 | /* 34 | * 动画部分 35 | * 第二种方案,用的是collectionView, 通过滑动到某个item进行动画 36 | * 结果:完美实现功能 37 | */ 38 | @property (nonatomic, strong) UICollectionView *collectionView; 39 | 40 | /* 41 | * flag,用以点击首页tabbar时 如果是火箭状态,则进行切换logo动画,且界面滑到顶部 42 | */ 43 | @property (nonatomic, assign) BOOL flag; 44 | @end 45 | 46 | @implementation WMTabBarItem 47 | 48 | - (instancetype)initWithFrame:(CGRect)frame index:(NSInteger )index { 49 | self = [super initWithFrame:frame]; 50 | if (self) { 51 | 52 | [self addSubview:self.titleLabel]; 53 | [self addSubview:self.imageView]; 54 | [self addSubview:self.homeTabSelectedBgView]; 55 | 56 | self.imageView.frame = CGRectMake(self.bounds.size.width/2-14, 7, 28, 28); 57 | self.titleLabel.frame = CGRectMake(0, CGRectGetMaxY(self.imageView.frame)+2, self.bounds.size.width, 14); 58 | self.homeTabSelectedBgView.frame = CGRectMake(self.bounds.size.width/2-21, 7, 42, 42); 59 | 60 | if (index == 0) { 61 | // 当为首页tab时,加上以下内容 62 | [self addSubview:self.homeTabSelectedBgView]; 63 | 64 | // /** 第一种方案 */ 65 | // [self.homeTabSelectedBgView addSubview:self.homeTabAnimateImageView]; 66 | // self.homeTabAnimateImageView.frame = CGRectMake(0, 0, 32, 32); 67 | // self.homeTabAnimateImageView.center = CGPointMake(self.homeTabSelectedBgView.frame.size.width/2, self.homeTabSelectedBgView.frame.size.height/2); 68 | 69 | /** 第二种方案 */ 70 | [self.homeTabSelectedBgView addSubview:self.collectionView]; 71 | self.homeTabSelectedBgView.frame = CGRectMake(self.bounds.size.width/2-21, 7, 42, 42); 72 | self.collectionView.frame = CGRectMake(0, 0, 42, 42); 73 | self.collectionView.center = CGPointMake(self.homeTabSelectedBgView.frame.size.width/2, self.homeTabSelectedBgView.frame.size.height/2); 74 | 75 | [self.collectionView registerClass:[WMTabBarItemCell class] 76 | forCellWithReuseIdentifier:NSStringFromClass([WMTabBarItemCell class])]; 77 | } 78 | } 79 | return self; 80 | } 81 | 82 | #pragma mark - collectionView 83 | 84 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 85 | return 2; 86 | } 87 | 88 | - (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 89 | WMTabBarItemCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([WMTabBarItemCell class]) forIndexPath:indexPath]; 90 | NSString *imageStr = (indexPath.item == 0) ? @"tabbar_home_selecetedLogo" : @"tabbar_home_selecetedPush"; 91 | [cell configItemImageString:imageStr]; 92 | return cell; 93 | } 94 | 95 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { 96 | 97 | } 98 | 99 | 100 | #pragma mark ----------- Action ------------- 101 | 102 | // 当点击tab的item时,执行 103 | - (void)configTitle:(NSString *)title normalImage:(NSString *)normalImage selectedImage:(NSString *)selectedImage index:(NSInteger)index selected:(BOOL)selected lastSelectIndex:(NSInteger )lastSelectIndex { 104 | self.titleLabel.text = title; 105 | // 当index == 0, 即首页tab 106 | if (index == 0) { 107 | if (selected) { 108 | [self.homeTabSelectedBgView setImage:[UIImage imageNamed:@"tabbar_home_selecetedBg"]]; 109 | self.homeTabSelectedBgView.hidden = NO; 110 | YES;self.imageView.hidden = self.titleLabel.hidden = YES; 111 | 112 | // /** 第一种方案 */ 113 | // [self.homeTabAnimateImageView setImage:[UIImage imageNamed:@"tabbar_home_selecetedLogo"]]; 114 | // /** 第二种方案 默认显示第一个cell 所以不用在这里设置图片 */ 115 | 116 | // 如果本次点击和上次是同一个tab 都是第0个,则执行push动画,否则执行放大缩小动画 117 | if (lastSelectIndex == index) { 118 | if (self.flag) { 119 | // 如果已经是火箭状态,则点击切换logo,且发通知 让首页滑到顶部 120 | [self pushHomeTabAnimationDown]; 121 | [[NSNotificationCenter defaultCenter] postNotificationName:@"kPushDownAnimationScrollTopNotification" object:nil]; 122 | } 123 | }else { 124 | [self animationWithHomeTab]; 125 | } 126 | }else { 127 | [self.imageView setImage:[UIImage imageNamed:normalImage]]; 128 | self.homeTabSelectedBgView.hidden = YES; 129 | self.imageView.hidden = self.titleLabel.hidden = NO; 130 | } 131 | }else { 132 | // 其他tab 133 | self.homeTabSelectedBgView.hidden = YES; 134 | self.imageView.hidden = self.titleLabel.hidden = NO; 135 | if (selected) { 136 | [self.imageView setImage:[UIImage imageNamed:selectedImage]]; 137 | self.titleLabel.textColor = [self colorFromHexRGB:@"18A2FF"]; 138 | // 如果本次点击和上次是同一个tab 则无反应,否则执行放大缩小动画 139 | if (lastSelectIndex != index) { 140 | [self animationWithNormalTab]; 141 | } 142 | }else { 143 | [self.imageView setImage:[UIImage imageNamed:normalImage]]; 144 | self.titleLabel.textColor = [self colorFromHexRGB:@"575D66"]; 145 | } 146 | } 147 | } 148 | 149 | /** tab之间切换动画 */ 150 | - (void)animationWithHomeTab { 151 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 152 | animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 153 | animation.duration = 0.2f; 154 | animation.fromValue = [NSNumber numberWithFloat:0.5f]; 155 | animation.toValue = [NSNumber numberWithFloat:1.f]; 156 | [self.homeTabSelectedBgView.layer addAnimation:animation forKey:nil]; 157 | } 158 | 159 | - (void)animationWithNormalTab { 160 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 161 | animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 162 | animation.duration = 0.25f; 163 | animation.fromValue = [NSNumber numberWithFloat:0.5f]; 164 | animation.toValue = [NSNumber numberWithFloat:1.f]; 165 | [self.imageView.layer addAnimation:animation forKey:nil]; 166 | [self.titleLabel.layer addAnimation:animation forKey:nil]; 167 | } 168 | 169 | // push动画,火箭头出来 170 | -(void)pushHomeTabAnimationUp { 171 | self.flag = YES; 172 | // /** 第一种方案 */ 173 | // [self.homeTabAnimateImageView setImage:[UIImage imageNamed:@"tabbar_home_selecetedPush"]]; 174 | // CATransition *animation = [CATransition animation]; 175 | // animation.type = kCATransitionPush;//设置动画的类型 176 | // animation.subtype = kCATransitionFromTop; //设置动画的方向 177 | // animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 178 | // animation.duration = 0.25f; 179 | // [self.homeTabAnimateImageView.layer addAnimation:animation forKey:@"pushAnimation"]; 180 | 181 | /** 第二种方案 */ 182 | [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:1 inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES]; 183 | } 184 | 185 | // push动画,火箭头落下 186 | -(void)pushHomeTabAnimationDown { 187 | self.flag = NO; 188 | // /** 第一种方案 */ 189 | // [self.homeTabAnimateImageView setImage:[UIImage imageNamed:@"tabbar_home_selecetedLogo"]]; 190 | // CATransition *animation = [CATransition animation]; 191 | // animation.type = kCATransitionPush;//设置动画的类型 192 | // animation.subtype = kCATransitionFromBottom; //设置动画的方向 193 | // animation.duration = 0.25f; 194 | // [self.homeTabAnimateImageView.layer addAnimation:animation forKey:@"pushAnimation"]; 195 | 196 | /** 第二种方案 */ 197 | [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES]; 198 | } 199 | 200 | 201 | #pragma mark ----------- lazy Load ------------- 202 | 203 | - (UILabel *)titleLabel { 204 | if (!_titleLabel) { 205 | _titleLabel = [[UILabel alloc] init]; 206 | _titleLabel.font = [UIFont systemFontOfSize:10]; 207 | _titleLabel.textColor = [self colorFromHexRGB:@"575D66"]; 208 | _titleLabel.textAlignment = NSTextAlignmentCenter; 209 | } 210 | return _titleLabel; 211 | } 212 | 213 | - (UIImageView *)imageView { 214 | if (!_imageView) { 215 | _imageView = [[UIImageView alloc] init]; 216 | _imageView.userInteractionEnabled = YES; 217 | } 218 | return _imageView; 219 | } 220 | 221 | - (UIImageView *)homeTabAnimateImageView { 222 | if (!_homeTabAnimateImageView) { 223 | _homeTabAnimateImageView = [[UIImageView alloc] init]; 224 | _homeTabAnimateImageView.userInteractionEnabled = YES; 225 | } 226 | return _homeTabAnimateImageView; 227 | } 228 | 229 | - (UIView *)homeTabSelectedBgView { 230 | if (!_homeTabSelectedBgView) { 231 | _homeTabSelectedBgView = [UIImageView new]; 232 | _homeTabSelectedBgView.userInteractionEnabled = YES; 233 | _homeTabSelectedBgView.hidden = YES; 234 | } 235 | return _homeTabSelectedBgView; 236 | } 237 | 238 | - (UICollectionView *)collectionView { 239 | if (!_collectionView) { 240 | UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; 241 | flowLayout.itemSize = CGSizeMake(42.f, 42.f); 242 | flowLayout.minimumInteritemSpacing = 0; 243 | flowLayout.minimumLineSpacing = 0; 244 | flowLayout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0); 245 | _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:flowLayout]; 246 | _collectionView.delegate = self; 247 | _collectionView.dataSource = self; 248 | _collectionView.showsVerticalScrollIndicator = NO; 249 | _collectionView.backgroundColor = [UIColor clearColor]; 250 | _collectionView.pagingEnabled = YES; 251 | _collectionView.scrollEnabled = NO; 252 | } 253 | return _collectionView; 254 | } 255 | 256 | 257 | // 16进制颜色 258 | - (UIColor *) colorFromHexRGB:(NSString *) inColorString { 259 | //删除字符串中的空格 260 | NSString *cString = [[inColorString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString]; 261 | // String should be 6 or 8 characters 262 | if ([cString length] < 6) return [UIColor blackColor]; 263 | // strip 0X if it appears 264 | //如果是0x开头的,那么截取字符串,字符串从索引为2的位置开始,一直到末尾 265 | if ([cString hasPrefix:@"0X"]) 266 | cString = [cString substringFromIndex:2]; 267 | 268 | //如果是#开头的,那么截取字符串,字符串从索引为1的位置开始,一直到末尾 269 | if ([cString hasPrefix:@"#"]) 270 | cString = [cString substringFromIndex:1]; 271 | 272 | if ([cString length] != 6&&[cString length] != 8) return [UIColor blackColor]; 273 | 274 | if([cString length] == 8){ 275 | NSRange range; 276 | range.location = 0; 277 | range.length = 2; 278 | NSString *rString = [cString substringWithRange:range]; 279 | 280 | range.location = 2; 281 | NSString *gString = [cString substringWithRange:range]; 282 | 283 | range.location = 4; 284 | NSString *bString = [cString substringWithRange:range]; 285 | 286 | range.location = 6; 287 | NSString *aString = [cString substringWithRange:range]; 288 | 289 | // Scan values 290 | unsigned int r, g, b, a; 291 | [[NSScanner scannerWithString:rString] scanHexInt:&r]; 292 | [[NSScanner scannerWithString:gString] scanHexInt:&g]; 293 | [[NSScanner scannerWithString:bString] scanHexInt:&b]; 294 | [[NSScanner scannerWithString:aString] scanHexInt:&a]; 295 | return [UIColor colorWithRed:((float) r / 255.0f) 296 | green:((float) g / 255.0f) 297 | blue:((float) b / 255.0f) 298 | alpha:((float) a / 255.0f)]; 299 | } 300 | // Separate into r, g, b substrings 301 | NSRange range; 302 | range.location = 0; 303 | range.length = 2; 304 | NSString *rString = [cString substringWithRange:range]; 305 | 306 | range.location = 2; 307 | NSString *gString = [cString substringWithRange:range]; 308 | 309 | range.location = 4; 310 | NSString *bString = [cString substringWithRange:range]; 311 | 312 | // Scan values 313 | unsigned int r, g, b; 314 | [[NSScanner scannerWithString:rString] scanHexInt:&r]; 315 | [[NSScanner scannerWithString:gString] scanHexInt:&g]; 316 | [[NSScanner scannerWithString:bString] scanHexInt:&b]; 317 | 318 | return [UIColor colorWithRed:((float) r / 255.0f) 319 | green:((float) g / 255.0f) 320 | blue:((float) b / 255.0f) 321 | alpha:1.0f]; 322 | } 323 | 324 | @end 325 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/TabBar/WMTabBarItemCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // WMTabBarItemCell.h 3 | // Micropulse 4 | // 5 | // Created by Climb 王 on 2019/3/20. 6 | // Copyright © 2019 iChoice. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface WMTabBarItemCell : UICollectionViewCell 14 | 15 | - (void)configItemImageString:(NSString *)imgString; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/TabBar/WMTabBarItemCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // WMTabBarItemCell.m 3 | // Micropulse 4 | // 5 | // Created by Climb 王 on 2019/3/20. 6 | // Copyright © 2019 iChoice. All rights reserved. 7 | // 8 | 9 | #import "WMTabBarItemCell.h" 10 | 11 | @interface WMTabBarItemCell () 12 | 13 | @property (nonatomic, strong) UIImageView *imageView; 14 | 15 | @end 16 | 17 | @implementation WMTabBarItemCell 18 | 19 | - (instancetype)initWithFrame:(CGRect)frame { 20 | self = [super initWithFrame:frame]; 21 | if (self) { 22 | 23 | self.imageView = [UIImageView new]; 24 | [self.contentView addSubview:self.imageView]; 25 | self.imageView.frame = CGRectMake(0, 0, 42.f, 42.f); 26 | self.imageView.contentMode = UIViewContentModeCenter; 27 | } 28 | return self; 29 | } 30 | 31 | - (void)configItemImageString:(NSString *)imgString { 32 | [self.imageView setImage:[UIImage imageNamed:imgString]]; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/ThirdViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ThirdViewController.h 3 | // TaobaoTabBarDemo 4 | // 5 | // Created by Climb 王 on 2019/3/22. 6 | // Copyright © 2019 Climb 王. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ThirdViewController : UIViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/ThirdViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ThirdViewController.m 3 | // TaobaoTabBarDemo 4 | // 5 | // Created by Climb 王 on 2019/3/22. 6 | // Copyright © 2019 Climb 王. All rights reserved. 7 | // 8 | 9 | #import "ThirdViewController.h" 10 | 11 | @interface ThirdViewController () 12 | 13 | @end 14 | 15 | @implementation ThirdViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | 20 | self.title = @"知识"; 21 | [self.view setBackgroundColor:[UIColor redColor]]; 22 | } 23 | 24 | /* 25 | #pragma mark - Navigation 26 | 27 | // In a storyboard-based application, you will often want to do a little preparation before navigation 28 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 29 | // Get the new view controller using [segue destinationViewController]. 30 | // Pass the selected object to the new view controller. 31 | } 32 | */ 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /TaobaoTabBarDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // TaobaoTabBarDemo 4 | // 5 | // Created by Climb 王 on 2019/3/22. 6 | // Copyright © 2019 Climb 王. 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 | -------------------------------------------------------------------------------- /TaobaoTabBarDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /TaobaoTabBarDemoTests/TaobaoTabBarDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // TaobaoTabBarDemoTests.m 3 | // TaobaoTabBarDemoTests 4 | // 5 | // Created by Climb 王 on 2019/3/22. 6 | // Copyright © 2019 Climb 王. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TaobaoTabBarDemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation TaobaoTabBarDemoTests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | } 20 | 21 | - (void)tearDown { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | - (void)testExample { 26 | // This is an example of a functional test case. 27 | // Use XCTAssert and related functions to verify your tests produce the correct results. 28 | } 29 | 30 | - (void)testPerformanceExample { 31 | // This is an example of a performance test case. 32 | [self measureBlock:^{ 33 | // Put the code you want to measure the time of here. 34 | }]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /TaobaoTabBarDemoUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /TaobaoTabBarDemoUITests/TaobaoTabBarDemoUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // TaobaoTabBarDemoUITests.m 3 | // TaobaoTabBarDemoUITests 4 | // 5 | // Created by Climb 王 on 2019/3/22. 6 | // Copyright © 2019 Climb 王. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TaobaoTabBarDemoUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation TaobaoTabBarDemoUITests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | 20 | // In UI tests it is usually best to stop immediately when a failure occurs. 21 | self.continueAfterFailure = NO; 22 | 23 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 24 | [[[XCUIApplication alloc] init] launch]; 25 | 26 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 27 | } 28 | 29 | - (void)tearDown { 30 | // Put teardown code here. This method is called after the invocation of each test method in the class. 31 | } 32 | 33 | - (void)testExample { 34 | // Use recording to get started writing UI tests. 35 | // Use XCTAssert and related functions to verify your tests produce the correct results. 36 | } 37 | 38 | @end 39 | --------------------------------------------------------------------------------