UITabBarController 虽然很强大,基本上也能满足常见的需求,但是用起来总没那么畅快。有时候,总有一些变态的需求,需要自定义。
之前也看过一些别人自定义的TabBarController,但是都不尽理想,准确的说,很多自定义的都是继承自UITabBarController的即是半自定义的。根本谈不上真正意义上的自定义。
今天就分析一个我认为比较好的自定义TabBarController.
tabBarItem,直观的显示,就是我们看到那几个点击来回切换的按键。当点击每一个选项的时候,选项就会有相应的变化,同时切换到对应的控制器界面。
有哪些属性和变化呢?
a. 本身基本属性:有选中/未选中图片、选中/未选中文字及颜色、选中/未选中背景色、有宽高大小位置偏移(供微调用);
b. 徽标显示:徽标值及其颜色大小、徽标图片、背景色
#import
@interface RDVTabBarItem : UIControl
/**
* itemHeight is an optional property. When set it is used instead of tabBar's height.
*/
@property CGFloat itemHeight;
#pragma mark - Title configuration
/**
* The title displayed by the tab bar item.
*/
@property (nonatomic, copy) NSString *title;
/**
* The offset for the rectangle around the tab bar item's title.
*/
@property (nonatomic) UIOffset titlePositionAdjustment;
/**
* For title's text attributes see
* https://developer.apple.com/library/ios/documentation/uikit/reference/NSString_UIKit_Additions/Reference/Reference.html
*/
/**
* The title attributes dictionary used for tab bar item's unselected state.
*/
@property (copy) NSDictionary *unselectedTitleAttributes;
/**
* The title attributes dictionary used for tab bar item's selected state.
*/
@property (copy) NSDictionary *selectedTitleAttributes;
#pragma mark - Image configuration
/**
* The offset for the rectangle around the tab bar item's image.
*/
@property (nonatomic) UIOffset imagePositionAdjustment;
/**
* The image used for tab bar item's selected state.
*/
- (UIImage *)finishedSelectedImage;
/**
* The image used for tab bar item's unselected state.
*/
- (UIImage *)finishedUnselectedImage;
/**
* Sets the tab bar item's selected and unselected images.
*/
- (void)setFinishedSelectedImage:(UIImage *)selectedImage withFinishedUnselectedImage:(UIImage *)unselectedImage;
#pragma mark - Background configuration
/**
* The background image used for tab bar item's selected state.
*/
- (UIImage *)backgroundSelectedImage;
/**
* The background image used for tab bar item's unselected state.
*/
- (UIImage *)backgroundUnselectedImage;
/**
* Sets the tab bar item's selected and unselected background images.
*/
- (void)setBackgroundSelectedImage:(UIImage *)selectedImage withUnselectedImage:(UIImage *)unselectedImage;
#pragma mark - Badge configuration
/**
* Text that is displayed in the upper-right corner of the item with a surrounding background.
*/
@property (nonatomic, copy) NSString *badgeValue;
/**
* Image used for background of badge.
*/
@property (strong) UIImage *badgeBackgroundImage;
/**
* Color used for badge's background.
*/
@property (strong) UIColor *badgeBackgroundColor;
/**
* Color used for badge's text.
*/
@property (strong) UIColor *badgeTextColor;
/**
* The offset for the rectangle around the tab bar item's badge.
*/
@property (nonatomic) UIOffset badgePositionAdjustment;
/**
* Font used for badge's text.
*/
@property (nonatomic) UIFont *badgeTextFont;
@end
2. 再来看TabBar
tabBar是一个视图,自然有视图的基本属性,里面有多个tabBarItem,所以必然有items个数的属性;有事件响应,所以有代理抛出接口
#import
@class RDVTabBar, RDVTabBarItem;
@protocol RDVTabBarDelegate
/**
* Asks the delegate if the specified tab bar item should be selected.
*/
- (BOOL)tabBar:(RDVTabBar *)tabBar shouldSelectItemAtIndex:(NSInteger)index;
/**
* Tells the delegate that the specified tab bar item is now selected.
*/
- (void)tabBar:(RDVTabBar *)tabBar didSelectItemAtIndex:(NSInteger)index;
@end
@interface RDVTabBar : UIView
/**
* The tab bar’s delegate object.
*/
@property (nonatomic, weak) id delegate;
/**
* The items displayed on the tab bar.
*/
@property (nonatomic, copy) NSArray *items;
/**
* The currently selected item on the tab bar.
*/
@property (nonatomic, weak) RDVTabBarItem *selectedItem;
/**
* backgroundView stays behind tabBar's items. If you want to add additional views,
* add them as subviews of backgroundView.
*/
@property (nonatomic, readonly) UIView *backgroundView;
/*
* contentEdgeInsets can be used to center the items in the middle of the tabBar.
*/
@property UIEdgeInsets contentEdgeInsets;
/**
* Sets the height of tab bar.
*/
- (void)setHeight:(CGFloat)height;
/**
* Returns the minimum height of tab bar's items.
*/
- (CGFloat)minimumContentHeight;
/*
* Enable or disable tabBar translucency. Default is NO.
*/
@property (nonatomic, getter=isTranslucent) BOOL translucent;
@end
TabBarController 里面有TabBar, 有默认选项,tabBarItem对应的View Controllers及其之间的关联。还有一些代理方法。故而
#import
#import "RDVTabBar.h"
@protocol RDVTabBarControllerDelegate;
@interface RDVTabBarController : UIViewController
/**
* The tab bar controller’s delegate object.
*/
@property (nonatomic, weak) id delegate;
/**
* An array of the root view controllers displayed by the tab bar interface.
*/
@property (nonatomic, copy) IBOutletCollection(UIViewController) NSArray *viewControllers;
/**
* The tab bar view associated with this controller. (read-only)
*/
@property (nonatomic, readonly) RDVTabBar *tabBar;
/**
* The view controller associated with the currently selected tab item.
*/
@property (nonatomic, weak) UIViewController *selectedViewController;
/**
* The index of the view controller associated with the currently selected tab item.
*/
@property (nonatomic) NSUInteger selectedIndex;
/**
* A Boolean value that determines whether the tab bar is hidden.
*/
@property (nonatomic, getter=isTabBarHidden) BOOL tabBarHidden;
/**
* Changes the visibility of the tab bar.
*/
- (void)setTabBarHidden:(BOOL)hidden animated:(BOOL)animated;
@end
@protocol RDVTabBarControllerDelegate
@optional
/**
* Asks the delegate whether the specified view controller should be made active.
*/
- (BOOL)tabBarController:(RDVTabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController;
/**
* Tells the delegate that the user selected an item in the tab bar.
*/
- (void)tabBarController:(RDVTabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController;
@end
@interface UIViewController (RDVTabBarControllerItem)
/**
* The tab bar item that represents the view controller when added to a tab bar controller.
*/
@property(nonatomic, setter = rdv_setTabBarItem:) RDVTabBarItem *rdv_tabBarItem;
/**
* The nearest ancestor in the view controller hierarchy that is a tab bar controller. (read-only)
*/
@property(nonatomic, readonly) RDVTabBarController *rdv_tabBarController;
@end
其实就是通过导航控制器来切换到对应编号的视图控制器。请看核心代码
- (BOOL)tabBar:(RDVTabBar *)tabBar shouldSelectItemAtIndex:(NSInteger)index {
if ([[self delegate] respondsToSelector:@selector(tabBarController:shouldSelectViewController:)]) {
if (![[self delegate] tabBarController:self shouldSelectViewController:[self viewControllers][index]]) {
return NO;
}
}
if ([self selectedViewController] == [self viewControllers][index]) {
if ([[self selectedViewController] isKindOfClass:[UINavigationController class]]) {
UINavigationController *selectedController = (UINavigationController *)[self selectedViewController];
if ([selectedController topViewController] != [selectedController viewControllers][0]) {
[selectedController popToRootViewControllerAnimated:YES];
}
}
return NO;
}
return YES;
}
限于篇幅,不直接贴出代码,
直接获取源码Demo:https://github.com/robbdimitrov/RDVTabBarController