iOS 自定义UITabBar点击凸起效果绘制 带阴影

476 阅读1分钟
  • 实现效果 WeChat527a033f860840b57acc9afd09e450b4.jpg

WeChate762b609b191f47c53baa1e8ce972dd8.jpg

  • 在自定义Tabbar页面实现如下代码
////didSelectItem 可用 tabBarController shouldSelectViewController 方法代替
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
    NSInteger index = [self.tabBar.items indexOfObject:item];
    if (self.selectedIndex != index) {

        [self setTabbarImageInsetsWithItem:item];
        [self setTabBarShadowWithCenter:CGPointMake((W/4*index + W/4/2), 10) radius:28];
    }
}

#pragma mark - 设置图片位置大小 向上偏移
- (void)setTabbarImageInsetsWithItem:(UITabBarItem *)item {
    for (UIViewController * vc in self.childViewControllers) {
        if (item == vc.tabBarItem) {
            vc.tabBarItem.imageInsets = UIEdgeInsetsMake(-15, 0, 0, 0);
        }else{
            vc.tabBarItem.imageInsets = UIEdgeInsetsMake(0, 0, 0, 0);
        }
    }
}

#pragma mark - 绘制阴影弧线
-(void)setTabBarShadowWithCenter:(CGPoint)center radius:(CGFloat)radius {
    //center 圆弧中心 radius 圆弧半径
    CAShapeLayer *layer = [CAShapeLayer new];
    //背景填充色
    layer.fillColor = [UIColor whiteColor].CGColor;
    //阴影设置 
    layer.shadowColor = [UIColor colorWithRed:78/255 green:112/255 blue:145/255 alpha:0.19].CGColor;
    layer.shadowOffset = CGSizeMake(0, -1.5);
    layer.shadowOpacity = 1;
    
    CGFloat a = center.y;
    CGFloat angle = asin(a/radius);
    //初始化一个路径
    UIBezierPath* path = [UIBezierPath bezierPath];
    //线条拐角
    path.lineCapStyle = kCGLineCapRound;
    //起点
    [path moveToPoint:CGPointMake(0, 0)];
    //绘制一条圆弧
    [path addArcWithCenter:center radius:radius startAngle:angle + M_PI endAngle:2*M_PI - angle clockwise:YES];
    [path addLineToPoint:CGPointMake(kScreenWidth, 0)];
    [path addLineToPoint:CGPointMake(kScreenWidth, TabBarHeight)];
    [path addLineToPoint:CGPointMake(0, TabBarHeight)];

    layer.path = [path CGPath];
    [path closePath];
    layer.shadowPath = [path CGPath];
    
    //删除重复添加的 CAShapeLayer
    NSArray<CALayer *> *subLayers = self.tabBar.layer.sublayers;
    NSArray<CALayer *> *removedLayers = [subLayers filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id  _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings){
        return [evaluatedObject isKindOfClass:[CAShapeLayer class]];
    }]];
    [removedLayers enumerateObjectsUsingBlock:^(CALayer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [obj removeFromSuperlayer];
    }];

    [self.tabBar.layer insertSublayer:layer atIndex:0];
}