Let me try and explain this. Within a project folder has .m and .h files (we all know that haha) however when you start a new ".m" with a xib like for example:
ViewTwoController *loginView = [[ViewTwoController alloc] initWithNibName:#"contentscreen" bundle:nil];
[self presentModalViewController:loginView animated:YES];
[loginView release];
I was wondering how do I create a method that runs as soon as that class (if I can call it that, I'm new to objective C) similar to a main method that Java would have. I want to run some code as soon as that .m has been called and started. Any help would be valued thanks :)
To be safe try to put this in - (void)viewDidLoad
Everything that happens here happens when the view is loaded onto the screen.
Note that there are number of places where you can put your method, in viewWillAppear or in your AppDelegate etc. But I found putting UI elements like your login popup better in viewDidLoad
Hope this helps...
You can add additional code in viewDidLoad method, which is called as soon as your view controller has been loaded.
Using the initWithNibName:bundle: method, your view controller will be automatically loaded and initialized.
Related
I don't really know if what I'm doing is the right way to do it. Right now it seems to be working until it hits a certain point with a EXC_BAD_ACCESS message.
I'll describe what I'm doing as best and with the most relevant details I can tell:
I have a CalendarViewController that inherits UIViewController which is loading from a .xib file (CalendarViewController.xib). The class contains a UIView called contentView which I created and which I initialize with another nib file based on a class which is also inherited from UIViewController:
- (void)viewDidLoad {
[super viewDidLoad];
calendarView = [[CalendarView alloc] initWithNibName:#"CalendarView" bundle:nil];
[contentView addSubview:calendarView.view];
}
(calendarView is the class inheriting UIViewController and viewDidLoad is from CalendarViewController.
CalendarView.xib has a UITableViewController with it's respective UITableView. This Table View Controller is linked to a CalendarTableController to which I also generated a .xib file for it.
Everything is being created just right (apparently) but it is crashing somewhere very unexpected. CalendarTableController also implements a DateLoaderDelegate which loads information from an xml on an external url.
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// When the data has all finished loading, we set a copy of the
// loaded data for us to access. This will allow us to not worry about
// whether a load is already in progress when accessing the data.
self.lastLoadedMatchXMLData = [self.matchXMLData copy];
// Make sure the _delegate object actually has the xmlDidFinishLoading
// method, and if it does, call it to notify the delegate that the
// data has finished loading.
if ([_delegate respondsToSelector:#selector(xmlDidFinishLoading)])
{
[_delegate xmlDidFinishLoading];
}
}
The application is getting to this point without any problem. _delegate is containing the correct object (a CalendarTableController which implements the DateLoaderDelegate). But when it arrives to the line:
if ([_delegate respondsToSelector:#selector(xmlDidFinishLoading)])
it crashes with the EXC_BAD_ACCESS, I don't really know the reason, if I look at the debugger, the crash is not occurring in any of my classes as any of them are appearing in the execution stack. URLConnectionClient seems to be generating it, but I don't really know why. The loading of the xml had worked earlier before I rearranged the ViewControllers to work as I have described now.
Any ideas?
It's weird. I fixed the problem but I had to dedicate the whole UIViewController to contain the UITableView. What I did was this:
Create an IBOutlet with the custom UITableViewController (CalendarTableViewController) in the custom UIViewController.
In the loaded .xib file I linked the IBOutlet to a created UITableViewController declared as a CalendarTableViewController.
This way I solved the problem of the UITableViewController being deallocated without reason. But now the image views I had placed in the intermediate UIViewController wouldn't appear. I had to set that UIViewController to contain solely the CalendarTableView and place the image views in the initial UIViewController. Weird, isn't it? I don't like much the hierarchy I created... but for now that will do =S
Check that you have defined properties for all of your subviews and that you are retaining everything that you need to be. Bad Access May mean that you're attempting to call respondsToSelector on an object that has been released.
Have you tried calling loadView before adding the nested controller's view to the parent's view?
Maybe viewDidLoad is not executing before you add the view and some variables were never initialized.
I'm getting a little confused about when I should use a NIB file and when I should use code.
Here's my problem :
I have a navigation based application with a RootController and its NIB file.
The RootController's NIB file contains a TableView.
When I click on a cell I initialize a new connection with a request to load content.
When the connection has finished loading I create a new postViewController (custom) from a NIB file and I push it on the navigationController viewController stack like that :
PostViewController *postViewController = [[PostViewController alloc] initWithNibName:#"PostViewController" bundle:[NSBundle mainBundle]];
[postViewController.webView setDelegate:self];
postViewController.postContent = [[postsData objectForKey:#"post"] objectForKey:#"content"];
[self.navigationController pushViewController:postViewController animated:YES];
[PostViewController release];
Then, as you can see I try to set the rootViewController as the delegate for the webView in order to be able to intercept a click on a link and push a new ViewController on the stack. I need that new view to have the navigation bar with the back button.
Problem : looks like the setDelegate isn't working because the webView:shouldStartLoadWithRequest:navigationType never gets called !
I guess I should set the delegate in the NIB file but I have no idea how. The NIB file from PostViewController doesn't know about the RootViewController...
Here are screenshots of the NIB files :
If you need more detail just ask me.
Thanks a lot...for helping me not banging my head for another day :)
Make sure postViewController.webView isn't nil when you call setDelegate: on it. Also make sure it isn't being called anywhere else, and make sure the delegate outlet isn't connected to anything in your NIB.
A couple other comments:
It's a bit unusual to use your root view controller as the webview's delegate in a case like this. It should work, but it might make more sense to move those delegate methods down into your PostViewController. From there you can still intercept the link clicks and call [self.navigationController pushViewController:animated:].
[PostViewController release] is releasing the class object. Not a good idea. Instead you should be calling [postViewController release].
[postViewController.webView setDelegate:self]; sets the delegate for the current Controller not postViewController. Try:
[postViewController.webView setDelegate:postViewController];
And you can put this line below pushViewController:animated: then the webView should already exist.
I have a design question/technical question about my iPhone app.
I have a pretty simple (read really really simple) single view application. And it does everything that I need it to do. However I find myself in need of a help view. And I really don't quite know what to do!
I have a simple helpButton() method in my main view controller, and I really just want to display a scrollview with a bunch of images that show what to do during the use of my app. However, should I make a new viewcontroller class? How do I call it from my method?
Really I was thinking of an unfortunately simple method, just putting a scrollview behind everything and hiding it. Then showing it when the IBAction is called. Horrible...
Sorry if this is elementary, I haven't needed to do anything more yet!
You can push a modalViewController. To do that just make a new viewController with the scrollview and associated data in it, then
MyViewController *myViewController = [[MyViewController alloc] init];
[self presentModalViewController:myViewController animated:YES];
Create an IBAction in your new viewController and a hooked up button to that action to dismiss the modalView (something like this:
IBAction done {
[self dismissModalViewControllerAnimated:YES];
}
A couple options:
1) Create a new UIView object, either programmatically, or even in your existing XIB file. Use the [self.view addSubview:view] method to display it.
2) Create a new UIViewController with its own XIB file. Use [self presentModalViewController:anaimated:] to display it.
Either way, you'll need to add something to the new view to dismiss it when you're done.
In a UIViewController subclass, I have the following methods:
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// do something
myTextField.text = #"Default";
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// do something
[myTextField selectAll:self];
[myTextField becomeFirstResponder];
}
- (void)viewDidLoad {
[super viewDidLoad];
// do something
myTextField.delegate = self;
}
The NIB has been created using Interface Builder. The corresponding view controller object is pushed by the navigation controller through pushViewController.
The inteded behavior is to show a default text entry in a text field, to select the entire text and to set the text field as first responder. [Edit: I've noticed that selecting all and making first responder makes no sense as the selection would dissapear; still, I wonder why the methods behave as described next.]
However, while methods viewDidLoad and viewWillAppear are called, the method viewDidAppear is not called. Can anybody tell me why? Most questions I found on the web and here deal with both viewWillAppear/viewDidAppear are not working; I also understood that in subviews or programmatically created views these methods are not evoked; but this does not apply in case and also I wonder why one of these "lifecycle" methods is evoked and the other not.
Any idea? Thanks!
I had this issue happen to me: viewWillAppear was being called but viewDidAppear was not!
I finally figured out that this was because I had a tabBarController where I overloaded it's own viewDidAppear and forgot the [super viewDidAppear:animated];
It threw off every VC in every tab! adding that line back in fixed it for my other VC's.
Hope this helps someone!
There is one case when viewWillAppear will be called but viewDidAppear will not.
Suppose you have two viewControllers and you push from the first to the second controller. Then, using the swipe, you want to go back to the first one, both controllers are displayed at the same time and at that moment viewWillAppear will be called from the first controller.
This way, you do not finish the swipe and stay on the second controller and viewDidAppear will not be called from the first controller.
I had the same problem.
I had copy/pasted viewDidAppear to create viewWillAppear but had forgotten to change the super.viewDidAppear() call. This then seemed to stop viewDidAppear from being called.
It sounds like somewhere in your code you have missed or messed-up a call to the superclass.
The call to viewDidAppear: should always follow viewWillAppear: unless you are doing something custom, which you say you don't. I don't know why it doesn't work but here are a few ideas:
Could it be that you are doing something strange in one of the delegate methods for UITextFieldDelegate? It's unlikely that it would affect viewDidAppear: being called but it could be a culprit.
Have you loaded a lot of stuff into memory before pushing the view? I'm not sure what would happen if you got a memory warning between viewWillAppear: and viewDidAppear:.
Have you tried to do a Clean? Sometimes that can help.
In cases like these when it should work I usually create a new class and the introduce the functionality one at a the time to see if I can get it work that way. I tried your code in a new Navigation Based project where I added a new UIViewController with an outlet to the text field. Then I pasted the code from the question and it did work as expected.
This can be because you added a child view controller to your parent VC in viewDidLoad or viewWillAppear. The child's appearance prevents the call to viewDidAppear.
This is a crazy thing to do, and I only know because this was a bug in my code. I meant to add the child VC to this VC, not the parent VC.
I hope that you will succeed in at least a little to clarify me how and what to do, I'm sure I'm wrong, so I really need an expert opinion.
I have two viewcontroller together with nibs what I want is to call function that is in first class from another ViewController, the problem is that another viewcontroller manages to call this function but the only thing I can see that is done is NSlog which outputs in the console (which I put in that position to know that the function is called)
example:
FirstViewController.m
-(void)drawingFunction:(NSString*)inputText{
NSLog("Feature was launched");
/* showing stuff in FirstView.xib */
}
SecondViewController.m
-(void)turnOnFunction:(id)sender{
FirstViewController *stuff= [[PrviViewController alloc] init];
[stuff drawingFunction:#"ShowAll"];
}
Basically when I call that function in the PrviViewController.m meaning without reference to the outside e.g.
[self drawingFunction:#"ShowAll"];
everything is well displayed, but when I try to call this function from SecondViewController.m all I see is just a "feature was launched" on the console
I really don't know what to do ...
if i get you right, the FirstViewController is on top of the view controller hierarchy (either within a navigation controller or presented modal)? So, if that is the case just creating an instance of SecondViewController and calling a function which should change the user interface on the view which corresponds to SecondViewController will do nothing at all.
You have to present the SecondViewController and its view with presentModalViewController:animated: for instance. After that the view of SecondViewController will be shown and you can do any changes on that view. Also calling the method drawingFunction: will act as you expect it.
Cheers,
Andreas
You're confusing instances with classes. You don't send messages (call functions) to classes, you send them to instances.
In this case, you have two entirely separate instances of FirstViewController. The first is created by loading the nib and the second is created in -[SecondController turnOnFunction:]. The drawingFunction: message is being sent to the second instance when you want it to be sent to the first.
You need to link the nib instance of FirstViewController to the SecondController instance. You can do that with an outlet in interface builder or you can assign it when you create the display the SecondController.