VTMagic
有很多開(kāi)發(fā)者曾嘗試模仿寫(xiě)出類似網(wǎng)易媳搪、騰訊等應(yīng)用的菜單分頁(yè)組件铭段,但遍觀其設(shè)計(jì),大多都比較粗糙秦爆,不利于后續(xù)維護(hù)和擴(kuò)展序愚。琢磨良久,最終決定開(kāi)源這個(gè)耗時(shí)近兩年打磨而成的框架等限,以便大家可以快速實(shí)現(xiàn)類似需求爸吮,而不用把大量的精力浪費(fèi)在重復(fù)造輪子的過(guò)程中芬膝,VTMagic目前在多個(gè)項(xiàng)目中穩(wěn)定運(yùn)行一年多。
特性概要
- 每個(gè)頁(yè)面都是一個(gè)完整的控制器形娇,友好支持個(gè)性化自定義锰霜;
- 頁(yè)面切換時(shí)能準(zhǔn)確觸發(fā)相應(yīng)的生命周期方法(
viewWillAppear:
等),便于管理各自頁(yè)面的數(shù)據(jù)加載和其它邏輯處理桐早; - 導(dǎo)航欄支持多種布局樣式癣缅,包括自適應(yīng)文本寬度、自動(dòng)平分哄酝、居中布局以及自定義寬度等友存;
- 可以在任意子控制器中,通過(guò)
self.magicController
獲取最近的上層主控制器陶衅,方便跨層級(jí)處理邏輯屡立; - 支持內(nèi)嵌webview,若滑動(dòng)手勢(shì)無(wú)法響應(yīng)搀军,可以通過(guò)
handlePanGesture:
解決膨俐; - 支持頁(yè)面重用和橫豎屏切換;
- 更多特性請(qǐng)參見(jiàn)
VTMagicView.h
文件奕巍。
使用
VTMagic支持CocoaPods,只需在Podfile文件中添加如下代碼即可:
pod "VTMagic"
提示:在使用Pod的過(guò)程中可能會(huì)遇到無(wú)法搜到VTMagic的情況儒士,這是因?yàn)?a target="_blank" rel="nofollow">VTMagic最近才上傳到CocoaPods的止,你需要更新一下本地的Pod倉(cāng)庫(kù):$ pod repo udpate
,或者你也可以嘗試一下升級(jí)Pod:$ sudo gem install cocoapods
$ pod setup
着撩。
當(dāng)然诅福,假如你們的項(xiàng)目暫時(shí)還不支持Pod,你可以先下載VTMagic拖叙,然后再將文件夾VTMagic
拖到你們的項(xiàng)目里面氓润,最后再import頭文件VTMagic.h
即可。
import "VTMagic.h"
集成
關(guān)于VTMagic的集成方法主要有以下兩種:
1. 直接實(shí)例化VTMagicController對(duì)象薯鳍,然后添加到當(dāng)前控制器中咖气。
- (void)viewDidLoad
{
[super viewDidLoad];
[self addChildViewController:self.magicController];
[self.view addSubview:_magicController.view];
[_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中完成相應(yīng)配置挖滤。
#import "VTMagicController.h"
@interface ViewController : VTMagicController
@end
@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協(xié)議
不管是通過(guò)以上哪種方法集成的崩溪,都需要實(shí)現(xiàn)數(shù)據(jù)源協(xié)議< VTMagicViewDataSource >
,主要有以下三個(gè)方法:
- (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;
}
集成效果
重要協(xié)議
除了數(shù)據(jù)源協(xié)議< VTMagicViewDataSource >
外 斩松,VTMagic中的重要協(xié)議還有< VTMagicViewDelegate >
和< VTMagicReuseProtocol >
伶唯。
VTMagicViewDelegate協(xié)議
主要用于在主控制器中處理頁(yè)面切換事件。當(dāng)子頁(yè)面顯示或消失時(shí)惧盹,會(huì)觸發(fā)viewDidAppeare:
和viewDidDisappeare:
代理方法乳幸;當(dāng)menuItem被點(diǎn)擊時(shí)瞪讼,會(huì)觸發(fā)didSelectItemAtIndex:
方法。
- (void)magicView:(VTMagicView *)magicView viewDidAppeare:(__kindof UIViewController *)viewController atPage:(NSUInteger)pageIndex
{
NSLog(@"pageIndex:%ld viewDidAppeare:%@",pageIndex, viewController.view);
}
- (void)magicView:(VTMagicView *)magicView viewDidDisappeare:(__kindof 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
用于子控制器被重用時(shí)粹断,清除舊數(shù)據(jù)符欠、修正頁(yè)面偏移等邏輯處理。
- (void)vtm_prepareForReuse
{
NSLog(@"clear old data if needed:%@", self);
[self.collectionView setContentOffset:CGPointZero];
}
其它
- 你可以在任意子控制器中姿染,通過(guò)self.magicController獲取最近的上層主控制器背亥,magicController遵循協(xié)議
< VTMagicProtocol >
,以便完成一些必要的跨層級(jí)的邏輯處理悬赏,前提是你需要import<VTMagic/VTMagic.h>
文件狡汉。
NSInteger currentPage = self.magicController.currentPage;
UIViewController *viewController = self.magicController.currentViewController;
- 切換到指定頁(yè)面,頁(yè)面切換有兩種方式:
[self.magicView switchToPage:3 animated:YES];
[self.magicController switchToPage:3 animated:YES];
- 獲取指定頁(yè)面控制器闽颇,同樣有兩種方式:
UIViewController *viewController = [self.magicView viewControllerAtPage:3];
UIViewController *viewController = [self.magicController viewControllerAtPage:3];
結(jié)束語(yǔ)
最后盾戴,按照慣例,如果你喜歡這個(gè)輪子兵多,請(qǐng)留下一顆star尖啡,這是對(duì)作者最大的鼓勵(lì)和支持,拜謝J1臁P普丁!假如你有更好的想法或方案怠褐,也歡迎提交pull requestN钒稹!奈懒!GitHub地址