前几天面试,被问到如果让你自定义tabbar会怎样写。所以写了的demo给大家分享一下。
- 首先需要自定义一个继承UITabBar的类去替代系统自己的UITabBar
ZYYTabBar *tabBar = [[ZYYTabBar alloc] init];
[self setValue:tabBar forKeyPath:@"tabBar"];
- 接着就要根据自己的实际情况来自定义tabBar了,下面是我的代码:
首先要在- (void)layoutSubviews方法中重新布局
NSInteger index = 0;
CGFloat space = 12;
CGFloat tabBarLabelHeight = 16;
for (UIView *button in self.subviews) {
if (![button isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
continue;
}
self.selectionIndicatorImage = [[UIImage alloc] init];
[self bringSubviewToFront:button];
UIView *tabBarImageView, *tabBarLabel, *tabBarBadgeView;
for (UIView *subview in button.subviews) {
if ([subview isKindOfClass:NSClassFromString(@"UITabBarSwappableImageView")]) {
tabBarImageView = subview;
} else if ([subview isKindOfClass:NSClassFromString(@"UITabBarButtonLabel")]) {
tabBarLabel = subview;
} else if ([subview isKindOfClass:NSClassFromString(@"_UIBadgeView")]) {
tabBarBadgeView = subview;
}
}
NSString *tabBarLabelText = ((UILabel *)tabBarLabel).text;
CGFloat y = CGRectGetHeight(self.bounds) - (CGRectGetHeight(tabBarLabel.bounds) + CGRectGetHeight(tabBarImageView.bounds));
NSLog(@"=======%f ======= %f", button.frame.origin.x, button.frame.size.width);
if (y < 0) {
if (!tabBarLabelText.length) {
space -= tabBarLabelHeight;
} else {
space = 12;
}
button.frame = CGRectMake(button.frame.origin.x, y - space, button.frame.size.width, button.frame.size.height - y + space);
} else {
space = MIN(space, y);
}
index++;
}
然后,发现超出tabBar的部分不响应点击事件,因为我们需要实现- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event方法
if (!self.clipsToBounds && !self.hidden && self.alpha > 0) {
UIView *result = [super hitTest:point withEvent:event];
if (result) {
return result;
} else {
for (UIView *subView in self.subviews.reverseObjectEnumerator) {
CGPoint subPoint = [subView convertPoint:point fromView:self];
if (CGRectContainsPoint(subView.bounds, subPoint)) {
result = subView;
return result;
}
}
}
}
return nil;
- 最后,大功告成。实现的效果如图: