I have a UIImageView that diaplays an image. Then I have a button titled 'save' . What I want to do is that when I click the button, it should save the image file name into a plist for further retrieval and stuff.
I know how to save into plist and all. The problem is only that I don't know how to get the file path of the image being displayed in the UIImageView.
I did homework and found few articles but im still confused. Any help will be appreciated.
I dont think it is possible to get the image path from a UIImage, if by path you mean the original location on disk, then i dont think that you can do it
The best way to do this is to Save the image in document folder with name image1, image2, etc or the exact name of the image if you know it. And you can save the image names in the plist. Using the names here you can do the further stuff easily.
Create UIImageview as CustomImageview class with NSString variable.Then while showing that image,store the image file path in that string variable.Then you can get it where ever you want with the use of that string.Use the following code
#import <UIKit/UIKit.h>
#interface Imager : UIImageView
{
NSString* imageFileName; #property(nonatomic,retain)NSString* imageFileName;
}
#end
#import "Imager.h"
#implementation
#synthesize imageFileName
and the assign the filepathname where you are assigning the image like your
Imageview.image = UIImage;
your Imageview.imageFileName=yourImageFilepath;
to get the yourImageFilepath add "AssetsLibrary.framework" to your framework folder.Then add #import "AssetsLibrary/AssetsLibrary.h"; to the header file of your class.
then add the following code in "didFinishPickingMediaWithInfo" method
UIImage *viewImage = yourImage;
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:[viewImage CGImage] orientation: (ALAssetOrientation)[viewImage imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error)
{
if (error)
{
NSLog(#"error");
}
else
{
NSLog(#"url %#", assetURL);
}
}];
[library release];
It will return a url.that is your yourImageFilepath.
Related
I'm trying to change a UIImage in a xib file but it wouldn't change until I comment on this code. I changed image name in this code to but it's not helped me.
#property (strong, nonatomic) IBOutlet UIImageView *imgHeaderImage;
if([Util getStringData:kAppNameWhiteImage] !=nil){
[self.imgHeaderImage sd_setImageWithURL:[Util EncodedURL:[Util getStringData:kAppNameImage]] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
if (image == nil)
{
self.imgHeaderImage.image = [UIImage imageNamed:#"Logo Original"];
}
else
{
self.imgHeaderImage.image = image;
}
}];
} else {
self.imgHeaderImage.image = [UIImage imageNamed:#"Logo Original"];
}
I'm not familiar with Objective-C that why cannot solve this problem. please help me out with this.
Thanks in advance.
It looks like you need to track down the constant: kAppNameWhiteImage and change it’s value. Do a search in the project. In the code you shared “Logo Original” is only loaded if it cant get a valid image from kAppNameWhiteImage.
Since the context of the whole issue is not particularly sufficient, I can only speculate roughly.
Please forgive me if my answer is not accurate.
Since the code is executed only after the Xib file has been loaded, the code you presented is executed.
So no matter how you modify the Image in Xib, but the Code remains the same, the result will always be obtained after the Code is executed. The Logo of the Original. Because Code is executed after the Xib file is loaded.
My app delegate has this method:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSImage *image = [[NSImage alloc]initWithContentsOfFile:#"/Users/mark/Documents/rocket.png"];
if (image == nil) {
NSLog(#"image nil");
}
}
The problem is the image is always nil. I've also tried with a .jpg file. Is there some way to find out exactly why the method is returning nil? eg. passing in an error object?
You might want to use the method dataWithContentsOfFile:options:error: of NSData where you can specify an error object. In case of success you can then create the image with initWithData: of NSImage. Otherwise you have error information for your message.
Apple demoed this code in their WWDC 2014 Session 608 video on best practices for SpriteKit.
AppDelegate.m
+ (instancetype)unarchiveFromFile:(NSString *)file {
/* Retrieve scene file path from the application bundle */
NSString *nodePath = [[NSBundle mainBundle] pathForResource:file ofType:#"sks"];
/* Unarchive the file to an SKScene object */
NSData *data = [NSData dataWithContentsOfFile:nodePath
options:NSDataReadingMappedIfSafe
error:nil];
NSKeyedUnarchiver *arch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
[arch setClass:self forClassName:#"SKScene"];
SKScene *scene = [arch decodeObjectForKey:NSKeyedArchiveRootObjectKey];
[arch finishDecoding];
return scene;
}
I understand the gist of what it's doing, but what I'm confused about is how to utilize this code in for any other .sks file. I tried calling the unarchiveFromFile method from my GameScene.m class, but to no avail. I read the post here on this topic, but it did not clarify things.
EDIT
As per what was suggested by Okapi, I tried the following in a new OS X SceneKit project in the GameScene.m class:
#import "GameScene.h"
#implementation GameScene
-(void)didMoveToView:(SKView *)view {
SKNode *nodeInScene2 = [self childNodeWithName:#"object1"];
for (SKNode *blah in [SKScene unarchiveFromFile:#"Scene2"].children) {
[nodeInScene2 addChild:blah];
}
}
-(void)update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */
}
#end
I have 2 .sks files. The first is called GameScene.sks and that has a sprite in there called "object1". I would like to add children stored in "Scene2.sks". The loop in the didMoveToView method gives me an error. What am I doing wrong? This is what Apple did in their WWDC 608 video, but perhaps I'm missing something since I can't find their project online.
+unarchiveFromFile: is defined as a category on SKScene in GameViewController.m. You would need to copy that code if you want to use it somewhere else.
#implementation SKScene (Unarchive)
+ (instancetype)unarchiveFromFile:(NSString *)file {
/* Retrieve scene file path from the application bundle */
NSString *nodePath = [[NSBundle mainBundle] pathForResource:file ofType:#"sks"];
/* Unarchive the file to an SKScene object */
NSData *data = [NSData dataWithContentsOfFile:nodePath
options:NSDataReadingMappedIfSafe
error:nil];
NSKeyedUnarchiver *arch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
[arch setClass:self forClassName:#"SKScene"];
SKScene *scene = [arch decodeObjectForKey:NSKeyedArchiveRootObjectKey];
[arch finishDecoding];
return scene;
}
#end
This one hung me up for a while too. I ended up declaring unarchiveFromFile in every subclass that needed it, then calling it when I wanted to transition scenes. Something like this...
if (contactQuery == (playerCategory | proceedCategory)) {
SKScene *levelTwo = [LevelTwo unarchiveFromFile:#"LevelTwo"];
[self.view presentScene:levelTwo transition:[SKTransition doorsCloseHorizontalWithDuration:0.5]];
}
Full sample code can be downloaded here.
I'm trying to add a QLPreviewController's view as a subview (no--I cannot use a nav controller or modal). It only shows the fabric background of the QLPreviewController.
I create one and add it as a subview:
QLPreviewController* preview = [[[QLPreviewController alloc] init] autorelease];
preview.dataSource = self;
preview.delegate = self;
preview.view.frame = CGRectMake(0, 0, self.pdfPreviewView.frame.size.width, self.pdfPreviewView.frame.size.height);
self.pdfPreviewView.previewController = preview;
[self.pdfPreviewView addSubview:preview.view];
[preview reloadData];
My QLPreviewControllerDataSource methods work fine (viewing 1 pdf at a time):
- (id <QLPreviewItem>) previewController: (QLPreviewController *) controller previewItemAtIndex: (NSInteger) index
{
NSString *path = [[ResourceManager defaultManager] pathForPDF:self.currentPDF];
NSURL *url = [NSURL fileURLWithPath:path];
if ([QLPreviewController canPreviewItem:url]) {
return url; // This always returns
}
return nil; // This line is never executed
}
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller
{
return 1;
}
The data source method always returns the file url, and QLPreviewController says it can open the file, but it never actually does. I just get the background. The self.currentPDF is set before I create the QLPreviewController and does contain the correct information (from CoreData).
The delegate methods never get called. But I'm also not using it in a standard way, so that's not totally unexpected.
I've also tried calling [preview setNeedsLayout], [preview setNeedsDisplay'], and [preview refreshCurrentPreviewItem] but those just call the data source methods and don't change anything.
The PDFs are valid. I can open them in both Xcode and Preview, so that's not the problem. I'm kind of stumped as to why this won't work. Any help would be appreciated in getting this to work.
Turns out I was sending QLPreviewController the wrong path. It wasn't finding the PDF in the bundle correctly. I needed to use pathForResource:ofType:inDirectory.
First off, InAppSettingsKit is just what I was looking for. Once I figure out some things it will save me tons of time.
My question is: how do I create my own store by subclassing IASKAbstractSettingsStore? The home of IASK states:
The default behaviour of IASK is to store the settings in [NSUserDefaults standardUserDefaults]. However, it is possible to change this behaviour by setting the settingsStore property on an IASKAppSettingsViewController.
and
The easiest way to create your own store is to create a subclass of IASKAbstractSettingsStore.
I've spent a good deal of time combing through the code, and I think I understand the basic structure of it. However, I can't figure out how and what to set the settingsStore property to.
I can see the settingsStore defined and implemented in IASKAppSettingsViewController:
id<IASKSettingsStore> _settingsStore;
and
- (id<IASKSettingsStore>)settingsStore {
if (!_settingsStore) {
_settingsStore = [[IASKSettingsStoreUserDefaults alloc] init];
}
return _settingsStore;
}
I tried subclassing IASKAbstractSettingsStore:
#import <Foundation/Foundation.h>
#import "IASKSettingsStore.h"
#interface IASKSettingsStoreMeals : IASKAbstractSettingsStore {
NSString * _filePath;
NSMutableDictionary * _dict;
}
- (id)initWithPath:(NSString*)path;
#end
and then modified IASKAppSettingsViewController's settingsStore property to allocate and initialize my new class IASKSettingsStoreMeals instead of IASKSettingsStoreUserDefaults - the only way I can see to change the property:
- (id<IASKSettingsStore>)settingsStore {
if (!_settingsStore) {
_settingsStore = [[IASKSettingsStoreMeals alloc] init];
}
return _settingsStore;
}
When I build and run, I get the following message when I try the first control (the toggle switch), all other fields do not get saved:
attempt to insert nil value at objects[0] (key: toggleSwitch)
What am I doing wrong? In addition to the changes needed to "rejigger" the code to use IASKSettingsStoreFile (or a subclassed IASKAbstractSettingsStore), I also can't see where to set the file path change the location of where the settings are saved - or is that done behind the scenes. Looking forward to get past this learning curve and using this.
Found the answer.
My question reveals my inexperience with object orientated languages on the whole, and the concept of encapsulation and frameworks in particular. No changes needed to be made to the IASK framework code, all code was added on my root view controller.
I created another instance of IASKAppSettingsViewController, and added the following code to change the plist location:
// the path to write file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *settingsFile = [documentsDirectory stringByAppendingPathComponent:#"mySettings"];
IASKSettingsStoreFile *mySettingsBundle = [[IASKSettingsStoreFile alloc] initWithPath:settingsFile];
self.appSettingsViewController.settingsStore = mySettingsBundle;
UINavigationController *aNavController = [[UINavigationController alloc] initWithRootViewController:self.appSettingsViewController];
[mySettingsBundle release];
self.appSettingsViewController.settingsStore = mySettingsBundle;
//[viewController setShowCreditsFooter:NO]; // Uncomment to not display InAppSettingsKit credits for creators.
// But we encourage you not to uncomment. Thank you!
self.appSettingsViewController.showDoneButton = YES;
[self presentModalViewController:aNavController animated:YES];
[aNavController release];