Introduction to the use of VTMagic


There are a lot of developers have tried to imitate a similar NetEase, Tencent and other applications menu paging components, but the concept of its design, mostly rough, is not conducive to the subsequent maintenance and expansion. Wondering for a long time, finally decided to open this took nearly two years of polished framework, so that we can quickly achieve similar needs, without having to waste a lot of energy in the process of repeat create the wheel, VTMagic is currently in a number of projects and stable operation for more than a year.


  1. Each page is a complete controller, friendly support for personalized customization;
  2. Page switching can accurately trigger the corresponding life cycle method (viewWillAppear:, etc.), to facilitate the management of their respective page data loading and other logical processing;
  3. The navigation bar supports a variety of layout styles, including adaptive text width, auto split, center layout, and custom width;
  4. Can be obtained in any sub controller, through the self.magicController to obtain the most recent top level controller, easy to deal with the level of logic;
  5. Support embedded WebView, if the sliding gestures can not respond, you can solve by handlePanGesture;
  6. Support page reuse and screen switch;
  7. See the VTMagicView.h file for more features.
Introduction to the use of VTMagic
preview map


VTMagic support CocoaPods, just add the following code in the Podfile file can be:

Pod "VTMagic"

Note: in the process of using the Pod may meet cannot be found to VTMagic, this is because VTMagic recently uploaded to CocoaPods, you need to update the local Pod warehouse: $pod repo udpate, or you can also try to upgrade the Pod:$sudo gem install cocoapods setup $pod.

Of course, if your project does not support Pod for the time being, you can download VTMagic, and then drag the folder VTMagic to your project, and then the last import header file VTMagic.h.

Import "VTMagic.h"


There are two main ways to integrate VTMagic:
1 directly instantiate the VTMagicController object, and then add it to the current controller.

- (void) viewDidLoad viewDidLoad] [self {[super; addChildViewController:self.magicController]; [self.view addSubview:_magicController.view]; [_magicController.magicView reloadData];} - (VTMagicController * magicController) {if (_magicController! = [[VTMagicController) {_magicController 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; _magicCon Troller.magicView.delegate = self;} return _magicController;}

2 inheritance VTMagicController, and then complete the corresponding configuration in viewDidLoad.

#import "VTMagicController.h" @interface ViewController: VTMagicController @end
@implementation ViewController - viewDidLoad [super viewDidLoad] (void) {self.magicView.navigationColor = [UIColor; self.magicView.sliderColor = whiteColor]; [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 protocol

Regardless of which of the above methods are integrated, we need to implement the data source protocol < VTMagicViewDataSource > mainly in the following three ways:

- (NSArray< NSString *> menuTitlesForMagicView: (VTMagicView * *)) magicView {return _menuList;} - (UIButton *) magicView: (* VTMagicView) magicView menuItemAtIndex: (NSUInteger itemIndex) {static NSString = *itemIdentifier @ *menuItem = "itemIdentifier"; UIButton [magicView dequeueReusableItemWithIdentifier:itemIdentifier]; if (menuItem! = [UIButton) {menuItem 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: (VTMagic) View *) magicView viewControllerAtPage: pageIndex (NSUInteger) {if (0 = = pageIndex) {static NSString = *recomId @ *recomViewController = "recom.identifier"; VTRecomViewController [magicView dequeueReusablePageWithIdentifier:recomId]; if (recomViewController! = [[VTRecomViewController) {recomViewController alloc] init]}}; return recomViewController; static NSString = *gridId @ VTGridViewController = "grid.identifier"; *gridViewController [magicView dequeueReusablePageWithIdentifier:gridId]; if (gridViewController! = [[VTGridViewController) {gridViewController alloc] init]}; return gridViewController;}

Integration effect

Introduction to the use of VTMagic
default style
Introduction to the use of VTMagic
bubble style
Introduction to the use of VTMagic

Important agreement

In addition to the data source protocol < VTMagicViewDataSource > outside, the important protocol in VTMagic and < VTMagicViewDelegate > and < VTMagicReuseProtocol >.

VTMagicViewDelegate protocol

Mainly used to handle page switching events in the main controller. When the page is displayed or disappear, will trigger viewDidAppeare: and viewDidDisappeare: proxy method; when menuItem is clicked, will trigger the didSelectItemAtIndex: method.

- (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) {NSLog (@ pageIndex pageIndex:%ld viewDidDisappeare:%@, pageIndex, viewController.view);} - (void) magicView: (VTMagicView *) magicView didSelectItemAtIndex: (NSUInteger itemIndex) {NSLog (@ didSelectItemAtIndex:%ld, itemIndex (long));}


When the sub controller is reused, remove the old data, modify the page offset and other logical processing.

- (void) vtm_prepareForReuse {NSLog (@ clear data if needed:%@), self); [self.collectionView setContentOffset:CGPointZero];}


  • You can be in any sub controller, the main controller to obtain the upper layer recently by self.magicController, magicController &lt VTMagicProtocol &gt follow the agreement;;, in order to complete some cross level logic to handle the necessary, the premise is that you need to import < VTMagic/ VTMagic.h> file. NSInteger currentPage = self.magicController.currentPage; UIViewController = self.magicController.currentViewController = *viewController;
  • Switch to the specified page, page switching in two ways:
[self.magicView switchToPage:3 animated:YES]; [self.magicController switchToPage:3 animated:YES];
  • There are two ways to get the specified page controller:
UIViewController *viewController = [self.magicView viewControllerAtPage:3]; UIViewController = [self.magicController viewControllerAtPage:3] *viewController;

Concluding remarks

Finally, according to the Convention, if you love this one, please leave a star, this is to encourage and support for the biggest, thanks!!! If you have a better idea or plan, also welcome to submit pull request!!! GitHub address

The next article: introduction to the use of VTMagic (two)