UITabBar selectionIndicatorImage padding

╄→гoц情女王★ 提交于 2019-12-18 03:10:29

问题


I set a custom indicator image for my UITabBar like this

UIImage *tabBarSelectedImage = [[UIImage imageNamed:@"tabBar_selected"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UITabBar appearance] setSelectionIndicatorImage:tabBarSelectedImage];

and get a 4px padding around my tabBarSelectedImage. Is it possible to set that padding to 0px? So that my tabBarSelectedImage fills the entire space and no border is visible?


回答1:


Here is the solution of your problem... I was not actually doing this...I was doing something else but the following code will help you a lot....First I tell you what I did...

  1. I made a catagory of UITabbar and implement the following method in that

    - (void)recolorItemsWithColor:(UIColor *)color shadowColor:(UIColor *)shadowColor 
    shadowOffset:(CGSize)shadowOffset shadowBlur:(CGFloat)shadowBlur
    {
    CGColorRef cgColor = [color CGColor];
    CGColorRef cgShadowColor = [shadowColor CGColor];
    for (UITabBarItem *item in [self items]) {
    
    if ([item respondsToSelector:@selector(selectedImage)] &&
        [item respondsToSelector:@selector(setSelectedImage:)] &&
        [item respondsToSelector:@selector(_updateView)])
    {
        CGRect contextRect;
        contextRect.origin.x = 0.0f;
        contextRect.origin.y = 0.0f;
    
        //instead of following line you can give our own desired size of contextRect. 
        //just change the method parameters and include a parameter of desired size in it.
        // and this desired size would be the tabbarbutton size...so you will pass the size of 
        // you tabbarbutton here...because on the back of image there is a tabbarbutton and if
        // set the image of button size it will occupy whole the are of button.
    
        contextRect.size = desired size //[[item selectedImage] size];
        // Retrieve source image and begin image context
        UIImage *itemImage = [item image];
        CGSize itemImageSize = [itemImage size];
    
        CGPoint itemImagePosition; 
        itemImagePosition.x = ceilf((contextRect.size.width - itemImageSize.width) / 2);
        itemImagePosition.y = ceilf((contextRect.size.height - itemImageSize.height) / 2);
        UIGraphicsBeginImageContext(contextRect.size);
        CGContextRef c = UIGraphicsGetCurrentContext();
    
        // Setup shadow
        CGContextSetShadowWithColor(c, shadowOffset, shadowBlur, cgShadowColor);
    
        // Setup transparency layer and clip to mask
        CGContextBeginTransparencyLayer(c, NULL);
        CGContextScaleCTM(c, 1.0, -1.0);
        CGContextClipToMask(c, CGRectMake(itemImagePosition.x, -itemImagePosition.y,
        itemImageSize.width, -itemImageSize.height), [itemImage CGImage]);
    
        // Fill and end the transparency layer
        CGContextSetFillColorWithColor(c, cgColor);
        contextRect.size.height = -contextRect.size.height;
        CGContextFillRect(c, contextRect);
        CGContextEndTransparencyLayer(c);
    
    
        // Set selected image and end context
        [item setSelectedImage:UIGraphicsGetImageFromCurrentImageContext()];
        UIGraphicsEndImageContext();
        // Update the view
        [item _updateView];
       }
       }
    
       }
    

    Now I called the above method in my custom class of UITabbarController... I override the method
    -(void)setSelectedIndex:(NSUInteger)selectedIndex and did the following in that method.

      -(void)setSelectedIndex:(NSUInteger)selectedIndex {
           self.selectedViewController = [self.viewControllers objectAtIndex:selectedIndex];
           NSLog(@"selectedIndex:%d, totalCount:%d",selectedIndex,[self.tabBar.subviews count]);
       for (uint i=1; i < [self.tabBar.subviews count]; i++)
       {
          UIView *view = [self.tabBar.subviews objectAtIndex:i];
          NSLog(@"class:%@",NSStringFromClass([view class]));
       if ([NSStringFromClass([view class]) isEqualToString:@"UITabBarButton"])
       {
        //view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y,  
        view.frame.size.width, self.tabBar.frame.size.height);
          NSLog(@"selectedIndex:%d,i:%d",self.selectedIndex,i);
        if (self.selectedIndex+1==i) {
            [self.tabBar recolorItemsWithColor:[UIColor whiteColor] shadowColor:[UIColor 
                                blackColor] shadowOffset:view.frame.size shadowBlur:0.5];
    
        }
        } 
        }
    
        }
    

You can optimize the code to avoid making catagory or subclassing...but for that you must have to grip on Objective C. In case of any issue you can tell me. Cheers




回答2:


I found a way simpler solution:

self.tabBar.frame = CGRectInset(self.tabBar.frame,0,-6);



回答3:


Well, here what I've found is that the padding appears only when using resizable images. When using non resizable images, the padding is not there.

Therefore, a possible solution is to subclass UITabBar and configure the selectionIndicatorImage whenever the item size changes.

@interface TKTabBar

@end

@implementation TKTabBar
{
    CGSize _selectionIndicatorImageSize;
}

- (void)tk_refreshSelectionIndicatorImageForItemSize:(CGSize)itemSize
{
    // Recompute the selection indicator image only if the size of the item has changed.
    if (!CGSizeEqualToSize(itemSize, _selectionIndicatorImageSize))
    {
        _selectionIndicatorImageSize = itemSize;

        // Compute here the new image from the item size.
        // In this example I'm using a Cocoa Pod called UIImage+Additions to generate images dynamically.

        UIImage *redImage = [UIImage add_imageWithColor:[UIColor add_colorWithRed255:208 green255:75 blue255:43] size:CGSizeMake(itemSize.width, 2)];
        UIImage *clearImage = [UIImage add_imageWithColor:[UIColor clearColor] size:CGSizeMake(itemSize.width, itemSize.height)];
        UIImage *mixImage = [clearImage add_imageAddingImage:redImage offset:CGPointMake(0, itemSize.height-2)];

        // Finally, I'm setting the image as the selection indicator image.
        [self setSelectionIndicatorImage:mixImage];
    }
}

// Using the layout subviews method to detect changes on the tab size
- (void)layoutSubviews
{
    [super layoutSubviews];

    // Only needed if at least one item
    if (self.items.count > 0)
    {
        CGSize itemSize = CGSizeZero;

        // Iterating over all subviews
        for (UIView *view1 in self.subviews)
        {
            // Searching for "UITabBarButtons"
            if ([view1 isKindOfClass:NSClassFromString(@"UITabBarButton")])
            {
                itemSize = view1.bounds.size;
                break;
            }
        }

        // Applying the new item size
        [self tk_refreshSelectionIndicatorImageForItemSize:itemSize];
    }
}

@end



回答4:


  1. First, setSelectionIndicatorImage to [UIColor clearColor]
  2. Second, Before you add any viewcontrollers to the tabbarcontroller, add your image as a subview to the tabbar. Then it will appear under the tabbaritems as the indicator image
  3. Implement the tabbarcontroller delegate method to change the position of the image.

I have implemented this way and it works perfect. You should tweak a little bit if you want to resize the tabbar for different orientations. You can subclass the UITabbarController and implement layoutSubview method.



来源:https://stackoverflow.com/questions/10035302/uitabbar-selectionindicatorimage-padding

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!