Transparent UITabBarController with changeable view in background - iphone

I want to have a UITabBarController, which is has an alpha of 0.5, whose transparency allows you to see a view in the background. The background view has to be accesible and changeable.
I'm able to add the background using this technique: https://gist.github.com/1157542
It's a Category which adds a subview to the UITabBarController, and sends the subview to the back. However, because it's a category, I can't make the subview a property. So I can't really access it.
Is there a way to make this background view more flexible and accessible? So I could, for instance, add other subviews to it easily from any of the tab bar controller's view controllers?

Instead of a category, you should subclass UITabBarController. This will allow you to have finer control over the object. Here's an example of a subclass.
// MPCustomTabBar.h
#interface MPCustomTabBar : UITabBarController
- (void) setBackgroundImage:(UIImage *)image;
#end
// MPCustomTabBar.m
#interface MPCustomTabBar
- (void) setBackgroundImage:(UIImage *)image {
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,480)];
imageView.backgroundColor = [UIColor colorWithPatternImage:i];
[[self view] addSubview:imageView];
[[self view] sendSubviewToBack:imageView];
[[self view] setOpaque:NO];
[[self view] setBackgroundColor:[UIColor clearColor]];
[imageView release];
}
#end
Now you can do all the customization you want, alloc and init your new subclass by something like this:
MPCustomTabBar *bar = [[MPCustomTabBar alloc] init];

A solution to my problem might be simply this..
In my AppDelegate, just before [self.window makeKeyAndVisible];
self.theImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image1.png"]];
[self.tabBarController.view insertSubview:self.theImage atIndex:0];
I can then easily change this image, in any of the tab bar controller's view controllers, like:
AppDelegate *appDelegate= (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.theImage.image = [UIImage imageNamed:#"image2.png"];
.. no categories required.

Here's what worked for me:
Make TabBar transparent (either by Storyboard or programmatically) by setting the Tint- and Background to Clear Color and Opaque to No.
The black background color is actually the window's colour. Assign the image you want to use as the background to the window itself:
UIImage *i = [UIImage imageNamed:#"main_background.png"];
UIColor *c = [[UIColor alloc] initWithPatternImage:i];
[self.window setBackgroundColor:c];

Related

Change the background color of UINavigationBar

I'd like to change the background color of an UINvaigationBar and I used tintColor property but it's not changing the color. You can checkout the code below.
In my Appdelegate I create a UITabBarController
tabbar = [[UITabBarController alloc] init];
Then I create a UINavigationController and attach my UITableViewController to it
UINavigationController *myNavigation = [[UINavigationController alloc] initWithRootViewController:myViewController];
Then attached the UINavigationControllers to my tabbar like this
[tabbar setViewControllers:viewControllers]; //viewControllers is an array of UINavigationControllers
I tried setting the property tintColor in myAppdelegate like this
[[myNavigation navigationBar] setTintColor:[UIColor redColor]];
But this didn't work as expected and so I tried the same in my ViewController
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController.navigationBar setTintColor:[UIColor blackColor]];
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
self.navigationItem.title = #"Test";
}
And still nothing happens. Please checkout the image below to see how navigation bar looks now.
Appreciate your help.
Cheers
Jugs
As a work around you may can use image on place of tint color please check below code for same.
if ([myNavigation respondsToSelector:#selector(setBackgroundImage:forToolbarPosition:barMetrics:)]) {
[myNavigation setBackgroundImage:[UIImage imageNamed:BAR_IMAGE_NAME] forbarMetrics:UIBarMetricsDefault];
}else {
[myNavigation insertSubview:[[[UIImageView alloc] initWithImage:[UIImage imageNamed:BAR_IMAGE_NAME]] autorelease] atIndex:0];
}

How to wire custom UINavigationBar to UINavigationController

So I've been researching on how to have an image in UINavigationBar and the safest way to do it that works for iOS 4 and iOS 5 is via subclassing the UINavigationBar, so I had:
#interface CustomNavigationBar : UINavigationBar
#end
#implementation CustomNavigationBar
-(void) drawRect:(CGRect)rect
{
UIImage *image = [UIImage imageNamed: #"myNavBarImage"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
#end
Now say I wanted to hook up ProfileViewController to have this custom UINavigationBar, how do I do that? Here's how I set ProfileViewController.
ProfileViewController *profile = [[ProfileViewController alloc] init];
localNavigationController = [[UINavigationController alloc] initWithRootViewController:profile];
[localControllersArray addObject:localNavigationController];
[localNavigationController release];
[profile release];
Any idea on how to wire this up? I've read that this has to be done via IB by changing the class of my UINavigationBar to the class that I just created. However, I don't have any UINavigationBar in my xib file, as it is created programatically via the UINavigationController.
One other issue also is that if I wanted to have a dynamic image that I can change/specify to the UINavigationBar, how do I do this? As of now it is hard wired that the UINavigationbar will have an image called myNavBarImage, but what if I wanted to set it to something else so I don't have to create 10 custom UINavigationBar, I somehow wanted to set the image name.
There is a solution similar to yours but uses categories instead of subclassing:
http://www.developers-life.com/custom-uinavigationbar-with-image-and-back-button.html
However, you have other choices that will make it easier for you such as adding an image as a subview to UINavigationBar. It is a safe way to do it,and I used it in a previous project which was approved.
My favorite way to do it is hiding the navigation bar and adding an imageView with buttons to have full control on how the navigation bar looks like (I especially use it when I need to add custom buttons as well).
Edit (Code to use for the second issue):
At viewDidLoad
UIImageView *imageview = [[UIImageView alloc] initWithImage: [UIImage imageNamed: #"image1.png"]];
[self.navigationController.navigationBar addSubview:imageview];
[self.navigationController.navigationBar sendSubviewToBack:imageview];
[imageview release];
At the method that changes the image:
-(void) changeNavigationBarImage: (NSString *) imageName{
for (UIView *view in self.navigationController.navigationBar.subviews) {
if ([view isKindOfClass:[UIImageView class]])
{
[(UIImageView *)view setImage:[UIImage imageNamed:imageName]];
break;
}
}
}
You can call this method when you want to change the image (i.e. button or timer)

Problem with custom UINavigationBar for MFMailComposeViewController

I have customize my UINavigationBar with UINavigationBar drawRect and it is working fine until I fire up MFMailComposeViewController, which gives me a trouble as I couldn't override UIBarButton for the mail class, it create akward view like below:
While I try to prevent the MFMailComposeViewController and produce code below for using the default drawRect for MFMailComposeViewController, it even worse it create a black UIBar:
The Code:
#implementation UINavigationBar (CustomImage)
- (void)drawRect:(CGRect)rect {
//Prevent Mail Controller For Customizing NavigationBar
for (UIView* next = [self superview]; next; next = next.superview) {
UIResponder* nextResponder = [next nextResponder];
if ([nextResponder isKindOfClass:[MFMailComposeViewController class]]) {
[super drawRect:rect];
return;
}
}
UIImage *image = [UIImage imageNamed: #"titleBar.png"];
[image drawInRect:CGRectMake(0, 0, 320, 44)];
}
#end
What I am trying to do here is to make sure MFMailComposeViewController having the same style of UINavigationBar and UIButtonItem. It can be either way:
1) Both UINavigationBar and UIButtonItem have customized background
2) Default UINavigationBar style (gradient blue)
Would like to know can I achieve this? Thanks in advance.
After some hacking and testing, still not manage to customize the button. But this is the closest I can get, by setting the tint color of mail controller.
MFMailComposeViewController *mailController = [[MFMailComposeViewController alloc] init];
mailController.mailComposeDelegate = self;
mailController.navigationBar.tintColor = [UIColor brownColor];

Background image for MoreNavigationController

I'd like to place an image behind the tableView in my UITabBarController moreNavigationController. I have tried inserting a subview like so when first setting up the TabBar:
UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"background3.png"]];
[self.tabBarController.moreNavigationController.topViewController.view insertSubview:imageView atIndex:0];
But this places the image over the top, presumably because the tableView isn't there at the time. Is there a better time when I can call this in order to have it work properly, or an easier approach?
With some assistance from this question, I figured out how to do this. Basically, the viewController in the moreNavigationController is a single TableView, so adding a background image won't work. What I need to do was to create a new view, add the background image, and then add the moreNavigationController view on top of that. I did this by overriding viewDidLoad in a subclass of UITabBarController, but I expect it could be done elsewhere as well.
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationController *moreController = self.moreNavigationController;
if ([moreController.topViewController.view isKindOfClass:[UITableView class]]) {
UIView* newView = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,367)];
UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"background3.png"]];
imageView.opaque = NO;
imageView.alpha = 0.4;
[newView addSubview:imageView];
moreController.topViewController.view.backgroundColor = [UIColor clearColor];
moreController.topViewController.view.frame = CGRectMake(0,0,320,367);
[newView addSubview:moreController.topViewController.view];
moreController.topViewController.view = newView;
}
}
You could probably be smarter with the frame sizes, etc, but this works for me. Hopefully it helps someone else too.
Now you can acess backgroundView property from UITableView subclasses .
UIViewController *moreViewController = tabBarController.moreNavigationController.topViewController;
img = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"BG_MORE+1.png"]];
//Got some crashs in initialization !! Need to check .
if ([moreViewController.view isKindOfClass:[UITableView class]]) {
UITableView *moreTableView = (UITableView*)moreViewController.view;
[moreTableView setBackgroundView:img];
}
Besides all the dotty mess here, you can use UIView's bringSubviewToFront: and sendSubviewToBack: to organize your subviews. Basically this should help, although if you have more subviews you will need to play around with it a little bit:
[self.tabBarController.moreNavigationController.topViewController.view addSubview:imageView];
[self.tabBarController.moreNavigationController.topViewController.view pushSubviewToBack:imageView];
//or [self.tabBarController.moreNavigationController.topViewController.view bringSubviewToFront:tableView];

UIViewController with background image

How can I insert into my UIViewController an image from the resources as background image?
thanks in advance!
Add it UIViewController's view, somewhat like this:
- (void) viewDidLoad
{
UIImage *background = [UIImage imageNamed: #"background.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage: background];
[self.view addSubview: imageView];
[imageView release];
[super viewDidLoad];
}
UIViewControllers don't have background images. Only views themselves have visual attributes.
UIView does not have a background image property. To display a background image, you usually simply put a UIImageView displaying the image in the view hierarchy so that it appears visually behind all other views. This can be done programmatically or in Interface Builder.