I have been trying to get a double picker to show both text and images. the left picker will have text and the right will have images. When I do text, it works fine but when I try to make images appear I get an error that says
0x6b8b230> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key column1.'
I got this so far but Im stuck and have no idea what to do.
#property (strong, nonatomic) NSArray *textvals;
#property (strong, nonatomic) NSArray *imagevals;
#synthesize textvals;
#synthesize imagevals;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSArray *totalArray = [[NSArray alloc] initWithObjects:#"Text 1",
#"text2", #"text 3", #"text 4", nil];
self.textvals = totaltextArray;
UIImage *image1 = [UIImage imageNamed:#"first.png"];
UIImage *image2 = [UIImage imageNamed:#"second.png"];
UIImage *image3 = [UIImage imageNamed:#"third.png"];
UIImage *image4 = [UIImage imageNamed:#"fourth.png"];
UIImageView *image1View = [[UIImageView alloc] initWithImage:image1];
UIImageView *image2View = [[UIImageView alloc] initWithImage:image2];
UIImageView *image3View = [[UIImageView alloc] initWithImage:image3];
UIImageView *image4View = [[UIImageView alloc] initWithImage:image4];
NSArray *totalimagearray = [[NSArray alloc] initWithObjects:image1View, image2View, image3View, image4View,nil];
//[self setValue:totalimagearray forKey:"1"];
self.imagevals = totalimagearray;
}
yes it is absolutely possible. u need to handle pickerView delegate method
(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row
forComponent:(NSInteger)component reusingView:(UIView *)view
here you simply return custom view(could be anything UIImage UILabel)
and set userInteractionEnable property to no for customize view..
Related
I've written some code to make a screenshot of the view. I write that image to the photo library. But the thing is, I want to use that image in an other imageView in another ViewController. How can I save the image somewhere in the app and use it in another ViewController?
My code:
UIView* captureView = self.view;
UIGraphicsBeginImageContextWithOptions(captureView.bounds.size, captureView.opaque, 0.0);
[captureView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGRect cropRect = CGRectMake(0 ,0 ,640,1136);
UIGraphicsBeginImageContextWithOptions(cropRect.size, captureView.opaque, 1.0f);
[screenshot drawInRect:cropRect];
UIImage * customScreenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(customScreenShot , nil, nil, nil);
You first need to save your image on the disk:
NSString *documentDirectory =
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
objectAtIndex:0];
NSString *pngFilePath = [NSString stringWithFormat:#"%#/myImage.png",documentDirectory];
NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(customScreenShot)];
[imageData writeToFile:pngFilePath atomically:YES];
And then you can create an UIImageView with the file:
UIImageView *myImageView = [[UIImageView alloc] initWithImage:[UIImage
imageWithContentsOfFile:pngFilePath]];
[self.view addSubview:myImageView];
If you are using Storyboards, you could pass it to the next view controller like so; in the prepareForSegue method ( this relieves you from having to save it to disk ):
Note: the name of the segue is set by you in MainStoryboard.storyboard. - mySegue.
kMySegue is just a key for that. i.e. #define kMySegue #"mySegue"
imageInOtherViewController is a UIImage in the other view controller.
// TheFirstViewController.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
id destinationViewController = [segue destinationViewController];
if ([[segue identifier] isEqualToString:kMySegue]){
if ([destinationViewController respondsToSelector:#selector(setImageInOtherViewController:)]){
[destinationViewController setImageInOtherViewController:[UIImage imageNamed:#"myImage.png"]];
FastCameraViewController *viewController = segue.destinationViewController;
viewController.delegate = self;
}
}
// OtherViewController.h
#interface OtherViewController : UIViewController
{
}
#property (nonatomic, strong) IBOutlet UIImageView *otherViewControllerImageView;
#property (nonatomic, strong) UIImage *imageInOtherViewController;
// OtherViewController.m
#implementation OtherViewController
#synthesize otherViewControllerImageView;
#synthesize imageInOtherViewController;
- (void)viewDidLoad{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[[self otherViewControllerImageView] setImage:imageInOtherViewController];
}
To cache your images I recommend using the NSCache class first ie
NSCache* imagesCache = [[NSCache alloc] init];
[imagesCache setName:#"imagesCache"];
[imagesCache setObject:customScreenShot forKey:#"image1"];
the good news is that NSCache accepts any object of type id so you can store images, mp3s, whatever you want.
If you would like to use the phone's file directory (which is more expensive to use than NSCache..) I recommend you use the Library/Caches directory instead of the Documents directory.. so building on iDevzilla's answer:
NSString *documentDirectory =
[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)
objectAtIndex:0];
I am building an App where the user can spin a UIPickerView like a slot machine. The problem I am facing at the moment that at runtime the images in my pickerView start disappearing at random. Then spin again and some of them are back.
Here is the code I use to make the array of images (in my project there are 17 images in every array but to save a bit of space I narrowed it down):
- (void)viewDidLoad{
[super viewDidLoad];
[drinkPickerView_ selectRow:1000 inComponent:0 animated:NO];
[drinkPickerView_ selectRow:1000 inComponent:1 animated:NO];
[drinkPickerView_ selectRow:1000 inComponent:2 animated:NO];
if (managedObjectContext_ == nil)
{
managedObjectContext_ = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}
drinkPickerView_.delegate = self;
drinkPickerView_.dataSource = self;
UIImage *fris1 = [UIImage imageNamed:#"fris01.PNG"];
UIImage *fris2 = [UIImage imageNamed:#"fris02.PNG"];
UIImage *fris3 = [UIImage imageNamed:#"fris03.PNG"];
UIImage *fris4 = [UIImage imageNamed:#"fris04.PNG"];
UIImage *fris5 = [UIImage imageNamed:#"fris05.PNG"];
UIImageView *frisView1 = [[UIImageView alloc]initWithImage:fris1];
UIImageView *frisView2 = [[UIImageView alloc]initWithImage:fris2];
UIImageView *frisView3 = [[UIImageView alloc]initWithImage:fris3];
UIImageView *frisView4 = [[UIImageView alloc]initWithImage:fris4];
UIImageView *frisView5 = [[UIImageView alloc]initWithImage:fris5];
UIImage *alcoholisch1 = [UIImage imageNamed:#"alcohol01.PNG"];
UIImage *alcoholisch2 = [UIImage imageNamed:#"alcohol02.PNG"];
UIImage *alcoholisch3 = [UIImage imageNamed:#"alcohol03.PNG"];
UIImage *alcoholisch4 = [UIImage imageNamed:#"alcohol04.PNG"];
UIImage *alcoholisch5 = [UIImage imageNamed:#"alcohol05.PNG"];
UIImageView *alcoholischView1 = [[UIImageView alloc]initWithImage:alcoholisch1];
UIImageView *alcoholischView2 = [[UIImageView alloc]initWithImage:alcoholisch2];
UIImageView *alcoholischView3 = [[UIImageView alloc]initWithImage:alcoholisch3];
UIImageView *alcoholischView4 = [[UIImageView alloc]initWithImage:alcoholisch4];
UIImageView *alcoholischView5 = [[UIImageView alloc]initWithImage:alcoholisch5];
UIImage *freaky1 = [UIImage imageNamed:#"freaky01.PNG"];
UIImage *freaky2 = [UIImage imageNamed:#"freaky02.PNG"];
UIImage *freaky3 = [UIImage imageNamed:#"freaky03.PNG"];
UIImage *freaky4 = [UIImage imageNamed:#"freaky04.PNG"];
UIImage *freaky5 = [UIImage imageNamed:#"freaky05.PNG"];
UIImageView *freakyView1 = [[UIImageView alloc]initWithImage:freaky1];
UIImageView *freakyView2 = [[UIImageView alloc]initWithImage:freaky2];
UIImageView *freakyView3 = [[UIImageView alloc]initWithImage:freaky3];
UIImageView *freakyView4 = [[UIImageView alloc]initWithImage:freaky4];
UIImageView *freakyView5 = [[UIImageView alloc]initWithImage:freaky5];
NSArray *frisImageArray = [[NSArray alloc]initWithObjects:frisView1,frisView2,frisView3,frisView4,frisView5, nil];
NSArray *alcoholischImageArray = [[NSArray alloc]initWithObjects:alcoholischView1,alcoholischView2,alcoholischView3,alcoholischView4,alcoholischView5, nil];
NSArray *freakyImageArray = [[NSArray alloc]initWithObjects:freakyView1,freakyView2,freakyView3,freakyView4,freakyView5, nil];
NSString *frisFieldName = [[NSString alloc]initWithFormat:#"frisDrankenPlaatjesArray"];
[self setValue:frisImageArray forKey:frisFieldName];
NSString *alcoholischFieldName = [[NSString alloc]initWithFormat:#"alcoholischeDrankenPlaatjesArray"];
[self setValue:alcoholischImageArray forKey:alcoholischFieldName];
NSString *freakyFieldName = [[NSString alloc]initWithFormat:#"freakyDrankenPlaatjesArray"];
[self setValue:freakyImageArray forKey:freakyFieldName];
}
This is the code where I load the images in the pickerView:
-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row
forComponent:(NSInteger)component reusingView:(UIView *)view{
if (component==0) {
NSString *arrayName = [[NSString alloc]initWithFormat:#"alcoholischeDrankenPlaatjesArray"];
NSArray *array = [self valueForKey:arrayName];
return [array objectAtIndex:(row%5)];
}
else if(component==1){
NSString *arrayName = [[NSString alloc]initWithFormat:#"frisDrankenPlaatjesArray"];
NSArray *array = [self valueForKey:arrayName];
return [array objectAtIndex:(row%5)];
}
else if (component==2){
NSString *arrayName = [[NSString alloc]initWithFormat:#"freakyDrankenPlaatjesArray"];
NSArray *array = [self valueForKey:arrayName];
return [array objectAtIndex:(row%5)];
}
else{
return nil;
}
}
this is the code that makes the pickerView spin:
-(IBAction)rotate:(id)sender{
int numInRow =1;
int lastVal = -1;
for (int i=0;i<3; i++) {
int newValue = arc4random()%1000;
if (newValue==lastVal)
numInRow++;
else
numInRow =1;
lastVal=newValue;
[drinkPickerView_ selectRow:newValue inComponent:i animated:YES];
[drinkPickerView_ reloadComponent:i];
}
}
I hope this is enough information and I hope somebody can help me out.
I had a similar problem. I tried retaining the objects, arrays, images but that didn't fix it. Turns out that if I populated the arrays again (ala how you initialized them in the viewDidLoad method) in the -pickerView viewForRow: method then it worked great. Seems inefficient to repopulate the same arrays with every method call but it seemed to do the trick.
I think the problem lays at where you initialize your UIImages:
UIImage *fris1 = [UIImage imageNamed:#"fris01.PNG"]; <-- this is autorelease!
You need to set your UIImages as properties so that they can be retained.
Like so:
#property (nonatomic,retain) UIImage *fris1;
and synthesize them in your .m. and applying the image as:
self.fris1 = [UIImage imageNamed:#"fris01.PNG"];
This way, the UIImage is retained throughout the app life.
This is from UIPickerView.h.
/*
these methods return either a plain UIString, or a view (e.g UILabel) to display the row for the component. for the view versions, we cache any hidden and thus unused views and pass them back for reuse. If you return back a different object, the old one will be released. the view will be centered in the row rect
*/
(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view;
So when your pickerview tries to show a previously shown uiimageview it releases the previous one. That's why you should create different uiimageview for each component.
So I'm adding a bunch of custom UIBarButtonItems to a UIToolbar, and they all load just fine and look great, and I can see them in my UIToolbar. The only problem is, I can't perform any actions on them. In my viewDidLoad, I set up everything. Here are my .h and .m files:
.h file:
#import <UIKit/UIKit.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import <QuartzCore/QuartzCore.h>
#interface PhotoEditViewController : UIViewController <UIPopoverControllerDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIGestureRecognizerDelegate> {
IBOutlet UIImageView *imageView;
}
- (IBAction)cancelEdit:(id)sender;
- (IBAction)savePhoto:(id)sender;
- (IBAction)chooseColor:(id)sender;
#property (retain) IBOutlet UIToolbar *editBar;
#property (retain) UIImageView *imageView;
#property (retain) UIImage *tempImage;
- (void) setupStache;
#end
.m file: (viewDidLoad)
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageView.image = tempImage;
NSMutableArray *toolbarItems = [NSMutableArray arrayWithCapacity:3];
// get the filepaths of all the images
NSString *imagePath_cancel = [[NSBundle mainBundle] pathForResource:#"barBtnPhotoEditCancel" ofType:#"png"];
NSString *imagePath_save = [[NSBundle mainBundle] pathForResource:#"barBtnSavePhoto" ofType:#"png"];
NSString *imagePath_color = [[NSBundle mainBundle] pathForResource:#"barBtnChangeColor" ofType:#"png"];
// get the images
UIImage *cancelImage = [[UIImage alloc] initWithContentsOfFile:imagePath_cancel];
UIImage *saveImage = [[UIImage alloc] initWithContentsOfFile:imagePath_save];
UIImage *changeColorImage = [[UIImage alloc] initWithContentsOfFile:imagePath_color];
// set the images to the UIBarButtonItem(s)
CGRect cancelFrame = CGRectMake(0, 0, cancelImage.size.width-25, cancelImage.size.height-25);
UIButton* cancelButton = [[UIButton alloc] initWithFrame:cancelFrame];
[cancelButton setBackgroundImage:cancelImage forState:UIControlStateNormal];
[cancelButton setShowsTouchWhenHighlighted:YES];
UIBarButtonItem *cancelBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:cancelButton];
[cancelBarButtonItem setTarget:self];
[cancelBarButtonItem setAction:#selector(cancelEdit:)];
CGRect saveFrame = CGRectMake(0, 0, saveImage.size.width-25, saveImage.size.height-25);
UIButton* saveButton = [[UIButton alloc] initWithFrame:saveFrame];
[saveButton setBackgroundImage:saveImage forState:UIControlStateNormal];
[saveButton setShowsTouchWhenHighlighted:YES];
UIBarButtonItem* saveBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:saveButton];
[saveBarButtonItem setTarget:self];
[saveBarButtonItem setAction:#selector(savePhoto:)];
CGRect colorFrame = CGRectMake(0, 0, changeColorImage.size.width-25, changeColorImage.size.height-25);
UIButton* colorButton = [[UIButton alloc] initWithFrame:colorFrame];
[colorButton setBackgroundImage:changeColorImage forState:UIControlStateNormal];
[colorButton setShowsTouchWhenHighlighted:YES];
UIBarButtonItem* colorBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:colorButton];
[colorBarButtonItem setTarget:self];
[colorBarButtonItem setAction:#selector(chooseColor:)];
// add all the items
[toolbarItems addObject:cancelBarButtonItem];
[toolbarItems addObject:saveBarButtonItem];
[toolbarItems addObject:colorBarButtonItem];
[self.editBar setItems:toolbarItems animated:NO];
// release everything
[cancelBarButtonItem release];
[cancelButton release];
[saveBarButtonItem release];
[saveButton release];
[colorBarButtonItem release];
[colorButton release];
}
- (IBAction)cancelEdit:(id)sender {
NSLog(#"Pressing the cancel button");
}
- (IBAction)savePhoto:(id)sender {
NSLog(#"Pressing the save button");
}
- (IBAction)chooseColor:(id)sender {
NSLog(#"Pressing the choose color button");
}
So, here's the answer.
I was inserting a custom subview that was the size of the entire screen (320x640). It also had gestureRecognizers attached to it. Therefore, whenever I tapped that view, the gestureRecognizer responded to the attached subview, instead of the uitoolbar, or the buttons on it. Man I'm foolish. Resized the image on the UIView, and everything works fine. :) Thanks everyone for the help.
initWithCustomView - view must be button and set action on button
I have the following code which works fine UIScrollView. But when loading the picture can be seen only at the last subview and UIActivityIndicatorView not working for loading each picture.
How to be done for such a task?
myProject2ViewController.h
#import <UIKit/UIKit.h>
#import "PageScrollView.h"
#interface myProject2ViewController : UIViewController
{
NSMutableArray *pages;
PageScrollView *scrollView;
UIView *myOneSubview;
UIImageView *imageView;
UIActivityIndicatorView *myIndicator;
}
#property (nonatomic, retain) PageScrollView *scrollView;
#property (nonatomic, retain) UIImageView *imageView;
#property (nonatomic, retain) UIActivityIndicatorView *myIndicator;
#end
myProject2ViewController.m
#import "myProject2ViewController.h"
#implementation myProject2ViewController
#synthesize scrollView;
#synthesize imageView;
#synthesize myIndicator;
- (void)dealloc
{
[super dealloc];
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *imageUrls = [NSArray arrayWithObjects:
#"link_1",
#"link_2",
#"link_3",
nil];
pages = [[NSMutableArray alloc] init];
for (int i = 0; i < [imageUrls count]; i++) {
CGRect frameOne = CGRectMake(0.0f, 50.0f, 320.0f, 416.0f);
myOneSubview = [[UIView alloc] initWithFrame:frameOne];
myOneSubview.backgroundColor = [UIColor blackColor];
NSString *imageUrl = [imageUrls objectAtIndex:i];
myIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
myIndicator.center = CGPointMake(160.0f, 130.0f);
myIndicator.hidesWhenStopped = YES;
myIndicator.backgroundColor = [UIColor clearColor];
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 50.0f, 320.0f, 416.0f)];
[NSThread detachNewThreadSelector:#selector(loadImages:) toTarget:self withObject:imageUrl];
[myOneSubview addSubview:imageView];
[pages addObject:myOneSubview];
}
scrollView = [[PageScrollView alloc] initWithFrame:self.view.frame];
scrollView.pages = pages;
scrollView.delegate = self;
self.view = scrollView;
}
- (void)loadImages:(NSString *)string
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[myIndicator startAnimating];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:string]];
UIImage *image = [[UIImage alloc] initWithData:imageData];
[imageView setImage:image];
[image release];
[imageData release];
[self performSelectorOnMainThread:#selector(loadImageComplete) withObject:self waitUntilDone:YES];
[pool drain];
}
-(void)loadImageComplete
{
NSLog(#"Load image complete!");
[myIndicator stopAnimating];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
#end
When you do:
CGRectMake(0.0f, 50.0f, 320.0f, 416.0f);
Inside your for loop, you're specifying those same exact position and dimension for EVERY image you create in the for loop. In other words, every next image you create will sit ontop of the previous image, as a result, you will only see the final image you created in the for loop.
Try adding your counter "i" variable to the X and Y value in CGRectMake() to offset every image that gets subsequently created.
So let say each image was 100 pixel by 100 pixel, then something like:
CGRectMake(0.0f + (i * 100.0f), 50.0f, 320.0f, 416.0f);
Would make each image sit right after the previous one (since each image is 100 pixel wide, we offset it by 100 pixel and use that value as the starting point of the next image). If you add an extra value after (i * 100) so it becomes (i * 100 + 50) then that would give you a left padding of 50 pixels from the previous image.
If your images are different dimensions you'll need to calculate the width and height of the image before hand and factor those into your CGRectMake() method.
Hope that helps.
In addition, instead of creating so many views to add to your scroll view, you could write the code like so:
scrollView = [[UIScrollview alloc] init];
. . .
for(...)
{
UIImageView *currentImage = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f + (i * 100.0f), 50.0f, 320.0f, 416.0f);
[currentImage setImage:[UIImage imageNamed:[imageUrls objectAtIndex:i]]];
. . .
[scrollView addSubview: currentImage];
[currentImage release];
}
I am not getting my image working. Can anyone tell me what I am doing wrong here?
musclePicture is a string in format of picture.png
1st view:
NSString *muscleURL = [[self.muscleArray objectAtIndex:indexPath.row]objectForKey:#"musclePicture"];
specificExerciseTableViewController.muscleImage = [UIImage imageNamed:muscleURL];
2nd view:
detailViewController.muscleImage = self.muscleImage;
3rd view:
self.image = [[UIImageView alloc]initWithImage:muscleImage];
[image release];
Edit:
MusclesTableViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *muscleURL = [[self.muscleArray objectAtIndex:indexPath.row]objectForKey:#"musclePicture"];
specificExerciseTableViewController.muscleImage = [UIImage imageNamed:muscleURL];
}
SpecificExerciseTableViewController.h
#property (nonatomic, retain) UIImage *muscleImage;
SpecificExerciseTableViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
detailViewController.muscleImage = self.muscleImage;
}
DetailViewController.h
#property (nonatomic, retain) UIImage *muscleImage;
#property (nonatomic, retain) IBOutlet UIImageView *image;
DetailViewController.m
- (void)viewDidLoad
{
self.image.image = muscleImage;
}
Try by giving a frame to your UIImageView after:
self.image = [[UIImageView alloc]initWithImage:muscleImage];
[image setFrame:CGRectMake(0,0,50,50)];
[image release];
Try this code snippet:
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[animal imageURL]]];
UIImage *animalImage = [[UIImage alloc] initWithData:imageData];
Assign it your UIImageView or UIImage.
I think you forgot to add image as subView to your view.
like this
[self.view addSubView:image];
or you are having a class variable that is connected to .xib file as an IBOutlet and you are reinitializing it using alloc and init, if that is the case then you have to do
self.image.image = [UIImage imageNamed: muscleImage];