toolbar does not get populated - iphone

In my loadView methoad of my view controller I have the following code:
// Populate self.view and add some views/UI elements
// load Gender selection Bar
self.navigationController.toolbarHidden = NO;
self.navigationController.toolbar.tintColor = [UIColor colorWithRed:0 green:0.37 blue:0.5 alpha:1];
self.genderControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:NSLocalizedString(#"Male", nil), NSLocalizedString(#"Female", nil), nil]];
genderControl.segmentedControlStyle = UISegmentedControlStyleBar;
genderControl.frame = CGRectMake(0, 0, 200, 30);
genderControl.tintColor = [UIColor colorWithRed:0 green:0.37 blue:0.5 alpha:1];
[genderControl addTarget:self action:#selector(changeGender:) forControlEvents:UIControlEventValueChanged];
genderControl.selectedSegmentIndex = GENDER_MALE;
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:genderControl];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
[[[self navigationController] toolbar] setItems:[NSArray arrayWithObjects:flexSpace, item, flexSpace, nil] animated:YES];
[item release];
However, if I load the view it displays the toolbar, but the Segmented Control does not get displayed. If I move my code to the viewWillAppear: method it works, but once I hide my view and redisplay it again the segmented control is gone anew.
Does anybody know this problem and/or has an idea how to solve it? Looks very strange to me.

Most of your code looks fine to me, and everything should work when called from the viewDidLoad or the loadView method.
However, when you use the included toolbar from the NavigationController, toolbar items are set on the ViewController rather than the toolbar itself. So replace this line:
[[[self navigationController] toolbar] setItems:[NSArray arrayWithObjects:flexSpace, item, flexSpace, nil] animated:YES];
With this:
[self setToolbarItems:[NSArray arrayWithObjects:flexSpace, item, flexSpace, nil] animated:YES];
Documentation here: http://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/setToolbarItems:animated:
You will also want to add this line:
[flexSpace release];

Are you sure that this code should be in loadView? Check the UIViewController docs: loadView is used for constructing your view controller's view entirely programmatically - nothing is loaded from a nib if you implement loadView. Should this code be in viewDidLoad instead? I see that you're not even creating and assigning the main UIView in your loadView method -- which you'd normally expect to see, e.g.:
self.view = [[[UIView alloc] init] autorelease];
If you did mean to implement loadView, as you have, you should add the above line for assigning your main view towards the top of the method, rather than later on.
Btw, perhaps don't bother calling [toolbar setItems] with animated=YES; not much point and I've seen the exact value of the animated parameter break things inexplicably in the past!

Related

Setting the inputAccessoryView of a UITextField to its superview

I have a UITableView with an Add cell... row and would like to have a keyboard pop up with a view above it like in the "Messages" application, where the user can type the name of the new cell.
I realize that there are several other ways to get user data, and several ways to implement the functionality that I am trying to achieve.
For example, the iPod application presents a popup when a new playlist should be created.
Right now, I have a hidden text field that is set to be the first responder when the Add cell... row is pressed, and I assign the view containing the input field and confirmation button as the inputAccessoryView for this hidden field. Alternatively, I could add this view as a subview of the table and position it using keyboard notifications.
I would just like to know if there is a cleaner way to accomplish what I am trying to do (such as setting the inputAccessoryView of the input textField to be displayed to be the textField's superview). I have tried several approaches, but I cannot seem to be able to dismiss the keyboard using resignFirstResponder when the view should close. I can get the inputAccessoryView to disappear, but the keyboard remains resolutely open, taking up necessary screen real estate. Also, when the nib's view is a UITableView with a UITableViewController as the File's Owner rather than a UIView with a UIViewController as the File's Owner, I get a very odd error: "setting the first responder view of the table but we don't know its type (cell/header/footer)"
Thanks in advance,
Julian Ceipek
You are on the right track with the setInputAccessoryView on the UITextView/UITextField classes' This method allows you to add any view you want to the top of a keyboard.
The view you create would then use a delegation method to tell the main view controller to resignFirstResponder.
So, to get you started:
#protocol TextFieldAccessoryViewDelegate
#required
- (void)keyboardShouldDismiss;
#end
#interface TextFieldAccessoryView : UIView
#property (nonatomic, retain) id<TextFieldAccessoryViewDelegate> delegate;
- (id)initWithFrame:(CGRect)frame withDelegate (id<TextFieldAccessoryViewDelegate>)aDelegate;
#end
The implementation might look a little like (only posting the code that makes the view):
#pragma mark - Private methods
- (void)doneButtonTapped:(id)sender
{
[delegate keyboardShouldDismiss];
}
- (void)setUpChildrenView
{
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(doneButtonTapped:)];
UINavigationItem *navigationItem = [[UINavigationItem alloc] initWithTitle:#""];
[navigationItem setRightBarButtonItem:doneButton];
[navigationItem setHidesBackButton:YES];
UINavigationBar *navigationBar = [[[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, self.width, 44.0f)] autorelease];
[navigationBar pushNavigationItem:navigationItem animated:NO];
[self addSubview:navigationBar];
}
I have used a standard NavigationBar looking view, but you could put in anything you like and include buttons, textfields, images of robot unicorns, the works
If you don't get everything thats going on in the above code you might need to brush up on Delegation and creating views programmatically.
- (void)viewDidLoad
{
[self createAccessoryView];
[textField setDelegate:self];
[textField setKeyboardType:UIKeyboardTypeDefault];
[textField setInputAccessoryView:fieldAccessoryView];
}
- (void)createAccessoryView
{
CGRect frame = CGRectMake(0.0, self.view.bounds.size.height, self.view.bounds.size.width, 44.0);
fieldAccessoryView = [[UIToolbar alloc] initWithFrame:frame];
fieldAccessoryView.barStyle = UIBarStyleBlackOpaque;
fieldAccessoryView.tag = 200;
[fieldAccessoryView setBarStyle:UIBarStyleBlack];
UIBarButtonItem *spaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(done:)];
UISegmentedControl* segmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:NSLocalizedString(#"Previous", #""), NSLocalizedString(#"Next", #""), nil]];
[segmentedControl addTarget:self action:#selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
[segmentedControl setMomentary:YES];
UIBarButtonItem *segmentButton = [[UIBarButtonItem alloc] initWithCustomView:segmentedControl];
[fieldAccessoryView setItems:[NSArray arrayWithObjects:segmentButton, spaceButton, doneButton, nil] animated:NO];
[segmentButton release];
[spaceButton release];
[doneButton release];
[segmentedControl release];
}

How to dismiss pop over view in content view?

see the screen shot is clear to understand what I mean
you can see I add a navigationItem in my pop view
I wish I can dismiss the pop view
But it seems only tab the cell under the pop view
The pop view will dismiss,I try to add this method
[self.view removeFromSuperview];
It only remove the table view , the pop view frame is still there ,only without the content view
Any reply will be helpful : )
Thanks
Webber
/******EDIT******/
I use WEPopoverView into my project
And this is the code I create the pop view when I select the table view
if (indexPath.row==2) {
DaysOfWeek *popView = [[DaysOfWeek alloc]init];
UINavigationController *navPopView = [[UINavigationController alloc] initWithRootViewController:popView];
if (self.popoverController) {
[self.popoverController dismissPopoverAnimated:YES];
self.popoverController = nil;
}
else {
self.popoverController = [[[WEPopoverController alloc] initWithContentViewController:navPopView] autorelease];
CGRect frame = [tableView cellForRowAtIndexPath:indexPath].frame;
[self.popoverController presentPopoverFromRect:frame
inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown|UIPopoverArrowDirectionUp
animated:YES];
}
}
/******EDIT2******/
I try to add Done button when I create the pop view
here is the code , But it only appear a navigation , no Done button
DaysOfWeek *popView = [[DaysOfWeek alloc]init];
UINavigationController *navPopView = [[UINavigationController alloc] initWithRootViewController:popView];
navPopView.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(hidePopView)];
While you add the popup view, set tag to that popupView and then, add them as subview,
then use:
for (UIView *tempView in [self.view subviews]) {
if ([tempView tag]==urTag) {
[tempView removeFromSuperview];
}
}
This retrieves all the subviews and then remove only your popupview
I think that simply releasing your self.popoverController will do the dismiss properly, including all the superviews.
You can also have a look at the dealloc method in WEPopoverController to see which views are involved and need to be removed:
[self dismissPopoverAnimated:NO];
[contentViewController release];
[containerViewProperties release];
[passthroughViews release];
Anyway, the only advantage I see is the possibility of calling dismissPopoverAnimated with YES.
Hope this helps.
EDIT:
How can you connect your done button to your controller?
Make your button accessible through a read-only property of DaysOfWeek; then in your controller, when you create DaysOfWeek, do:
DaysOfWeek *popView = [[DaysOfWeek alloc]init];
[propView.doneButton addTarget:self action:#selector(fullyDismissPopover) forControlEvents:UIControlEventTouchUpInside];
In fullyDismissPopover, you call release or call the sequence of functions highlighted above (but release would be better, I think).
DaysOfWeek *popView = [[DaysOfWeek alloc]init];
UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeContactAdd];
[doneButton addTarget:self action:#selector(hidePopView) forControlEvents:UIControlEventTouchUpInside];
popView.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:doneButton] autorelease];
UINavigationController *navPopView = [[UINavigationController alloc] initWithRootViewController:popView];
This also can figure out the problem !

UIToolBar creating problem while application returns from background

I am using a uitoolbar in a view that is initialized using initWithFrame: method in sdk. I mean I am adding tool bar porgrammatically. While multitasking, this toolbar is creating problem. Can anyone give me some solution or a ray of light to proceed. I cant add it in xib since I am using a custom uitablecontroller class. My code is as follows:
-(void)viewDidLoad
{
[super viewDidLoad];
actionToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 373, 320, 44)];
[actionToolbar insertSubview:[[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"top-bar.png"]] autorelease] atIndex:0];
actionButton = [NotesList createSquareBarButtonItemWithTitle:#"Delete" target:self action:#selector(noAction:)];
flexibleSpace1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
flexibleSpace2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
composeButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:self action:#selector(addNewGroup:)]autorelease];
composeButton.style = UIBarButtonItemStylePlain;
[actionToolbar setItems:[NSArray arrayWithObjects:flexibleSpace1, flexibleSpace2, composeButton, nil]];
[self.view.superview addSubview:actionToolbar];
self.tableView.frame = CGRectMake(0, 0, 320, 400);
[self.tableView setAllowsSelectionDuringEditing:YES];
[flexibleSpace1 retain];
[flexibleSpace2 retain];
[actionButton retain];
[composeButton retain];
[self parseDataForThisFile];
}
I had resolved the code by setting frames of tab bar controller when the app returns from background
You can use a NIB-file even if you use a custom UITableViewController subclass. The exact class to use can be specified on the identity tab of the inspector in Interface Builder.
(source: peylow.se)
If you are having problem when multitasking, then I suspect you do not properly handle unloading of the view. Your app can unload views from view controllers when going to the background in order to free more memory.
It is important that you make sure that any connection that is setup/created in loadView and viewDidLoad is also properly disconnected/released in viewDidUnload. Otherwise strange and unexpected things can happen to your app.

Wrong UIToolbar Appears After Popping View

I'm new to Objective-C/Cocoa Touch and hope someone can help with the following issue.
I've got a view with a mapview control and a UIToolBar at the bottom of the screen. When a user clicks a pin on the map they can drill down to a grouped UITableView with details of the location.
This is done by pushing a new navigationController:
MapAnnotation *tappedLocation = (MapAnnotation *)[view annotation];
LocationDetailsViewController *placeDetails = [[LocationDetailsViewController alloc] initWithNibName:#"LocationDetailsViewController" bundle:nil];
[self.navigationController pushViewController:placeDetails animated:YES];
[placeDetails release];
In the grouped UITableView there's also a UIToolbar at the bottom of the screen, but it's set up programmatically (code below).
The issue is that when the user leaves the grouped UITableView and comes back to the main view with the map, they still see the UIToolbar from the UITableView, not the original one that was set up in IB.
Anyone know how I can 'cancel' the UIToolbar from the grouped UITableView?
UIToolbar *toolbar = [UIToolbar new];
toolbar.barStyle = UIBarStyleDefault;
[toolbar sizeToFit];
toolbar.frame = CGRectMake(0, 436, 320, 44);
toolbar.tag = 123;
UIBarButtonItem *flexItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
UIBarButtonItem *emailButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAction
target:self
action:#selector(email:)];
//Add buttons to the array
NSArray *items = [NSArray arrayWithObjects: flexItem, flexItem, flexItem, emailButton, nil];
[emailButton release];
[flexItem release];
//add array of buttons to toolbar
[toolbar setItems:items animated:YES];
[self.navigationController.view addSubview:toolbar];
Don't add the toolbar as a subview of the navigationController. That view stays on screen as long as the app is running (you'll be stacking up a lot of them if you keep on going into the details view and back).
Simply set the toolbar's items using [UIViewController setToolbarItems:animated:]

What to do when UIBarButtonItem are not visible in UINavigationBar?

Hello Everyone
I am writing a simple code in ViewDidLoad, and class is child of UITableViewController, like below but buttons are not visible, while title is visible,
Another thing that I am clicking a button which in ViewDidLoad method ViewController.m, and which is call a method, code of that method is as below
//Code of button target method
-(void)statusMethod {
NSLog(#"statusMethod");
Status *ob=[[Status alloc]init];
[self presentModalViewController:ob animated:YES];
}
//Code of ViewDidLoad of Status.m
UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, width, 43)];
navBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self.view addSubview:navBar];
[navBar release];
UIBarButtonItem *home = [[UIBarButtonItem alloc] initWithTitle:#"HOME" style:UIBarButtonItemStylePlain target:self action:#selector(homeMethod)];
self.navigationItem.rightBarButtonItem = home;
UIBarButtonItem *add = [[UIBarButtonItem alloc] initWithTitle:#"Add" style:UIBarButtonSystemItemAdd target:self action:#selector(addMethod)];
self.navigationItem.leftBarButtonItem = add;
UILabel *label = [[UILabel alloc] initWithFrame:
CGRectMake(10,10,width-20,25)];
label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
label.text = #"Status";
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont systemFontOfSize:25];
label.textAlignment = UITextAlignmentCenter;
[navBar addSubview:label];
[label release];
Any Idea, what is problem in code?
I you don't understand, then u can ask me again,
I will praise, if I will get solution of my problem
It seems like self.navigationItem is only looked at by the UINavigationController (controller, not bar). The bar itself isn’t going to check that.
So you should either
1) Use a real UINavigationController which comes with its own navigationBar and will handle the navigationItems for you. The self.navigationItem code above will work in that case. (you should consider self.navigationItem.title = #"Status";)
If your UITableViewController is going to be pushing stuff on and off the navigation stack, this is the path you should take in any case.
2) Use the UINavigationBar’s own navigation item. Except it doesn’t seem to come with a navigation item, so you have to add your own:
UINavigationItem *navItem = [[UINavigationItem alloc] initWithTitle:#"Status"];
[navBar setItems:[NSArray arrayWithObject:navItem]];
[navItem release];
and then set the left and right buttons as
[navBar topItem].leftBarButtonItem = add;
[add release];
[navBar topItem].rightBarButtonItem = home;
[home release];
Dealing with UINavigationController/UINavigationBar/UINavigationItem can be confusing, but luckily Apple has a decent explanation of how all these things work together at the top of its UINavigationController documentation.