single uiview for many viewcontrollers - objective-c

I have a viewcontroller name it as viewcontroller1. I have dragged a uiview to this viewcontroller and added some buttons to that view with actions. And also a custom view class is created for that uiview. This uiview is acting as a top bar for viewcontroller1. I have some more viewcontrollers and I am using the same uiview for those viewcontrollers too by getting the uiview using viewwithtag method. But the delegates are not working when I am using this method. I am getting a thread1 exc_bad access when the delegates are called from the uiview class. Any help is appreciated.
This is my uiview class
//topview.h
#protocol buttonprotocol <NSObject>
-(void) button1pressed;
-(void) button2pressed;
#end
#import <UIKit/UIKit.h>
#interface topview : UIView
- (IBAction)button1action:(id)sender;
- (IBAction)button2action:(id)sender;
#property (nonatomic,assign) id <buttonprotocol> delegate;
#property (weak, nonatomic) IBOutlet UIButton *button1;
#property (weak, nonatomic) IBOutlet UIButton *button2;
#end
//topview.m
#import "topview.h"
#implementation topview
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
- (IBAction)button1action:(id)sender
{
[self.delegate button1pressed];
}
- (IBAction)button2action:(id)sender
{
[self.delegate button2pressed];
}
#end
The given below is the first viewcontroller
// ViewController.h
#import <UIKit/UIKit.h>
#import "topview.h"
#import "button1ViewController.h"
#import "button2ViewController.h"
#interface ViewController : UIViewController
<buttonprotocol>
#property (weak, nonatomic) IBOutlet topview *topviewobj;
#end
// ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_topviewobj.delegate=self;
UIView *newview=[[UIView alloc]initWithFrame:CGRectMake(0, 250, 320, 100)];
newview=[self.view viewWithTag:1];
[self.view addSubview:newview];
// Do any additional setup after loading the view, typically from a nib.
}
-(void) button1pressed
{
UIStoryboard *storyboard=[UIStoryboard storyboardWithName:#"Main" bundle:nil];
button1ViewController *vc=[storyboard instantiateViewControllerWithIdentifier:#"button1ViewController"];
[self presentViewController:vc animated:NO completion:nil];
}
-(void) button2pressed
{
UIStoryboard *storyboard=[UIStoryboard storyboardWithName:#"Main" bundle:nil];
button2ViewController *vc=[storyboard instantiateViewControllerWithIdentifier:#"button2ViewController"];
[self presentViewController:vc animated:NO completion:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
the given below is the view controller class for the viewcontroller when the first button is tapped.
// button1ViewController.h
#import <UIKit/UIKit.h>
#import "topview.h"
#import "ViewController.h"
#import "button2ViewController.h"
#class topview;
#interface button1ViewController : UIViewController
<buttonprotocol>
{
UIView *newview;
topview *topviewobj;
}
#end
// button1ViewController.m
#import "button1ViewController.h"
#interface button1ViewController ()
#end
#implementation button1ViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
topviewobj=[topview new];
topviewobj.delegate=self;
NSLog(#"%#",topviewobj.delegate);
self.view.backgroundColor=[UIColor purpleColor];
UIStoryboard *storyboard=[UIStoryboard storyboardWithName:#"Main" bundle:nil];
ViewController *vc=[storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
newview=[[UIView alloc]init];
newview=[vc.view viewWithTag:1];
UIButton *backbutton=[[UIButton alloc]init];
[backbutton setTitle:#"Back" forState:UIControlStateNormal];
[backbutton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[backbutton setFrame:CGRectMake(5, 30, 60, 30)];
[backbutton addTarget:self action:#selector(back) forControlEvents:UIControlEventTouchUpInside];
[newview addSubview:backbutton];
[self.view addSubview:newview];
// Do any additional setup after loading the view.
}
-(void) back
{
UIStoryboard *storyboard=[UIStoryboard storyboardWithName:#"Main" bundle:nil];
ViewController *vc=[storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
[self presentViewController:vc animated:NO completion:nil];
}
-(void) button1pressed
{
UIStoryboard *storyboard=[UIStoryboard storyboardWithName:#"Main" bundle:nil];
button1ViewController *vc=[storyboard instantiateViewControllerWithIdentifier:#"button1ViewController"];
[self presentViewController:vc animated:NO completion:nil];
}
-(void) button2pressed
{
UIStoryboard *storyboard=[UIStoryboard storyboardWithName:#"Main" bundle:nil];
button2ViewController *vc=[storyboard instantiateViewControllerWithIdentifier:#"button2ViewController"];
[self presentViewController:vc animated:NO completion:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Given below is the class for viewcontroller for the viewcontroller when second button is tapped.
// button2ViewController.h
#import <UIKit/UIKit.h>
#import "topview.h"
#import "ViewController.h"
#class topview;
#interface button2ViewController : UIViewController
<buttonprotocol>
{
UIView *newview;
topview *topviewobj;
}
#end
// button2ViewController.m
#import "button2ViewController.h"
#interface button2ViewController ()
#end
#implementation button2ViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
topviewobj=[topview new];
topviewobj.delegate=self;
NSLog(#"%#",topviewobj.delegate);
self.view.backgroundColor=[UIColor purpleColor];
UIStoryboard *storyboard=[UIStoryboard storyboardWithName:#"Main" bundle:nil];
ViewController *vc=[storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
newview=[[UIView alloc]init];
newview=[vc.view viewWithTag:1];
UIButton *backbutton=[[UIButton alloc]init];
[backbutton setTitle:#"Back" forState:UIControlStateNormal];
[backbutton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[backbutton setFrame:CGRectMake(5, 30, 60, 30)];
[backbutton addTarget:self action:#selector(back) forControlEvents:UIControlEventTouchUpInside];
[newview addSubview:backbutton];
[self.view addSubview:newview];
// Do any additional setup after loading the view.
}
-(void) back
{
UIStoryboard *storyboard=[UIStoryboard storyboardWithName:#"Main" bundle:nil];
ViewController *vc=[storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
[self presentViewController:vc animated:NO completion:nil];
}
-(void) button1pressed
{
UIStoryboard *storyboard=[UIStoryboard storyboardWithName:#"Main" bundle:nil];
button1ViewController *vc=[storyboard instantiateViewControllerWithIdentifier:#"button1ViewController"];
[self presentViewController:vc animated:NO completion:nil];
}
-(void) button2pressed
{
// UIStoryboard *storyboard=[UIStoryboard storyboardWithName:#"Main" bundle:nil];
// button2ViewController *vc=[storyboard instantiateViewControllerWithIdentifier:#"button2ViewController"];
// [self presentViewController:vc animated:NO completion:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
This is all I got. I can't show my original code due to privacy concerns. This is a sample created to show the issue. I can't upload images as I have low reputation.

This looks highly suspect...
UIView *newview=[[UIView alloc]initWithFrame:CGRectMake(0, 250, 320, 100)];
newview=[self.view viewWithTag:1];
[self.view addSubview:newview];
You shouldn't have to alloc init a new view if the next line you are going to use viewWithTag because that view would already be inited. Also in the next line you call addSubView on the same thing you just got the view which would only work if the view was already added.
Edit
After further inspection of your code I see what you are trying to do. There are a couple of things to note. If you want to pass an object to a new view controller you can do that when you create the new view controller.
UIStoryboard *storyboard=[UIStoryboard storyboardWithName:#"Main" bundle:nil];
button1ViewController *vc=[storyboard instantiateViewControllerWithIdentifier:#"button1ViewController"];
//if button1ViewController had a property for topviewobj instead of an instance variable.
button1ViewController.topviewobj = (topview *)[self.view viewWithTag:1];
[self presentViewController:vc animated:NO completion:nil];
//in button1ViewController viewDidLoad
self.topviewobj.delegate = self;
[self.view addSubView:self.topviewobj];
With that being said I think what you really want to do is look into nibs or create topview just in code.
If just in code it would be something like
_topviewobj = [[topview alloc]initWithFrame:CGRectMake(0,250, 320, 100)];
_topviewobj.delegate = self;
[self.view addSubview:_topviewobj];
Also this will likely cause issues in the future...
-(void) back
{
UIStoryboard *storyboard=[UIStoryboard storyboardWithName:#"Main" bundle:nil];
ViewController *vc=[storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
[self presentViewController:vc animated:NO completion:nil];
}
Creating new UIViewControllers over and over again isn't ideal. Try this...
-(void) back
{
[self dismissViewControllerAnimated:YES completion:nil];
}
As I said before I would look into nibs or just creating a UIView Subclass and alloc/init, set delegate, and add as subview when you need one.
I hope all that makes sense and helps.

Related

UIButton not respond in UIView

UIButton in my view does not respond when I click it. Some one figure
out what I am doing wrong? Here is my entire code:
MyView.h
#interface Myview : UIView
#end
MyView.m
#import "MyView.h"
- (init){
self = [super init];
if(self)
[self createButton];
return self;
}
- (void) createButton{
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(100,100,100,50)];
[button setTitle:#"Go" forState:UIControlStateNormal];
[button addTarget:self
`action:#selector(goAction)
forControlEvents:UIControlEventTouchUpInside];
[self addSubview:button];
}
- (void) goAction{
NSString *test = #"Some text";
}
MyViewController.m
- (id) init{
self = [super init];
if (self) {
MyView *myview = [[MyView alloc] init];
[self.view addSubview:myview];
}
return self;
}`
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
ViewController.m
#import "ViewController.h"
#import "MyViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
MyViewController *myTestView = [[MyViewController alloc] init];
[self.view addSubview:myTestView.view];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
The reason why clicks does not work is that you don't set frame of MyView
This way it works (although I still don't understand why you need to add one ViewController into another)
#implementation MyViewController
- (instancetype)init
{
self = [super init];
if (self) {
MyView *myview = [[MyView alloc] init];
myview.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.width);
[self.view addSubview:myview];
}
return self;
}

Trying to fix subview flipping and now subview buttons no longer work?

I have a view which includes two subviews. I had it working so that only one subview was shown at a time and each subview had a button and when the button was clicked the subview would flip over and the next subview would appear. The problem was that it appeared as though the entire view was flipping. After reading on this site about how to solve the problem I attempted to add the subviews to a container and flip that instead. However now, although my first subview is showing up when I press the button it no longer flip. It doesn't do anything. I put a log statement in the method which flips the subviews, as well as a breakpoint and as far as I can tell it no longer gets called. I'm very new to xcode and objective c and delegates and I have no idea how to proceed. Any help would be appreciated. Thanks.
I have included the relevant code here:
The header for the ViewController
#interface ExerciseViewController : UIViewController<ExerciseSubViewDelegate>
//stuff for subviews
#property (nonatomic, strong) ExerciseSubViewImage *subViewImage;
#property (nonatomic, strong) ExerciseSubViewText *subViewText;
#property UIView *panel;
#end
This is the code for the ViewController:
#interface ExerciseViewController ()
#end
#implementation ExerciseViewController
#synthesize subViewImage, subViewText;
- (void)viewDidLoad
{
self.subViewImage.delegate = self;
_panel = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.bounds.size.width, self.view.bounds.size.height/2)];
_panel.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_panel];
[_panel addSubview:subViewImage];
}
-(ExerciseSubViewImage *)subViewImage
{
if (!subViewImage)
{
CGRect subViewImageFrame = CGRectMake(0,0, _panel.bounds.size.width, _panel.bounds.size.height);
self.subViewImage = [[ExerciseSubViewImage alloc] initWithFrame:subViewImageFrame];
[_panel addSubview:subViewImage];
}
return subViewImage;
}
-(ExerciseSubViewText *)subViewText
{
if (!subViewText)
{
CGRect subViewTextFrame = CGRectMake(0,0, _panel.bounds.size.width, _panel.bounds.size.height);
self.subViewText = [[ExerciseSubViewText alloc] initWithFrame:subViewTextFrame];
self.subViewText.backgroundColor = [UIColor blueColor];
[_panel addSubview:subViewText];
}
return subViewText;
}
-(void)exerciseSubViewImagePressed
{
[UIView transitionWithView:_panel
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[subViewImage removeFromSuperview];
[_panel addSubview:subViewText];
}
completion: nil];
//This is how I did it before I added the container
/*[UIView transitionFromView:subViewImage
toView:subViewText
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
self.subViewText.delegate = self;*/
NSLog(#"Ipushedtheimage");
}
-(void)exerciseSubViewTextPressed
{//I haven't updated this yet
[UIView transitionFromView:subViewText
toView:subViewImage
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
self.subViewImage.delegate = self;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
subViewImage = nil;
subViewText = nil;
}
#end
This is the code for the delegate
#import
#protocol ExerciseSubViewDelegate <NSObject>
-(void) exerciseSubViewImagePressed;
-(void) exerciseSubViewTextPressed;
#end
I am also added the code for the first subview:
#import
#import "ExerciseSubViewDelegate.h"
#interface ExerciseSubViewImage : UIView
#property (nonatomic, strong) UIButton *button;
#property (nonatomic, assign) id<ExerciseSubViewDelegate>delegate;
#property (strong, nonatomic) UIImageView *exerciseImageView;
#end
#import "ExerciseSubViewImage.h"
#import "UIImage+animatedGIF.h"
#implementation ExerciseSubViewImage
#synthesize button;
#synthesize delegate;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//Initialization code
self.button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
CGRect buttonFrame = CGRectMake(50,200,100,35);
self.button.frame = buttonFrame;
[self.button setTitle:#"Image"forState:UIControlStateNormal];
[self.button addTarget:self
action:#selector(buttonTouched)
forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.button];
_exerciseImageView = [[UIImageView alloc] initWithFrame:CGRectMake(50,20,160,158)];
NSURL *url = [[NSBundle mainBundle] URLForResource:#"AppleLogo" withExtension:#"gif"];
_exerciseImageView.image = [UIImage animatedImageWithAnimatedGIFURL:url];
[self addSubview:self.exerciseImageView];
}
return self;
}
-(void)buttonTouched
{
NSLog(#"imagebuttonpressed");
[self.delegate exerciseSubViewImagePressed];
}
Again, any help would be appreciate. I know I'm probably just not understanding something simple.
Ok. This took me all weekend but I finally figured it out on my own. I thought I would shere the answer here in case anyone else ever has a similar problem. After trying several other approaches I finally went back to the approach I used here and started inserting a whole bunch of NSLogs to determine the order that every thing was executing in. What I finally ended up doing was changing this: (all in the top ViewController)
self.subViewImage.delegate = self;
_panel = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.bounds.size.width, self.view.bounds.size.height/2)];
_panel.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_panel];
[_panel addSubview:subViewImage];
to this:
//create panel
_panel = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.bounds.size.width, s self.view.bounds.size.height/2)];
_panel.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_panel];
[_panel addSubview:subViewImage];
//Set the subview delegates
self.subViewImage.delegate = self;
self.subViewText.delegate = self;

Can't override a simple method

I've created a new project with two ViewControllers and imported a class that pushes ViewController from right to left instead LTR but can't manage to use it. I can see that pushViewController inside UIRightToLeft.m is not being called and I don't understand why.
My main goal is to get that working with RTL aniamtion.
#import "UIRightToLeft.h"
#implementation UIRightToLeft
- (id)initWithRootViewController:(UIViewController *)rootViewController
{
self = [super initWithRootViewController:rootViewController];
if (!self)
return nil;
return self;
}
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
NSLog(#"pushViewController");
// Add the viewController and a fake controller without animation. Then pop the fake controller with animation.
UIViewController *fakeController = [[UIViewController alloc] init] ;
[super setViewControllers:[[self viewControllers] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:viewController, fakeController, nil]] animated:NO];
[super popViewControllerAnimated:animated];
}
- (void)popViewControllerAnimatedStep2:(UIViewController *)viewController
{
// Push the new top controller with animation
[super pushViewController:viewController animated:YES];
// Remove the view that should have been popped
NSMutableArray *arr = [NSMutableArray arrayWithArray:[self viewControllers]];
[arr removeObjectAtIndex:[[self viewControllers] count]-2];
[super setViewControllers:[NSArray arrayWithArray:arr] animated:NO];
}
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
NSLog(#"popViewControllerAnimated");
if (animated)
{
// Save the controller that should be on top after this pop operation
UIViewController *newTopController = [[self viewControllers] objectAtIndex:[[self viewControllers] count]-2];
// Remove it from the stack. Leave the view that should be popped on top
NSMutableArray *arr = [NSMutableArray arrayWithArray:[self viewControllers]];
[arr removeObjectAtIndex:[[self viewControllers] count]-2];
[super setViewControllers:[NSArray arrayWithArray:arr] animated:NO];
// Schedule the next step
[self performSelector:#selector(popViewControllerAnimatedStep2:) withObject:newTopController afterDelay:0];
return [arr objectAtIndex:[arr count]-1];
}
return [super popViewControllerAnimated:NO];
}
#end
ViewController.m:
#import "ViewController.h"
#import "UIRightToLeft.h"
#import "SecondViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)pressMe:(UIButton *)sender {
SecondViewController *next = [[SecondViewController alloc]init];
[self.navigationController pushViewController:next animated:YES];
}
#end
ViewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
- (IBAction)pressMe:(UIButton *)sender;
#end
(In my ViewController there's only one button draged to the second ViewController with push)
After looking at your error log I think you actually need to have your navigation controller subclass UIRightToLeft.
If you are using a Storyboard, select your navigation controller and set Custom Class to UIRightToLeft.

initWithFrame is filling the screen instead of creating a frame of the size I want

I'm new to Cocoa development and suspect that this is a noob issue.
I'm creating a simple background canvas with a bespoke UIView. I was expecting that I would be able to create this canvas to be slightly indented down from the main view so that I could add a toolbar at a later date. However, when I use initWithFrame (and any other init for that matter), the canvas is always created to be the size of the full screen rather than slightly smaller than the full screen. Even if I completely override the values for CGRect it doesn't make a difference. I've set a touchesBegan event and set the background colour to green to be able to determine success but all I get are a completely green screen and a touch event that works everywhere.
Please help - this is driving me mad and I can't find the answer anywhere on the web.
The relevant code is as follows (there actually isn't much more code than this in the whole app so far):
AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.objMainViewController = [[MainViewController alloc] init];
self.window.rootViewController = self.objMainViewController;
[self.window makeKeyAndVisible];
return YES;
}
MainViewController.h
#import <UIKit/UIKit.h>
#import "viewCanvas.h"
#interface MainViewController : UIViewController
#property (strong, nonatomic) viewCanvas *objViewCanvas;
-(id)init;
#end
MainViewController.m
#import "MainViewController.h"
#import "viewCanvas.h"
#implementation MainViewController
#synthesize objViewCanvas;
-(id)init
{
if (self = [super init]) {
CGRect frame = CGRectMake(100, 100, 100, 100);
objViewCanvas = [[viewCanvas alloc] initWithFrame:frame];
}
return self;
}
- (void)loadView {
self.view = objViewCanvas;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
viewCanvas.h
#import <UIKit/UIKit.h>
#import "viewCanvas.h"
#interface viewCanvas : UIView {
}
//Init
- (id) initWithFrame:(CGRect)frame;
//Events
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
#end
viewCanvas.m
#import "viewCanvas.h"
#implementation viewCanvas
//Standard inits
- (id) initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
[self setBackgroundColor:[UIColor greenColor]];
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Touches Began Canvas" message:#"Canvas Touches Began" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles: nil];
[alert show];
}
#end
I think by default the view of a view controller fills the whole screen, so you need to add a subview to that view that's your smaller viewCanvas object (BTW, you should conform to the naming rules and name your classes with capital letters, ViewCanvas). Try this in your MainViewController .m file:
-(id)init{
if (self = [super init]) {
CGRect frame = CGRectMake(100, 100, 100, 100);
objViewCanvas = [[ViewCanvas alloc] initWithFrame:frame];
self.contentView = [[UIView alloc] initWithFrame:CGRectMake(1, 1, 1, 1)]; //this frame doesn't matter
[self.contentView setBackgroundColor:[UIColor whiteColor]];
}
return self;
}
- (void)loadView {
self.view = self.contentView;
[self.view addSubview:objViewCanvas];
}

MySecondViewController won't display correctly

I have programmatically created a second view controller (MySecondViewController) which was all done and hooked up without using the visual object editor.
My problem is that when I run the app, only the original view controller (HelloWorldViewController) comes up; the second view controller does not show up. When I click on the view for HelloWorldViewController, nothing comes up.
Can you tell me what's wrong?
windowBasedAppAppDelegate.h
#import <UIKit/UIKit.h>
//-- Add a forward reference to the HelloWorldViewController class --
#class HelloWorldViewController;
#interface windowBasedAppAppDelegate : NSObject <UIApplicationDelegate> {
//-- create an instance of the view controller--
HelloWorldViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
//--Expose the view controller as a property--
#property (nonatomic, retain) IBOutlet HelloWorldViewController *viewController;
#end
windowBasedAppAppDelegate.m
#import "windowBasedAppAppDelegate.h"
#import "HelloWorldViewController.h"
#import "MySecondViewController.h"
#implementation windowBasedAppAppDelegate
#synthesize window;
#synthesize viewController;
//-- a second view controller object--
MySecondViewController *mySecondViewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
//-- add the new view to the current window--
//-- instantiate the second view controller --
mySecondViewController = [[MySecondViewController alloc]
initWithNibName:nil
bundle:nil];
// -- add the view from the second controller --
//[window addSubview:mySecondViewController.view];
[window addSubview:viewController.view];
[self.window makeKeyAndVisible];
return YES;
}
- (void)dealloc
{
[MySecondViewController release];
[viewController release];
[window release];
[super dealloc];
}
#end
MySecondViewController.h
#import <UIKit/UIKit.h>
#interface MySecondViewController : UIViewController {
//-- create two outlets, label and button --
UILabel *label;
UIButton *button;
}
//-- expose the outlets as properties --
#property (nonatomic, retain) UILabel *label;
#property (nonatomic, retain) UIButton *button;
// -- declaring the IBAction ---
- (IBAction) buttonClicked: (id)sender;
#end
MySecondViewController.h
#import "MySecondViewController.h"
#implementation MySecondViewController
#synthesize label, button;
- (IBAction) buttonClicked: (id)sender {
UIAlertView *alert =
[[UIAlertView alloc] initWithTitle:#"Action Invoked!" message:#"Button clicked" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
HelloWorldViewController.h
#import <UIKit/UIKit.h>
#interface HelloWorldViewController : UIViewController {
}
#end
HelloWorldViewController.m
import "HelloWorldViewController.h"
#implementation HelloWorldViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
Added code from MySecondViewController.m
//-- add the views to the view window --
[self.view addSubview:label];
[self.view addSubview:button];
[view exchangeSubviewAtIndex:1 withSubviewAtIndex:0];
self.view = view;
[super viewDidLoad];
Since the view is being initialized and that it has a proper frame, the problem could be this sequence of code,
[window addSubview:mySecondViewController.view];
[window addSubview:viewController.view];
As the viewController's view will have the same frame, it will be added over mySecondViewController's view. So you will have to remove the second line for the view to show up.
You never actually push the new view controller onto the screen.
mySecondViewController = [[MySecondViewController alloc]
initWithNibName:nil
bundle:nil];
// -- add the view from the second controller --
//[window addSubview:mySecondViewController.view];
[window addSubview:viewController.view];
You add viewController.view, (which should be undefined...), but not mySecondViewController.view.
Also, programHasFinishedLaunching may not be the best possible place to push it. If I were you, I'd put a button on the front page that pushes the new view in, it's easier that way.