How to set a custom background image to tabbar?

2019-08-18 05:28发布

问题:

I am writing a Rubymotion app and I want to customize the TabBar. On NSScreencasts.com they explain how to do it in Objective-C but how can I transform the below code into Ruby?

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self customize];        
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self customize];
    }
    return self;
}

- (void)customize {
    UIImage *tabbarBg = [UIImage imageNamed:@"tabbar-background.png"];
    UIImage *tabBarSelected = [UIImage imageNamed:@"tabbar-background-pressed.png"];
    [self setBackgroundImage:tabbarBg];
    [self setSelectionIndicatorImage:tabBarSelected];
}

@end

This is my attempt:

class CustomTabbar < UITabBarController
  def init
    super
    customize
    self
  end

  def customize
    tabbarBg = UIImage.imageNamed('tabbar.jpeg')
    self.setBackgroundImage = tabbarBg
  end
end

But if I run it I get this error:

Terminating app due to uncaught exception 'NoMethodError', reason: 'custom_tabbar.rb:5:in `init': undefined method `setBackgroundImage=' for #<CustomTabbar:0x8e31a70> (NoMethodError)

UPDATE

*This is my app_delete file:*

class AppDelegate
  def application(application, didFinishLaunchingWithOptions:launchOptions)
    first_controller = FirstController.alloc.init
    second_controller = SecondController.alloc.init

    tabbar_controller = CustomTabbar.alloc.init
    tabbar_controller.viewControllers = [first_controller, second_controller]

    @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
    @window.rootViewController = tabbar_controller
    @window.makeKeyAndVisible
    true
  end
end

回答1:

According to the "chat" we had, it seems to me you are very confused about the proper hierarchy of views and controllers. A controller is an object which owns a view, but the controller doesn't have any visual properties. The view has visual things (like background image). So e.g. a when you have a tab bar, you actually have: 1) TabBarController 2) TabBar (the view).

Now, the TabBar is a view and it has a property called "backgroundImage", through which you can change the background. Of couse, the TabBarController has no such thing, but it has a list of "inner" controllers.

Let me show you some code that does what you want. It's in Obj-C, but it should be straightforward to rewrite it into Ruby. I have this in my AppDelegate's didFinishLaunchingWithOptions method:

UITabBarController *tbc = [[UITabBarController alloc] init];

UIViewController *v1 = [[UIViewController alloc] init];
UIViewController *v2 = [[UIViewController alloc] init];

tbc.viewControllers = @[v1, v2];
tbc.tabBar.backgroundImage = [UIImage imageNamed:@"a.png"];

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = tbc;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;

Notice, that the TabBarController has a property "viewControllers" - this is a list of inner controllers. It also has a property "tabBar", which is a reference to the view, the UITabBar. I access it and set the background image.