i create a view based project named myclass.
and i add another UIviewcontroller subclass to it, named as webdata.
In the webdataviewcontroller.m i get image from the webserver.
I need to display this image on imageview in myclassViewController.m from webdataViewController.m
for this my code in webdataViewController.m is
docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
imagepath = [NSString stringWithFormat:#"%#/image.png",docDir];
logopath = [NSString stringWithFormat:#"%#/logo.png",docDir];
myclassViewController *obj = [[myclassViewController alloc]init];
obj.homeimage.image = [UIImage imageWithContentsOfFile:imagepath];
but image is not displayed,i try to print image in console
NSLog(#"image to display %#",obj.homeimage.image);
NSLog(#"image to display %#",[UIImage imageWithContentsOfFile:imagepath]);
but i get like this
image to display (null)
image to display <UIImage: 0x6f614b0>
why i get null for obj.homeimage.image,i did n't get can any one please help me.
Thank u in adavance.
(Let me add comment if question is not understandable)
Are you sure that obj.homeimage is not nil? If it is nil then obj.homeimage.image = ... will result to setting image property to nil object, that is "nothing".
Why don't you give us the code for myclassViewController ?
Also you have a lot of mistakes in capitalization, etc. It makes it hard to read your code and it's messy.
myClassViewController should be MyClassViewController
webdataViewController should be WebDataViewController
You should camel case variable names
homeimage should be homeImage
imagepath should be imagePath
You said you subclassed myclassViewController, I think by that you meant you added it as a subview. If so when you execute the code:
myclassViewController *obj = [[myclassViewController alloc]init];
you are creating a NEW myclassViewController, not referencing the parent view controller. You need a pointer to the the instance of the myclassViewController that added webdataViewController as a subview, and add the image to it's property. Also I'm guessing here lies your problem, you are creating a new empty instance of myclassViewController therefore you have not initialized your ivars. (Unless you did so in your -init method, but I would doubt that). So you alloc-ed and init-ed a new myclassViewController but none of it's variables are initialized so you are just messaging nil objects probably. Which is why your code isn't crashing yet still not responding. Once again this is a guess, but it probably is the problem.
I can edit with more information if you give the code for myclassViewController.
Related
Rookie question: I am writing a program that will generate a specific string and then display it in a text window in a different view controller. I have been testing to ensure that the code in fact generates the string using NSLog commands and I know the code is working as intended. For some reason it is not transferring across the view controller and I cant figure out why. Any help? Here is a snippet of the code:
CreateStoryViewController.m
- (IBAction)makeStory:(id)sender
{
StoryLine *myStory =[[StoryLine alloc] init];
[myStory setStory];
self.story = myStory.plot;
NSLog(#"story is %#", self.story);//this is generating the correct story string
self.displayStoryController = [[BIDDisplayStoryViewController alloc] initWithNibName:#"DisplayStoryView" bundle:nil];
[self.view insertSubview:self.displayStoryController.view atIndex:1];
}
DisplayStoryViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
BIDCreateStoryViewController *newStory = [[BIDCreateStoryViewController alloc] init];
NSLog(#"newStory.story is %#",newStory.story);//this generates null message
self.storyDisplay.text = newStory.story;
}
This is wrong. You're instantiating a new BIDCreateViewController object inside your second view controller. This is not the same as the original BIDCreateViewController object that pushed your second BIDDisplayStoryViewController.
You need to declare a string property in your BIDDisplayStoryViewController's header file.
Something like
#property (nonatomic, retain /*or strong, if using ARC*/) NSString *storyToDisplay;
Be sure to synthesize this in your implementation file as well.
When you create BIDDisplayStoryViewController inside your first view controller, you need to do it as follows:
self.displayStoryController = [[BIDDisplayStoryViewController alloc] initWithNibName:#"DisplayStoryView" bundle:nil];
self.displayStoryViewController.storyToDisplay = self.story;
Now inside your second view controller you can access this using self.myStory.
While this will solve your problem (and please do understand that it's not my intention to be rude here), I feel that there's a lack of understanding of how iOS (and OOP in general) works.
In your viewDidLoad method you are making a whole new story. This story is totally different from the one you made in the makeStory: method. You should add a StoryLine Property to DisplayStoryViewController.h, and set that after you init your displayStoryController.
make the intended variable a property type at .h file, so the other file can access it
I am setting the value for the string in the viewdidload method and getting the string value in the button action method the app gets crashed. can I know the reason for crashing and how to pass the values to the method.
in .h file
NSString *test;
in .m file
-(void)viewDidLoad
{
test = [NSString stringWithFormat:#"sample"];
}
-(IBAction) buttonPressed:(id)sender
{
NSLog(#"%#", test);
}
When I pressed the button the app crashes.
Please try using this solution, I think this will help you,
Create Property of test in .h file like this,,
#property(nonatomic,retain) NSString *test;
and synthesize it in .m file like this,
#synthesize test;
now use test as self.test in .m file like this,
-(void)viewDidLoad
{
self.test = [NSString stringWithFormat:#"sample"];
}
-(IBAction) buttonPressed:(id)sender
{
NSLog(#"%#", self.test);
}
Another solution for this is just retain that test string in ViewDidLoad also, I think this will also help you..
Hope this will help you..
Let me try to explain it in more detail:
You have a string variable in .h file. In view did load you are assigning it as:
test = [NSString stringWithFormat:#"sample"];
What actually happning in this code is your test is a autoreleased object. When you use this and object without alloc and init this is autoreleased object and will release memory after the method you occupied it.
For avoiding this situation you can use #Mehul's solution by creating property. This is against encapsulation concept. Sometimes you have objects you don't want to access outside of the class or don't want to show with objects. Use following in those conditions:
test = [[NSString stringWithFormat:#"sample"] retain]; // or
test = [[NSString alloc] initWithFormat:#"sample"];
this will keep your string alive till you release it.
There is another way that is not good to use but want to tell you so you can understand it better. Using
test = #"sample";
If you don't want to append string or use it with format you can assign simple string to you NSString object.
using this will have a infinite retainCount of your test variable. You can use this to avoid crash but this is not preferable because as I told this have a infinite retaiCount you can't release it and free your memory after use. So earlier methods are more correct.
This is true with all of your autorelease objects which are created with class methods and not with init.
Hope this will clear you more.
I think simple allocation will solve the problem. Just replace this code in the viewDidLoad method
-(void)viewDidLoad {
test=[[NSString alloc]initWithString:#"Sample"];
}
I have a NSXMLParser that parses YT's API. It then turns all the videos into a class I wrote called video. Then the class is put into an array. Then back at my rootviewcontroller I access xmlParser.allVideos (xmlParser is a class I wrote that is the delegate for the xml parser.
Here is what I do with it in the viewDidLoad:
arrayFromXML = xmlParser.allVideos;
Then in the drawing of the tableView I do this:
tempVideo = [arrayFromXML objectAtIndex:indexPath.row];
cell.textLabel.text = tempVideo.videoTitle; //crashes here and says NSString has been deallocated.
How can I fix this?
If arrayFromXML is an instance variable you have to retain or copy (to be safe from later manipulation) the array as xmlParser simply might not be alive anymore when other methods are called later:
arrayFromXML = [xmlParser.allVideos copy];
Or better yet using a copy or retain property:
self.arrayFromXML = xmlParser.allVideos;
UIImage *image = [[UIImage alloc] initWithData:data];
((YKSubCategory *)[_subCategories objectAtIndex:connection.tag - 1]).menuImage = image;
[image release];
Here is the code I've written. The data is exists and the designed image is created. (I've tested it with an imageview and the image appears).
The problem comes when I try to set the menuImage property. It will not be set. I don't know why. So the value of the menuImage property remains nil.
Here is the property definition:
#property (nonatomic, retain) UIImage *menuImage;
What can be the problem?
Edit:
I've divided the code for the request of walkytalky.
Here is the code I've written:
UIImage *image = [[UIImage alloc] initWithData:data];
YKSubCategory *subCategory = (YKSubCategory *)[_subCategories objectAtIndex:connection.tag - 1];
subCategory.menuImage = image;
[image release];
[_tableView reloadData];
So now the funny thing is that the subCategory variable is the variable what I expect. Then after I set the menuImage property then the variable for this property is set. I can see in the debugger, but in the array isn't set. What is this?
(i) Have you #synthesize-d menuImage?
(ii) Can you break up the setter line to first get the YKSubCategory object and test it exists and is what you expect?
YKSubCategory* target = (YKSubCategory*)[_subCategories objectAtIndex:connection.tag - 1];
NSLog("subcategory target = %#", target);
// other tests here
target.menuImage = image;
Otherwise, I don't think we have enough info to solve this. What does menuImage look like immediately after setting?
EDIT: when you say "in the array isn't set", do you mean that the actual object in the array differs from the one you've just set right there and then? Or that when you come back to the array when loading the table data the menuImage is no longer set? Or that it just doesn't show in the table?
The first seems impossible on the face of it, so let's think about the second and third.
If menuImage has been reset by the time you come back to it, there must be some code setting it somewhere. This may not go through the property accessor, but for starters you might explicitly implement the setter to log the changes:
- (void) setMenuImage:(UIImage*)newImage
{
if ( newImage != menuImage )
{
NSLog(#"Changing menuImage from %# to %#", menuImage, newImage);
[newImage retain];
[menuImage release];
menuImage = newImage;
}
}
Another possibility is that the actual YKSubCategory object in the array has changed, or even that the arrays are different, so check that the pointers are the same in both locations.
On the other hand, if the menu image ivar is set, but it's not showing up in the table, you need to check your drawing code.
UPDATED Scroll down to see the question re-asked more clearly....
If I had the name of a particular UIImageView (IBOutlet) stored in a variable, how can I use it to change the image that is displayed. I tried this, but it does not work.
I'm still new to iphone programming, so any help would be appreciated.
NSString *TmpImage = #"0.png";
NSString *Tst = #"si1_1_2";
TmpImage = #"1.png";
UIImage *sampleimage = [[UIImage imageNamed:TmpImage] retain];
((UIImageView *) (Tst)).image = sampleimage; // This is the line in question
[sampleimage release];
RESTATED:
I have a bunch of images on the screen.... UIImageView *s1, *s2 ,*s3 etc up to *s10
Now suppose I want to update the image each displays to the same image.
Rather than doing
s1.image = sampleimage;
s2.image = sampleimage;
:
s10.image = sampleimage;
How could i write a for loop to go from 1 to 10 and then use
the loop var as part of the line that updates the image.
Something like this.
for ( i = 1; i <- 10; ++i )
s(i).image = sample; // I know that does not work
Basic question is how do I incorporate the variable as part of the statement to access the image? Don't get hung up on my example. The main question is how to use a variable as part of the access to some element/object.
Bottom Line... If I can build the name of a UIImageView into a NSString object, How can I then use that NSString object to manipulate the UIImageView.
Thanks!
Ugh! Your line in question:
((UIImageView *) (Tst)).image = sampleimage;
is casting a string pointer as a UIImageView pointer - you're basically saying that your pointer to a string is actually a pointer to a UIImageView! It will compile (because the compiler will accept your assertion happily) but will of course crash on running.
You need to declare a variable of type UIImageView. This can then hold whichever view you want to set the image of. So your code could look like the following:
NSString *TmpImage = #"0.png";
UIImageView *myImageView;
If (someCondition == YES) {
myImageView = si1_1_2; //Assuming this is the name of your UIImageView
} else {
myImageView = si1_1_3; //etc
}
UIImage *sampleimage = [UIImage imageNamed:TmpImage]; //no need to retain it
myImageView.image = sampleImage;
Hopefully this makes sense!
Edit: I should add, why are you trying to have multiple UIImageViews? Because a UIImageView's image can be changed at any time (and in fact can hold many), would it not be better to have merely one UIImageView and just change the image in it?