UITabBarItem Image is in Blue and not changed - ios

Um using my own TabBarController which is ElWafyatTabBarController basically it inherits from UITabBarController.
In ElWafyatTabBarController.m -> viewDidLoad
I've created some ViewControllers, Then I created UINavigationController's with rootViewController to the viewControllers I've made in the step before.
then I've created UITabBarItem and set it with image and title for each navigation controller which has rootViewController to the viewControllers that I've created in the first step, and set the tabBarItem for these navigationController to these tabBarItem.
The problem I found is even the title for the UITabBarItem is shown correctly, but the image is displayed at blue Color.
FYI: I've created two images named test.png and test#2x.png with dimensions 32x32 and 64x64
and I still have these issue,
So any one can help ?
this is my Code:
ElWafyatTabBarController -> viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
HomeViewController *homeViewController = [[HomeViewController alloc]
initWithNibName:#"HomeViewController" bundle:nil];
NaaiViewController *naaiViewController = [[NaaiViewController alloc]
initWithNibName:#"NaaiViewController" bundle:nil];
MushatraViewController *mushatraViewController = [[MushatraViewController alloc]
initWithNibName:#"MushatraViewController" bundle:nil];
TakremViewController *takremViewController = [[TakremViewController alloc]
initWithNibName:#"TakremViewController" bundle:nil]
UINavigationController *homeNavC = [[UINavigationController alloc]initWithRootViewController:homeViewController];
UINavigationController *naaiNavC = [[UINavigationController alloc]initWithRootViewController:naaiViewController];
UINavigationController *mushatraNavC = [[UINavigationController alloc]initWithRootViewController:mushatraViewController];
UINavigationController *takremNavC = [[UINavigationController alloc]initWithRootViewController:takremViewController];
// Setup Controllers for Tab Bar. (first level).
// [homeNavC.tabBarItem setTitle:#"الرئيسية"];
// [naaiNavC.tabBarItem setTitle:#"نعي"];
// [mushatraNavC.tabBarItem setTitle:#"مشاطرة"];
// [takremNavC.tabBarItem setTitle:#"تكريم"];
homeNavC.navigationBar.titleTextAttributes = [NSDictionary dictionaryWithObject:[UIColor whiteColor] forKey:UITextAttributeTextColor];
naaiNavC.navigationBar.titleTextAttributes = [NSDictionary dictionaryWithObject:[UIColor whiteColor] forKey:UITextAttributeTextColor];
mushatraNavC.navigationBar.titleTextAttributes = [NSDictionary dictionaryWithObject:[UIColor whiteColor] forKey:UITextAttributeTextColor];
takremNavC.navigationBar.titleTextAttributes = [NSDictionary dictionaryWithObject:[UIColor whiteColor] forKey:UITextAttributeTextColor];
homeNavC.navigationBar.barStyle = UIBarStyleBlack;
naaiNavC.navigationBar.barStyle = UIBarStyleBlack;
mushatraNavC.navigationBar.barStyle = UIBarStyleBlack;
takremNavC.navigationBar.barStyle = UIBarStyleBlack;
UITabBarItem* tabBarItem = [[UITabBarItem alloc] initWithTitle:#"Colors" image:[UIImage imageNamed:#"test.png"] tag:9];
homeNavC.tabBarItem = tabBarItem;
myViewControllers = [ NSArray arrayWithObjects:takremNavC, mushatraNavC, naaiNavC, homeNavC,nil];
[self setViewControllers:myViewControllers animated:YES];
[self.tabBarController setSelectedIndex:3];
[self setSelectedIndex:3];
}
and these the output:

If you want to see your image, you need to set the image's rendering mode to UIImageRenderingModeAlwaysOriginal, otherwise the image is displayed as a template image. You should read the documentation on tab bars, it has this statement:
Tab Bar Item Icons
Each item in a tab bar can have a custom selected image and unselected
image. You can specify these images when you initialize a tab bar item
using the initWithTitle:image:selectedImage: method. Note that a tab
bar item image will be automatically rendered as a template image
within a tab bar, unless you explicitly set its rendering mode to
UIImageRenderingModeAlwaysOriginal. For more information, see Template
Images.

Go to Assets.xcassets > Click on you image > Attribute Inspector > Render As > Original Image

Blue is the default tint color for UITabbar in iOS 7. You can change it to whatever color you like by setting:
myTabbar.tintColor = [UIColor greenColor]; //Put the color of your choice

if you have UITabBar:
UITabBar *tabBar = _tabBarController.tabBar;
UITabBarItem *tabBarItem1 = [tabBar.items objectAtIndex:0];
set the image of tabBarItem1 like this :
[tabBarItem1 setFinishedSelectedImage:[UIImage imageNamed:#"Selected_your_image"] withFinishedUnselectedImage:[UIImage imageNamed:#"UNSelected_your_image"]];
set selected and unselectedimage every UITabBarItem(s) of UITabBar.

Related

Is it possible to display a SFSafariViewController inside of a UITabBarController?

I want to load SFSafariViewController inside of a tab, so the tab bar is at the bottom of the entire Safari view.
Is this possible? I tried this with no luck:
[self.tabBarController presentViewController:sfController animated:YES completion:nil];
Is it required that the Safari view be full screen?
I was able to achieve this programmatically. They key to not have the UITabBar overlay on top of your UIViewController is to set translucent to NO:
In your AppDelegate.m:
#import SafariServices;
// ...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UITabBarController *tabBarController = [[UITabBarController alloc] init];
tabBarController.tabBar.translucent = NO;
SFSafariViewController *firstVC = [[SFSafariViewController alloc] initWithURL:[NSURL URLWithString:#"http://stackoverflow.com"]];
firstVC.title = #"SFSafariViewController";
UIViewController *secondVC = [[UIViewController alloc] init];
secondVC.view.backgroundColor = [UIColor blueColor];
secondVC.title = #"Blue VC";
tabBarController.viewControllers = #[firstVC, secondVC];
self.window.rootViewController = tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
Using JAL's answer as a base, I was able to implement this myself in an app that had existing structure with tabs already.
I wanted tab #3 to go into a Safari controller within the tab after a button was pressed on the existing view, and not pop the Safari controller into its own window like it does using Apple's default code.
The key was to swap in a SFSafariViewController into the existing UITabBarController's array of view controllers. I saved the existing original view controller on tab #3 (index 2) to come back to it when the Done button was pressed on the Safari controller.
Here's what I did to go into the Safari controller from with my tab when a button was pressed:
NSMutableArray *viewArray = [NSMutableArray arrayWithArray:self.tabBarController.viewControllers];
self.savedController = [viewArray objectAtIndex:2];
[viewArray replaceObjectAtIndex:2 withObject:safariController];
self.tabBarController.viewControllers = viewArray;
[self setTabIconTitle];
Then I could swap back to the original view on that tab like this when the Done button was pressed on the Safari controller using this delegate call:
- (void)safariViewControllerDidFinish:(SFSafariViewController *)controller
{
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
NSMutableArray *viewArray = [NSMutableArray arrayWithArray:tabBarController.viewControllers];
[viewArray replaceObjectAtIndex:2 withObject:self.savedController];
tabBarController.viewControllers = viewArray;
[self setTabIconTitle];
}
When I swapped controllers in an out of the tabBarController view controller array, I lost my tab icon and tab name, so I had to set those. Here is how I fixed that issue (and kept my theming when the tab icon was touched):
- (void)setTabIconTitle
{
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
UITabBar *tabBar = tabBarController.tabBar;
UITabBarItem *marketplaceTab = [tabBar.items objectAtIndex:2];
marketplaceTab.image = [[UIImage imageNamed:#"tab2-icon"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
marketplaceTab.selectedImage = [UIImage imageNamed:#"tab2-icon"];
marketplaceTab.title = #"My Tab";
}
I must admit that I am not sure that Apple intended that the SFSafariViewController be used in this way within a tab, based on what the normal behavior of calling SFSafariViewController currently does. Just be aware that future iOS updates may change this behavior and always test your code when new iOS versions go into Beta.

Add new tab dynamically in IOS

In Tab bar Controller, Initially I had added 3 tab bar items in it.After successful login, I need to add one more item dynamically in my current Tab bar Controller . Is it possible to add dynamically ? Below is the code i have tried but its not working.
if (AppContext.loginUser.userId!=nil) {
UITabBarItem *tabBarItem4;// = [tabBar.items objectAtIndex:3];
tabBarItem4.selectedImage = [[UIImage imageNamed:#"SelectedProfileTab"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
tabBarItem4.image = [[UIImage imageNamed:#"Profiletab"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
tabBarItem4.title = #"Profile";
tabBarItem4.tag =4;
ProfileVC *profile = loadViewController(TabbarSB, VC_Profile);
UINavigationController *nv=[[UINavigationController alloc] initWithRootViewController:profile];
NSMutableArray *arrayOfTabBars=[AppContext.mainTabbar.viewControllers mutableCopy];
[arrayOfTabBars addObject:nv];
// [AppContext.mainTabbar setViewControllers:nil];
[AppContext.mainTabbar setViewControllers:arrayOfTabBars];
//AppContext.mainTabbar.viewControllers = arrayOfTabBars;
// [self.tabBarController.tabBarController addChildViewController:profile];
}
You can do that programmatically:
if (AppContext.loginUser.userId!=nil) {
// First, create your view controller
ProfileVC *profile = loadViewController(TabbarSB, VC_Profile);
// then embed it to a navigation controller
// this is not required, only if you need it
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:profile];
// Get viewControllers array and add navigation controller
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:self.tabBarController.viewControllers];
[viewControllers addObject:nav];
// Set back the array
[self.tabBarController setViewControllers:viewControllers];
// Create tab bar item for ProfileVC
profile.tabBarItem = [[UITabBarItem alloc] initWithTitle:title image:image selectedImage:selectedImage];
}

Dynamically reload UIViewControllers on language change

I am changing UITabBarItem title after the user changes his language preferences in the app settings. The problem is that the whole item disappears for a while after this change is made and then appears again with the new title.
In AppDelegate I am initializing UITabBarController:
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.delegate = self;
BFNCategoriesTableViewController *shopViewController = [[BFNCategoriesTableViewController alloc] init];
UINavigationController *shopNavigationController = [[UINavigationController alloc] initWithRootViewController:shopViewController];
shopNavigationController.tabBarItem = [[UITabBarItem alloc] initWithTitle:BFNLocalizedString(kTranslationShop) image:[UIImage imageNamed:#"TabBarShopUnselected"] selectedImage:[UIImage imageNamed:#"TabBarShopSelected"]];
self.tabBarController.viewControllers = #[offersNavigationController,
shopNavigationController,
//wishlistNavigationController,
cartNavigationController,
moreNavigationController];
Then after the translation is downloaded I just set different title like this:
navigationController.title = BFNLocalizedString(kTranslationCart);
Do you have an idea why this happens and eventually how to ovecome this issue?
Thanks.
Firstly, I can't understand regarding code above, how tabBarController is connected with UINavigationController.
You should
self.tabBarController.viewControllers = [NSArray arrayWithObject: shopViewController];
UINavigationController *shopNavigationController = [[UINavigationController alloc] initWithRootViewController: self.tabBarController ];
UINavigationController doesn't have a property is tabBarItem.
Following that:
shopViewController.title = = BFNLocalizedString(kTranslationCart);
It changes a title is on top of navController and title of tabBar as well.
Another way, It can change a tabBarTitle directly.
UITabBar *tabBar = self.tabBarController.tabBar;
UITabBarItem * itemBar = [ [UITabBarItem alloc] initWithTitle:BFNLocalizedString(kTranslationCart)
image:(UIImage *)image // your image
selectedImage:(UIImage *)selectedImage]; // highlighted image
[tabBar setItems:[NSArray arrayWithObject:itemBar
animated:YES ];
I think a first way is enough it must certainly work.

UINavigationBar appearance proxy when contained in UIPopoverController

I'm doing something that supposed to work in iOS7 and 8, but for some reason it doesn't. I want to customize navigation bar properties via appearance proxy and want it to be applied to all navigation bars even the ones that are inside UIPopover.
So, first step I do the following:
UINavigationBar *appearance = [UINavigationBar appearance];
appearance.barTintColor = [UIColor redColor];
appearance.titleTextAttributes = #{
NSForegroundColorAttributeName: [UIColor yellowColor]
};
This supposed to make all navigation bars red with yellow title. Works in iOS8. Mostly work in iOS7. For some reason when view controller is being presented inside UIPopoverController - it gets default appearance.
This is how I present popover (nothing fancy - almost standard sample code):
UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"vc2"];
vc.title = #"View Controller 2";
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
self.popover = [[UIPopoverController alloc] initWithContentViewController:nav];
[self.popover presentPopoverFromRect:CGRectMake(100, 100, 100, 100) inView:self.view permittedArrowDirections:0 animated:YES];
Ok, so I decided to try appearanceWhenContainedIn and explicitly set its appearance there. Added the following code to initial appearance customization:
appearance = [UINavigationBar appearanceWhenContainedIn:[UIPopoverController class], nil];
appearance.barTintColor = [UIColor greenColor];
appearance.titleTextAttributes = #{
NSForegroundColorAttributeName: [UIColor blueColor]
};
Now. For some reason this last code doesn't affect anything. In iOS8 navigation bars inside UIPopoverControllers are still red + yellow, not green + blue, and iOS7 still uses default appearance.
What am I doing wrong here?
Here is link to the test project: https://dl.dropboxusercontent.com/u/6402890/TestAppearance.zip
For iOS 8
NS_CLASS_AVAILABLE_IOS(8_0) #interface UIPopoverPresentationController : UIPresentationController
Using the following worked for me. Navigation controller is contained in the UIPopoverPresentationController.
appearance = [UINavigationBar appearanceWhenContainedIn:[UIPopoverPresentationController class], nil];
For iOS 7
appearance = [UINavigationBar appearanceWhenContainedIn:[UIPopoverController class], nil];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
nav.navigationBar.barStyle = UIBarStyleBlack;
If navigation controller is loaded from storyboard, barStyle is also needed to be set to UIBarStyleBlack in storyboard.

Black Translucent Navigation Bar Flashes Opaque on First Push

I have a Navigation Controller where I set the navigationBar.barStyle = UIBarStyleBlack and the navigationBar.translucent = YES (as per Apple's advice since they deprecated UIBarStyleBlackTranslucent). In my two nib files (this is not using storyboard) in the simulated metrics I have Top Bar set to Black Navigation Bar.
SettingsViewController *controller = [[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
controller.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(closeSettings)];
controller.navigationController.navigationBar.barStyle = UIBarStyleBlack;
controller.navigationController.navigationBar.translucent = YES;
[self presentViewController:navController animated:YES completion:nil];
When I present the navigation controller, it opens up with the black translucent bar properly, but when I then push to the next table view, the navigation bar quickly fades to opaque and then back to translucent in the course of about 200ms. Its pretty much flashing opaque then back to translucent.
When I then push to the next table view, or go back (either by pressing the button in the top left of the nav bar, or by popping the view) it doesn't flash. It stays translucent the whole way through until the whole navigation controller is dismissed.
I thought this might be because of the way the nib was set up with an opaque bar, but I have tried every type of option (translucent, the regular blue, no bar) and it still does it.
Also, it does this across both completely separate navigation controllers in my app. Sorry if I am doing something obviously wrong, but I have tried so many combinations of options and am just at a loss.
Thanks!
I think you shouldn't use BarStyle at all but just :
[controller.navigationController.navigationBar setTintColor:[UIColor blackColor]];
[controller.navigationController.navigationBar setTranslucent:YES];
I would also try to animate the style change to get a smoother one with that in the presented view controller viewDidAppear method (think to begin with a black opaque bar in your code):
...
// Keep that where you want
SettingsViewController *controller = [[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
controller.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(closeSettings)];
// remove the two lines
[self presentViewController:navController animated:YES completion:nil];
}
Then in the SettingViewController code put :
- (void) viewDidAppear:(BOOL)animated {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:duration];
[controller.navigationController.navigationBar setTintColor:[UIColor blackColor]];
[controller.navigationController.navigationBar setTranslucent:YES];
[UIView commitAnimations];
}
Set appropriate value to your UIViewController instance property edgesForExtendedLayout, and set backgroundColor to your navigationController, for example:
self.edgesForExtendedLayout = UIRectEdgeBottom;
self.navigationController.view.backgroundColor = [UIColor whiteColor];
Hope this can help you.
SWIFT 5 VERSION
self.edgesForExtendedLayout = UIRectEdge.bottom
self.view.backgroundColor = .white

Resources