Parse.com iOS issue, PFImageView does not seem to support CopyWithZone - ios

i am sending a PFImageView*(Parse.com subclass of UIImageView)* to a new View, where i am adding it as a subview, this ofc leads to the PFImageView getting detached from its previous view, which id like to avoid.
I have to call Copy, and CopyWithZone on the PFImageView, but the class does not seem to support that method, i have also tried the following:
UIImage *copiedImage = [[UIImage alloc] initWithCGImage:[[sender image] CGImage]];
PFImageView *copiedImageView = [[PFImageView alloc] initWithImage:copiedImage];
[segue.destinationViewController setFullSizeImage:copiedImageView];
But this leads to an empty PFImageView? Can i add a category to PFImageView and implement the CopyWithZone protocol ? And if so, how would i implement it?

fixed it by implementing a category with the following:
-(id)copyPFImageView
{
PFImageView *copy = [[PFImageView alloc] init];
[copy setFile:[self file]];
[copy setImage:[self image]];
return copy;
}
Remember that the data in file is quite essential

Related

Inability to create my UIImageView classes from string

I am creating subclasses of UIImageView class, something like LittleImageView, RedImageView, etc.
These subclasses have this convenience method for the creation of specific images:
+ (UIImageView *)novo {
UIImageView *newImage = [[super alloc] initWithImage:...
// do stuff
return newImage;
}
When I try to create such classes using this new command by string
id newObject = [NSClassFromString(nameOfClass) novo];
I get a crash with "unrecognized selector sent to class". Apparently objective-c is trying to do a [UIImageView novo] instead of doing a [RedImageView novo], for instance.
Any ideas how to solve this?
I can't reproduce your experience exactly, but there are a few changes you should consider: (1) declare the constructor as returning the derived type, (2) declare the local variable as the derived type, (3) used the derived class to alloc (self, not super)...
// in MyImageView.h
+ (instancetype)myImageView:(UIImage *)image;
// in MyImageView.m
+ (instancetype)myImageView:(UIImage *)image {
MyImageView *miv = [[self alloc] initWithImage:image];
// ...
return miv;
}
Now you can use elsewhere without the sketchy use of id in your local variable declaration. It looks like this, and in my test, generates instances of the correct type...
MyImageView *firstTry = [MyImageView myImageView:nil];
MyImageView *secondTry = [NSClassFromString(#"MyImageView") myImageView:nil];
NSLog(#"%#, %#", firstTry, secondTry);

Objective C setCenter on Image

I am fairly new to iOS development. I have the following code
#property (nonatomic, strong) NSMutableArray *myImages;
-(void) viewDidLoad
{
[super viewDidLoad];
self.myImages = [[NSMutableArray alloc] init];
UIImageView *image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image1"]];
[self.myImages addObject:image];
[image setCenter:CGPointMake(10, 10)];
[self.view addSubview:image];
}
-(void) viewDidAppear:(BOOL)animated
{
for (;;) {
for (int i=0; i<[self.myImages count]; i++) {
[self.myImages[i] setCenter:CGPointMake(300, 300)];
}
}
}
When I do this, the image shows up at point 10,10. However it doesn't get changed to 300,300. Can any one suggest what I am doing wrong.
If I do something like
[self.myImages[0] setCenter:CGPointMake(300, 300)];
before the infinite loop, that works fine. but in the infinite loop no luck.
This code is just a snippet and a lot of the code is missing, but you should be able to understand what I am getting at with this.
Thanks
You forgot to add the imageView to the array. Add
[self.myImages addObject:image];
... in viewDidLoad.
As a side note: It's not common to abbreviate identifiers in Objective-C. Use imageView instead of image. Code becomes much easier to read.
You probably don't want the infinite loop in viewDidAppear, too.
first i'm kinda new to ios too so i am not sure.
i think there are 2 options:
i am not sure if view did appear is the right method to change the image i would suggest view will appear. and if you really want the one you used maybe try dispatch_async in order to change the image on the main ui thread.
Maybe try for in loop? that why you will set itrator as UIimage and it will recognize the image. this is less likly to solve it but maybe...

How to check NSCache instance value set or not

I have an instance of NSCache, like: NSCache *imageCache; It is basically used for holding some remote "image" values with different "#keys". I alloc & init NSCache in a Global class at the beginning and set a if else condition, like this:
if (self.imageCache == nil)
{
self.imageCache = [[NSCache alloc] init];
}
else
{
NSLog(#"cache set");
}
I #import that "Global Class" in all of ViewControllers, so that I don't have to parse images every time. But the problem is when I go to other ViewControllers It seems like, NSCache alloc & init every time. Because It takes same time to load the images as 1stVC. I think the if else condition didn't working perfectly or it's not the appropriate way to check either NSCache set or not.
Can anyone tell me whats wrong with it? One thing more, The imageCache is used from a global variable.
Thanks in advance.
Have a good day.
ADDITION:
This is the method where I load the UIButtons in UIScrollView as subView. This is a UIViewClass which I add in my "EveryViewController" as a subView Just take have a look on the if (cachedImage) line. It works fine. But when I want to check either the NSCache (iADImageCache) set or not, it shows me it's not set. But which should be set. In this situation how can I check all several iADImageCache with their different #"Key" name?
Thanks again.
-(void) loadUIButton
{
[self loadScrollView];
for (int i = 0; i < [iADDisplayArray count]; i++)
{
adButtonOutLet = [[UIButton alloc] initWithFrame:CGRectMake(i*320, 0, ButtonWidth, ButtonHight)];
currentAd = [iADDisplayArray objectAtIndex:i];
NSString *path = currentAd.bannerIconURL;
NSURL *url = [NSURL URLWithString:path];
NSMutableURLRequest *requestWithBodyParams = [NSMutableURLRequest requestWithURL:url];
NSData *imageData = [NSURLConnection sendSynchronousRequest:requestWithBodyParams returningResponse:nil error:nil];
UIImage *originalImage = [UIImage imageWithData:imageData];
UIImage *cachedImage = [self.iADImageCache objectForKey:currentAd.bannerIconURL];
if (cachedImage)
{
[adButtonOutLet setImage:cachedImage forState:UIControlStateNormal];
//NSLog(#"OnecachedImage %#", cachedImage);
}
else
{
[self.iADImageCache setObject:originalImage forKey:currentAd.bannerIconURL];
[adButtonOutLet setImage:originalImage forState:UIControlStateNormal];
NSLog(#"OneimageCache %#", self.iADImageCache);
}
adButtonOutLet.userInteractionEnabled= YES;
[adButtonOutLet setTag:i];
[adButtonOutLet addTarget:self action:#selector(goToURL:) forControlEvents:UIControlEventTouchUpInside];
[self.iADScrollView addSubview:adButtonOutLet];
}
}
You could make a singleton class, instance at application did finish launching and use it wherever you are, through all the view controllers. In the singleton class put a property
#property(nonatomic,strong) NSCache* imageCache;
then instance it just once in the singleton class init method. In this way you don't have to care about it, and you can just add images to that cache. Of course you have to check if the image is cached or not based on the existance of a key inside that cache.
NSCache* globalCache = [SingletonClass sharedInstanceMethod].imageCache;
UIImage *imageX = [globalCache objectForKey: #"keyX"];
if (!imageX) {
// download your image
imageX = <Download method>;
[globalCache setObject: imageX forKey: #"keyX"];
}
// Do your stuff (like showing the image)
....
...
..
.
Hope it helps
Unless actually needed across the whole program, I would suggest another approach that would restrict the caching to the class that actually needs to use it by adding the class method:
+ (NSCache *)staticCacheForClass
{
static NSCache *staticCache;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
staticCache = [NSCache new];
staticCache.name = #"myCache";
});
return staticCache;
}
Using this - you restrict the changes to the cache to be internal to the class that uses it and avoid creating another singleton. The cache is also preserved across creating and destroying instances of this class.
That said, a singleton could be a viable solution if you need to access the cache from different classes, since a cache singleton is not really a global state.
Cheers.

NSInvalidArgumentException exception when adding image to imageView iOS

.H files
#property (strong, nonatomic) LAClaimReport *claimReport;
.M file
#interface LACreateReportViewController ()
{
NSArray *_thumbnails;
LAPhotoThumb *_lastSelectedPhoto;
}
_thumbnails = _claimReport.photos.allObjects;
if (_thumbnails.count >0)
{
_photosCaption.textColor = [UIColor colorWithRed:0/255.0 green:46/255.0 blue:91/255.0 alpha:1];
UIImageView *image = [[UIImageView alloc] initWithFrame:CGRectMake(30, 1838, 300, 600)];
NSLog(#"image:%#" , _thumbnails[0]);
[image setImage:(UIImage *) _thumbnails[0]]; // exception here.
}
NSInvalidArgumentException', reason: '-[LAPhoto size]: unrecognized selector sent to instance 0xa76b720'
Photos is a column in the class file of LAClaimReport. What am i missing in regards to size here? pls guide.
_thumbnails doesn't contain UIImage instances, it contains some other type of object. Enough information isn't included to tell what kind of objects it contains however.
size is a method on UIImage that is used by the image view to determine how to display the image, and whatever object is actually in _thumbnails doesn't implement that method.
Your NSLog(#"image:%#" , _thumbnails[0]); should list the class type that you're trying to use as an image.
make sure that you have UIImage class objects in _thumbnails Array, I Think you have LAPhoto type objects in that array
id arrContent=_thumbnails[0];
if ([arrContent isKindOfClass:[LAPhoto Class]])
{
//read LAPhoto class and find a way to get the UIImage from LAPhoto Object
}
else if ([arrContent isKindOfClass:[UIImage class]])
{
[image setImage:(UIImage *) _thumbnails[0]];
}

UIImageView not displaying images

For some reason I cannot get an image album into my UIImageView. It is added in storyboard and declared:
#property (strong, nonatomic) IBOutlet UIImageView *displayAlbum;
#synthesize displayAlbum, titleLbl, artist;
In my code:
displayAlbum = [[UIImageView alloc] init];
MPMediaPropertyPredicate *predicate = [MPMediaPropertyPredicate predicateWithValue:#"1079287588763212246" forProperty:MPMediaEntityPropertyPersistentID];
MPMediaQuery *query = [[MPMediaQuery alloc] init];
[query addFilterPredicate: predicate];
NSArray *queryResults = [query items];
for (MPMediaItem *song in queryResults) {
MPMediaItemArtwork *artwork = [song valueForProperty: MPMediaItemPropertyArtwork];
[displayAlbum setImage: [artwork imageWithSize:CGSizeMake(displayAlbum.frame.size.width, displayAlbum.frame.size.height)]];
}
I am able to get other song information so its definitely getting the right song, but the ImageView always shows up blank.
On a side note, if anybody could help me clean up the above bit of code, especially get rid of the for loop (it should always only return one result anyways) that would be great. Thanks
It's because you're creating a new image view with alloc init, instead of using the one you created in IB. You should just delete that alloc init line.
Why are you allocating displayAlbum, when it is IBOutlet? If it is already made in NIB, then by allocating new one, it should not work, as you will have completelly new UIImageView which is not part of your view controller. If it is not made in NIB, then you should add it to your view controller by adding subview of some of your views that are part of your view controller and set some frame for it.
At first, try to comment this line:
displayAlbum = [[UIImageView alloc] init];

Resources