23

I have this code

[tabBarItem1 setFinishedSelectedImage:[UIImage imageNamed:@"tab_pressed_home_icon"] withFinishedUnselectedImage:[UIImage imageNamed:@"tab_home_icon"]];

tabBarItem1.imageInsets = UIEdgeInsetsMake(8, 0, -2, 0);

which set an icon on the tab bar.

everything work fines so far until last night that i update Xcode 5.1

and run the app on ios7.1 simulator.

here is the app enter image description here

now when i tap the tab bar the icon image size is decrease an when i release the finger image is back to normal. But if i tap the icon and drag it the image is look like this (scale down).

like this enter image description here

how can this happen? is there anyway to solve this?

Thanks.

SaintTail
  • 6,160
  • 4
  • 31
  • 51
  • 2
    i got the same problem, and found it caused by setting image insets with UITabBarItem. this is the code: `[barItem setImageInsets:UIEdgeInsetsMake(15, 7.5, 0, 7.5)];`everything goes well while comment it. – yuhua Mar 15 '14 at 15:33
  • Yes it is creating the problem in IOS 7.1. And I think tabbar height has been changed to 44 now. – TheTiger Mar 20 '14 at 08:16
  • Same thing here. This bug is naaasty! The strange thing is, it only happens for one of my tab bar icons and I don't even use storyboards... – the_critic Mar 24 '14 at 18:06
  • have you tried run it on device? I got similar problem with simple uiimageView - it looks OK on device but streched on the simulator. – Roma Apr 01 '14 at 11:35
  • 1
    Has anyone find the solution of the problem? – iEinstein May 22 '14 at 15:29
  • same issue , it should ios bug – iXcoder Apr 02 '18 at 02:32

12 Answers12

25

This problem was resolved by setting the imageInsets of the tabBarItem as others have mentioned. You can do this in code or you can do it in Interface Builder, it doesn't matter.

The important point is to have the top inset BE EQUAL to the bottom inset.

wrightak
  • 646
  • 4
  • 7
  • 2
    This solved the problem. Basically they have to cancel each other out: `item.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0);` – daspianist Jun 30 '14 at 01:40
  • 7
    The top inset does not have to be equal to the bottom inset. The sum of the top and bottom should be equal to the sum of the left and right (if you don't want to stretch or shrink). – clocksmith Aug 10 '14 at 16:45
  • @clocksmith mine are both equal and i still have this issue – Charlton Provatas Jan 10 '17 at 21:57
11

I had the same problem on iOS 7.1 when trying to set the Image insets by code like:

[self.tabBarItem setImageInsets:UIEdgeInsetsMake(5, 0, -5, 0)];

So I solved it using directly the Bar Item Size on my Storyboard.

Bar Item Size menu

Take in count that for this to work you should be assigning the image of you TabBarItem in the following way

UITabBar *tabBar = self.tabBarController.tabBar;
UITabBarItem *myItem = [tabBar.items objectAtIndex:0];

[homeItem setFinishedSelectedImage:[UIImage imageNamed:@"A.png"]
       withFinishedUnselectedImage:[UIImage imageNamed:@"B.png"]];

instead of this way

[self.tabBarItem setFinishedSelectedImage:[UIImage imageNamed:@"A.png"]
              withFinishedUnselectedImage:[UIImage imageNamed:@"B.png"]];

Update

To access the Bar Item Size select directly the 'Item' element under the Scene of any of your Tab Bar Controller's child. (Image1)

enter image description here

CoderPug
  • 908
  • 9
  • 19
  • How does one get to the bar item size area of story board? – John Mar 09 '15 at 20:49
  • Directly select on of your Tab Bar Controller's child they have an 'item' which represents the Bar Item. I will upload an image and update my answer – CoderPug Mar 09 '15 at 21:12
7

my problem is similar, the tabbar icon changed it position in 7.1 update, this problem is really annoying, and I did a quick solution because I have to approve the app. Was this:

tab bar soluction in nib

Ok I not sure that is the best solution, but for me works.

Felipe FMMobile
  • 1,641
  • 20
  • 17
3

Same problem here. Also after update to iOS 7.1 and xcode 5.1 My solution: The tab bar item size was set at 4 for Bottom.(in Size inspector) I changed it to 0 like all the others and the problem was gone.

iHilas
  • 103
  • 1
  • 1
  • 7
2

I give it up, my solution is here:

use the function to resize and make offset with UIImage

- (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize andOffSet:(CGPoint)offSet{
    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [image drawInRect:CGRectMake(offSet.x, offSet.y, newSize.width-offSet.x, newSize.height-offSet.y)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

and set the tab bar item image properly:

UITabBarItem *barItem  = [self.tabBarController.tabBar.items objectAtIndex:i];
CGSize size = CGSizeMake(49, 49);
CGPoint offset = CGPointMake(10, 10);
[barItem setFinishedSelectedImage:[self imageWithImage:selectedImage scaledToSize:size andOffSet:offset]
         withFinishedUnselectedImage:[self imageWithImage:unSelectedImage scaledToSize:size andOffSet:offset]];

if any other solutions would be help!

yuhua
  • 1,239
  • 8
  • 18
2

My answer is based on others posted here - setting to 0 all ImageInsets in tab bar items:

for (UITabBarItem* item in self.tabBar.items)
{
    [item setImageInsets: UIEdgeInsetsMake(0, 0, 0, 0)];
}
IdoT
  • 2,831
  • 1
  • 24
  • 35
1

You may put a UIView on top of the tab bar, and add a UITapGestureReognizer to the UIView. When tapped, I determine where it is and call the appropriate selected item for the tabbar. Hack, but works quite nicely and lets you keep your inset values to whatever you want.

 @property UIView  tabBarCover;//place on top of uitabbar and give it clear color background

 - (void)viewDidLoad
 {
   [tabBar setSelectedItem:[tabBar.items objectAtIndex:0]];
    UITapGestureRecognizer *singleFingerTap =
                        [[UITapGestureRecognizer alloc] initWithTarget:self
                                        action:@selector(handleSingleTap:)];
   [tabBarCover addGestureRecognizer:singleFingerTap];

 }

Then each time the UIView is tapped, set the selected item based on where the user touched. I had 3 tab bar items, so I just did some logic for the x coordinate.

-(void) handleSingleTap:(UITapGestureRecognizer *) recognizer
{
    CGPoint location = [recognizer locationInView:[recognizer.view superview]];
    //NSLog(@"tapped it %lf", location.x);
    if(location.x<=105){
        //1st 3rd tapped, do something

    }
    else if(location.x >105 && location.x<=210)
    {
       //do nothing, selected item stays same. this is glas
    }else{
       //must be in 3rd section so do that load

    }

}

Hope it helps.

Tope
  • 938
  • 2
  • 11
  • 15
1

I spent about 3 hours of it! And I have found our mistake. it is not bug of iOS.

Note: imageInsets will not help! because this is problem with image's scale. I played 2 hours with it! and no result. it was stupid way to try solve the problem!

Please look this project http://www.raywenderlich.com/50310/storyboards-tutorial-in-ios-7-part-2

on this project Players and Gestures icons works perfectly! because there are icons for retina and non-retina.

if you have icons for both scale, then no problem. use them! everything will work fine! it was 1-variant!

2-variant. if you have only one big image and you want use for both display, then you need specify the "scale" of the resized image:

(UIImage *)thumbnailImageSize:(CGSize)size fromImage:(UIImage *)image { 
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES && [[UIScreen mainScreen] scale] == 3.00) {
        _scale = 3.00; 
    } else if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES && [[UIScreen mainScreen] scale] == 2.00) { 
        _scale = 2.00; 
    } else 
        _scale = 1.00;

    UIGraphicsBeginImageContextWithOptions(size, NO, _scale); 
    [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; 
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext(); 
    return newImage; 
}
Cyril Durand
  • 15,834
  • 5
  • 54
  • 62
1

My solution was to divide by 2 the x and y points, then I set it to left, right, top and bottom respectively.

0

try this it should do the trick and won't affect the older versions

Put the below lines in the any controller init method:

UIImage* image = [UIImage imageNamed: @"Your tabbar image name goes here"];
    if ([image respondsToSelector: @selector(imageWithRenderingMode:)])
            [self.tabBarItem setImage: [image imageWithRenderingMode: UIImageRenderingModeAlwaysOriginal]];
Ahmad Al-Attal
  • 435
  • 4
  • 13
  • i think i made a mistake in here, as per to your question your problem is with the selected image so in the last line of code replace "setImage:" with "setSelectedImage:". – Ahmad Al-Attal Mar 23 '14 at 06:16
0

Top and bottom insets are set in your code — it should be enough to set just on of these (say, top). The reason the highlighted image gets compressed might be that the raster has different dimensions, not the same as the default image — in this case the insets make the image scale vertically.

Leon Deriglazov
  • 1,132
  • 9
  • 13
0

I fixed the same problem by using this category for UIImage that create an Image from an UIView

+ (UIImage *) imageWithView:(UIView *)view
{
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];

    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return img;
}

And then, using this method you can create a new image with the custom offset you need. (I need only Y offset).

-(UIImage *) uiNewImageForTabBar: (UIImage *) i withOffsetForY: (CGFloat) offsetY
{
    UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, i.size.width, i.size.height+offsetY)];
    [v setBackgroundColor:[UIColor clearColor]];
    [v setOpaque:NO];

    UIImageView *sub = [[UIImageView alloc] initWithImage:i];
    [sub setY:offsetY];

    [v addSubview:sub];

    return [UIImage imageWithView:v];
}
eold
  • 324
  • 4
  • 12