Настройка фонового изображения для вкладки

Я пытаюсь программно установить фоновое изображение для вкладки в моем приложении. Мой код выглядит следующим образом:

RootViewController.h

IBOutlet UITabBar *mainTabBar; IBOutlet UITabBarItem *settingsBarItem; IBOutlet UITabBarItem *infoBarItem; IBOutlet UITabBarItem *aboutBarItem; 

RootViewController.m

 -(void)viewDidLoad { UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"smallMenuBackground.png"]]; [mainTabBar insertSubview:imageView atIndex:0]; [imageView release]; [super viewDidLoad]; } 

Это не работает для меня.

ОБНОВИТЬ

ОБНОВЛЕНИЕ 23 января 2012 г.

Хорошо, я немного продвинулся вперед. Это только перестало работать, так как я обновился до Xcode 4.2 и IOS5. Мне удалось вернуть его с помощью опций в Interface Builder, но теперь он работает только для IOS5. В идеале мне хотелось бы работать программно, но сейчас я соглашусь на решение IB.

Я просто не могу заставить его работать для любых предыдущих выпусков.

ПРИМЕЧАНИЕ. Моя TabBar находится только на моем RootViewController, который является основным экраном моего приложения.

В идеале, если бы я мог получить код, который предложил Нитин, это было бы здорово:

 UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"tabBG.png"]]; if ([[[UIDevice currentDevice] systemVersion] floatValue] > 4.9) { //iOS 5 [self.tabBarController.tabBar insertSubview:imageView atIndex:1]; } else { //iOS 4.whatever and below [self.tabBarController.tabBar insertSubview:imageView atIndex:0]; } [imageView release]; 

Любая помощь будет оценена по достоинству.

С уважением, Стивен

    Вы можете использовать собственный class для UITabBarController и переопределить свой tabBarController. Там вы можете установить нужные кнопки и их действия с изображением.

    Вот как выглядит ваш пользовательский class controllerа панели вкладок:

    // CustomTabBarController.h

     #import  @interface CustomTabBarController : UITabBarController { UIButton *settingsButton; UIButton *infoButton; UIButton *aboutUsButton; } @property (nonatomic, retain) UIButton *settingsButton; @property (nonatomic, retain) UIButton *infoButton; @property (nonatomic, retain) UIButton *aboutUsButton; -(void) addCustomElements; -(void) selectTab:(int)tabID; @end 

    // CustomTabBarController.m

     #import "CustomTabBarController.h" @implementation CustomTabBarController @synthesize settingsButton, infoButton, aboutUsButton; - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; } -(void)viewDidLoad { [super viewDidLoad]; [self addCustomElements]; } -(void)addCustomElements { // Background UIImageView* bgView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"tabBarBackground.png"]] autorelease]; bgView.frame = CGRectMake(0, 420, 320, 60); [self.view addSubview:bgView]; // Initialise our two images UIImage *btnImage = [UIImage imageNamed:@"settings.png"]; UIImage *btnImageSelected = [UIImage imageNamed:@"settingsSelected.png"]; self.settingsButton = [UIButton buttonWithType:UIButtonTypeCustom]; //Setup the button settingsButton.frame = CGRectMake(10, 426, 100, 54); // Set the frame (size and position) of the button) [settingsButton setBackgroundImage:btnImage forState:UIControlStateNormal]; // Set the image for the normal state of the button [settingsButton setBackgroundImage:btnImageSelected forState:UIControlStateHighlighted]; // Set the image for the selected state of the button [settingsButton setBackgroundImage:btnImageSelected forState:UIControlStateSelected]; // Set the image for the selected state of the button [settingsButton setBackgroundImage:btnImageSelected forState:UIControlStateDisabled]; [settingsButton setImage:btnImageSelected forState:(UIControlStateHighlighted|UIControlStateSelected)]; [settingsButton setTag:101]; // Assign the button a "tag" so when our "click" event is called we know which button was pressed. [settingsButton setSelected:true]; // Set this button as selected (we will select the others to false as we only want Tab 1 to be selected initially // Now we repeat the process for the other buttons btnImage = [UIImage imageNamed:@"info.png"]; btnImageSelected = [UIImage imageNamed:@"infoSelected.png"]; self.infoButton = [UIButton buttonWithType:UIButtonTypeCustom]; infoButton.frame = CGRectMake(110, 426, 100, 54); [infoButton setBackgroundImage:btnImage forState:UIControlStateNormal]; [infoButton setBackgroundImage:btnImageSelected forState:UIControlStateSelected]; [infoButton setBackgroundImage:btnImageSelected forState:UIControlStateHighlighted]; [infoButton setImage:btnImageSelected forState:(UIControlStateHighlighted|UIControlStateSelected)]; [infoButton setTag:102]; btnImage = [UIImage imageNamed:@"aboutUs.png"]; btnImageSelected = [UIImage imageNamed:@"aboutUsSelected.png"]; self.aboutUsButton = [UIButton buttonWithType:UIButtonTypeCustom]; aboutUsButton.frame = CGRectMake(210, 426, 100, 54); [aboutUsButton setBackgroundImage:btnImage forState:UIControlStateNormal]; [aboutUsButton setBackgroundImage:btnImageSelected forState:UIControlStateSelected]; [aboutUsButton setBackgroundImage:btnImageSelected forState:UIControlStateHighlighted]; [aboutUsButton setImage:btnImageSelected forState:(UIControlStateHighlighted|UIControlStateSelected)]; [aboutUsButton setTag:103]; // Add my new buttons to the view [self.view addSubview:settingsButton]; [self.view addSubview:infoButton]; [self.view addSubview:aboutUsButton]; // Setup event handlers so that the buttonClicked method will respond to the touch up inside event. [settingsButton addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; [infoButton addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; [aboutUsButton addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; } - (void)buttonClicked:(id)sender { int tagNum = [sender tag]; [self selectTab:tagNum]; } - (void)selectTab:(int)tabID { switch(tabID) { case 101: [settingsButton setSelected:true]; [infoButton setSelected:false]; [aboutUsButton setSelected:false]; break; case 102: [settingsButton setSelected:false]; [infoButton setSelected:true]; [aboutUsButton setSelected:false]; break; case 103: [settingsButton setSelected:false]; [infoButton setSelected:false]; [aboutUsButton setSelected:true]; break; } self.selectedIndex = tabID; } - (void)dealloc { [settingsButton release]; [infoButton release]; [aboutUsButton release]; [super dealloc]; } @end 

    Надеюсь, это вам очень поможет.

     UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"tabBG.png"]]; if ([[[UIDevice currentDevice] systemVersion] floatValue] > 4.9) { //iOS 5 [self.tabBarController.tabBar insertSubview:imageView atIndex:1]; } else { //iOS 4.whatever and below [self.tabBarController.tabBar insertSubview:imageView atIndex:0]; } [imageView release]; 

    Вам придется условно кодировать это по версии ОС.

    Если вы поддерживаете только iOS 5, вы можете просто использовать свойство backgroundImage на вкладке. Если вам нужно поддерживать версии iOS ниже 5, вы должны добавить условный код, который «взломает» его на месте. Для этого есть несколько подходов:

    Пользовательское фоновое изображение панели вкладок – в iOS 4.x

    Снято с: http://ios-blog.co.uk/tutorials/ios-custom-ui-series-tabbar-navbar/

     // Change the tab bar background UIImage *tabBarBackground = [UIImage imageNamed:@"CustomUITabbar.png"]; [[UITabBar appearance] setBackgroundImage:tabBarBackground]; [[UITabBar appearance] setTintColor:[UIColor whiteColor]]; 

    Как уже упоминалось ранее на iOS 5, я предлагаю вам использовать фоновое изображение:

     UITabBar *tabBar = tabController.tabBar; if ([tabBar respondsToSelector:@selector(setBackgroundImage:)]) { tabBar.backgroundImage = [UIImage imageNamed:@"TabBackground.png"]; } 

    Всегда используйте проверку, например respondsToSelector вместо явной проверки версий. Это приводит к более безопасному и более надежному будущему коду.

    На iOS 4 я предложил бы использовать метод -[UITabBar drawRect:] , предпочтительно в подclassе. Затем в Interface Builder задайте пользовательский class UITabBarController UITabBar (обычно в MainWindow.xib) для вашего пользовательского подclassа.

    Однако, если вы не используете MainWindow.xib и, подобно шаблонам кода iOS 5, вы генерируете код UITabBarController в коде, вы можете только перезаписать метод drawRect: используя категорию на UITabBar .

     // UITabBar+CustomBackground.h @interface UITabBar (CustomBackground) @end // UITabBar+CustomBackground.m @implementation UITabBar (CustomBackground) - (void) drawRect:(CGRect)frame { [[UIColor redColor] set]; CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextFillRect(ctx, [self bounds]); } @end 

    Это работает только в системах iOS 4.x и более ранних версиях, но это нормально, потому что мы уже рассмотрели iOS 5.

    Вам просто нужно идентифицировать каждый случай, проверяя версию с -respondToSelector как сказал Винод. Я предлагаю вам создать категорию на UITabBar и сделать это легко. Таким образом, код будет иметь следующую форму:

      // UITabBar+Custom.h #import  #import  @interface UITabBar (Custom) -(void)setTabBarBackground:(UIImage *)backgroundImage; @end 

    И файл .m:

      // UITabBar+Custom.m #import "UITabBar+Custom.h" #import  static char *backgroundImageKey; -(void)setImage:(UIImage *)anImage { objc_setAssociatedObject(self, &backgroundImageKey, anImage, OBJC_ASSOCIATION_RETAIN_NONATOMIC); [self setNeedsDisplay]; } -(UIImage *)image { return objc_getAssociatedObject(self, &backgroundImageKey); } -(void)setTabBarBackground:(UIImage *)backgroundImage { if([self respondsToSelector:@selector(setBackgroundImage:)]) { [self setBackgroundImage:backgroundImage]; } else { [self setImage:backgroundImage]; } } -(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx { UIGraphicsPushContext(ctx); UIImage *currentImage = [self image]; CGContextTranslateCTM(ctx, 0, currentImage.size.height); CGContextScaleCTM(ctx, 1.0, -1.0); CGContextDrawImage(ctx, self.bounds, currentImage.CGImage); UIGraphicsPopContext(); } 

    -drawLayer:inContext рисует фоновое изображение.

    Как я уже сказал выше, без добавления UIView можно добавить фоновое изображение в UITabBar, изображение, которое может исчезнуть при вызове [tabBar setNeedsDisplay] , поэтому я подумал о том, чтобы нарисовать изображение в -drawLayer:layer inContext:ctx (the -drawInRect:rect не вызывается). Однако, если вы можете избежать вызова [tabBar setNeedsDisplay] , есть простой способ сделать это:

     // UITabBar+Custom.m #import "UITabBar+Custom.h" #import  -(void)setTabBarBackground:(UIImage *)backgroundImage { if([self respondsToSelector:@selector(setBackgroundImage:)]) { // ios 5+ [self setBackgroundImage:backgroundImage]; } else { // ios 3.x / 4.x self.layer.contents = (id)backgroundImage.CGImage; } } 

    Сделайте индивидуальный вид и добавьте его на панель UITaB. теперь добавьте кнопку на этом представлении и предоставите ссылку метода кнопкам панели вкладок. Теперь вы можете делать что-либо в этом представлении, добавляя изображение или любую вещь. Он работает как настраиваемая панель вкладок.

    То, что я делал в прошлом, это создать свой собственный TabbarController для загрузки разных UIViewControllers . С помощью этого controllerа я могу манипулировать внешним видом элементов вкладки и элементов табуляции.

    Это работает отлично, но это изначально немного работа. Потому что вам нужно «имитировать» UITabBarController , так как вы фактически не используете «native» UITabBar

      jUst call these two methods hideTabBar; addCustomElements; hideTabBar method hides the original tabbar And addCustomElements method will add the custom tabbar image as well as custom tabbar button also - (void)hideTabBar { for(UIView *view in self.tabBarController.view.subviews) { // if([view isKindOfClass:[UITabBar class]]) // { // view.hidden = YES; // break; // } if([view isKindOfClass:[UITabBar class]]) { [view setFrame:CGRectMake(view.frame.origin.x, 480, view.frame.size.width, view.frame.size.height)]; } else { [view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 480)]; } } } -(void)addCustomElements { // Initialise our two images UIImage *btnImage = [UIImage imageNamed:@"homet.png"]; UIImage *btnImageSelected = [UIImage imageNamed:@"homehovert.png"]; self.btn1 = [UIButton buttonWithType:UIButtonTypeCustom]; //Setup the button btn1.frame = CGRectMake(28, 446, 25,28); // Set the frame (size and position) of the button) [btn1 setBackgroundImage:btnImage forState:UIControlStateNormal]; // Set the image for the normal state of the button [btn1 setBackgroundImage:btnImageSelected forState:UIControlStateSelected]; // Set the image for the selected state of the button [btn1 setTag:0]; // Assign the button a "tag" so when our "click" event is called we know which button was pressed. [btn1 setSelected:true]; // Set this button as selected (we will select the others to false as we only want Tab 1 to be selected initially // Now we repeat the process for the other buttons btnImage = [UIImage imageNamed:@"blogt.png"]; btnImageSelected = [UIImage imageNamed:@"bloghovert.png"]; self.btn2 = [UIButton buttonWithType:UIButtonTypeCustom]; btn2.frame = CGRectMake(107, 448, 22,28); [btn2 setBackgroundImage:btnImage forState:UIControlStateNormal]; [btn2 setBackgroundImage:btnImageSelected forState:UIControlStateSelected]; [btn2 setTag:1]; btnImage = [UIImage imageNamed:@"networkt.png"]; btnImageSelected = [UIImage imageNamed:@"networkhovert.png"]; self.btn3 = [UIButton buttonWithType:UIButtonTypeCustom]; btn3.frame = CGRectMake(180, 446, 35,29); [btn3 setBackgroundImage:btnImage forState:UIControlStateNormal]; [btn3 setBackgroundImage:btnImageSelected forState:UIControlStateSelected]; [btn3 setTag:2]; btnImage = [UIImage imageNamed:@"contactt.png"]; btnImageSelected = [UIImage imageNamed:@"contacthovert.png"]; self.btn4 = [UIButton buttonWithType:UIButtonTypeCustom]; btn4.frame = CGRectMake(262, 447, 32,28); [btn4 setBackgroundImage:btnImage forState:UIControlStateNormal]; [btn4 setBackgroundImage:btnImageSelected forState:UIControlStateSelected]; [btn4 setTag:3]; self.img1 = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"tabbar.png"]] ; img1.frame = CGRectMake(0, 440, 320, 40); [self.tabBarController.view addSubview:img1]; // Add my new buttons to the view [self.tabBarController.view addSubview:btn1]; [self.tabBarController.view addSubview:btn2]; [self.tabBarController.view addSubview:btn3]; [self.tabBarController.view addSubview:btn4]; // Setup event handlers so that the buttonClicked method will respond to the touch up inside event. [btn1 addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; [btn2 addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; [btn3 addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; [btn4 addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; } 
     // not supported on iOS4 UITabBar *tabBar = [tabController tabBar]; if ([tabBar respondsToSelector:@selector(setBackgroundImage:)]) { // set it just for this instance [tabBar setBackgroundImage:[UIImage imageNamed:@"tabbar_brn.jpg"]]; // set for all // [[UITabBar appearance] setBackgroundImage: ... } else { // ios 4 code here } 
     // Change the tab bar background UIImage* tabBarBackground = [UIImage imageNamed:@"tabbar.png"]; [[UITabBar appearance] setBackgroundImage:tabBarBackground]; 
    Давайте будем гением компьютера.