Cocoa-Touch: Check if UIViewController exists before init it - iphone

Is there a way to check if a UIViewController is loaded in memory/visible on screen?
Something like this:
if([ContentRvController exists]){
contentView *ContentRvController = [[contentView alloc]
initWithNibName:#"contentView" bundle:nil]; //ContentView is a custom UIViewController
....
//Code to set the UIViewController
....
}
else{
[ContentRvController release];
}
That should happen when a button (that right now initializes the ViewControllers) is tapped. Right now, when tapped it opens n ViewControllers, it is supposed to display only one at a time.
Thats pretty much it, greetings and hope you can help me out.

Is this based on existing code?
Classes should start upper case, and instances should be camel case, e.g.
if([contentRvController exists]){
ContentView *contentRvController = [[ContentView alloc]
initWithNibName:#"contentView" bundle:nil]; //ContentView is a custom UIViewController
....
//Code to set the UIViewController
....
}
else{
[contentRvController release];
}
it is probably worth declaring it in the header, i.e.
#interface SomeClass : NSObject {
}
#property(non-atomic, retain) ContentView *contentRvController;
#end
and then in code you could do
if(contentRvController!=nil){
ContentView *aView=[[[ContentView alloc] init] autorelease];
self.contentRvController=aView;
}
Also, don't do the else{[contentRv release];} bit, if you have autoreleased it anywhere, this will leak at some point.

If you are using UINavigationController check for the property topViewController.

Related

Xcode moving from view to view

I'm coding in Xcode, and i have a problem moving from view to view (xib to xib) My xib-files all have a personal .h and .m file.
this is the code i have:
The code to go from the first view to the quiz view in this case:
-(IBAction)switchviewMainToQuiz:(id)sender {
ViewControllerQuiz *quizView = [[ViewControllerQuiz alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:quizView animated:YES];
}
The code to go back from a view to my first view:
-(IBAction)switchviewQuizToMain:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}
the problem is that the second code just goes back and that gives sometimes an error or a fail in the app. So when i go to other views and then want to go back it often gets stuck. So does someone have an other code to switch the views, or maybe an other solution? Thank You!
I wouldn't create new viewController in IBAction. For me i would do this in this way:
1 Create property with viewController:
#property(nonatomic, strong) UIViewController *quizView ;
2 Synthesize it:
#synthesize quizView = _quizView;
3 Create method:
- (UIViewController *) quizView {
if (_quizView == nil) {
_quizView = [[ViewControllerQuiz alloc] initWithNibName:nil bundle:nil];
}
return _quizView;
}
4 In your IBAction:
-(IBAction)switchviewMainToQuiz:(id)sender {
[self presentModalViewController:self.quizView animated:YES];
}

removeFromSuperview causes my app to crash

I'm sure this is some stupid mistake, but i'm trying for the past hour to remove a subview from my superview without any success.
On my first view i'm having
UIViewController *helpView = [[[UIViewController alloc] initWithNibName:#"HelpView" bundle:nil] autorelease];
[self.view addSubview:helpView.view];
And then inside helpView i have a button which is connected to an IBAction called "closeHelp" which just does the following:
- (IBAction) closeHelp{
[self.view removeFromSuperview];
}
But this causes my app to crash with EXC_BAS_ACCESS for some weird reason, even those this is inside the HelpView, meaning self.view should be pointed to the correct subview..
Would appreciate your help
Thank you.
Shai.
As Andreas answered, you are trying to remove self.view from its super/parent view.
You basically need to remove the helpView from its parent view.
so it should be
- (IBAction) closeHelp{
[helpView removeFromSuperview];
}
But we dont know what is "helpView" in the above method. As we dont have any handle for it.
So our code should finally look like this.
#define HELP_VIEW_TAG 101 // Give tag of your choice
HelpView *helpView = [[HelpView alloc] initWithNibName:#"HelpView" bundle:nil];
helpView.view.tag = HELP_VIEW_TAG;
[self.view addSubview:helpView.view];
[helpView release];
- (IBAction) closeHelp{
UIView *helpView = [self.view viewWithTag:HELP_VIEW_TAG];
[helpView removeFromSuperview];
}
The self.view does not point to your subview but the root view which your uiviewcontroller manages. You should probably remove only the last object in the subview stack, not the whole view, because now you are removing the whole help view.
Anyway, why do you not present the viewcontroller modally instead of doing this?
[self presentModalViewController:helpView animated:NO/YES];
helpView. modalTransitionStyle = //One of the constants below
UIModalTransitionStyleCoverVertical
UIModalTransitionStyleFlipHorizontal
UIModalTransitionStyleCrossDissolve
UIModalTransitionStylePartialCurl
Usually I am writing self.modalTransitionStyle = // One of the constants
in the viewcontroller which will be presented modally, instead of spreading the code.
You are initializing helpView as a UIViewController.
Make sure you have #import "HelpView.h" (or whatever the helpView .h file is called) in the .h file of the view controller where you are initializing it.
Then, use this code:
HelpView *helpView = [[HelpView alloc] initWithNibName:#"HelpView" bundle:nil];
[self.view addSubview:helpView.view];
That should fix it.
The easiest solution for me eventually was to just define my XIB's file owner as the same class as the parent controller, meaning the parent controller would control both the parent and the subview, which just makes a lot easier. :)
Declare the help view on calss level.
in.h file
#class HelpView;
..
#interface
{
HelpView *helpView;
}
#property(nonatomic,retain)HelpView* helpView;
In.m file
#import "HelpView"
#synthensize helpView;
now add this Code where you want
helpView = [[HelpView alloc] initWithNibName:#"HelpView" bundle:nil];
helpView.view.tag = HELP_VIEW_TAG;
[self.view addSubview:helpView.view];
- (IBAction) closeHelp{
//UIView *helpView = [self.view viewWithTag:HELP_VIEW_TAG];
[helpView removeFromSuperview];
}
-(void)dealloc
{
[helpView release];
}

transfer information between navigation based application

I have application
I want a button to open another screen with done button
after click this button a data be transfered from the current screen to the previous one
like opening options screen , how to let the main view know the changes be done on this subview
Best regards
You can use properties for this.
Create a property in the second class: .h file
#interface DetailViewController : UIViewController {
NSString *head;
}
#property(nonatomic,retain)NSString *head;
#end
in .m file
#synthesize head;
Now in your firstviewcontroller or first class
if (dt==nil) {
DetailViewController *d = [[DetailViewController alloc]initWithNibName:#"Detailview" bundle:nil];
self.dt = d;
[d release];
}
dt.head=itemsum;
[self.navigationController pushViewController:self.dt animated:YES];
Suppose you have to pass NSString to other class then declare one Nsstring in second class and make accessor method for nsstring and then call this code from first view controller
yournextviewcontroller *viewcontroller = [[yournextviewcontroller alloc] initWithNibName:#"yournextviewcontroller" bundle:nil];
viewcontroller.Stringname = name;
[self.navigationController viewcontroller:evernotebook animated:YES];
You can take UIView as IBOutlet in the same ViewController. Show that view with click on Button like
IBOutlet UIView *yourAnotherScreenView; //Bind this to your view in XIB file.
[self.view addSubView:yourAnotherScreenView];
[self.view bringSubViewtoFront:yourAnotherScreenView];
Take Done button on the view and wireup the action event in the same controller and do the necessary stuff as required.
Use the simple delegate concept of Objective-C .
Check very simple answers in the below post for using delegate in Objective-C .
How do I set up a simple delegate to communicate between two view controllers?

Value from parentViewController

This class is a subclass of UITabBarViewController.
In my init parent view controller file I have this:
UIBarButtonItem *button1 = [[UIBarButtonItem alloc]
initWithTitle:#"Button1"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(button1:)];
self.navigationItem.rightBarButtonItem = button1;
[button1 release];
And the method:
-(IBAction)button1:(id)sender {
if (self.nvc == nil) {
ChildViewController *vc = [[ChildViewController alloc] init];
self.nvc = vc;
[vc release];
}
[self presentModalViewController:self.nvc animated:YES];
I want to get an value from the parentviewcontroller in my childviewcontroller class, which also is a UITabBarViewController subclass.
How do I do this, I have tried several hours, and I only get a nil-reference.
The object I want to get(which is a property in the parent) is a NSString.
Thanks in advance
The cleanest way would probably be to create a ChildViewControllerDelegate protocol that the parent view controller implements. This is a common idiom in iOS development.
#protocol ChildViewControllerDelegate
- (NSString *)getSomeNSString;
#end
Then you should make ChildViewController have this delegate as an instance variable and be assignable via a property
#property (nonatomic, assign) id<ChildViewControllerDelegate> delegate;
Now from within ChildViewController you can use this delegate to access methods on the delegate which in your case will be ParentViewController. This will allow you to retreive the string you want.
[delegate getSomeNSString]
This may seem like a lot of work for something simple but it avoids the problems inherit with storing a back reference from ChildViewController to its parent ParentViewController.
There are a lot of ways to do this. The easiest would be to add a property to ChildViewController that points to your parent view controller. You could call it delegate. Then the method will look like:
-(IBAction)newbuilding:(id)sender {
if (self.nvc == nil) {
ChildViewController *vc = [[ChildViewController alloc] init];
vc.delegate = self;
self.nvc = vc;
[vc release];
}
[self presentModalViewController:self.nvc animated:YES];
}
Then from the ChildViewController instance you can access self.delegate.someProperty.
There are also ways to get the parent view controller without your own explicit reference (typically self.tabBarController, self.navigationController depending on context), but the above method is fool-proof, understandable and easy to debug.

pass data to object of uiviewcontroller on iPhone

I have an iPhone app with a tableviewcontroller. When you click a certain cell it opens a new uiviewcontroller with this code:
nextViewController = [[avTouchViewController alloc] initWithNibName:#"avTouchViewController" bundle:nil];
The uiviewcontroller above called avTouchViewController has a property that looks like:
IBOutlet SomeObject *controller;
SomeObject is an object with all relevant view properties.
I would like to pass an nsstring parameter from the tableviewcontroller I initialize the avTouchViewController with to someObject.
How can I do this?
I'm a little confused by your question; you say you're creating your avTouchViewControllers when a cell is tapped inside an existing UITableView, but your last part describes the inverse situation.
Basically, if you want to pass information to a view controller, just give it a property that can be set (which may already be the case), e.g.:
nextViewController = [[avTouchViewController alloc] initWithNibName:#"avTouchViewController" bundle:nil];
nextViewController.controller = theInstanceOfSomeObjectIWantToPass;
You also may want to rename your controller property. To a reader, it doesn't make sense that a view controller has a property called controller which is actually a SomeObject*. As well, your class names should be capitalized, i.e. use AvTouchViewController instead of avTouchViewController.
If I were doing this I would add my own initializer to my UIViewController subclass:
- (id)initWithController:(NSString *pController) {
if (self = [super initWithNibName:#"avTouchViewController" bundle:nil]) {
self.controller = pController;
}
return self;
}
And then just call the following (in tableView:didSelectRowAtIndexPath: or whereever):
NSString *controller = #"Sample String";
AVTouchViewController *nextViewController = [[AVTouchViewController alloc] initWithController:controller];
[controller release];
[self.navigationController pushModalViewController:nextViewController animated:YES];
[nextViewController release];
As a point of style, class names conventionally begin with uppercase letters (hence my change to AVTouchViewController).