UITabBarController image iOS 5 - iphone

I created a UITabBarController with storyboard for iOS5. I don't have the UITabBar declared in my ViewController and I can't set background image for tab bar.
UIImage *tabBackground = [[UIImage imageNamed:#"tabBarBackground.jpg"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
// Set background for all UITabBars
[[UITabBar appearance] setBackgroundImage:tabBackground];
// Set background for only this UITabBar
[[tabBarController tabBar] setBackgroundImage:tabBackground];

You'll need to designate tabBarController as an IBOutlet property
#property (nonatomic, strong) IBOutlet UITabBarController *tabBarController;
Then wire them up in the Connections inspector in Interface Builder, and you'll be able to use your code as shown.

Related

Attempts to control offset of UIBarButtonItem title in UIToolbar are failing

The button is declared as a property (via the storyboard) in the view controller's header file:
#property (strong, nonatomic) IBOutlet UIBarButtonItem *settingsButton;
And set up like so in the implementation:
self.settingsButton.title = #"⚙";
[self.settingsButton setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIFont systemFontOfSize:24.0], NSFontAttributeName,nil] forState:UIControlStateNormal];
[self.settingsButton setTitlePositionAdjustment:UIOffsetMake(0.0f, 5.0f) forBarMetrics:UIBarMetricsDefault];
However, the offset settings just don't do anything at all. No matter what I change the values to, the button just sits slightly too high in the UIToolbar like it always has.

Use a View Controller as a camera overlay?

I have an app that loads the camera and overlays buttons for fire, reload, and back, as well as a png that animates when the fire and reload buttons are tapped. How would I load the View Controller, which has a .xib with the buttons and image, as an overlay when the camera view loads?
I have the camera view loading when a button on the main screen is tapped, which used to open another View with the buttons and gun image.
Below is what I have done so far, which is loading the camera. I have a separate View Controller named PlayViewController, with an xib for the interface:
-(IBAction)getCameraPicture:(id)sender {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
PlayViewController* overlay = [[PlayViewController alloc] initWithNibName:#"PlayViewController" bundle:nil];
picker.cameraOverlayView = overlay.view;
[picker setDelegate:overlay];
[self presentModalViewController:picker animated:YES];
}
This is in the PlayViewController.m: code
#import "PlayViewController.h"
#import "SoundViewController.h"
#interface PlayViewController ()
#end
#implementation PlayViewControlleriPad...
`
PlayViewController.h:
#interface PlayViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
{
two array declarations...
}
#property (weak, nonatomic) IBOutlet UIButton *reloadButton;
#property (weak, nonatomic) IBOutlet UIButton *fireButton;
#property (weak, nonatomic) IBOutlet UITextField *ammoField;
#property (weak, nonatomic) IBOutlet UIImageView *type;
#end
Create your view controller and xib as usual, then add this to your code:
YourOverlay* overlay = [[YourOverlay alloc] initWithNibName:#"YourOverlayView" bundle:nil];
picker.cameraOverlayView = overlay.view;
[picker setDelegate:overlay];
[self presentModalViewController:picker animated:YES];
The overlay must implement UIImagePickerControllerDelegate and UINavigationControllerDelegate
picker.cameraOverlayView = someViewController.view;

Memory issue with iphone app development

I am developing an iphone application which uses very simple interface and does database handling at the backend. I am enabling ARC OPTION as well.
My viewDidLoad method is as follows:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
/*********needed to implement scroll view********/
svScroll.frame = CGRectMake(0, 0, 320, 460);
svScroll.contentSize = CGSizeMake(320, 800);
/*********************************************/
//[DataHelper openDbCompany];
NSString *date=[DataHelper getFinYr];
[btDate setTitle:[DataHelper dateSqliteToNormal:date] forState:UIControlStateNormal];
arrayUnitsMeasure=[[NSMutableArray alloc]initWithArray:[DataHelper getUnitsOfMeasure]];
//[DataHelper closeDbCompany];
tfValue.keyboardType=UIKeyboardTypeDecimalPad;
tfQuantity.keyboardType=UIKeyboardTypeDecimalPad;
tfCostUnit.keyboardType=UIKeyboardTypeDecimalPad;
//catching the notification for text field value change.
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(textFieldChanged:) name:UITextFieldTextDidChangeNotification object:tfQuantity];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(textFieldChanged:) name:UITextFieldTextDidChangeNotification object:tfCostUnit];
}
My .h file contains contains IBOutlets which are defined as follows:
#interface
Create_Inventory_Item:UIViewController<Date_Picker_Protocol,Picker_View_Protocol,UITextFieldDelegate>
{
IBOutlet UIScrollView *svScroll;
IBOutlet UITextField *tfItemName;
IBOutlet UILabel *lbUnitsOfMeasure;
IBOutlet UIButton *btSelectUnitsMeasure;
IBOutlet UIButton *btDate;
IBOutlet UINavigationBar *btBack;
IBOutlet UITextField *tfQuantity;
IBOutlet UITextField *tfCostUnit;
IBOutlet UITextField *tfValue;
IBOutlet UIButton *btCreate;
NSMutableArray *arrayUnitsMeasure;
UIButton *btKeyboardDone;
UIView *accessoryView;
UITextField *txtActiveField;
UIButton *btMinus;
Picker_View *callPickerView;
Date_Picker *callDatePicker;
}
#property(nonatomic,retain) UIButton *btMinus;
#property(nonatomic,retain)UITextField *txtActiveField;
#property(nonatomic,retain) UIButton *btKeyboardDone;
#property(nonatomic,retain)UIView *accessoryView;
#property(nonatomic,retain) IBOutlet UINavigationBar *btBack;
#property(nonatomic,retain)IBOutlet UIScrollView *svScroll;
#property(nonatomic,retain)IBOutlet UITextField *tfItemName;
#property(nonatomic,retain)IBOutlet UILabel *lbUnitsOfMeasure;
#property(nonatomic,retain)IBOutlet UIButton *btSelectUnitsMeasure;
#property(nonatomic,retain) IBOutlet UIButton *btDate;
#property(nonatomic,retain) IBOutlet UITextField *tfQuantity;
#property(nonatomic,retain) IBOutlet UITextField *tfCostUnit;
#property(nonatomic,retain)IBOutlet UITextField *tfValue;
#property(nonatomic,retain) IBOutlet UIButton *btCreate;
-(IBAction)btSelectUnitsMeasure:(id)sender;
-(IBAction)btDate:(id)sender;
-(IBAction)btCreate:(id)sender;
-(IBAction) hideKeyboard:(id)sender;
-(IBAction)showAlerView:(NSString *)message;
-(IBAction)btBack:(id)sender;
Please tell me what do I need to do in dealloc and viewDidUnloadMethod?
I am using ARC OPTION.
Also, when I run the app with profile option in simulator for memory allocation and leak, it sometimes shows MEMORY LEVEL LOW WARNING and MEMORY LEVEL NORMAL. What is the cause of this?
If you're using ARC you just need a dealloc that nullifies all the object-based members in that class instance.
All apps get memory warnings once in a while. You can choose to respond by nullifying members that can be lazy-initialized later.
In my apps I lazy-initialize most visual members (UIViews etc...) in viewWillAppear and aggressively release in the viewDidDisappear method. This way only 2 views can have their members initialized at once (during view controller transitions) and only 1 view when that view is the only visible one.
As a result I get very few memory warnings, except for when manipulating big images and such.

Changing width of UITabbarItems and margins between them in iPad app

Is it possible to change the width of UITabbarItem in UITabbar and margins between each UITabbarItem for iPad Application?
The problem is that standard margins are too large for my layout - client want tabs to be more compact :/
Or should I mess with UIToolbar to achieve this goal?
For Tabbar item width :
[[UITabBar appearance] setItemWidth:self.window.frame.size.width/NUMBER_OF_ITEMS];
For tabbar frame :
[self.tabBar setFrame:rectFrame];
I have solved just the same problem it this way:
my goal was to customize tab bar by using images, that were sent by the designer for me.
I have attached the .png files for the project, initialized the correspondent variables of type UIImage* and used UITabBarItem function setFinishedSelectedImage: withFinishedUnselectedImage: to set the images for active / inactive state of UITabbarItem:
UIImage * left_active, *left_inactive, *center_active, *center_inactive, *right_active, *right_inactive;
left_active = [UIImage imageNamed:#"left_active_img"];
...
[self.leftTabBarItem setFinishedSelectedImage:left_active withFinishedUnselectedImage:left_inactive];
[self.centerTabBarItem setFinishedSelectedImage:center_active withFinishedUnselectedImage:center_inactive];
[self.rightTabBarItem setFinishedSelectedImage:right_active withFinishedUnselectedImage:right_inactive];
But the customized tabbarItems were smaller, than the designer's images and were allocated at the center of the screen one upon other:
2) To fix this I have ADDED ADDITIONAL UITABBARITEMS - at the left and at the right corner of the initial ones
3) the were created the correspondent outlets for the UITabBarItems:
.h-file:
#property (nonatomic, retain) IBOutlet UITabBar * tabBar;
// THE INTIAL items
#property (nonatomic, retain) IBOutlet UITabBarItem * leftTabBarItem;
#property (nonatomic, retain) IBOutlet UITabBarItem * centerTabBarItem;
#property (nonatomic, retain) IBOutlet UITabBarItem * rightTabBarItem;
// THE ADDITIONAL items
#property (nonatomic, retain) IBOutlet UITabBarItem * left_1;
#property (nonatomic, retain) IBOutlet UITabBarItem * left_2;
#property (nonatomic, retain) IBOutlet UITabBarItem * center_1;
#property (nonatomic, retain) IBOutlet UITabBarItem * center_2;
#property (nonatomic, retain) IBOutlet UITabBarItem * right_1;
#property (nonatomic, retain) IBOutlet UITabBarItem * right_2;
then attached the Outlets to the UITabBarItems in the order listed below:
left_1
leftTabBarItem
left_2
center_1
centerTabBarItem
center_2
right_1
rightTabBarItem
right_2
and CORRECTED THE UITabbarDelegate METHOD in the delegating class to switch ONLY beet wen the visible items
.m-file:
#pragma mark - UITabbarDelegate
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item{
if (item == self.leftTabBarItem)
{
NSLog(#"0"); // first visible item selected
} else if (item == self.centerTabBarItem)
{
NSLog(#"1"); // second visible item selected
} else if (item == self.rightTabBarItem)
{
NSLog(#"2"); // third visible item selected
} else if (item == self.left_1){
[self.tabBar setSelectedItem: self.leftTabBarItem];
} else if (item == self.left_2){
[self.tabBar setSelectedItem: self.leftTabBarItem];
} else if (item == self.center_1){
[self.tabBar setSelectedItem: self.centerTabBarItem];
}else if (item == self.center_2){
[self.tabBar setSelectedItem: self.centerTabBarItem];
}else if (item == self.right_1){
[self.tabBar setSelectedItem: self.rightTabBarItem];
} else if (item == self.right_2){
[self.tabBar setSelectedItem: self.rightTabBarItem];
}
}
Now everything looks and works properly.
You can use the same steps to customize the size and interspaces between UITabBarItems by adding additional items and correcting delegate methods.
I don't think it is possible. You can create a custom tab bar. Also messing around with default UItabbar might cause rejection during App approval process.
You can change the spacing of the tab bar items by subclassing UITabBar and overriding its layoutSubviews method. You will find all tab bar buttons in the self.subViews array. Their class is the non-public UITabBarButton but they inherit from UIControl so you can identify all tab bar buttons checking if they are kind of UIControl class. Then all you need is to change the frame of the tab bar buttons.
You can use setSelectionIndicatorImage to make your tab more compact.
The UITabBarItem width in iPad will match the selectionIndicatorImage's width
in AppDelegate.m
[[UITabBar appearance] setItemWidth:self.window.frame.size.width/NUMBER_OF_YOUR_TAB];
[[UITabBar appearance] setItemSpacing:0];
[[UITabBar appearance] setSelectionIndicatorImage:[self imageFromColor:[UIColor clearColor] forSize:CGSizeMake(self.window.frame.size.width/NUMBER_OF_YOUR_TAB, 10) withCornerRadius:0]];
you can use below code to create a image programmatically
- (UIImage *)imageFromColor:(UIColor *)color forSize:(CGSize)size withCornerRadius:(CGFloat)radius
{
CGRect rect = CGRectMake(0, 0, size.width, size.height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIGraphicsBeginImageContext(size);
[[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius] addClip];
// Draw your image
[image drawInRect:rect];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
No subclassing is needed.
tabBarController.tabBar.itemPositioning = .centered
tabBarController.tabBar.itemWidth = 40
tabBarController.tabBar.itemSpacing = 38
You cannot change the width of the the UITabBarItem, and you cannot do this even after subclassing the UITabBarItem. Apple has certain restrictions in the way they want the developers to implement the applications.
You will need to use a UIToolBar for this, and my best bet is for you to go to github and as there a lot of sample applications which use a scrollable UIToolBar at the bottom instead of the UITabBar.

Calling pushViewController on a UINavigationController does nothing (no crash)

I have a UINavigationController as one of the views inside a tab bar control. It looks fine, and I have a UIBarButtonItem that is supposed to load a subview. I have the button wired up to an IBAction that calls pushViewController but when I do this nothing happens. It doesn't crash or anything.. it just doesn't do anything. I've tried: using different view controllers as the subview (no luck). Does anybody have any suggestions? Here is my code:
Header file:
#import <UIKit/UIKit.h>
#import "FSSettings.h"
#import "MeasureSelector.h"
#import "Dashboard.h"
#interface DashboardNavigationController : UIViewController {
IBOutlet UINavigationController *navController;
IBOutlet UINavigationBar *navBar;
IBOutlet UIBarButtonItem *measureButton;
}
#property (nonatomic, retain) IBOutlet UINavigationController *navController;
#property (nonatomic, retain) IBOutlet UINavigationBar *navBar;
#property (nonatomic, retain) IBOutlet UIBarButtonItem *measureButton;
- (IBAction) showMeasureScreen:(id)sender;
#end
And the .m file containing the action:
// Displays the measure screen
- (IBAction) showMeasureScreen:(id)sender
{
NSLog(#"Loaded measure screen");
MeasureSelector *msel = [[MeasureSelector alloc] initWithNibName:#"MeasureSelector" bundle:nil];
[[self navigationController] pushViewController:msel animated:YES];
NSLog(#"Done.");
}
When I click the button nothing happens (but I do see the log messages). I can do this over and over with no ill effects, however.
The navigationController property of UIViewController refers to the nav controller of which the UIViewController is part of the hierarchy. If I understand the scenario correctly, DashboardNavigationController manages the view that is the container for the UINavigationController, so it makes sense that this property would be nil.
Use the outlet you created to access the nav controller from outside of the nav controller's hierarchy.