改造 UITabBarController
之前看到网上有不少同学自己实现了一些别具一格的系统控件,有一些做得很漂亮。今天我看到了一个UITabBarController的自定义实现,于是我也自己实现了一个TabBarController; 与其他自定义的实现不同,我这个实现自己不新增任何类,也不添加任何资源文件(如图片),完全靠改造系统的UITabBarController实现,在这里我自定义了一个继承UITabBarController的类RZTabBarController(其实也可以不定义它,但是处于个人的私心,我还是用我的名字前缀命名他吧……^_^……)。好,闲话少叙,贴出我的实现代码:
//
// RZTabBarController.h
// CustomTabBarController
//
#import <UIKit/UIKit.h>
@interface RZTabBarController : UITabBarController <UITabBarControllerDelegate> {
@private
NSUInteger lastSelectedIndex;
}
@end
在这个实现文件中我为了不让它感觉太空旷就加了一个私有变量 lastSelectedIndex 我们将在实现文件中用到它,动然如果我们不自定义一个新的类,我们完全可以将它作为一个全局静态变量声明在实现文件中。
//
// RZTabBarController.m
// CustomTabBarController
//
#import "RZTabBarController.h"
#import <QuartzCore/QuartzCore.h>
@implementation RZTabBarController
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
self.delegate = self;
}
return self;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
self.delegate = self;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#pragma mark -
#pragma mark UITabBarControllerDelegate
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
NSInteger index = tabBarController.selectedIndex;
if (index > 4) {
index = 4;
}
UIControl *selectedItem = [[tabBarController.tabBar subviews] objectAtIndex:index];
UIView *indicatorView = [selectedItem valueForKey:@"_selectedIndicator"];
NSInteger distanceIndex = lastSelectedIndex - index;
CGRect originFrame = indicatorView.frame;
CGRect customFrame = indicatorView.frame;
customFrame.origin.x = distanceIndex * customFrame.size.width;
indicatorView.frame = customFrame;
[UIView beginAnimations:nil context:UIGraphicsGetCurrentContext()];
[UIView setAnimationDuration:0.25];
indicatorView.frame = originFrame;
[UIView commitAnimations];
CATransition *animation = [CATransition animation];
animation.timingFunction = UIViewAnimationCurveEaseInOut;
animation.subtype = kCATransitionFromBottom;
animation.duration = 0.25;
UIImageView *imageView = nil;
NSArray *subviews = [selectedItem subviews];
if ([subviews count] > 2) {
imageView = [subviews objectAtIndex:1];
} else {
imageView = [subviews objectAtIndex:0];
}
animation.type = @"rippleEffect";
[imageView.layer addAnimation:animation forKey:@"anmation"];
UILabel *label = [selectedItem valueForKey:@"_label"];
animation.type = @"cube";
[label.layer addAnimation:animation forKey:@"anmation"];
lastSelectedIndex = index;
}
- (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed {
NSArray *array = tabBarController.tabBar.subviews;
array = [array sortedArrayUsingComparator:^(id control1, id control2) {
NSComparisonResult result = NSOrderedSame;
if (((UIControl *)control1).frame.origin.x > ((UIControl *)control2).frame.origin.x) {
result = NSOrderedDescending;
} else if (((UIControl *)control1).frame.origin.x == ((UIControl *)control2).frame.origin.x) {
result = NSOrderedSame;
} else if (((UIControl *)control1).frame.origin.x < ((UIControl *)control2).frame.origin.x) {
result = NSOrderedAscending;
}
return result;
}];
[tabBarController.tabBar setValue:array forKey:@"_subviewCache"];
}
@end
其实在实现文件中我也只是对UITabBarController的点代理方法进行了个实现,代码如是很多相信大家看到后就自然明白了,可能唯一比较高级的一点就是用到了KeyValueCoding编程,但是使用这个东西的使用我已经在前面的随笔中也已经讲道了,这里是相同的作用。
因为这个一个动态的过程,我就没有办法给大家贴出图来了,想要试试的同学可以将我的代码粘贴一下。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步