I am loading a mapview. I have created a barbutton in the bottombar toolbar of the view, setting its identifier as pagecurl. As expected, a barbutton with page curl icon is loaded. From this mapview I move to anotherv view, by clicking on annotations in the mapview. And then I return to the mapview. At that time my pagecurl barbutton icon(pagecurl icon) is not displayed, and my barbutton width is also reduced. I am not able to figure out the problem.
- (void)viewDidLoad
{
[super viewDidLoad];
if(isSingleContactSelected)
{
[self.navigationController.navigationBar setBarStyle:UIBarStyleDefault];
self.navigationItem.leftBarButtonItem = self.cancelButton ;
[self.cancelButton setTarget:self];
[self.cancelButton setAction:#selector(onClose:)];
[addressFieldSearchBar setFrame:CGRectMake(66, 0, 256, 44)];
addressFieldSearchBar.delegate =self;
[self.navigationController.navigationBar setBarStyle:UIBarStyleDefault];
[self.navigationController.navigationBar addSubview:addressFieldSearchBar];
[searchDirectionSegmentedControl addTarget:self action:#selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
UIBarButtonItem *searchDirectionSegmentedButton = [[UIBarButtonItem alloc] initWithCustomView:searchDirectionSegmentedControl];
flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
NSArray *toolbarItems = [NSArray arrayWithObjects: compassButton , flexibleSpace, searchDirectionSegmentedButton, flexibleSpace, pageButton, nil];
[self setToolbarItems:toolbarItems];
self.navigationController.toolbarHidden = NO;
[compassButton release];
[pageButton release];
[searchDirectionSegmentedControl release];
mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
mapView.delegate=self;
[self.view addSubview:mapView];
}
}
- (void)viewDidUnload{
[super viewDidUnload];
}
-(void) viewWillAppear:(BOOL)animated{
if(isSingleContactSelected){
[self.navigationController.navigationBar setHidden:NO];
[self.navigationController.toolbar setHidden:NO];
[self.navigationController.toolbar setBarStyle:UIBarStyleDefault];
[self.addressFieldSearchBar setHidden:NO];
}
}
-(void) viewWillDisappear:(BOOL)animated{
if(isSingleContactSelected){
[self.addressFieldSearchBar setHidden:YES];
[self.navigationController.toolbar setHidden:YES];
}
}
Though its a long shot, it could be something to do with the setHidden calls in your appear and disappear methods.
[self.navigationController.toolbar setHidden:YES];
[self.navigationController.toolbar setHidden:NO];
The best way to do this using UIViewController's "-setHidesBottomBarWhenPushed:" method.
Maybe try some NSLog() in -viewWillAppear:
// If pageButton is an instance variable
NSLog(#"%#",pageButton);
// Enumerate through all toolbar items.
// Check to see if NSLog output differs after pushing/popping this view controller.
for (UIBarButtonItem *item in [self.navigationController.toolbar.items])
{
NSLog(#"%#",item);
}
setHidesBottomBarWhenPushed method did the trick in this case.
Related
I have added a view with buttons on top of keyboard using setInputAccessoryView.
Now i want functionality like when i click button from the view i want to display a pickerView on top of keyboard. Means like adding pickerView as subview of keyboard.
How can i do this?
Make a view you want to at the top of the keyboard. You can do this from xib or manually, but I think xib will be a better option.
Then make the reference to this view by doing this
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
textField.inputAccessoryView = YOURCustomView;
return YES;
}
Whenever you want to hide this or remove this just put this
textField.inputAccessoryView = nil;
self.pickerContainerView = [[UIView alloc] initWithFrame:CGRectMake(0, 194, 320, 224)];
self.pickerContainerView.backgroundColor = [UIColor clearColor];
[self.view addSubview:self.pickerContainerView];
UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
pickerToolbar.barStyle = UIBarStyleBlackTranslucent;
[pickerToolbar sizeToFit];
self.lblPickerViewTitle = [[UILabel alloc] initWithFrame:CGRectMake(15, 7, 230, 30)];
self.lblPickerViewTitle.backgroundColor = [UIColor clearColor];
[self.lblPickerViewTitle setFont: [UIFont fontWithName:#"Arial-BoldMT" size:17]];
self.lblPickerViewTitle.textAlignment = UITextAlignmentLeft;
self.lblPickerViewTitle.textColor =[UIColor whiteColor];
[pickerToolbar addSubview:self.lblPickerViewTitle];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItems addObject:flexSpace];
[flexSpace release];
UIBarButtonItem *btnCancel = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(closePickerView:)];
[barItems addObject:btnCancel];
[btnCancel release];
UIBarButtonItem *btnDone = [[UIBarButtonItem alloc] initWithTitle:#"ShowPicker" style:UIBarButtonItemStyleBordered target:self action:#selector(donePickerView:)];
[barItems addObject:btnDone];
[btnDone release];
[pickerToolbar setItems:barItems animated:YES];
[barItems release];
[self.pickerContainerView addSubview:pickerToolbar];
And in ShowPicker Method , write code for display UIPicker
You need to create another UIWindow first:
UIWindow *newWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0,100,320,20)];
newWindow.windowLevel = UIWindowLevelStatusBar; // this will make to place your WINDOW above the keyboard
[newWindow makeKeyAndVisible]; // show the new window
// [newWindow addSubview:yourView];
like add button on keyboard you can also add view like bellow...
here you find window of keyboard and then set frame of button and also yourView and then add to keyboard
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
return YES;
}
- (void)keyboardDidShow:(NSNotification *)note {
UIButton *returnBtn = [UIButton buttonWithType:UIButtonTypeCustom];
returnBtn.frame = CGRectMake(0,-25,320,25);
returnBtn.adjustsImageWhenHighlighted = NO;
returnBtn.backgroundColor=[UIColor darkGrayColor];
returnBtn.titleLabel.textColor=[UIColor whiteColor];
[returnBtn setBackgroundImage:[UIImage imageNamed:#"keyBtn.png"] forState:UIControlStateNormal];
[returnBtn addTarget:self action:#selector(keyboardBtn:) forControlEvents:UIControlEventTouchUpInside];
// locate keyboard view
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++) {
keyboard = [tempWindow.subviews objectAtIndex:i];
// keyboard found, add the button
if([[keyboard description] hasPrefix:#"<UIPeripheralHost"] == YES)
// if (txtTag==5) {
[keyboard addSubview:returnBtn];
}
}
-(IBAction)keyboardBtn:(id)sender{
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++) {
keyboard = [tempWindow.subviews objectAtIndex:i];
// keyboard found, add the button
if([[keyboard description] hasPrefix:#"<UIPeripheralHost"] == YES)
// if (txtTag==5) {
[keyboard addSubview:yourView];// here add your view with frame
}
}
i hope this help you...
:)
From Jonas Schnelli's answer
UIWindow *newWindow = [[UIWindow alloc]initWithFrame:CGRectMake(0,100,320,20)];
newWindow.windowLevel = CGFLOAT_MAX; // this will make to place your WINDOW above the keyboard
[newWindow addSubview:yourView];
Just change UIWindowLevelStatusBar to CGFLOAT_MAX will be ok.
this is my code
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *segmentTextContent = [NSArray arrayWithObjects:
NSLocalizedString(#"button1", #""),
NSLocalizedString(#"button2", #""),
NSLocalizedString(#"button3", #""), nil];
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] nitWithItems:segmentTextContent];
segmentedControl.selectedSegmentIndex = 0;
segmentedControl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.frame = CGRectMake(0, 0, 400, 30);
self.navigationItem.titleView = segmentedControl;
[segmentedControl release];
}
three buttons are displayed but i don't know how to set action in button help me thanks in advance
add target at the time of segmentedControl creation like below
[segmentedControl addTarget:self action:#selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
in that selector
-(IBAction) segmentAction:(id)sender{
UISegmentedControl *segmentedControl = (UISegmentedControl *)sender;
NSLog(#"Segment clicked: %d", segmentedControl.selectedSegmentIndex);
switch (segmentedControl.selectedSegmentIndex) {
case 0:
self.segmentLabel.text =#"Segment 1 selected.";
break;
case 1:
self.segmentLabel.text =#"Segment 2 selected.";
break;
default:
break;
}
You have to make 3 buttons and add them to an UIToolbar.
- (void)viewDidLoad
{
[super viewDidLoad];
// create a toolbar to have the buttons at the right side of the navigationBar
UIToolbar* toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 150, 44.01)];
toolbar.tintColor = [UIColor clearColor];
[toolbar setTranslucent:YES];
// create the array to hold the buttons, which then gets added to the toolbar
NSMutableArray* buttons = [[NSMutableArray alloc] initWithCapacity:3];
// Create button1
UIBarButtonItem *button1 = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:#selector(button1Pressed)];
[buttons addObject:button1];
[button1 release];
// Create button2
UIBarButtonItem *button2 = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:self action:#selector(button2Pressed)];
[buttons addObject:button2];
[button2 release];
// Create button3
UIBarButtonItem *button3 = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks target:self action:#selector(button3Pressed)];
[buttons addObject:button3];
[button3 release];
// stick the buttons in the toolbar
[toolbar setItems:buttons animated:NO];
//self.toolbarItems = buttons;
[buttons release];
// and put the toolbar in the nav bar
[[self navigationItem] setRightBarButtonItem:[[[UIBarButtonItem alloc] initWithCustomView:toolbar] autorelease]];
[toolbar release];
}
...
- (void)button1Pressed
{
//do stuff
}
- (void)button2Pressed
{
//do stuff
}
- (void)button3Pressed
{
//do stuff
}
Trying to add a button to the right side of the toolbar of the detailviewcontroller in a split-view based app. I used flexible space to get it to the right side. In portrait it works fine, but in landscape (when the menu button disappears), the button gets moved so that half of it is off the screen.
Here's the relevant code (in DetailViewController.m):
- (void) viewDidLoad
{
// initialize toolbar
toolbar = [[UIToolbar alloc] initWithFrame: CGRectMake( 0, 0, 768, 44 )];
titleLabel = [[UILabel alloc] initWithFrame: CGRectMake( 284, 3, 200, 35 )];
titleLabel.text = #"Title & Location";
titleLabel.textAlignment = UITextAlignmentCenter;
[toolbar addSubview: titleLabel];
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFlexibleSpace target: nil action: nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle: #"Add Event" style: UIBarButtonItemStyleDone target: rootController action: #selector(parseDone)];
NSArray *buttonArray = [NSArray arrayWithObjects: flexibleSpace, doneButton, nil];
[toolbar setItems: buttonArray];
[doneButton release];
[flexibleSpace release];
[self.view addSubview: toolbar];
}
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem
{
NSMutableArray *itemsArray = [toolbar.items mutableCopy];
[itemsArray insertObject: barButtonItem atIndex: 0];
[toolbar setItems:itemsArray animated:NO];
}
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem
{
NSMutableArray *itemsArray = [toolbar.items mutableCopy];
[itemsArray removeObject:barButtonItem];
[toolbar setItems:itemsArray animated:NO];
[itemsArray release];
}
I recognize this problem from a project I worked on a while back. I think it only happened occasionally and I don't remember if we actually fixed it.
In your case it seems like it would be easier to just use the navigation bar and set rightBarButtonItem and leftBarButtonItem. That should solve your problem.
In fact, if you put your view controller in a UINavigationController you get the UINavigationBar and all the functionality of the navigation controller, if you choose to use it.
Well the problem was that I wasn't correctly resizing the toolbar when the iPad rotates to landscape mode. Fixed the problem by add this code:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if( interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight ) {
[toolbar setFrame: CGRectMake( 0, 0, 700, 44 )];
}
else {
[toolbar setFrame: CGRectMake( 0, 0, 768, 44 )];
}
return YES;
}
Right now I'm using this in my -viewDidLoad method:
UIToolbar *toolbar = [[UIToolbar alloc] init];
UIBarButtonItem *flexibleSpace = [UIBarButtonItem alloc];
flexibleSpace = [flexibleSpace initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
// Add a back button to allow user to close the modal view
NSString *back = NSLocalizedString(#"Back", nil);
UIBarButtonItem *backButton = [UIBarButtonItem alloc];
backButton = [backButton initWithTitle:back
style:UIBarButtonItemStyleDone
target:self
action:#selector(dismissModalViewControllerAnimated:)];
// Add a centered title to the toolbar
// I doubt this is the "correct" way to do this, but it seems to work.
// The "width" property of a UIBarButtonItem doesn't seem to correspond to
// the actual width if the button is flexible (i.e. the width isn't explicitly
// set), so I'm using this hack instead.
// This is obviously NOT an optimal solution. For one thing, if the button padding
// ever changes, it has to be changed manually here as well. For another, it is
// a pain to do this for every button I add to the toolbar, and furthermore the title
// is centered only according to its own width, not the toolbar's.
const CGRect toolbarFrame = [toolbar frame];
const CGFloat backWidth = [back sizeWithFont:[UIFont boldSystemFontOfSize:[UIFont buttonFontSize]]
constrainedToSize:toolbarFrame.size].width;
const CGRect titleFrame = {{0.0f, 0.0f},
{toolbarFrame.size.width - (backWidth * 2.0f), 50.0f}};
UILabel *titleLabel = [[UILabel alloc] initWithFrame:titleFrame];
[titleLabel setText:[self title]];
[titleLabel setBackgroundColor:[UIColor clearColor]];
[titleLabel setTextAlignment:UITextAlignmentCenter];
[titleLabel setFont:[UIFont boldSystemFontOfSize:20.0f]];
[titleLabel setTextColor:[UIColor whiteColor]];
[titleLabel setShadowColor:[UIColor colorWithWhite:0.0f alpha:0.5f]];
[titleLabel setShadowOffset:CGSizeMake(0.0f, -1.0f)];
UIBarButtonItem *titleItem = [[UIBarButtonItem alloc] initWithCustomView:titleLabel];
[titleLabel release];
NSArray *items = [[NSArray alloc] initWithObjects:flexibleSpace, titleItem, backButton, nil];
[flexibleSpace release];
[titleItem release];
[backButton release];
[toolbar setItems:items];
[items release];
[view addSubview:toolbar];
[toolbar release];
Does anyone have a better method for doing this? What I'm using feels like a major hack :(.
Edit:
Thanks for the suggestion Darren!
Here's what I'm using now, if anyone's interested:
First, in accordance with Darren's suggestion, I'm wrapping my modal view controller in a generic UINavigationController (which contains it's own UIToolbar, UINavigationBar, that comes with a title):
MyCustomViewController *myModalViewController = [[MyModalViewController alloc] init];
[myModalViewController setTitle:#"Foo"];
UINavigationController *modalNavController = [[UINavigationController alloc] initWithRootView:myModalViewController];
[myModalViewController release];
// This is intended to be presented in another view controller class
[self presentModalViewController:modalNavController animated:YES];
[modalNavController release];
Then in my -init method for the MyModalViewController class, I have this:
- (id)init
{
if (self = [super init]) {
UIBarButtonItem *backButtonItem = [UIBarButtonItem alloc];
backButtonItem = [backButtonItem initWithTitle:back
style:UIBarButtonItemStyleDone
target:[self navigationController]
action:#selector(dismissModalViewControllerAnimated:)];
[[self navigationItem] setRightBarButtonItem:backButtonItem];
[backButtonItem release];
}
return self;
}
This is a much cleaner solution than before. Thanks.
You should wrap your view controller inside a generic UINavigationController when you present the modal view:
MyCustomController* myController = [[MyCustomController alloc] init];
editor.title = #"My Title";
UINavigationController* modalController = [[UINavigationController alloc] initWithRootViewController:myController];
[self.navigationController presentModalViewController:modalController animated:YES];
[modalController release];
[myController release];
Your custom controller can specify its toolbar buttons in its init method:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self
action:#selector(doCancel:)] autorelease];
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave
target:self
action:#selector(doSave:)] autorelease];
}
return self;
}
You should be adding the title in the items property
i.e.
#property(nonatomic, copy) NSArray *items
where items is init with a title
initWithTitle:style:target:action:
See http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIToolbar_Class/Reference/Reference.html#//apple_ref/occ/instp/UIToolbar/items
and
http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIBarButtonItem_Class/Reference/Reference.html#//apple_ref/occ/instm/UIBarButtonItem/initWithTitle:style:target:action:
for the details.
Hope that helps
[Edit]
P.S. The UIBarButtonItem is also where you would be adding your buttons ;-)
All of the examples I've seen on here and other sites involved creating a UIActivityIndicatorView and loading it with something like:
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]
initWithCustomView:myActivityIndicatorView
target:nil
action:nil]
autorelease];
However, that just creates a plain activity indicator in the navigation bar. What I want to do is have a button that looks just like the normal UIBarButtonSystemItem buttons but with an activity indicator instead of one of the default images. I've tried doing initWithImage and initWithTitle with nil images or titles and then adding the activity indicator as a subview, but that doesn't work.
Any ideas?
My Solution is to create a subclass of UIButton:
in SOActivityButton.h:
#interface SOActivityButton : UIButton
{
UIActivityIndicatorView* activityIndicator;
}
#end
in SOActivityButton.m:
#implementation SOActivityButton
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
CGRect innerFrame = CGRectInset(frame, 8.0f, 8.0f);
activityIndicator = [[UIActivityIndicatorView alloc]
initWithFrame:innerFrame];
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
[self addSubview:activityIndicator];
}
return self;
}
- (void)dealloc
{
[activityIndicator release], activityIndicator = nil;
[super dealloc];
}
- (void) startAnimating
{
[activityIndicator startAnimating];
}
- (void) stopAnimating
{
[activityIndicator stopAnimating];
}
#end
Then to use it:
SOActivityButton* activityButton = [[SOActivityButton alloc]
initWithFrame:CGRectMake(0.0f, 0.0f, 32.0f, 32.0f)];
[activityButton setImage:[UIImage imageNamed:#"button-background.png"]
forState:UIControlStateNormal];
[activityButton addTarget:self action:#selector(myAction:)
forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *activityBarButtonItem = [[UIBarButtonItem alloc]
initWithCustomView:activityButton];
[activityButton release];
self.navigationItem.rightBarButtonItem = activityBarButtonItem;
[activityBarButtonItem release];
You will need to find or create a button-background.png. The PSD here should have one.
have you tried creating a UIButton in the button bar and then adding an activity indicator as a subView of the UIButton?
I have this working and it is very simple. Just place the activity indicator where you want it with IB, but make sure it's lower in the list than the bar you want it on, and is at the "top level" (not a subview of anything else). Then control it in code via an outlet.
Here's something that can help:
activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
[activityIndicator startAnimating];
UIBarButtonItem *activityItem = [[UIBarButtonItem alloc] initWithCustomView:activityIndicator];
[activityIndicator release];
self.navigationItem.rightBarButtonItem = activityItem;
[activityItem release];
[activityIndicator startAnimating];