I'm using MHVideoPhotoGallery to create gallery's of images that are stored on my website. The current way to add images (as shown in the example on Github) is
MHGalleryItem *photo1 = [MHGalleryItem.alloc initWithURL:#"*ENTER IMAGE URL HERE*"
galleryType:MHGalleryTypeImage];
MHGalleryItem *photo2 = [MHGalleryItem.alloc initWithURL:#"*ENTER IMAGE URL HERE*"
galleryType:MHGalleryTypeImage];
MHGalleryItem *photo3 = [MHGalleryItem.alloc initWithURL:#"*ENTER IMAGE URL HERE*"
galleryType:MHGalleryTypeImage];
self.galleryDataSource = #[#[photo1,photo2,photo3]];
But I want to add hundreds of images and this is not the most ideal way to do it. What would be an easier way for me to accomplish this?
Thanks!
You have to start with a list of the URLs. What I would do is put this in a text file in my bundle. In code, when the app runs, I would open the text file (as an NSString) and split it into an NSArray. Now I've got an NSArray of the URLs. I would then cycle through the NSArray. So now we're inside a loop. For each item the array, I would initialize the MHGalleryItem and then add it to a previously created NSMutableArray with addObject:. Thus we have a two or three-line loop which is repeated, running through all the URLs.
The following is pseudo-code and untested (so it might contain errors), but it should give the general idea of the structure I'm suggesting:
NSMutableArray* temp = [NSMutableArray new];
NSString* s =
[NSString stringWithContentsOfFile:
[[NSBundle mainBundle] pathForResource:#"urls" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:nil];
NSArray* urls = [s componentsSeparatedByString:#"\n"];
for (NSString* url in urls) {
MHGalleryItem *item = [[MHGalleryItem alloc] initWithURL:url
galleryType:MHGalleryTypeImage];
[temp addObject:item];
}
self.galleryDataSource = temp;
Loop. If you're putting numbers at the end of your variable names, you need a loop and/or an array.
NSMutableArray * photos = [NSMutableArray new];
NSArray * photoPaths = [NSArray arrayWithContentsOfFile:plistContainingPhotoPaths];
for( NSString * path in photoPaths ){
NSURL * photoURL = [NSURL URLWithString:path];
MHGalleryItem * photo = [[MHGalleryItem alloc] initWithURL:photoURL
galleryType:MHGalleryTypeImage];
[photos addObject:photo];
}
And don't use dot syntax for alloc, or your code will burst into flames.
Use a naming protocol on your website such as:
www.mywebsite.com/appImageGallery/insertImageNumber
And replace the insertImageNumber with the number of you image. Then add this for loop to get all of the images and add them to the array.
NSMutableArray *mutableGalleryDataSource = [self.galleryDataSource mutableCopy]
for(int i = 0; i < numberOfImagesOnWebsite; i++){ //replace numberOfImagesOnWebsite with the number of images on your website.
MHGalleryItem *newItem = [MHGalleryItem.alloc initWithURL:[#"www.mywebsite.com/appImageGallery/" stringByAppendingString:[NSString stringWithFormat: #"%i", i]] galleryType:MHGalleryTypeImage];
[mutableGalleryDataSource addObject:newItem];
}
self.galleryDataSource = mutableGalleryDataSource;
There is also an -addObjectsFromArray method on NSMutableArray.
Related
I've created NSManagedObject* imagesArrayData that stores strings (paths) to images stored in the documents directory:
- (void)setImagesArray:(NSMutableArray *)imagesArray {
NSMutableArray* newImagesArray = [NSMutableArray new];
int i = 1;
for (UIImage* image in imagesArray) {
//generate path to createdFile
NSString* fileName = [NSString stringWithFormat:#"%#_%d", self.name, i];
NSString* filePath = [self documentsPathForFileName:fileName];
//save image to disk
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:filePath atomically:YES];
//add image path to CoreData
[newImagesArray addObject:filePath];
i++;
}
//set new value of imagesArray
imagesArrayData = [NSKeyedArchiver archivedDataWithRootObject:newImagesArray];
I am now not showing pathsToImages in header file, but property imagesArray:
-(NSMutableArray*) imagesArray {
NSMutableArray* images = [NSMutableArray new];
NSArray* imagePaths = [NSKeyedUnarchiver unarchiveObjectWithData:imagesArrayData];
for (NSString* imagePath in imagePaths) {
UIImage *image = [[UIImage alloc] initWithContentsOfFile: imagePath];
[images addObject:image];
}
return images;
The problem is, that whenever I want to get to [imagesArray objectatIndex:xxx], the imagesArray getter is called, and it takes time to recreate the full array. When trying to switch fast between images, the UI slows down.
What would be the elegant way to overcome this problem? Maybe creating another array full of images and updating it from time to time? Maybe something else? Please, help.
One thing you could do is refactor your getter to lazily load the array. If it is already defined, simply return it. If not, build it:
-(NSMutableArray*) imagesArray
{
if (!_imagesArray)
{
NSMutableArray* _imagesArray = [NSMutableArray new];
NSArray* imagePaths =
[NSKeyedUnarchiver unarchiveObjectWithData: imagesArrayData];
for (NSString* imagePath in imagePaths)
{
UIImage *image = [[UIImage alloc] initWithContentsOfFile: imagePath];
[_imagesArray addObject:image];
}
return _imagesArray;
}
I'm not sure what you mean about updating an array of images from time to time.
If your array of image names changes you will need some method to respond to those changes.
I need to pull out the excel file to interface that user can only read the information in file.
what is the solution to implement it?
The most easy way to solve this is first, convert the Excel file to CSV format, which stands for Comma Seperated Value. Meaning it's formatted like: cell 1,cell 2,cell 3. And a new line for each row.
The second is to read the file into a String which can be done in two ways, depending if you have it local or not. Let's say you have it on a server.
NSURL *url = [NSURL urlWithString:#"http://urltoyour.excel/file.csv"];
NSData *data = [NSData dataWithContentOfURL:url];
NSString *string = [NSString stringWithData:data];
Then you can easily convert this to arrays using
NSArray *lines = [string componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
Now you have each excel line in that array. Now for each line you probably want the columns in an array too, you can do that using:
NSMutableArray *finalArray = [NSMutableArray new];
for (NSString *line in lines) {
NSArray *array = [line componentsSeperatedByString:#","];
[finalArray addObject:array];
}
Good luck and let me know if that works out for you!
Trying to read a plist and change my font color depending on the option that was selected in the following settings bundle.
The following is how I am trying to accomplish it:
NSString *path = #"/var/mobile/Library/Preferences/NCNotes.plist";
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
fontSize = [[dict objectForKey:#"slideSwitched"] floatValue];
if ([[dict objectForKey:#"noteColor"] valueForKey:#"Purple"]) {
noteView.textColor = [UIColor purpleColor];
} else {
noteView.textColor = [UIColor blackColor];
}
Any ideas why this is why my app is crashing? How do I read the values and change the color depending on what was selected?
It appears that the top level of your plist is an array, not a dictionary, because at the top it says "Item 1" where all of your content is within that. So you have a dictionary within an array. So you can change your code like this:
NSString *path = #"/var/mobile/Library/Preferences/NCNotes.plist";
NSArray *array = [[NSArray alloc] initWithContentsOfFile:path];
NSDictionary *dict = array[0];
You could also change the structure of your plist so that you have a dictionary as the root instead of an array.
Also, keys are supposed to be on the left-hand side and their values on the right-hand side, so I don't see a key "noteColor". You have a key "key" with a value "noteColor", so you'll need to make that correction. I'm also not seeing a "slideSwitched" key, though it might just be outside the bounds of your screenshot.
Also the following won't work:
[[dict objectForKey:#"noteColor"] valueForKey:#"Purple"]
Whatever you get from [dict objectForKey:#"noteColor"] isn't going to be a dictionary, so calling valueForKey: on that isn't going to give you what you want.
simply you should do this with document directory
NSString *contentPath=[[NSBundle mainBundle] pathForResource:#"PLIST_FILE_NAME" ofType:#"plist"];
NSDictionary *dictionary=[NSDictionary dictionaryWithContentsOfFile:contentPath];
write your logic after this, wait a minute , its seems like you dont have a key "noteColor" also. check your plist
Here is some example code documented up the wazoo. Hopefully it will help you understand how these plists and dictionaries work. Everything will be based on your plist file (which could definitely be improved upon, but that's up to you as I don't know your specific situation).
Your question is "How do I find color based on user selection?" I will assume you get the user selection as an int. Something like "User selected 7".
//Load your plist dictionary
NSString *path = #"/var/mobile/Library/Preferences/NCNotes.plist";
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
//Get the array of validValues and the array of validTitles
NSArray *valuesArray = [dict objectForKey:#"validValues"];
NSArray *titlesArray = [dict objectForKey:#"validTitles"];
//Now get the user selected index from the validValues array
int arraySelection = -1;
for(int i = 0; i < [valuesArray count]; i++)
{
NSNumber *number = [valuesArray objectAtIndex:i];
if([number intValue] == userSelectedInput)
{
arraySelection = i;
break;
}
}
if(arraySelection == -1)
{
//Not found in array
return;
}
//Now with that index get the title of the object that the user selected
NSString *userSelectedTitle = [titlesArray objectAtIndex:arraySelection];
//Now do your checking on what the user selected based on that:
if([userSelectedTitle isEqualToString:#"Purple"])
...
You could boil this down quite a bit. Currently your validValues array is completely useless. If it were out of order or missing numbers then it would be needed, but straight counting can be achieved by the validTitles array.
I was wondering if anyone could lend some assistance. Basically I am calling a web service and then trying to get the large hosted image url. The output from the web service is so:
images = (
{
hostedLargeUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.l.jpg";
hostedSmallUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.s.jpg";
}
);
The main problem is that the two strings are in only one of my array elements when I think they should be in 2. Also I'm not 100% but possibly they may be a dictionary :-S I'm just not sure. My code is as follows:
NSArray *imageArray = [[NSArray alloc]init];
imageArray = [self.detailedSearchYummlyRecipeResults objectForKey:#"images"];
NSLog(#"imageArray: %#", imageArray);
NSLog(#"count imageArray: %lu", (unsigned long)[imageArray count]);
NSString *hostedLargeurlString = [imageArray objectAtIndex:0];
NSLog(#"imageArrayString: %#", hostedLargeurlString);
The output (nslog's) from the above code is:
2013-04-28 18:59:52.265 CustomTableView[2635:11303] imageArray: (
{
hostedLargeUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.l.jpg";
hostedSmallUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.s.jpg";
}
)
2013-04-28 18:59:52.266 CustomTableView[2635:11303] count imageArray: 1
2013-04-28 18:59:52.266 CustomTableView[2635:11303] imageArrayString: {
hostedLargeUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.l.jpg";
hostedSmallUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.s.jpg";
}
Does anyone have any idea how I can seperate the one element into hostedlargeUrl and hostedsmallUrl respectively?
Any help you can provide is greatly appreciated!
Actually the images array contains a dictionary
images = (
{
hostedLargeUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.l.jpg";
hostedSmallUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.s.jpg";
}
);
so :
NSDictionary *d = [self.detailedSearchYummlyRecipeResults objectForKey:#"images"][0];
NSString *largeURL = d[#"hostedLargeUrl"];
NSString *smallURL = d[#"hostedSmallUrl"];
The value of [imageArray objectAtIndex:0] is a NSDictionary. You've incorrectly specified it as a NSString. You need the following:
NSDictionary *hostedLarguerDictionary =
(NSDictionary *) [imageArray objectAtIndex:0];
and then to access the 'large url' use:
hostedLarguerDictionary[#"hostedLargeUrl"]
or, equivalently
[hostedLarguerDictionary objectForKey: #"hostedLargeUrl"];
looks like an array with in an array so
NSArray* links = [self.detailedSearchYummlyRecipeResults objectForKey:#"images"];
NSString* bigLink = [links objectAtIndex:0];
NSString* smallLink = [links objectAtIndex:1];
or it could be a dictionary
NSDictionary* links = [self.detailedSearchYummlyRecipeResults objectForKey:#"images"];
NSString* bigLink = [links objectForKey:#"hostedLargeUrl "];
NSString* smallLink = [links objectForKey:#"hostedSmallUrl "];
you can see the class of the object by printing out the class name
NSLog(#"Class Type: %#", [[self.detailedSearchYummlyRecipeResults objectForKey:#"images"] class]);
I want to add NSString Name in NSmutableArray but I dont know about that.
I get 5 NSString name from url in wamp server and I want add these names in NSMutableArray.
this is my code but do not work!!! :
NSMutableArray *file;
for (int j=0; j < 5; j++) {
NSString *fileName = [[NSString alloc]initWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://192.168.1.101/janatan/filemanager.php?dir=root&file=%d&name",j]]];
NSLog(#"%#",fileName);
[file addObject:fileName] //right???
}
You are not allocating NSMutableArray
NSMutableArray *file = [[NSMutableArray alloc] initWithCapacity:5];
If you are not sure about the number of elements gets added to array beforehand, you can use
NSMutableArray *file = [[NSMutableArray alloc] init];
Firstly, the NSMutableArray must be allocated.
Secondly, the using of magic numbers must be avoided.
Next, the readability of code should be improved by replace
NSString *fileName = [[NSString alloc]initWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://192.168.1.101/janatan/filemanager.php?dir=root&file=%d&name",j]]];
to something more convenient. Moreover, the memory here is allocated but never released.
Your code may be as follows:
const int numberOfFiles = 5;
NSMutableArray *file = [NSMutableArray array]
for(int i = 0; i < numberOfFiles; ++i){
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://192.168.1.101/janatan/filemanager.php?dir=root&file=%d&name", i]];
NSString *fileName = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
[file addObject:fileName];
}
But here are we can find some problems.
For example if url is changed on server-side you'd rewrite the code. If the number of elements is changed it's the same. So it would be good to find a way to avoid this kind of dependence.