UITabBar customisation not working as expected - objective-c

I have a three tab UITabBar in which the background of each tab is set, along with the background of the tabbar itself, as seen in the first image below. Each UITabBarItem has its FinishedSelectedImage and FinishedUnselectedImage set, and an NSString to its title. These images are glyphs (icons).
However, having set the selectionIndicatorImage to an image sized 106x48px, there is ~1px space to the right of the third tab, when in its selected state (see second photo).
Please can you tell me how I can remove the additional space? I have tried using an image sized 1px wider, but that made no difference.
Edit--- I read that this could be a problem due to an incorrectly sized selectionIndicatorImage, but I can confirm that this was not a fix -- I tried using a 107x49px image, and that too did not make a difference.
Max.
Tab Bar (how it should be upon selection)
Tab Bar (how it shows up on the third tab - notice the 1px on the right)
// customise the UITabBar - set the background image and the selected background image
[self.tabBarController.tabBar setBackgroundImage:[UIImage imageNamed:#"tab_bar"]];
[self.tabBarController.tabBar setSelectionIndicatorImage:[UIImage imageNamed:#"tabbar_selection_bg_3"]];
// this is in a for loop.
UITabBarItem *item = [[UITabBarItem alloc] init];
[item setTitle:[titles objectAtIndex:index]];
[item setImage:[UIImage imageNamed:[image_titles objectAtIndex:index]]];
[item setFinishedSelectedImage:[UIImage imageNamed:[[image_titles objectAtIndex:index] stringByAppendingString:#"_selected"]] withFinishedUnselectedImage:[UIImage imageNamed:[image_titles objectAtIndex:index]]];
[navigationController setTabBarItem:item];
[item release];

I ended up subclassing UITabBarController using three UIImageViews as each tab's selectionIndicatorBackground, and then using a further UIImageView to display the tab's glyph, and a UILabel for displaying its title.
Here is the code:
#interface LPTabBarController : UITabBarController
#property (nonatomic, retain) UIImageView *firstTab, *secondTab, *thirdTab, *firstTabBG, *secondTabBG, *thirdTabBG;
#property (nonatomic, retain) UILabel *firstTabLabel, *secondTabLabel, *thirdTabLabel;
#end
#implementation LPTabBarController
#synthesize firstTab, secondTab, thirdTab, firstTabBG, secondTabBG, thirdTabBG, firstTabLabel, secondTabLabel, thirdTabLabel;
- (id) init {
if ((self = [super init])) {
[self initialise];
}
return self;
}
- (void) setViewControllers:(NSArray *)viewControllers {
[self setViewControllers:viewControllers animated:NO];
}
- (void) setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated {
[super setViewControllers:viewControllers animated:animated];
for (UITabBarItem *item in self.tabBar.items) {
[item setEnabled:NO];
}
}
- (void) initialise {
UIImageView *bg = [[UIImageView alloc] initWithFrame:CGRectMake(0, self.tabBar.frame.origin.y - 10, 320, 59)];
[bg setUserInteractionEnabled:YES];
[bg setImage:[UIImage imageNamed:#"tab_bar"]];
CGFloat widthbg = ceilf(self.view.frame.size.width / 3);
CGFloat heightbg = self.tabBar.frame.size.height;
CGFloat width = 23, y = 5;
UITapGestureRecognizer *gest = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
self.firstTab = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tab_bar_user"]] autorelease];
[self.firstTab setFrame:CGRectMake(ceilf((widthbg - width) / 2), y, 23, 23)];
self.firstTabLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0, 27, widthbg, 20)] autorelease];
[self.firstTabLabel setTextAlignment:NSTextAlignmentCenter];
[self.firstTabLabel setText:#"Profile"];
[self.firstTabLabel setFont:[UIFont boldSystemFontOfSize:13]];
[self.firstTabLabel setTextColor:RGB(80, 23, 17)];
[self.firstTabLabel setShadowColor:[UIColor colorWithWhite:1 alpha:0.35]];
[self.firstTabLabel setShadowOffset:CGSizeMake(0, 1)];
[self.firstTabLabel setBackgroundColor:[UIColor clearColor]];
self.firstTabBG = [[[UIImageView alloc] initWithImage:nil] autorelease];
[self.firstTabBG setTag:01];
[self.firstTabBG setFrame:CGRectMake(0, 10, widthbg, heightbg)];
[self.firstTabBG addSubview:self.firstTab];
[self.firstTabBG addSubview:self.firstTabLabel];
[self.firstTabBG setUserInteractionEnabled:YES];
[self.firstTabBG addGestureRecognizer:gest];
[bg addSubview:self.firstTabBG];
[gest release];
gest = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
self.secondTab = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tab_bar_explore_selected"]] autorelease];
[self.secondTab setFrame:CGRectMake(ceilf((widthbg - width) / 2), y, 23, 23)];
self.secondTabLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0, 27, widthbg, 20)] autorelease];
[self.secondTabLabel setTextAlignment:NSTextAlignmentCenter];
[self.secondTabLabel setText:#"Explore"];
[self.secondTabLabel setFont:[UIFont boldSystemFontOfSize:13]];
[self.secondTabLabel setTextColor:RGB(80, 23, 17)];
[self.secondTabLabel setShadowColor:[UIColor colorWithWhite:1 alpha:0.35]];
[self.secondTabLabel setShadowOffset:CGSizeMake(0, 1)];
[self.secondTabLabel setBackgroundColor:[UIColor clearColor]];
self.secondTabBG = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tab_bar_selected_bg"]] autorelease];
[self.secondTabBG setTag:02];
[self.secondTabBG setUserInteractionEnabled:YES];
[self.secondTabBG addGestureRecognizer:gest];
[self.secondTabBG setFrame:CGRectMake(widthbg, 10, widthbg, heightbg)];
[self.secondTabBG addSubview:self.secondTab];
[self.secondTabBG addSubview:self.secondTabLabel];
[bg addSubview:self.secondTabBG];
[self tapped:gest];
[gest release];
gest = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
self.thirdTab = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tab_bar_settings"]] autorelease];
[self.thirdTab setFrame:CGRectMake(ceilf((widthbg - width) / 2), y, 23, 23)];
self.thirdTabLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0, 27, widthbg, 20)] autorelease];
[self.thirdTabLabel setTextAlignment:NSTextAlignmentCenter];
[self.thirdTabLabel setText:#"Settings"];
[self.thirdTabLabel setFont:[UIFont boldSystemFontOfSize:13]];
[self.thirdTabLabel setTextColor:RGB(80, 23, 17)];
[self.thirdTabLabel setShadowColor:[UIColor colorWithWhite:1 alpha:0.35]];
[self.thirdTabLabel setShadowOffset:CGSizeMake(0, 1)];
[self.thirdTabLabel setBackgroundColor:[UIColor clearColor]];
self.thirdTabBG = [[[UIImageView alloc] initWithImage:nil] autorelease];
[self.thirdTabBG setTag:03];
[self.thirdTabBG setFrame:CGRectMake(widthbg * 2, 10, widthbg, heightbg)];
[self.thirdTabBG addSubview:self.thirdTab];
[self.thirdTabBG addSubview:self.thirdTabLabel];
[self.thirdTabBG setUserInteractionEnabled:YES];
[self.thirdTabBG addGestureRecognizer:gest];
[bg addSubview:self.thirdTabBG];
[gest release];
[self.view addSubview:bg];
[bg release];
}
static int lastIndex = 2;
- (void) tapped:(UITapGestureRecognizer *) gest {
switch (lastIndex) {
case 1:
[self.firstTab setImage:[UIImage imageNamed:#"tab_bar_user"]];
[self.firstTabBG setImage:nil];
[self.firstTabLabel setTextColor:RGB(80, 23, 17)];
[self.firstTabLabel setShadowColor:[UIColor colorWithWhite:1 alpha:0.35]];
[self.firstTabLabel setShadowOffset:CGSizeMake(0, 1)];
break;
case 2:
[self.secondTab setImage:[UIImage imageNamed:#"tab_bar_explore"]];
[self.secondTabBG setImage:nil];
[self.secondTabLabel setTextColor:RGB(80, 23, 17)];
[self.secondTabLabel setShadowColor:[UIColor colorWithWhite:1 alpha:0.35]];
[self.secondTabLabel setShadowOffset:CGSizeMake(0, 1)];
break;
case 3:
[self.thirdTab setImage:[UIImage imageNamed:#"tab_bar_settings"]];
[self.thirdTabBG setImage:nil];
[self.thirdTabLabel setTextColor:RGB(80, 23, 17)];
[self.thirdTabLabel setShadowColor:[UIColor colorWithWhite:1 alpha:0.35]];
[self.thirdTabLabel setShadowOffset:CGSizeMake(0, 1)];
break;
}
switch (gest.view.tag) {
case 1 :{
[self setSelectedIndex:0];
[self.firstTab setImage:[UIImage imageNamed:#"tab_bar_user_selected"]];
[self.firstTabBG setImage:[UIImage imageNamed:#"tab_bar_selected_bg"]];
[self.firstTabLabel setTextColor:RGB(252, 208, 170)];
[self.firstTabLabel setShadowColor:RGB(80, 23, 17)];
[self.firstTabLabel setShadowOffset:CGSizeMake(0, -1)];
break;
}
case 2: {
[self setSelectedIndex:1];
[self.secondTab setImage:[UIImage imageNamed:#"tab_bar_explore_selected"]];
[self.secondTabBG setImage:[UIImage imageNamed:#"tab_bar_selected_bg"]];
[self.secondTabLabel setTextColor:RGB(252, 208, 170)];
[self.secondTabLabel setShadowColor:RGB(80, 23, 17)];
[self.secondTabLabel setShadowOffset:CGSizeMake(0, -1)];
break;
}
case 3: {
[self setSelectedIndex:2];
[self.thirdTab setImage:[UIImage imageNamed:#"tab_bar_settings_selected"]];
[self.thirdTabBG setImage:[UIImage imageNamed:#"tab_bar_selected_bg"]];
[self.thirdTabLabel setTextColor:RGB(252, 208, 170)];
[self.thirdTabLabel setShadowColor:RGB(80, 23, 17)];
[self.thirdTabLabel setShadowOffset:CGSizeMake(0, -1)];
break;
}
}
lastIndex = gest.view.tag;
}
- (void) dealloc {
[firstTab release];
[firstTabBG release];
[secondTab release];
[secondTabBG release];
[thirdTab release];
[thirdTabBG release];
[firstTabLabel release];
[secondTabLabel release];
[thirdTabLabel release];
[super dealloc];
}

Related

UIView Animation Block Not Doing Anything

I have a very small animation I want to do by moving a view's frame using blocks (rather than the animation headers).
My view hierarchy is quite big so I will explain everything in regards of the specific view I want to animate.
The biggest view is the one that takes the whole screen, so it is 320x480 points. Inside this view, I have another view called "keypadContainerView" that is 320x200 points, located on 0, 261 and it appears at the bottom of the screen. This keypadContainerView has a subview called keypadView, which has a bunch of small buttons as subviews.
Biggest View -> KeypadContainerView -> keypadView -> UIbuttons.
An screenshot:
Although this could go without saying, the keypad there is the keypadContainerView, with is't keypadView and buttons. I need this hierarchy because I'm aiming for eye candy here, and each layer has a different background.
The way I create and deal with that view is here:
keypadViewContainer = [[[UIView alloc] initWithFrame:CGRectMake(0, 261, 320, 200)] autorelease]; //(Original is 0, 261, 320, 200)
keypadView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 200)];
[keypadViewContainer addSubview:keypadView];
//Add the buttons
[self.view addSubview:keypadViewContainer];
And this is how I'm trying to animate it:
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[UIView animateWithDuration:5.0 animations:^{
self.keypadViewContainer.frame = CGRectMake(0, 0, 320, 200);
} completion:NULL];
}
What is funny is that if I NSLog something in the animations: parameter, I actually get some output so the method is definitely getting called. It's just not animating anything at all.
The whole controller code is here, in case you need it:
//UnlockKeyboardViewController
//------------------------------------------------------------------------
#interface UnlockKeyboardViewController : UIViewController
{
NSArray *buttons;
NSArray *passcodeFields;
UIImage *buttonBackgroundImage;
UIImage *buttonBackgroundHighlightedImage;
UIImage *middleButtonBackgroundImage;
UIImage *middleButtonBackgroundImageHighlighted;
UIImage *screenBackgroundImage;
UIImage *infoViewContainerImage;
UIImage *keypadViewContainerImage;
UIImage *passcodeFieldsContainerImage;
UIImage *infoViewImage;
UIImage *passcodeViewImage;
UIView *infoViewContainer;
UIView *keypadViewContainer;
UIView *passcodeFieldsContainer;
UIView *infoView;
UIView *keypadView;
UIView *passcodeFieldsView;
UIView *infoToDisplayView; //The view the programmer passes to show in infoView.
}
#property(nonatomic, retain)UIImage *buttonBackgroundImage;
#property(nonatomic, retain)UIImage *buttonBackgroundHighlightedImage;
#property(nonatomic, retain)UIImage *screenBackgroundImage;
#property(nonatomic, retain)UIImage *keypadViewBackgroundImage;
#property(nonatomic, retain)UIImage *infoViewContainerImage;
#property(nonatomic, retain)UIImage *keypadViewContainerImage;
#property(nonatomic, retain)UIImage *passcodeFieldsContainerImage;
#property(nonatomic, retain)UIImage *infoViewImage;
#property(nonatomic, retain)UIImage *passcodeViewImage;
#property(nonatomic, retain)UIView *infoToDisplayView;
//Properties for container views.
#property(nonatomic, retain)UIView *infoViewContainer;
#property(nonatomic, retain)UIView *keypadViewContainer;
#property(nonatomic, retain)UIView *passcodeFieldsContainer;
#end
#implementation UnlockKeyboardViewController
#synthesize buttonBackgroundImage = _buttonBackgroundImage;
#synthesize buttonBackgroundHighlightedImage = _buttonBackgroundHighlightedImage;
#synthesize screenBackgroundImage = _screenBackgroundImage;
#synthesize keypadViewBackgroundImage = _keypadViewBackgroundImage;
#synthesize infoViewContainerImage = _infoViewContainerImage;
#synthesize keypadViewContainerImage = _keypadViewContainerImage;
#synthesize passcodeFieldsContainerImage = _passcodeFieldsContainerImage;
#synthesize infoViewImage = _infoViewImage;
#synthesize passcodeViewImage = _passcodeViewImage;
#synthesize infoToDisplayView = _infoToDisplayView;
//Synthesizers for container views.
#synthesize infoViewContainer = _infoViewContainer;
#synthesize keypadViewContainer = _keypadViewContainer;
#synthesize passcodeFieldsContainer = _passcodeFieldsContainer;
-(void)loadView
{
[super loadView];
self.view.frame = CGRectMake(0, 0, 320, 480);
_unlockKeyboardBundle = [NSBundle bundleForClass:[self class]];
buttonBackgroundImage = [UIImage imageWithContentsOfFile:[_unlockKeyboardBundle pathForResource:#"button" ofType:#"png"]];
middleButtonBackgroundImage = [UIImage imageWithContentsOfFile:[_unlockKeyboardBundle pathForResource:#"middleButton" ofType:#"png"]];
buttonBackgroundHighlightedImage = [UIImage imageWithContentsOfFile:[_unlockKeyboardBundle pathForResource:#"pushedButton" ofType:#"png"]];
middleButtonBackgroundImageHighlighted = [UIImage imageWithContentsOfFile:[_unlockKeyboardBundle pathForResource:#"pushedButtonMiddle" ofType:#"png"]];
infoViewContainerImage = [UIImage imageWithContentsOfFile:[_unlockKeyboardBundle pathForResource:#"infoViewContainerImage" ofType:#"png"]];
keypadViewContainerImage = [UIImage imageWithContentsOfFile:[_unlockKeyboardBundle pathForResource:#"keypadViewContainerImage" ofType:#"png"]];
passcodeFieldsContainerImage = [UIImage imageWithContentsOfFile:[_unlockKeyboardBundle pathForResource:#"passcodeViewContainerImage" ofType:#"png"]];
infoViewImage = [UIImage imageWithContentsOfFile:[_unlockKeyboardBundle pathForResource:#"infobackground" ofType:#"png"]];
passcodeViewImage = [UIImage imageWithContentsOfFile:[_unlockKeyboardBundle pathForResource:#"passcodescreen" ofType:#"png"]];
//self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithContentsOfFile:[_unlockKeyboardBundle pathForResource:#"lockbackground" ofType:#"png"]]];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
keypadViewContainer = [[[UIView alloc] initWithFrame:CGRectMake(0, 261, 320, 200)] autorelease]; //(Original is 0, 261, 320, 200)
keypadView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 200)];
[keypadViewContainer addSubview:keypadView];
keypadViewContainer.backgroundColor = [UIColor colorWithPatternImage:keypadViewContainerImage];
NSMutableArray *tempButtons = [NSMutableArray array];
self.view.opaque = YES;
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeCustom];
[button1 setTitle:#"1" forState:UIControlStateNormal];
button1.frame = CGRectMake(0, 0, 106, 50);
UIButton *button4 = [UIButton buttonWithType:UIButtonTypeCustom];
[button4 setTitle:#"4" forState:UIControlStateNormal];
button4.frame = CGRectMake(0, 50, 106, 50);
UIButton *button7 = [UIButton buttonWithType:UIButtonTypeCustom];
[button7 setTitle:#"7" forState:UIControlStateNormal];
button7.frame = CGRectMake(0, 100, 106, 50);
UIButton *cancel = [UIButton buttonWithType:UIButtonTypeCustom];
[cancel setTitle:NSLocalizedString(#"cancel", #"Cancel string") forState:UIControlStateNormal];
cancel.frame = CGRectMake(0, 150, 106, 50);
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeCustom];
[button2 setTitle:#"2" forState:UIControlStateNormal];
button2.frame = CGRectMake(106, 0, 108, 50);
UIButton *button5 = [UIButton buttonWithType:UIButtonTypeCustom];
[button5 setTitle:#"5" forState:UIControlStateNormal];
button5.frame = CGRectMake(106, 50, 108, 50);
UIButton *button8 = [UIButton buttonWithType:UIButtonTypeCustom];
[button8 setTitle:#"8" forState:UIControlStateNormal];
button8.frame = CGRectMake(106, 100, 108, 50);
UIButton *button0 = [UIButton buttonWithType:UIButtonTypeCustom];
[button0 setTitle:#"0" forState:UIControlStateNormal];
button0.frame = CGRectMake(106, 150, 108, 50);
UIButton *button3 = [UIButton buttonWithType:UIButtonTypeCustom];
[button3 setTitle:#"3" forState:UIControlStateNormal];
button3.frame = CGRectMake(214, 0, 106, 50);
UIButton *button6 = [UIButton buttonWithType:UIButtonTypeCustom];
[button6 setTitle:#"6" forState:UIControlStateNormal];
button6.frame = CGRectMake(214, 50, 106, 50);
UIButton *button9 = [UIButton buttonWithType:UIButtonTypeCustom];
[button9 setTitle:#"9" forState:UIControlStateNormal];
button9.frame = CGRectMake(214, 100, 106, 50);
UIButton *cancelOrDelete = [UIButton buttonWithType:UIButtonTypeCustom];
[cancelOrDelete setTitle:#"<-" forState:UIControlStateNormal];
cancelOrDelete.frame = CGRectMake(214, 150, 108, 50);
[tempButtons addObject:button1];
[tempButtons addObject:button2];
[tempButtons addObject:button3];
[tempButtons addObject:button4];
[tempButtons addObject:button5];
[tempButtons addObject:button6];
[tempButtons addObject:button7];
[tempButtons addObject:button8];
[tempButtons addObject:button9];
[tempButtons addObject:button0];
[tempButtons addObject:cancel];
[tempButtons addObject:cancelOrDelete];
buttons = [[NSArray arrayWithArray:tempButtons] retain];
for(UIButton *theButton in buttons)
{
if([theButton.currentTitle isEqualToString:#"2"] || [theButton.currentTitle isEqualToString:#"5"] || [theButton.currentTitle isEqualToString:#"8"] || [theButton.currentTitle isEqualToString:#"0"])
{
[theButton setBackgroundImage:middleButtonBackgroundImage forState:UIControlStateNormal];
[theButton setBackgroundImage:middleButtonBackgroundImageHighlighted forState:UIControlStateHighlighted];
}else
{
[theButton setBackgroundImage:buttonBackgroundImage forState:UIControlStateNormal];
[theButton setBackgroundImage:middleButtonBackgroundImageHighlighted forState:UIControlStateHighlighted];
}
[keypadView addSubview:theButton];
}
[self.view addSubview:keypadViewContainer];
passcodeFieldsView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0,320, 110)] autorelease];
passcodeFieldsContainer = [[[UIView alloc] initWithFrame:CGRectMake(0, 151, 320, 110)] autorelease];
passcodeFieldsContainer.backgroundColor = [UIColor colorWithPatternImage:passcodeFieldsContainerImage];
passcodeFieldsView.backgroundColor = [UIColor colorWithPatternImage:passcodeViewImage];
NSMutableArray *passTemps = [NSMutableArray array];
UITextField *tf1 = [[[UITextField alloc] initWithFrame:CGRectMake(24, 27, 50, 50)] autorelease];
UITextField *tf2 = [[[UITextField alloc] initWithFrame:CGRectMake(98, 27, 50, 50)] autorelease];
UITextField *tf3 = [[[UITextField alloc] initWithFrame:CGRectMake(172, 27, 50, 50)] autorelease];
UITextField *tf4 = [[[UITextField alloc] initWithFrame:CGRectMake(246, 27, 50, 50)] autorelease];
[passTemps addObject:tf1];
[passTemps addObject:tf2];
[passTemps addObject:tf3];
[passTemps addObject:tf4];
passcodeFields = [[NSArray arrayWithArray:passTemps] retain];
for(UITextField *theTf in passcodeFields)
{
theTf.borderStyle = UITextBorderStyleBezel;
theTf.backgroundColor = [UIColor whiteColor];
theTf.enabled = NO;
theTf.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
theTf.textAlignment = UITextAlignmentCenter;
theTf.adjustsFontSizeToFitWidth = YES;
theTf.alpha = 0.7;
theTf.secureTextEntry = YES;
[passcodeFieldsView addSubview:theTf];
}
[passcodeFieldsContainer addSubview:passcodeFieldsView];
[self.view addSubview:passcodeFieldsContainer];
infoView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 151)] autorelease];
infoView.backgroundColor = [UIColor colorWithPatternImage:infoViewImage];
infoViewContainer = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 151)] autorelease];
infoViewContainer.backgroundColor = [UIColor colorWithPatternImage:infoViewContainerImage];
[infoViewContainer addSubview:infoView];
[self.view addSubview:infoViewContainer];
[pool drain];
}
-(void)viewDidLoad
{
[super viewDidLoad];
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[UIView animateWithDuration:5.0 animations:^{
self.keypadViewContainer.frame = CGRectMake(0, 0, 320, 200);
} completion:NULL];
}
-(void)dealloc
{
[buttons release];
[passcodeFields release];
[buttonBackgroundImage release];
[buttonBackgroundHighlightedImage release];
[screenBackgroundImage release];
[infoView release];
[keypadView release];
[passcodeFieldsView release];
[infoViewContainerImage release];
[keypadViewContainerImage release];
[passcodeFieldsContainerImage release];
[infoViewImage release];
[passcodeViewImage release];
[infoToDisplayView release];
[super dealloc];
}
#end
I have a small feeling it may have something to do with the way I'm dealing with my views, so there's the whole source code.
Any help with this will be highly appreciated.
Instead of those :
keypadViewContainer = [[[UIView alloc] initWithFrame:CGRectMake(0, 261, 320, 200)] autorelease];
Use
Self.keypadViewContainer = .....
and your #synthesize are wrong.
You declare iVars explicitly without underscore,
But use synthesize to create underscored iVars.
So your properties correspond to
_keypadViewContainer
but in your loadView you assign to keypadViewController
Quickest fix: just use #synthesize instead of synthesize = ...
(that is only if you don't use Xcode 4.4!)
Best fix: get rid of the explicit iVar declaration and
Make sure to use _keypadViewContainer etc. when you access iVar directly like in dealloc.
Ideal fix: use ARC and use IB to build your keypad interface (why don't you btw?)

Altering selected state for UITableViewCell

I've got a standard UITableView where each cell is a custom UIView. Everything works fine, except when the cell is selected, it turns blue (as expected) but the UIView is hidden!
How can I change the contents of the view to be visible when the cell is selected?
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 100)];
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, 300, 40)];
[headerLabel setText:[[[todayCollection events]objectAtIndex:indexPath.row]name]];
[headerLabel setFont:[UIFont boldSystemFontOfSize:22]];
headerLabel.highlightedTextColor = [UIColor whiteColor];
UILabel *venueLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 40, 300, 20)];
[venueLabel setText:[[[[todayCollection events]objectAtIndex:indexPath.row]venue]name]];
[venueLabel setFont:[UIFont italicSystemFontOfSize:16]];
LBVenueBadge *venueBadge = [[LBVenueBadge alloc] initWithGenre:[[[todayCollection events]objectAtIndex:indexPath.row]genre] frame:CGRectMake(85, 73, 100, 20)];
UIImageView *pinImage = [[UIImageView alloc] initWithFrame:CGRectMake(10, 75, 18, 18)];
[pinImage setImage:[UIImage imageNamed:#"193-location-arrow.png"]];
UILabel *distanceLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 75, 100, 15)];
[distanceLabel setFont:[UIFont systemFontOfSize:12]];
NSString *distanceString = [[[[todayCollection events]objectAtIndex:indexPath.row]venue]distanceString];
if([[[[todayCollection events]objectAtIndex:indexPath.row]performances]count] == 1)
{
UILabel *performanceLabel = [[UILabel alloc] initWithFrame:CGRectMake(200, 75, 50, 15)];
[performanceLabel setText:[[[[[todayCollection events]objectAtIndex:indexPath.row]performances]objectAtIndex:0]time]];
[performanceLabel setBackgroundColor:[UIColor clearColor]];
[performanceLabel setFont:[UIFont systemFontOfSize:12]];
[containerView addSubview:performanceLabel];
}else{
UILabel *performanceLabel = [[UILabel alloc] initWithFrame:CGRectMake(200, 75, 50, 15)];
[performanceLabel setText:[NSString stringWithFormat:#"%i shows", [[[[todayCollection events]objectAtIndex:indexPath.row]performances]count]]];
[performanceLabel setBackgroundColor:[UIColor clearColor]];
[performanceLabel setFont:[UIFont systemFontOfSize:12]];
[containerView addSubview:performanceLabel];
}
[distanceLabel setText:distanceString];
[containerView addSubview:pinImage];
[distanceLabel setBackgroundColor:[UIColor clearColor]];
[containerView addSubview:distanceLabel];
[headerLabel setBackgroundColor:[UIColor clearColor]];
[containerView addSubview:headerLabel];
[venueLabel setBackgroundColor:[UIColor clearColor]];
[containerView addSubview:venueLabel];
[containerView addSubview:venueBadge];
if(indexPath.row % 2 == 0)
{
[containerView setBackgroundColor:[UIColor colorWithRed:0.239 green:0.239 blue:0.232 alpha:0.05]];
}else{
[containerView setBackgroundColor:[UIColor colorWithRed:0.239 green:0.239 blue:0.232 alpha:0.02]];
}
cell.backgroundView = containerView;
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
return cell;
}
Thanks,
As the contentView property is readonly, I can add a subview to it instead.
[cell.contentView addSubview:containerView];
You are adding views to the background rather than the contentView of the cell replace this line.
cell.backgroundView = containerView;
with
[cell.contentView addSubview:containerView];

big tableview scrolling lags

i have a performance issue in my tableview
my cellForRow looks like that:
if (tableView == allMonthTable) {
static NSString *cellIdentifier = #"cell";
AllMonthCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[AllMonthCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier] ;
}
Month *mo = [[dataHandler allMonth]objectAtIndex:indexPath.section];
double budgetValue = mo.budget.doubleValue;
[cell.budgetLabel setText:[NSString stringWithFormat:#"%.2f",budgetValue ]];
double spentValue = mo.spent.doubleValue;
[cell.spentLabel setText:[NSString stringWithFormat:#"%.2f",spentValue ]];
if (spentValue > 0) {
[cell.spentLabel setText:[NSString stringWithFormat:#"+%.2f",spentValue]];
[cell.spentLabel setTextColor:[self greenColor]];
}
else if (spentValue < 0){
[cell.spentLabel setText:[NSString stringWithFormat:#"%.2f",spentValue]];
[cell.spentLabel setTextColor:[self redColor]];
}
double balanceValue = budgetValue+spentValue;
[cell.balanceLabel setText:[NSString stringWithFormat:#"%.2f",balanceValue ]];
if (balanceValue > 0) {
[cell.balanceLabel setText:[NSString stringWithFormat:#"+%.2f",balanceValue]];
[cell.balanceLabel setTextColor:[self greenColor]];
}
else{
[cell.balanceLabel setText:[NSString stringWithFormat:#"%.2f",balanceValue]];
[cell.balanceLabel setTextColor:[self redColor]];
}
double avgDayValue = mo.avgDay.doubleValue;
[cell.avgDayLabel setText:[NSString stringWithFormat:#"%.2f",avgDayValue ]];
if (avgDayValue > 0) {
[cell.avgDayLabel setText:[NSString stringWithFormat:#"+%.2f",avgDayValue]];
}
int numberOfExpValue = mo.expenses.intValue;
[cell.numberOfExpLabel setText:[NSString stringWithFormat:#"%d",numberOfExpValue ]];
return cell;
}
return nil;
}
and my AllMonthCell.m files looks like that:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
UIFont *font = [UIFont fontWithName:#"Cochin" size:14.0];
UIFont *fontBold = [UIFont fontWithName:#"Cochin-Bold" size:14.0];
self.frame = CGRectMake(0, 0, 312, 100);
UIView *top = [[UIView alloc]initWithFrame:CGRectMake(4, 0, 304, 1)];
[top setBackgroundColor:[UIColor lightGrayColor]];
UILabel *budgetStringLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 102, 16)];
[budgetStringLabel setTextAlignment:UITextAlignmentLeft];
[budgetStringLabel setFont:font];
[budgetStringLabel setTextColor:[UIColor lightGrayColor]];
[budgetStringLabel setText:#"Month Budget:"];
[budgetStringLabel setBackgroundColor:[self grayColor]];
UILabel *spentStringLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 30, 102, 16)];
[spentStringLabel setTextAlignment:UITextAlignmentLeft];
[spentStringLabel setFont:font];
[spentStringLabel setTextColor:[UIColor lightGrayColor]];
[spentStringLabel setText:#"Spent Money:"];
[spentStringLabel setBackgroundColor:[self grayColor]];
UIView *divide1 = [[UIView alloc]initWithFrame:CGRectMake(10, 50, 292, 1)];
[divide1 setBackgroundColor:[UIColor lightGrayColor]];
UILabel *balanceStringLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 55, 102, 16)];
[balanceStringLabel setTextAlignment:UITextAlignmentLeft];
[balanceStringLabel setFont:font];
[balanceStringLabel setTextColor:[UIColor lightGrayColor]];
[balanceStringLabel setText:#"Month Balance:"];
[balanceStringLabel setBackgroundColor:[self grayColor]];
UIView *divide2 = [[UIView alloc]initWithFrame:CGRectMake(10, 74, 292, 1)];
UIView *divide3 = [[UIView alloc]initWithFrame:CGRectMake(10, 76, 292, 1)];
[divide2 setBackgroundColor:[UIColor lightGrayColor]];
[divide3 setBackgroundColor:[UIColor lightGrayColor]];
UILabel *avgDayStringLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 94, 200, 16)];
[avgDayStringLabel setTextAlignment:UITextAlignmentLeft];
[avgDayStringLabel setFont:font];
[avgDayStringLabel setTextColor:[UIColor lightGrayColor]];
[avgDayStringLabel setText:#"Per Day:"];
[avgDayStringLabel setBackgroundColor:[self grayColor]];
UILabel *numberOfExpStringLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 114, 102, 16)];
[numberOfExpStringLabel setTextAlignment:UITextAlignmentLeft];
[numberOfExpStringLabel setFont:font];
[numberOfExpStringLabel setTextColor:[UIColor lightGrayColor]];
[numberOfExpStringLabel setText:#"Expenses Made:"];
[numberOfExpStringLabel setBackgroundColor:[self grayColor]];
[self addSubview:budgetStringLabel];
[self addSubview:top];
[self addSubview:spentStringLabel];
[self addSubview:divide1];
[self addSubview:balanceStringLabel];
[self addSubview:divide2];
[self addSubview:divide3];
[self addSubview:numberOfExpStringLabel];
[self addSubview:avgDayStringLabel];
self.budgetLabel = [[UILabel alloc]initWithFrame:CGRectMake(200, 10, 102, 16)];
[self.budgetLabel setTextAlignment:UITextAlignmentRight];
[self.budgetLabel setFont:font];
[self.budgetLabel setBackgroundColor:[self grayColor]];
[self.budgetLabel setTextColor:[UIColor darkGrayColor]];
self.spentLabel = [[UILabel alloc]initWithFrame:CGRectMake(200, 30, 102, 16)];
[self.spentLabel setTextAlignment:UITextAlignmentRight];
[self.spentLabel setFont:font];
[self.spentLabel setBackgroundColor:[self grayColor]];
[self.spentLabel setTextColor:[UIColor lightGrayColor]];
self.balanceLabel = [[UILabel alloc]initWithFrame:CGRectMake(200, 55, 102, 16)];
[self.balanceLabel setTextAlignment:UITextAlignmentRight];
[self.balanceLabel setFont:fontBold];
[self.balanceLabel setBackgroundColor:[self grayColor]];
self.avgDayLabel = [[UILabel alloc]initWithFrame:CGRectMake(200, 94, 102, 16)];
[self.avgDayLabel setFont:font];
[self.avgDayLabel setBackgroundColor:[self grayColor]];
[self.avgDayLabel setTextColor:[UIColor lightGrayColor]];
[self.avgDayLabel setTextAlignment:UITextAlignmentRight];
self.numberOfExpLabel = [[UILabel alloc]initWithFrame:CGRectMake(200, 114, 102, 16)];
[self.numberOfExpLabel setTextAlignment:UITextAlignmentRight];
[self.numberOfExpLabel setFont:font];
[self.numberOfExpLabel setBackgroundColor:[self grayColor]];
[self.numberOfExpLabel setTextColor:[UIColor lightGrayColor]];
[self addSubview:self.budgetLabel];
[self addSubview:self.spentLabel];
[self addSubview:self.balanceLabel];
[self addSubview:self.numberOfExpLabel];
[self addSubview:self.avgDayLabel];
[self setBackgroundColor:[self grayColor]];
}
return self;
}
here is a screenshot of time profiling while scrolling:
so i create reusable cells of the type AllMonthCell, and assign the values to them, is there a way to make it faster? i have pretty serious lags while scrolling the table..
a hint would be great :)
You should reuse the cells
Let me derive you a pattern
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"cell";
UILabel *noExpense;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier] autorelease];
//Just the view alone should be created here no assigning of data here
//let me add just one custom view for easy understanding
noExpense = [[UILabel alloc]initWithFrame:CGRectMake(8, 20, 296, 16)];
[noExpense setTextAlignment:UITextAlignmentCenter];
[noExpense setFont:fontName];
//[noExpense setText:#"No data available yet."]; Dont do this
[noExpense setTextColor:[UIColor lightGrayColor]];
[noExpense setBackgroundColor:tableView.backgroundColor];
[noExpense setTag:100]; //Must set tag here
[cell addSubview:noExpense];
}
else
{
noExpense = [cell viewWithTag:100];
//You have to initialize your custom views which you created already.
//Just the view alone should be assigned here no assigning of data here
}
//Load all the data into the views here
[noExpense setText:#"Somedata which you have to set"];
return cell;
}
To know more about tableview see the doc. Its the bible for understanding tableviews.
http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7

how to redirect to a new screen on the button click in the table view in objective c

I have created a table view and added some labels and displaying it, now i need a button in each cell, where on click on the button, it has redirect to the new screen.
The following is the code which i am trying to redirect,
- (void)viewDidLoad
{
vendorsArray = [CommonUserDetails sharedUserDetails].mVendorDictionary;
NSLog(#"vendorsArray is %# \n count is %d",vendorsArray,[vendorsArray count]);
loTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 43, 320, 400) style:UITableViewStylePlain];
[loTableView setBackgroundColor:[UIColor whiteColor]];
loTableView.delegate = self;
loTableView.dataSource = self;
loTableView.separatorColor = [UIColor grayColor];
[self.view addSubview:loTableView];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:#"myCell"];
if (cell == nil)
{
cell = [self tableviewCellWithReuseIdentifier:#"myCell"];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[self configureCell:cell forIndexPath:indexPath];
//cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
#define L1_TAG 1
#define L2_TAG 2
#define L3_TAG 3
#define L4_TAG 4
- (UITableViewCell *)tableviewCellWithReuseIdentifier:(NSString *)identifier
{
UITableViewCell* cell = [[UITableViewCell alloc]initWithFrame:CGRectMake(0, 0, 320, 100)reuseIdentifier:identifier];
UILabel* l1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 290, 30)];
[l1 setBackgroundColor:[UIColor clearColor]];
[l1 setFont:[UIFont systemFontOfSize:14]];
// [l1 setTextColor:[UIColor blackColor]];
l1.textColor = [UIColor colorWithRed:153/(CGFloat)255 green:51/(CGFloat)255 blue:0 alpha:1.0];
[l1 setAdjustsFontSizeToFitWidth:YES];
[l1 setTextAlignment:UITextAlignmentRight];
l1.tag = L1_TAG;
[cell.contentView addSubview:l1];
UILabel* l2 = [[UILabel alloc] initWithFrame:CGRectMake(5, 20 , 300, 30)];
[l2 setBackgroundColor:[UIColor clearColor]];
l2.font = [UIFont boldSystemFontOfSize:14];
l2.textColor = [UIColor blackColor];
//l2.textColor = [UIColor colorWithRed:102/(CGFloat)255 green:102/(CGFloat)255 blue:153/(CGFloat)255 alpha:1.0];
l2.tag = L2_TAG;
[l2 setTextAlignment:UITextAlignmentLeft];
[cell.contentView addSubview:l2];
UILabel* l3 = [[UILabel alloc] initWithFrame:CGRectMake(5, 40, 190, 30)];
[l3 setBackgroundColor:[UIColor clearColor]];
[l3 setFont:[UIFont systemFontOfSize:14]];
[l3 setTextColor:[UIColor grayColor]];
// l3.textColor = [UIColor colorWithRed:102/(CGFloat)255 green:102/(CGFloat)255 blue:0/(CGFloat)255 alpha:1.0];
[l3 setAdjustsFontSizeToFitWidth:YES];
l3.tag = L3_TAG;
[cell.contentView addSubview:l3];
UILabel* l4 = [[UILabel alloc] initWithFrame:CGRectMake(5, 60, 190, 30)];
[l4 setBackgroundColor:[UIColor clearColor]];
[l4 setFont:[UIFont systemFontOfSize:14]];
[l4 setTextColor:[UIColor grayColor]];
//l4.textColor = [UIColor colorWithRed:0/(CGFloat)255 green:51/(CGFloat)255 blue:0/(CGFloat)255 alpha:1.0];
[l4 setAdjustsFontSizeToFitWidth:YES];
l4.tag = L4_TAG;
[cell.contentView addSubview:l4];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(150, 60, 70, 30);
[button setTitle:#"Pay" forState:UIControlStateNormal];
[cell.contentView addSubview:button];
[button addTarget:self action:#selector(payButton)
forControlEvents:UIControlEventTouchUpInside];
return cell;
}
- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath
{
UILabel *myl1 = (UILabel*)[cell viewWithTag:L1_TAG];
UILabel *myl2 = (UILabel*)[cell viewWithTag:L2_TAG];
UILabel *myl3 = (UILabel*)[cell viewWithTag:L3_TAG];
UILabel *myl4 = (UILabel*)[cell viewWithTag:L4_TAG];
NSDictionary *dictionary = [vendorsArray objectAtIndex:indexPath.row];
myl1.text= [NSString stringWithFormat:#"INo:%#",[dictionary objectForKey:#"iNo"]];
myl2.text=[dictionary objectForKey:#"vendorName"];
myl3.text= [NSString stringWithFormat:#"Amount:%#",[dictionary objectForKey:#"amount"]];
myl4.text= [NSString stringWithFormat:#"DDate:%#",[dictionary objectForKey:#"dDate"]];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
NSLog(#"count is %d",[vendorsArray count]);
return [vendorsArray count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return #"Payables";
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 100;
}
-(IBAction) payButton{
PayDescriptionController *mPayDescriptionController = [[PayDescriptionController alloc]initWithNibName:#"PayDescriptionController" bundle:nil];
mPayDescriptionController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self.navigationController presentModalViewController:mPayDescriptionController animated:YES];
}
Where i am going wrong in the above code.
try this,
[self.navigationController pushViewController:mPayDescriptionController animated:YES];
see ,it is navigating to next view or not !! and if not then may be one of your object is null.

Changing value on a label with UISlider control in WePopoverControler

I am in a process of implementing WePopovercontroller in my app and I have a question on how to implement uislider on it. I am able to show the slider in the UIView and get the action when slider moved but not sure how to set the value of the label in that view. Here is the part of the code
-(void)popoverSliderMoved:(UISlider *) sender{
NSLog(#"slider %f",sender.value);
}
-(IBAction)showSettingsMenu:(UIButton *)sender{
if(!self.popoverSettingsController) {
// Create a label and button for the popover
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 40)];
[label setText:#"Bookmark it!"];
[label setBackgroundColor:[UIColor clearColor]];
[label setTextColor:[UIColor whiteColor]];
[label setTextAlignment:UITextAlignmentCenter];
UISlider *slider = [[UISlider alloc]initWithFrame:CGRectMake(0, 45, 100, 40)];
[slider addTarget:self action:#selector(popoverSliderMoved:) forControlEvents:UIControlEventValueChanged];
UIFont *font = [UIFont boldSystemFontOfSize:20];
[label setFont:font];
CGSize size = [label.text sizeWithFont:font];
CGRect frame = CGRectMake(0, 0, size.width + 10, size.height + 10); // add a bit of a border around the text
label.frame = frame;
UIButton *button = [[UIButton alloc] initWithFrame:label.frame];
[button addSubview:label];
[button addTarget:self action:#selector(popoverButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
UIViewController *viewCon = [[UIViewController alloc] init];
[viewCon.view addSubview:slider];
[viewCon.view addSubview:button];
CGRect popOverFrm = CGRectMake(0, 0, frame.size.width + slider.frame.size.width, frame.size.height + slider.frame.size.height);
viewCon.contentSizeForViewInPopover = popOverFrm.size;//CGSizeMake(100, 36);
NSLog(#"Label Frame: %#", NSStringFromCGRect(label.frame));
NSLog(#"Popover size: %#", NSStringFromCGSize(viewCon.contentSizeForViewInPopover));
NSLog(#"ViewCon: %#", NSStringFromCGRect(viewCon.view.frame));
self.popoverSettingsController = [[WEPopoverController alloc] initWithContentViewController:viewCon];
//[self.popoverSettingsController setDelegate:self];
}
if([self.popoverSettingsController isPopoverVisible]) {
[self.popoverSettingsController dismissPopoverAnimated:YES];
// [navPopover setDelegate:nil];
self.popoverSettingsController = nil;
} else {
[self.popoverSettingsController presentPopoverFromRect:CGRectMake(sender.frame.size.width, 0, 200, 57)
inView:self.navigationController.view
permittedArrowDirections:UIPopoverArrowDirectionUp | UIPopoverArrowDirectionDown
animated:YES];
}
}
Would i need to use a delegate in this case or a property for this viewcontroller to set the label.
Thanks!!!
Yes using a property would be what I would do.