I have created a View controller with some methods I need to use often in different aplications. It works like a charm if I use it directly but when I try to create another UIViewController that extend my class I cannot access self.view anymore. This is the init method of the original class:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil slideFrom:(HalfViewControllerType) from {
self.slideFrom = from;
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
CGRect viewScreen = [self.view bounds];
[self moveTo:startPoint inDuration:0.0];
}
return self;
}
At the point of retrieving [self.view bounds] I got an EXC_BAD_ACCESS.
Even hacking the values manually it then fail to all the other self.view like transform animation and so on.
The call to create the view is this, but it never got after the init method:
SelectViewController *sVC = [[SelectViewController alloc] initWithNibName:#"SelectViewController" bundle:nil slideFrom:top];
[sVC setDelegate:self];
[self.view addSubview:sVC.view];
[sVC slideIn];
[sVC release];
Any help on understanding what I am doing wrong would be really appreciated.
Francesco.
I couldn't understand what was happening, so I re-wrote everything and now works. I can just guess I was releasing something I shouldn't have.
Related
I am trying to add a page with a UIScrollView and UIPageControl to my app. I am making the call to the new class from a UITableView as below.
MultiPageViewController *mpvc = [[MultiPageViewController alloc]initWithNibName:#"MultiPageViewController" bundle:[NSBundle mainBundle]];
[[self navigationController]pushViewController:mpvc animated:YES];
The viewDidLoad function is never called, thus my UIScrollview and UIPageControl are never initialized. When I go along further and call viewWillAppear these objects are both still nil. Further the view never appears only a white screen. Below is the code from initWithNibName and viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
NSLog(#"initWithNibName returned self != null");
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"View did load called");
}
Thanks for your help in advance.
I've got 2 viewControllers:
DemoAppViewController
AboutViewController
I have an info button in DemoAppViewController which is supposed to open AboutViewController.
At the moment I'm getting a run time error and i can't seem to work out why..
Here's the code:
DemoAppViewController .h:
- (IBAction)showInfo;
DemoAppViewController.m:
- (IBAction)showInfo {
AboutViewController *controller = [[AboutViewController alloc] initWithNibName:#"AboutViewController" bundle:nil];
//setting style with modalTransition property
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
//show on screen
[self presentViewController:controller animated:YES completion:nil];
}
When i create the AboutViewController object with initWithNibName xCode adds the following code to AboutViewController.m:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
I've left the above untouched.
Runtime error:
[DemoAppViewController showInfo:]: unrecognized selector sent to instance 0x688e450
Can someone tell me where I'm going wrong?
Thanks.
The selector for this method is #selector(showInfo), not #selector(showInfo:). If you assign it programmatically, just correct it. If you use IB - add :(id) sender parameter to the method.
I am trying to push an opengl UIView to my navigation controller like this
GraphViewController *gvc = [[GraphViewController alloc] initWithTicker:[listOfItems objectAtIndex:indexPath.row]];
[self.navigationController pushViewController:gvc animated:YES];
[gvc release];
The initWithTicker method looks like this
-(id) initWithTicker:(NSString*)ticker{
self = [super initWithNibName:nil bundle:nil];
if (self) {
self.title = ticker;
EAGLView *eagl = [[EAGLView alloc] initWithFrame:[UIScreen mainScreen].bounds];
eagl.animationInterval = 1.0 / 60.0;
[eagl startAnimation];
self.view = eagl;
}
return self;
}
When I go back and forward in my UINavigationController, the drawView method (in EAGLView) keeps looping. Furthermore, if I pushViewController again, the first one does not stop and a new one is created! I've tried making this an instance variable so only one is created and it has the same effect. I would be grateful if anyone has insight as to why this is happening
sergio Suggestion:
-(id) initWithTicker:(NSString*)ticker{
self = [super initWithNibName:nil bundle:nil];
if (self) {
self.title = ticker;
}
return self;
}
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
eagl = [[EAGLView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.view = eagl;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
eagl.animationInterval = 1.0 / 60.0;
[eagl startAnimation];
[super viewDidLoad];
}
same behaviour.
---This is how I fixed my drawView looping problem--
-(void)viewDidAppear:(BOOL)animated {
[eagl startAnimation];
[super viewDidAppear:animated];
}
-(void)viewDidDisappear:(BOOL)animated {
[eagl stopAnimation];
[super viewDidDisappear:animated];
}
--Craigs solution --
if(graphView == nil){
graphView = [[GraphViewController alloc] initWithTicker:[listOfItems objectAtIndex:indexPath.row]];
}else{
[graphView release];
graphView = [[GraphViewController alloc] initWithTicker:[listOfItems objectAtIndex:indexPath.row]];
}
Are you creating a new GraphViewController every time you want to push one onto your navigation stack? If so, it doesn't really matter how you're handling the creation of your EAGLView instance variable, since you're never going to be interacting with that view controller again anyway.
For example:
User taps something, a new GraphViewController is pushed on the stack
User goes back, this view controller continues to run
Return to 1. and repeat (thus creating a SECOND GraphViewController, and then a third, and then a fourth... etc.)
What you should probably be doing is maintaining your GraphViewController as an instance variable, and only creating it once. This will ensure that you're in turn only creating one EAGLView.
if (_graphViewController == nil) {
_graphViewController = [[GraphViewController alloc] initWithTicker:[listOfItems objectAtIndex:indexPath.row]];
}
[self.navigationController pushViewController:_graphViewController animated:YES];
Then, be sure to release the view controller in your dealloc method if you're going to be maintaining it as an ivar.
Would you try executing this code of yours:
EAGLView *eagl = [[EAGLView alloc] initWithFrame:[UIScreen mainScreen].bounds];
eagl.animationInterval = 1.0 / 60.0;
[eagl startAnimation];
self.view = eagl;
inside of loadView? I am not sure about why your view is behaving like you say, but that is the place where you are supposed to build your UI... so it might make a difference...
Furthermore, I would call [eagl startAnimation]; only in viewDidLoad...
Hope it helps...
I have trawled SO for an answer that makes sense to my question, so don't hate me if this is an easy one!
I am adding two views to the window:
self.appView = [[AppViewController alloc] initWithNibName:nil bundle:nil] ;
self.buttonBar = [[ButtonBar alloc] initWithNibName:nil bundle:nil];
[window insertSubview:[self.appView view] belowSubview:[self.launchScreen view]];
[window insertSubview:[self.buttonBar view] belowSubview:[self.launchScreen view]];
Before I remove the self.launchScreen.
When I add elements to the appView (it's a uitableviewcontroller) they work as expected, but when I add a button to the buttonBar (either in the XIB or via code), click them causes EXC_BAD_ACCESS.
Here's the init code from buttonBar (which is adding one button):
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.settingsButton = [[UIButton alloc] initWithFrame:CGRectMake(0,10,40,28)];
[self.settingsButton addTarget:self action:#selector(settings:) forControlEvents:UIControlEventTouchUpInside];
UIImage *btnImage = [UIImage imageNamed:#"play.png"];
[self.settingsButton setImage:btnImage forState:UIControlStateNormal];
[btnImage release];
[self.view addSubview:self.settingsButton];
}
return self;
}
My question is in two parts, 1) WHAT GIVES?! I've been at this way too long, and 2) How can I debug this stuff? I hate coming to SO to ask n00b questions when I'm sure XCODE's debugging tools would help me track this stuff down...
Use #selector(settings) instead.
I'm not exactly sure if this is the problem but I dont think you need the "retain" at the end in this line
self.settingsButton = [[[UIButton alloc] initWithFrame:CGRectMake(0,10,40,28)] retain];
I'm assuming settingsButton is already in your header file with a #property(retain) and you have synthesized it in your .m file.
release it in the dealloc method instead.
In previous applications I have customised my tabBarItems by overriding init (see below)
- (id)init {
self = [super init];
if(self) {
UITabBarItem *tabBarItem = [self tabBarItem];
[tabBarItem setTitle:#"ONE"];
}
return self;
}
After looking at the Xcode templates I am now thinking that I would be better to add this customisation to initWithNibName:bundle: instead.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
UITabBarItem *tabBarItem = [self tabBarItem];
[tabBarItem setTitle:#"ONE"];
}
return self;
}
does this make sense, it seems like it does to me, but I just wanted to check?
Gary
It depends on whether you load your controller from a Nib (xib) file or not (and so you do all the work programmatically in the init) I guess