这是得物iOS开发一道面试题,要求详细描述自定义Tabbar

UITabBarController也可以轻松地管理多个控制器,轻松完成控制器之间的切换,UITabBarController的展现形式就是平时大家手机上使用的APP界面底部菜单通用样式。

UITabBarController的使用:

1.使用步骤:

(1)初始化UITabBarController

(2)设置UIWindow的rootViewController为UITabBarController

(3)创建相应的子控制器(viewcontroller)

(4)把子控制器添加到UITabBarController

当我们初始化时为UITabbarController添加两个控制器时,我们利用Xcode看到,界面底部出现了一个UITabBar菜单栏,UITabBar上面添加了响应的UITabbarItem,实际就是添加了对应的UIButton。

添加几个控制器,UITabbar上面就有几个UITabBarButton,他们一一对应。每个控制器都有一个tabBarItem,设置tabBarItem在normal和select两种状态下的title和image,实现UI效果。

 这种方式实现了普通UITabbar菜单效果,如果需要实现比如中间按钮凸起效果,就要自定义UITabBar了。

自定义UITabBar,实现按钮凸起效果

步骤:

1.自定义UIButton(代替系统UITabBar上面的UITabBarButton)

2.自定义UITabBar(UITabBar的一些封装)

3.自定义UITabbarController(UITabbarController的封装)

代码如下:

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSUInteger, CustomTabBarItemType) {
    CustomTabBarItemNormal = 0,
    CustomTabBarItemRise,
};

extern NSString *const CustomTabBarItemAttributeTitle;// NSString
extern NSString *const CustomTabBarItemAttributeNormalImageName;// NSString
extern NSString *const CustomTabBarItemAttributeSelectedImageName;// NSString
extern NSString *const CustomTabBarItemAttributeType;// NSNumber, CustomTabBarItemType

@interface CustomTabBarItem : UIButton

@property (nonatomic, assign) CustomTabBarItemType tabBarItemType;

@end

NS_ASSUME_NONNULL_END

#import "CustomTabBarItem.h"

NSString *const CustomTabBarItemAttributeTitle = @"CustomTabBarItemAttributeTitle";
NSString *const CustomTabBarItemAttributeNormalImageName = @"CustomTabBarItemAttributeNormalImageName";
NSString *const CustomTabBarItemAttributeSelectedImageName = @"CustomTabBarItemAttributeSelectedImageName";
NSString *const CustomTabBarItemAttributeType = @"CustomTabBarItemAttributeType";

@implementation CustomTabBarItem

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    
    if (self) {
        [self config];
    }
    
    return self;
}

- (instancetype)init {
    self = [super init];
    
    if (self) {
        [self config];
    }
    
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    
    if (self) {
        [self config];
    }
    
    return self;
}

- (void)config {
    /**
     UIButton.Configuration是一个新的结构体,
     它指定按钮及其内容的外观和行为。它有许多与按钮外观和内容相关的属性,如cornerStyle、baseForegroundColor、baseBackgroundColor、buttonSize、title、image、subtitle、titlePadding、imagePadding、contentInsets、imagePlacement等。
     */
    self.adjustsImageWhenHighlighted = NO;
    self.imageView.contentMode = UIViewContentModeScaleAspectFit;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    [self.titleLabel sizeToFit];
    CGSize titleSize = self.titleLabel.frame.size;

    CGSize imageSize = [self imageForState:UIControlStateNormal].size;

    if (imageSize.width != 0 && imageSize.height != 0) {
        /**image布局为image底部距离lable顶部距离为5*/
        CGFloat imageViewCenterY = CGRectGetHeight(self.frame) - 3 - titleSize.height - imageSize.height / 2 - 5;
        self.imageView.center = CGPointMake(CGRectGetWidth(self.frame) / 2, imageViewCenterY);
    } else {
        CGPoint imageViewCenter = self.imageView.center;
        imageViewCenter.x = CGRectGetWidth(self.frame) / 2;
        imageViewCenter.y = (CGRectGetHeight(self.frame) - titleSize.height) / 2;
        self.imageView.center = imageViewCenter;
    }
    /**lable距离底部是3*/
    CGPoint labelCenter = CGPointMake(CGRectGetWidth(self.frame) / 2, CGRectGetHeight(self.frame) - 3 - titleSize.height / 2);
    self.titleLabel.center = labelCenter;
    
}

@end
#import <UIKit/UIKit.h>
#import "CustomTabBarItem.h"

NS_ASSUME_NONNULL_BEGIN

@protocol CustomTabBarDelegate <NSObject>

- (void)tabBarDidSelectedRiseButton;

@end

@interface CustomTabBar : UIView

@property (nonatomic, copy) NSArray<NSDictionary *> *tabBarItemAttributes;

@property (nonatomic, weak) id <CustomTabBarDelegate> delegate;

@end

NS_ASSUME_NONNULL_END
#import "CustomTabBar.h"

@interface CustomTabBar ()

@property (strong, nonatomic) NSMutableArray *tabBarItems;

@end

@implementation CustomTabBar

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    
    if (self) {
        [self config];
    }
    
    return self;
}

#pragma mark - Private Method

- (void)config {
    self.backgroundColor = [UIColor whiteColor];
    
    UIImageView *topLine = [[UIImageView alloc] initWithFrame:CGRectMake(0, -5, [UIScreen mainScreen].bounds.size.width, 5)];
    topLine.image = [UIImage imageNamed:@"tapbar_top_line"];
    [self addSubview:topLine];
}

- (void)setTabBarItemAttributes:(NSArray<NSDictionary *> *)tabBarItemAttributes {
    _tabBarItemAttributes = tabBarItemAttributes.copy;
    
    CGFloat itemWidth = ([UIScreen mainScreen].bounds.size.width) / _tabBarItemAttributes.count;
    CGFloat tabBarHeight = CGRectGetHeight(self.frame);
    NSInteger itemTag = 0;
    BOOL passedRiseItem = NO;
    
    _tabBarItems = [NSMutableArray arrayWithCapacity:_tabBarItemAttributes.count];
    for (id item in _tabBarItemAttributes) {
        if ([item isKindOfClass:[NSDictionary class]]) {
            NSDictionary *itemDict = (NSDictionary *)item;
            CustomTabBarItemType type = [itemDict[CustomTabBarItemAttributeType] integerValue];
            CGRect frame = CGRectMake(itemTag * itemWidth + (passedRiseItem ? itemWidth : 0), 0, itemWidth, tabBarHeight);
            CustomTabBarItem *tabBarItem = [self tabBarItemWithFrame:frame
                                                               title:itemDict[CustomTabBarItemAttributeTitle]
                                                     normalImageName:itemDict[CustomTabBarItemAttributeNormalImageName]
                                                   selectedImageName:itemDict[CustomTabBarItemAttributeSelectedImageName] tabBarItemType:type];
            if (itemTag == 0) {
                tabBarItem.selected = YES;
            }
            [tabBarItem addTarget:self action:@selector(itemSelected:) forControlEvents:UIControlEventTouchUpInside];
            if (tabBarItem.tabBarItemType != CustomTabBarItemRise) {
                [tabBarItem setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
                [tabBarItem setTitleColor:[UIColor redColor] forState:UIControlStateSelected];
                tabBarItem.tag = itemTag;
                itemTag++;
            } else {
                [tabBarItem setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
                [tabBarItem setTitleColor:[UIColor greenColor] forState:UIControlStateSelected];
                passedRiseItem = YES;
            }
            
            [_tabBarItems addObject:tabBarItem];
            [self addSubview:tabBarItem];
        }
    }
    
}

- (void)itemSelected:(CustomTabBarItem *)sender {
    if (sender.tabBarItemType != CustomTabBarItemRise) {
        [self setSelectedIndex:sender.tag];
    } else {
        if (self.delegate) {
            if ([self.delegate respondsToSelector:@selector(tabBarDidSelectedRiseButton)]) {
                [self.delegate tabBarDidSelectedRiseButton];
            }
        }
    }
}

- (void)setSelectedIndex:(NSInteger)index {
    for (CustomTabBarItem *item in self.tabBarItems) {
        if (item.tag == index) {
            item.selected = YES;
        } else {
            item.selected = NO;
        }
    }
    
    UIWindow *keyWindow = [[[UIApplication sharedApplication] delegate] window];
    UITabBarController *tabBarController = (UITabBarController *)keyWindow.rootViewController;
    if (tabBarController) {
        tabBarController.selectedIndex = index;
    }
}


- (CustomTabBarItem *)tabBarItemWithFrame:(CGRect)frame title:(NSString *)title normalImageName:(NSString *)normalImageName selectedImageName:(NSString *)selectedImageName tabBarItemType:(CustomTabBarItemType)tabBarItemType {
    CustomTabBarItem *item = [[CustomTabBarItem alloc] initWithFrame:frame];
    [item setTitle:title forState:UIControlStateNormal];
    [item setTitle:title forState:UIControlStateSelected];
    item.titleLabel.font = [UIFont systemFontOfSize:8];
    UIImage *normalImage = [UIImage imageNamed:normalImageName];
    UIImage *selectedImage = [UIImage imageNamed:selectedImageName];
    [item setImage:normalImage forState:UIControlStateNormal];
    [item setImage:selectedImage forState:UIControlStateSelected];
    [item setTitleColor:[UIColor colorWithWhite:51 / 255.0 alpha:1] forState:UIControlStateNormal];
    [item setTitleColor:[UIColor colorWithWhite:51 / 255.0 alpha:1] forState:UIControlStateSelected];
    item.tabBarItemType = tabBarItemType;
    return item;
}
@interface CustomTabBarViewController ()<CustomTabBarDelegate>

@end

@implementation CustomTabBarViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // 修改tabbar背景
    if (@available(iOS 15.0, *)) {
        
        UITabBarAppearance *appearance = [UITabBarAppearance new];
        //tabBar背景颜色
        appearance.backgroundColor = [UIColor whiteColor];
        // 去掉半透明效果
        appearance.backgroundEffect = nil;

        self.tabBar.scrollEdgeAppearance = appearance;
        self.tabBar.standardAppearance = appearance;
        
    }else {
        [[UITabBar appearance] setBarTintColor:[UIColor whiteColor]];
    }
    [self initViewController];
    
}

-(void)initViewController{
   // [self.tabBar.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    
    FirstViewController *homePageVC = [[FirstViewController alloc] init];
    homePageVC.view.backgroundColor = [UIColor redColor];
    ThirdViewController *centerPageVC = [[ThirdViewController alloc] init];
    centerPageVC.view.backgroundColor = [UIColor greenColor];
    self.viewControllers = @[homePageVC,centerPageVC];
    

    CustomTabBar *customTabBarView = [[CustomTabBar alloc] initWithFrame:self.tabBar.bounds];

    customTabBarView.tabBarItemAttributes = @[@{CustomTabBarItemAttributeTitle : @"首页", CustomTabBarItemAttributeNormalImageName : @"tab1", CustomTabBarItemAttributeSelectedImageName : @"tab1_select", CustomTabBarItemAttributeType : @(CustomTabBarItemNormal)},
                                   @{CustomTabBarItemAttributeTitle : @"访客邀请", CustomTabBarItemAttributeNormalImageName : @"tab2_select", CustomTabBarItemAttributeSelectedImageName : @"tab2_select", CustomTabBarItemAttributeType : @(CustomTabBarItemRise)},
                                   @{CustomTabBarItemAttributeTitle : @"我的", CustomTabBarItemAttributeNormalImageName : @"tab3", CustomTabBarItemAttributeSelectedImageName : @"tab3_select", CustomTabBarItemAttributeType : @(CustomTabBarItemNormal)}];
    customTabBarView.delegate = self;
   [self.tabBar addSubview:customTabBarView];
    
    
    
}

- (void)tabBarDidSelectedRiseButton {
    NSLog(@"点击了中间tabbar");
    [[NSNotificationCenter defaultCenter] postNotificationName:@"customBarNotification" object:nil];
}

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐