VTMagic
有很多开发者曾尝试模仿写出类似网易、腾讯等应用的菜单分页组件,但遍观其设计,大多都比较粗糙,不利于后续维护和扩展。琢磨良久,最终决定开源这个耗时近两年打磨而成的框架,以便大家可以快速实现类似需求,而不用把大量的精力浪费在重复造轮子的过程中,VTMagic目前在多个项目中稳定运行一年多。
特性概要
- 每个页面都是一个完整的控制器,友好支持个性化自定义;
- 页面切换时能准确触发相应的生命周期方法(viewWillAppear:等),便于管理各自页面的数据加载和其它逻辑处理;
- 导航栏支持多种布局样式,包括自适应文本宽度、自动平分、居中布局以及自定义宽度等;
- 可以在任意子控制器中,通过self.magicController获取最近的上层主控制器,方便跨层级处理逻辑;
- 支持内嵌webview,若滑动手势无法响应,可以通过handlePanGesture:解决;
- 支持页面重用和横竖屏切换;
- 更多特性请参见
VTMagicView.h
文件。
预览图
使用
VTMagic支持CocoaPods,只需在Podfile文件中添加如下代码即可:
1 |
pod "VTMagic" |
集成
关于VTMagic的集成方法主要有以下两种:
1. 直接实例化VTMagicController对象,然后添加到当前控制器中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
- (void)viewDidLoad { [super viewDidLoad]; [self addChildViewController:self.magicController]; [self.view addSubview:_magicController.view]; [_magicController didMoveToParentViewController:self]; [_magicController.magicView reloadData]; } - (VTMagicController *)magicController { if (!_magicController) { _magicController = [[VTMagicController alloc] init]; _magicController.magicView.navigationColor = [UIColor whiteColor]; _magicController.magicView.sliderColor = [UIColor redColor]; _magicController.magicView.layoutStyle = VTLayoutStyleDivide; _magicController.magicView.switchStyle = VTSwitchStyleDefault; _magicController.magicView.navigationHeight = 40.f; _magicController.magicView.dataSource = self; _magicController.magicView.delegate = self; } return _magicController; } |
2. 继承VTMagicController,然后在viewDidLoad中完成相应配置。
1 2 3 4 5 |
#import "VTMagicController.h" @interface ViewController : VTMagicController @end |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.magicView.navigationColor = [UIColor whiteColor]; self.magicView.sliderColor = [UIColor redColor]; self.magicView.layoutStyle = VTLayoutStyleDefault; self.magicView.switchStyle = VTSwitchStyleDefault; self.magicView.navigationHeight = 40.f; self.magicView.dataSource = self; self.magicView.delegate = self; [self.magicView reloadData]; } |
VTMagicViewDataSource协议
不管是通过以上哪种方法集成的,都需要实现数据源协议< VTMagicViewDataSource >
,主要有以下三个方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
- (NSArray<NSString *> *)menuTitlesForMagicView:(VTMagicView *)magicView { return _menuList; } - (UIButton *)magicView:(VTMagicView *)magicView menuItemAtIndex:(NSUInteger)itemIndex { static NSString *itemIdentifier = @"itemIdentifier"; UIButton *menuItem = [magicView dequeueReusableItemWithIdentifier:itemIdentifier]; if (!menuItem) { menuItem = [UIButton buttonWithType:UIButtonTypeCustom]; [menuItem setTitleColor:RGBCOLOR(50, 50, 50) forState:UIControlStateNormal]; [menuItem setTitleColor:RGBCOLOR(169, 37, 37) forState:UIControlStateSelected]; menuItem.titleLabel.font = [UIFont fontWithName:@"Helvetica" size:16.f]; } return menuItem; } - (UIViewController *)magicView:(VTMagicView *)magicView viewControllerAtPage:(NSUInteger)pageIndex { if (0 == pageIndex) { static NSString *recomId = @"recom.identifier"; VTRecomViewController *recomViewController = [magicView dequeueReusablePageWithIdentifier:recomId]; if (!recomViewController) { recomViewController = [[VTRecomViewController alloc] init]; } return recomViewController; } static NSString *gridId = @"grid.identifier"; VTGridViewController *gridViewController = [magicView dequeueReusablePageWithIdentifier:gridId]; if (!gridViewController) { gridViewController = [[VTGridViewController alloc] init]; } return gridViewController; } |
集成效果
下划线样式
气泡样式
其它
重要协议
除了数据源协议< VTMagicViewDataSource >
外 ,VTMagic中的重要协议还有< VTMagicViewDelegate >
和< VTMagicReuseProtocol >
。前者用于在主控制器中处理页面切换事件;后者用于子控制器被重用时,清除旧数据等逻辑处理。
VTMagicViewDelegate协议
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
- (void)magicView:(VTMagicView *)magicView viewDidAppeare:(UIViewController *)viewController atPage:(NSUInteger)pageIndex { NSLog(@"pageIndex:%ld viewDidAppeare:%@",pageIndex, viewController.view); } - (void)magicView:(VTMagicView *)magicView viewDidDisappeare:(UIViewController *)viewController atPage:(NSUInteger)pageIndex { NSLog(@"pageIndex:%ld viewDidDisappeare:%@",pageIndex, viewController.view); } - (void)magicView:(VTMagicView *)magicView didSelectItemAtIndex:(NSUInteger)itemIndex { NSLog(@"didSelectItemAtIndex:%ld", (long)itemIndex); } |
VTMagicReuseProtocol
1 2 3 4 |
- (void)vtm_prepareForReuse { NSLog(@"clear old data if needed:%@", self); } |
其它
- 你可以在任意子控制器中,通过self.magicController获取最近的上层主控制器,magicController遵循协议
< VTMagicProtocol >
,以便完成一些必要的跨层级的逻辑处理,前提是你需要import<VTMagic/VTMagic.h>
文件。