I want is on main window to present the created modalViewController view when the infobutton is pressed. But when I press Info button on the main window nothing happens.
In the mainviewcontroller.h file I have following code:
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface imageviewViewController : UIViewController{
AVAudioPlayer *audioPlayer;
}
#property (nonatomic, retain) UIToolbar *toolbar;
#property (nonatomic, assign) UIBarButtonSystemItem currentSystemItem;
#property (nonatomic, retain) AVAudioPlayer *audioPlayer;
#end
In the mainviewcontroller.m file have following code:
#import "imageviewViewController.h"
#import "Infoviewcontroller.h"
#implementation imageviewViewController
#synthesize toolbar;
#synthesize currentSystemItem;
#synthesize audioPlayer;
UIBarButtonItem *infoItem = [[UIBarButtonItem alloc]
initWithTitle:#"Info"
style:UIBarButtonItemStyleBordered
target:nil
action:#selector(Infobuttonpressed)];
// flex item used to put space in between buttons
UIBarButtonItem *flexItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
//Add buttons to the array
NSArray *toolbarItems = [NSArray arrayWithObjects: settingsButton, flexItem, systemItem, flexItem, systemItem1,flexItem, systemItem2, flexItem, systemItem3, flexItem, infoItem, nil];
[toolbar setItems:toolbarItems];
[settingsButton release];
[systemItem release];
[systemItem1 release];
[systemItem2 release];
[systemItem3 release];
[infoItem release];
[flexItem release];
[super viewDidLoad];
}
- (void) Infobuttonpressed: (id) sender
{
Infoviewcontroller *myView = [[Infoviewcontroller alloc] init];
[self presentModalViewController:myView animated:YES]; // present view modally
[self.navigationController pushViewController:myView animated:YES]; // add to navigation stack
[myView release];
}
In the Infoviewcontroller.h file have following code:
#import <UIKit/UIKit.h>
#interface Infoviewcontroller : UIViewController <UITextViewDelegate>
{
UITextView *textView;
}
#property (nonatomic, retain) UITextView *textView;
#property (nonatomic, assign) UINavigationBar *navBar;
#end
Then in the infoviewcontroller.m file have the following code:
#import "Infoviewcontroller.h"
#implementation Infoviewcontroller
#synthesize textView;
#synthesize navBar;
-(void)dealloc
{
[textView release];
[navBar release];
[super dealloc];
}
-(void)setupTextView
{
self.textView = [[[UITextView alloc] initWithFrame:self.view.frame] autorelease];
self.textView.textColor = [UIColor redColor];
self.textView.font = [UIFont fontWithName:#"System Bold" size:13];
self.textView.delegate = self;
self.textView.backgroundColor = [UIColor whiteColor];
self.textView.textAlignment = UITextAlignmentCenter;
self.textView.text = #"This is UITextView\nThis is UITextView\nThis is UITextView\nThis is UITextView";
[self.view addSubview: self.textView];
}
- (void)viewDidLoad
{
[super viewDidLoad];
navBar = [[UINavigationBar alloc] init];
UINavigationItem *navItem = [[[UINavigationItem alloc] initWithTitle:#"ModalViewControllerTest"] autorelease];
UIBarButtonItem *done = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissView:)] autorelease];
navItem.rightBarButtonItem = done;
navBar.items = [NSArray arrayWithObject:navItem];
[self.view addSubview:navBar];
}
UIBarButtonItem *infoItem = [[UIBarButtonItem alloc]
initWithTitle:#"Info"
style:UIBarButtonItemStyleBordered
target:nil
action:#selector(Infobuttonpressed)];
Should be
UIBarButtonItem *infoItem = [[UIBarButtonItem alloc]
initWithTitle:#"Info"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(Infobuttonpressed:)];
Spot the difference? First, you're missing a target (should be self, not nil). Second, the colon at the end of the selector is part of the signature, you were missing it so it was not calling your method (which is InfoButtonPressed:(id)sender).
As an aside, methods should start with a lower case name.
you dont need both pushModalViewController and pushViewController
Assuming your views are already controlled within an instance of a UINavigationController pushModalViewController on its own will work.
edit - remove the reference to pushViewController. Does it now work?
-(void) Infobuttonpressed: (id) sender;
{ Infoviewcontroller *myView = [[Infoviewcontroller alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myView];
UIViewController *pushController = [[UIViewController alloc] init];
[self addSubview:pushController.view];
[pushController presentModalViewController:navController animated:YES];
[myView release];
}
The target of your infoItem is set to nil. You should set this to an instance of the class where the Infobuttonpressed is defined. I assume that is the mainviewController?
Also, the selector to call is specified as: #selector(Infobuttonpressed), while the method is called "Infobuttonpressed:", that is, with a parameter. That will likely result in a runtime error once you fix the target.
Then, there are some peculiarities in the way you handle things. As Nik already answered, you need to choose whether you want to present the view modally (with presentModalViewController), or present it as part of the navigation stack (with pushViewController), you cannot do both.
If you present it as part of the navitation stack, then it already has a navigation bar, and so you should not add one yourself. Just set the properties of the self.navigationItem.
Have a look at the View Controller Programming Guide for more info.
Related
I've got a UIButton that I'd like to display in the same position in front of all of the viewControllers of my UINavigationController, much in the same way that a UINavigationBar would - but in this case, I'd like the button to float in the lower-left corner of the screen, like so:
I could try manually adding it to each viewController, but I'd prefer to do it once and forget about it.
Adding the button as a subview to the UIWindow doesn't seem to work - it winds up behind the rootViewController.
Update: I've figured out a way to do it, but because it involves iOS 7, I can't post the solution here until the NDA is lifted. The good news is, it's fairly simple to accomplish this! I'll post something once it's OK to share.
create a NSObject class buttonPanel and allocate the button and you can call the button panel as follow:
buttonPanel * buttonPanel = [[buttonPanel alloc] init];
buttonPanel.delegate = self;
[buttonPanel showButtonWithNavigationController:self.navigationController inView:self.parentViewController.view];
ButtonPanel class:
//ButtonPanel.h
#import <Foundation/Foundation.h>
#class ButtonPanel;
#protocol ButtonPanelDelegate <NSObject>
-(void) ButtonPanel:(ButtonPanel*) buttonPanel ;
#end
#interface ChatMessagePanel : NSObject<UIActionSheetDelegate> {
UINavigationController *navigationController;
id<ButtonPanelDelegate> delegate;
}
#property(nonatomic,retain) UINavigationController *navigationController;
#property (nonatomic,retain) id<ButtonPanelDelegate> delegate;
-(void)showButtonWithNavigationController:(UINavigationController*) navigationController inView:(UIView*) view;
#end
// ButtonPanel.m
#import "ChatMessagePanel.h"
#implementation ButtonPanel
#synthesize userListModal,delegate,navigationController;
-(void)showMessageWithNavigationController:(UINavigationController*) _navigationController inView:(UIView*) view
{
self.navigationController = _navigationController;
baseViewWidth = view.frame.size.width;
baseViewHeight = view.frame.size.height;
incomingRequestActionSheet = [[UIActionSheet alloc] initWithTitle:#"" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil, nil];
[incomingRequestActionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
[incomingRequestActionSheet showInView:view];
UIButton *blockUserBttn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 80, 40)];
[blockUserBttn setTitle:NSLocalizedString(#"BLOCK_USERS",#"") forState:UIControlStateNormal];
[blockUserBttn setBackgroundColor:[UIColor clearColor]];
[blockUserBttn addTarget:self action:#selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *blockUserBarBttn = [[UIBarButtonItem alloc] initWithCustomView:blockUserBttn];
[optionToolBar setItems:[NSArray arrayWithObjects:blockUserBarBttn, nil]];
[incomingRequestActionSheet addSubview:optionToolBar];
}
-(void)buttonAction:(id) sender
{
}
#end
I don't think this is possible in the ios. You must have to do
individual for all view.
You can simply add the UIButton on the window like
[self.window addSubview:Button];
after self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
I made a application with the templet of a Single View Application. Then I added a label and connected it to the .h file of my ViewController. Then I made a picker, filled it, then set it (and a toolBar I made) to the textfield. But when I tap the textfield, the picker is just all black. If this made no sense, the code will explain it all.
.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController {
}
#property (weak, nonatomic) IBOutlet UITextField *habitField;
#property (weak, nonatomic) NSArray *PickerData;
#end
.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSArray *array = [[NSArray alloc] initWithObjects:#"1",#"2",#"3", nil];
self.PickerData = array;
UIToolbar *toolBar = [[UIToolbar alloc] init];
toolBar.barStyle = UIBarStyleBlackOpaque;
[toolBar sizeToFit];
[toolBar setBackgroundImage:[UIImage imageNamed:#"red_navigation_bar.png"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:self
action:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(releasePicker)];
UIPickerView *Picker = [[UIPickerView alloc] init];
doneButton.image = [UIImage imageNamed:#"button.png"];
[toolBar setItems:#[flexSpace, doneButton] animated:YES];
self.habitField.inputAccessoryView = toolBar;
[self.habitField setInputView:Picker];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [self.PickerData count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [self.PickerData objectAtIndex:row];
}
#end
The simulator looks like this
As i see you forgot to set delegate for picker ( UIPickerViewDelegate )
Picker.delegate = self;
Remember to add :)
#interface ViewController : UIViewController<UIPickerViewDelegate> {
}
Cheers
I have added navigation controller into my appication in didFinishLaunchingWithOptions like this
LoginViewController *mainView = [[[LoginViewController alloc]initWithNibName:#"LoginViewController" bundle:nil] autorelease];
navigationController = [[[UINavigationController alloc]initWithRootViewController:mainView]autorelease];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
And in my LoginViewController's viewDidLoad i have,
self.navigationItem.hidesBackButton = YES;
[super viewDidLoad];
UIImage *img = [[UIImage alloc] init];
img = [UIImage imageNamed:#"top_bar.png"];
bar = [self.navigationController navigationBar];
[bar setBackgroundImage:img forBarMetrics:UIBarMetricsDefault];
UIImage *signIn = [UIImage imageNamed:#"signin_btn.png"];
UIButton *phButton = [UIButton buttonWithType:UIButtonTypeCustom];
[phButton setImage:signIn forState:UIControlStateNormal];
phButton.frame = CGRectMake(0.0, 0.0, signIn.size.width, signIn.size.height);
UIBarButtonItem *phBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:phButton];
self.navigationItem.rightBarButtonItem = phBarButtonItem;
[phButton addTarget:self action:#selector(checkConnection) forControlEvents:UIControlEventTouchUpInside];
[phButton release];
When i run the app in my phone it crashes. When i remove the navigationcontroller from the appDelagate it works... Y cant i get my navigation to work properly and how can i avaoid it from getting crashed.
Modify your code
try this code
Declare appdelete.h file
#class LoginViewController;
LoginViewController *viewController;
#property (nonatomic, retain) IBOutlet LoginViewController *viewController;
appdelegate.m file declare
#synthesize viewController;
in didFinishLaunchingWithOptions
UINavigationController *nav=[[UINavigationController alloc] initWithRootViewController:viewController];
[window addSubview:nav.view];
[window makeKeyAndVisible];
return YES;
-(void) dealloc
{
[viewController release];
......//some code
}
I this this cause crash.
[phButton release];
phButton does not need to be released;
By the way,
phBarButtonItem need to be released;
Try this one...
self.window.rootViewController = navigationController;
instead of [self.window addSubview:navigationController.view];
[phButton release]; remove that line &
img & phBarButtonItem needs to be released
I think the problem is with your autorelease with navigation controller.
you try removing autorelease or
navigationController = [[UINavigationController
alloc]initWithRootViewController:mainView];
try using property (if you have),
self.navigationController = [[[UINavigationController
alloc]initWithRootViewController:mainView]autorelease];
Have a mainviewcontroller and on it have UIToolbar which has a UIBarButtonItem Info which shows UIViewcontroller modally.
Now when pressing Infobutton it is showing UIViewController modally which has UITextView but not showing UINavigationController with Done button.
I am not able to figure it out what i am missing in my code.
This is how i am showing UITextView and NavigationController in UIViewController modally.
#import "ModalViewController.h"
#import <QuartzCore/QuartzCore.h>
#implementation ModalViewController
#synthesize textView;
#synthesize navBar;
#synthesize navigationController;
#synthesize delegate;
-(void)dealloc
{
[textView release];
[navBar release];
[navigationController release];
[super dealloc];
}
- (void) viewDidLoad
{
[super viewDidLoad];
self.title = #"Info";
UINavigationController *navigationController = [[UINavigationController alloc]init];
//initWithRootViewController:viewController];
self.navigationController.navigationBar.tintColor = [UIColor brownColor];
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(Done:)] autorelease];
self.textView = [[[UITextView alloc] initWithFrame:CGRectMake(0, 0, 320, 416)]autorelease];
self.textView.textColor = [UIColor whiteColor];
self.textView.font = [UIFont fontWithName:#"Georgia-BoldItalic" size:14];
//self.textView.delegate = self;
self.textView.backgroundColor = [UIColor brownColor];
self.textView.layer.borderWidth = 1;
self.textView.layer.borderColor = [[UIColor whiteColor] CGColor];
self.textView.layer.cornerRadius = 1;
self.textView.textAlignment = UITextAlignmentCenter;
self.textView.text = #"This is UITextView presenting modally.\nThis is UITextView presenting modally.\nThis is UITextView presenting modally.\nThis is UITextView presenting modally.\nThis is UITextView presenting modally.\nThis is UITextView presenting modally.
self.textView.editable = NO;
//[self.view addSubview:navigationController.view];
[self.view addSubview: self.textView];
//[navigationController release];
}
And this is how UIViewController presented modally
//Create a final modal view controller
UIButton *modalViewButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
[modalViewButton addTarget:self action:#selector(modalViewAction:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *modalBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:modalViewButton];
self.navigationItem.rightBarButtonItem = modalBarButtonItem;
- (void) modalViewAction:(id)sender
{
self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]autorelease];
//self.viewController = [[ModalViewController alloc] init];
[self.view setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
//ModalViewController *myModalViewController = [[ModalViewController alloc] init];
//UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:myModalViewController];
//navigationController.navigationBar.tintColor = [UIColor brownColor];
_viewController = [[ModalViewController alloc] init];
//[navigationController pushViewController:_viewController animated:YES];
[self presentModalViewController:self.viewController animated:YES];
//[self.view addSubview:navigationController.view];
//[navigationController release];
[myModalViewController release];
}
I will appreciate if you can figure out what i m doing wrong or missing in my code.
Thanks a lot.
This seems like a needlessly convoluted way of displaying the new controller. In my apps, I do it like this:
//this function displays (modally) view controller nested inside a navcontroller
- (void) showModalController
{
YourViewController * ecreator = [[YourViewController alloc] initWithNibName:#"YourViewController" bundle:nil];
UINavigationController * navcontrol = [[UINavigationController alloc] initWithRootViewController: ecreator];
[self presentModalViewController: navcontrol animated:YES];
[navcontrol release];
[ecreator release];
}
Now you want to do the graphical setup (navbar color etc) in the initWithNib and/or viewDidLoad functions of the YourViewController.
#synthesize navigationController;
so navigationController is your class member variable.
in the function
- (void) viewDidLoad
you declare a local variable
UINavigationController *navigationController
Please notice that the second navigationController is different from your member variable navigationController .
So, inside viewDidLoad you need to create object of your member variable navigationController. Not the local variable navigationController.
Do not RE-declare navigationController in viewDidLoad. Instead, create the object using member variable like:
navigationController = [[UINavigationController alloc]init];
Try this, it worked great for me. I had the exact same problem
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#“segue_name"])
{
UINavigationController *nav = [segue destinationViewController];
ExampleViewController *exampleVC = (ExampleViewController *) nav.topViewController;
//Setup any properties here and segue
}
}
For the first time I'm subclassing UIToolbar for creating ones with custom UIBarButton.
I'm doing this:
#interface CustomToolbar : UIToolbar
#end
#implementation CustomToolbar
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// add buttons
UIBarButtonItem *myButton = [[UIBarButtonItem alloc] initWithTitle:#"Button" style:UIBarButtonItemStyleBordered target:self action:#selector(pressSignupButton:)];
// add buttons to the array
NSArray *items = [NSArray arrayWithObjects:myButton, nil];
[self setItems:items];
}
return self;
}
#end
Then in my view controller:
CustomToolbar *myToolbar = [[CustomToolbar alloc] init];
[self.navigationController.view addSubview:myToolbar];
The problem is that I can see the toolbar but there aren't buttons. Why?
NB: I prefer to have all programmatically without nib.
Does this work?
CustomToolbar *myToolbar = [[CustomToolbar alloc]
initWithFrame:CGRectMake(0,0,self.navigationController.view.frame.size.width, 44)];
[self.navigationController.view addSubview:myToolbar];