I have opened gallery on a BUTTON click and choose an image.I save image full path
in a string.Now How can i save that string in button.I have to save string into a button so that button can hold the path.I have so many buttons like same in my view.and have to perform the same.The code I have used for saving Image path is written below.
// Get the image from the result
UIImage* image = [info valueForKey:#"UIImagePickerControllerOriginalImage"];
// Get the data for the image as a PNG
NSData* imageData = UIImagePNGRepresentation(image);
// Give a name to the file
NSString * imageName = #"Myimage.png";
// Now, we have to find the documents directory so we can save it
// Note that you might want to save it elsewhere, like the cache directory,
// or something similar.
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
// Now we get the full path to the file
NSString* fullPathToFile = [documentsDirectory stringByAppendingPathComponent:imageName];
// and then we write it out
[imageData writeToFile:fullPathToFile atomically:NO];
Button = fullPathToFile; ///This is the button
return;
Here the solution to add property to an object like UIButton etc.
UIButton+String.h
#import <Foundation/Foundation.h>
#interface UIButton (String)
#property (nonatomic, retain) NSString *path;
#end
UIButton+String.m
#import "UIButton+String.h"
#import <objc/runtime.h>
#implementation UIButton (String)
static char UIB_PROPERTY_KEY;
#dynamic path;
-(void)setPath:(NSDictionary *)attributes {
objc_setAssociatedObject(self, &UIB_PROPERTY_KEY, path, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSString *)path {
return (NSString*)objc_getAssociatedObject(self, &UIB_PROPERTY_KEY);
}
#end
Create a model class, that is a class that has the necessary methods and properties to persist the data, add, delete and obtain the data. The model class can be a singleton to allow app wide access if necessary.
Views should just be used to display or to obtain user input.
Related
I have an app,that contains UIImageView. it's working on iOS 8 but not showing image on iOS 7. I searched it, they always said that "it's auto layout problem." ok i removed all constraints on my view. but still not showing images.
NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:sf._foto];
[Img setImage:[UIImage imageNamed:savedImagePath]];
Img.frame = CGRectMake(0,0,screenWidth,screenHeight);
Don't know if this will help but this is how I saved and then accessed an image through the documents directory
- (void)savePaystubToFile: (UIImage *)image {
if (image != nil)
{
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentsDirectory = [paths objectAtIndex:0];
NSString * path = [documentsDirectory stringByAppendingPathComponent: #"example.png" ];
NSData * data = UIImagePNGRepresentation(image);
[data writeToFile:path atomically:YES];
}
}
- (UIImage*)loadPaystub {
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentsDirectory = [paths objectAtIndex:0];
NSString * path = [documentsDirectory stringByAppendingPathComponent: #"example.png" ];
// If nothing is stored at that location then return nil
UIImage * image = [UIImage imageWithContentsOfFile:path] ? [UIImage imageWithContentsOfFile:path] : nil;
return image;
}
The main difference here seems to be me using the imageWithContentsOfFile function and the basic set up of the process step by step.
I don't know whether this is the issues which you are struggling with but this is a better way of separating the storage and retrieval of your image. If this is working correctly then you know that the problem will be in accessing the frame.
If you are finding it is an autolayout issue, then you will need to remove the view from your xib and add it programmatically. I've had similar issues and just creating it programmatically, even if that means creating another xib with your view and loading it and adding it to your view's addSubview:. Every view that I want to modify later, but don't want to deal with modifying constraints, I add programmatically.
Alternatively, you could add your constraints and then put outlets to them in your code to modify when you want to change things.
Hopefully this helps.
I know this question has been asked a hundred times here because I have been reading most of the questions about reading and writing to plists in this forum, in fact this is the main reason why I'm posting this question. I'm tired of trying outdated tutorials about this topic. I have tried a few tutorials but most of them are using .xib files or are not using ARC and I usually end up with a bunch of errors.
Does anyone know about a tutorial about reading/writing to a plist that uses storyboards and ARC? In other words an updated tutorial.
All I need is a tutorial that I can reference to have a better understanding on how to persist data using plists.
Thanks a lot
Here is a very simple piece of code that shows how to read and write to a plist. Code is based on this tutorial.
What I have here is basically two labels and two buttons on screen, one button to write the data and the other one is to read the data when clicked, the two labels are to show the first two items from an array (plist), item 0 will be shown in the first label and item 1 will be shown in the the second label.
.m file
-(NSString *)getFilePath
{
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return [[pathArray objectAtIndex:0] stringByAppendingPathComponent:#"fruitList.plist"];
}
-(void)saveData
{
NSArray *value = [[NSArray alloc] initWithObjects: #"Orange", #"Apple", nil];
[value writeToFile:[self getFilePath] atomically:YES];
}
-(void)loadData
{
NSString *myPath = [self getFilePath];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:myPath];
if(fileExists)
{
NSArray *values = [[NSArray alloc]initWithContentsOfFile:myPath];
self.labelOne.text = [values objectAtIndex:0];
self.labelTwo.text = [values objectAtIndex:1];
}
}
- (IBAction)writeData:(id)sender
{
[self saveData];
}
- (IBAction)readData:(id)sender
{
[self loadData];
}
.h file
#property (weak, nonatomic) IBOutlet UILabel *labelOne;
#property (weak, nonatomic) IBOutlet UILabel *labelTwo;
-(NSString*) getFilePath;
-(void) saveData;
-(void) loadData;
- (IBAction)writeData:(id)sender;
- (IBAction)readData:(id)sender;
I've already made an app that compares the user's location to an array of locations with format...
NSArray *myStationArray;
myStationArray = #[
#{
kStation : #"27200",
kLatitude : #( 41.656467),
kLongitude : #(-81.277963)
},
#{
kStation : #"27650",
kLatitude : #(41.657118),
kLongitude : #(-81.276545)
},
...
Now I want the user to be able to create this array dynamically where they can select an IBAction button that will add their current location (lat long) to a mutable array with the format shown. The kStation value will be inputted by the user. I know conceptual questions are frowned upon so I'll offer these specific questions based on this idea.
1.) Where should I create the mutable array (viewDidLoad, IBAction, didUpdateToLocation, ect.)? It will need to be saved to the app so the user can add and delete from it throughout its life.
2.) What will my IBAction code look like to save the current location and kStation input to create an array to match the example above?
3.) Is this something where you'd want to use a database such as sqlite? I'd prefer to avoid using a database if possible but would like to know the best method of doing this.
Thank you for your time in advance.
You would probably define this NSMutableArray for your list as a class property:
#property (nonatomic, strong) NSMutableArray *stations;
While you're at it, you could define a NSString property for your filename:
#property (nonatomic, strong) NSString *filename;
You could load the previous values or initialize it in viewDidLoad, where kFilename is set to #"stations.plist" or something like that:
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
self.filename = [docsPath stringByAppendingPathComponent:kFilename];
if ([[NSFileManager defaultManager] fileExistsAtPath:self.filename])
self.stations = [NSMutableArray arrayWithContentsOfFile:self.filename];
else
self.stations = [NSMutableArray array];
You could add new values in your IBAction (if you want them to be added when the user clicks on the button) or in didUpdateToLocation (if you want it to be added automatically as the user moves). For example, if you did it in IBAction:
- (IBAction)didTouchUpInsideAddButton:(id)sender
{
NSDictionary *newItem = #{
kStation : ..., // grab your station identifier however you want to do that
kLatitude : #(self.locationManager.location.coordinate.latitude),
kLongitude : #(self.locationManager.location.coordinate.longitude)
};
[self.stations addObject:newItem];
[self.stations writeToFile:self.filename atomically:YES];
}
If your list of stations is likely to get large, then you might want to consider using Core Data or SQLite, but if this list is likely to be reasonably short (i.e. something that you don't mind loading the whole thing into memory at the same time), the above technique of using plists via arrayWithContentsOfFile and writeToFile is probably sufficient.
To answer your questions in order:
1) You would probably want to create and initialize your NSMutableArray in viewDidLoad.
2) You could either create your own class, something similar like MKAnnotation format or create a dictionary and then stick that into an array like so:
-(IBAction)myButtonAction:(id)sender {
NSDictionary *myDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:#"Station", #"27200", #"Latitude", #"41.656467", #"Longitude", #"-81.277963", nil];
[myArray addObject:myDictionary];
}
3) You can load your MutableArray file like this:
NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES);
NSMutableString *documentDirectory = [documentDirectories objectAtIndex:0];
NSString *myPath = [documentDirectory stringByAppendingPathComponent:#"UserData"];
NSMutableArray *myArray = [[NSMutableArray alloc] initWithContentsOfFile:myPath];
You can save your MutableArray file like this:
NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSMutableString *documentDirectory = [documentDirectories objectAtIndex:0];
NSString *filePath = [documentDirectory stringByAppendingPathComponent:#"UserData"];
BOOL fileError = [myArray writeToFile:filePath atomically:YES];
In my app I am downloading images from url and saving into application documents directory. Now I want to show these downloaded images as image gallery. For image gallery I am using fGallery, I am able to configure it and successfully pushed it on navigation controller and fGallery view is also visible but its not showing my images, I provide fGalley with images array like this
Header File
#interface myController <FGalleryViewControllerDelegate>
#property (strong, nonatomic) FGalleryViewController *localGallery;
#property (strong, nonatomic) NSMutableArray *localImages;
Class File
//These are delegate methods of FGalleryViewControllerDelegate
- (NSString*)photoGallery:(FGalleryViewController*)gallery filePathForPhotoSize:(FGalleryPhotoSize)size atIndex:(NSUInteger)index
{
return [localImages objectAtIndex:index];
}
- (NSString*)photoGallery:(FGalleryViewController *)gallery urlForPhotoSize:(FGalleryPhotoSize)size atIndex:(NSUInteger)index
{
return [localImages objectAtIndex:index];
}
- (int)numberOfPhotosForPhotoGallery:(FGalleryViewController *)gallery
{
int num;
num = [localImages count];
return num;
}
- (FGalleryPhotoSourceType)photoGallery:(FGalleryViewController *)gallery sourceTypeForPhotoAtIndex:(NSUInteger)index
{
return FGalleryPhotoSourceTypeLocal;
}
//Delegate method ends here
// My method to show gallery with my images
-(void)ShowGallery
{
localImages = [[NSMutableArray alloc]init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *dataPath = [documentsDir stringByAppendingPathComponent:chatWithUser;
NSString *msgsColumn;
//database query to fetch all images name and then
while([results next])
{
msgsColumn = [results stringForColumn:#"msgs"];
if([[[msgsColumn componentsSeparatedByString:#"."]objectAtIndex:1]isEqualToString:#"jpg"])
{
[localImages addObject:[dataPath stringByAppendingPathComponent:msgsColumn]];
}
}
[database close];
localGallery = [[FGalleryViewController alloc]initWithPhotoSource:self];
[self.navigationController pushViewController:localGallery animated:YES];
}
For images path i used stringByAppendingPathComponent but I also tried stringByAppendingString to guide that images resides in documents directory but nothing is working.
Please assist me to figure out what is going wrong.
I found the solution, and here it is
https://github.com/gdavis/FGallery-iPhone/issues/15
I wrote a simple program to help me debug.
#import "UIImage+saveScreenShotOnDisk.h"
#implementation UIImage (saveScreenShotOnDisk)
-(void)saveScreenshot{
NSData * data = UIImagePNGRepresentation(self);
[data writeToFile:#"foo.png" atomically:YES];
}
#end
After it's executed, I want to know where foo.png is located.
I went to
~Library/Application Support
and I can't find foo.png. Where is it?
If I do
BOOL result = [data writeToFile:#"foo.png" atomically:YES];
the result will be NO, which is kind of strange given that the simulator, unlike the iPhone, can write anywhere.
You need to direct the NSData object to the Path you want the data to be saved in:
NSString *docsDir;
NSArray *dirPaths;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
NSString *databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent:#"foo.png"]];
[data writeToFile:databasePath atomically:YES];
This will save your file in your App's Folder on the device (or the simulator).
The default place, where the files are stored, is the folder your executable is stored.
See where your executable is stored via right clicking Products->YourExecutable :
Then open in finder.
Here pawel.plist resource create via
NSArray *a = #[#"mybike", #"klapki", #"clapki", #"ah"];
[a writeToFile:#"pawel.plist" atomically:NO];
For Swift, based on Shachar's answer:
let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] + "/foo.png"
data?.writeToFile(path, atomically: true)
U forgot to provide location or path where u want to write.Check this writeToFile:options:error:
Writes the bytes in the receiver to the file specified by a given path.
- (BOOL)writeToFile:(NSString *)path options:(NSDataWritingOptions)mask error:(NSError **)errorPtr
Parameters
path
The location to which to write the receiver's bytes.
mask
A mask that specifies options for writing the data. Constant components are described in “NSDataWritingOptions”.
errorPtr
If there is an error writing out the data, upon return contains an NSError object that describes the problem.
You can give a search for "NSDocumentsDirectory", I usually search the path for the documents directory using this method, and then append my file name to it. in the method writeToFile:, this appended path is provided. Then using iTunes>application, scroll to bottom, select your app, and you should be able to see the saved file.
PS: you should have set a valur in plist that specifies that you application uses the phone storage.