Play sounds with displayed images one by one - objective-c

I have ten image files and sound files, and when I display "a.png" I want to play "a.mp3". Then when I click a "Next" button, display "b.png" and play "b.mp3". How can I solve this?

-(void) viewDidLoad;{
sounds = [[NSArray alloc]initWithObjects:#"a.mp3", #"b.mp3",#"c.mp3", nil];
imageArray = [[NSArray arrayWithObjects:
[UIImage imageNamed:#"a.jpg"],
[UIImage imageNamed:#"b.jpg"],
[UIImage imageNamed:#"c.jpg"],
nil] retain];
[super viewDidLoad];}
-(IBAction) next; {
currentSound++;
if (currentSound >= sounds.count) currentSound = 0;
//what kind of code play this sound////images work perpectly but sound not//
currentImage++;
if (currentImage >= imageArray.count) currentImage = 0;
UIImage *img = [imageArray objectAtIndex:currentImage];
[imageView setImage:img];}

To play the sound, use this
type this in your .h file:
AVAudioPlayer *theaudio;
and this goes in your .m, when you want to play the music
NSString *path = [[NSBundle mainBundle] pathForResource:#"nameofmusicfile" ofType:#"mp3"];
theaudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[path release];
[theaudio play];
to stop it, use [theaudio stop];
to display the image use UIImageView *i;
i = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image.png"]];
to put it on - [view addSubview: i];
to move it i.center = CGPointMake(0.0,0.0);

Related

Unable to load an image into NSImageView

I wrote the following and no image comes up. I displayed the pointer and it comes out as "0".
In the next code block I checked the path and made shore the image was present there. Still nothing loads.
NSImageView *vi = [[NSImageView alloc] initWithFrame:CGRectMake(10, 10, 220, 220)];
[self.view addSubview:vi];
NSImage *dog = [NSImage imageNamed:#"airnow3.jpg"];
NSLog(#"pointer %d", dog);
[vi setImage:dog];
NSFileManager *filemgr;
NSString *currentpath;
filemgr = [[NSFileManager alloc] init];
currentpath = [filemgr currentDirectoryPath];
NSLog(#"%#", currentpath);
Why don't you use InitWithImage:(NSImage) instead of InitWithFrame
Maybe you should use UIImageView.
UIImageView *imageView = [[UIImageView alloc] initWithFrame: CGRectMake(10,10,220,220)];
UIImage *image = [UIImage imageNamed:#"airnow3.jpg"];
[imageView setImage: image];
[self.view addSubview: imageView];

UIImage Animation delay Array

i found this code which is very helpful to avoid delay at first animation:
NSMutableArray *menuanimationImages = [[NSMutableArray alloc] init];
for (int aniCount = 1; aniCount < 21; aniCount++) {
NSString *fileLocation = [[NSBundle mainBundle] pathForResource: [NSString stringWithFormat: #"bg%i", aniCount + 1] ofType: #"png"];
// here is the code to pre-render the image
UIImage *frameImage = [UIImage imageWithContentsOfFile: fileLocation];
UIGraphicsBeginImageContext(frameImage.size);
CGRect rect = CGRectMake(0, 0, frameImage.size.width, frameImage.size.height);
[frameImage drawInRect:rect];
UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[menuanimationImages addObject:renderedImage];
}
settingsBackground.animationImages = menuanimationImages;
But i want to use the same image sometimes - can i fill within the code above my array manually via
testArray = [[NSArray alloc] initWithObjects:[UIImage imageNamed:#"test_001.png"],
[UIImage imageNamed:#"test_002.png"],
[UIImage imageNamed:#"test_001.png"],
nil];
Thanks for ideas!
Yes you can by using this
UIImageView * animatedImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200,200)];
testArray = [[NSArray alloc] initWithObjects:[UIImage imageNamed:#"test_001.png"], [UIImage imageNamed:#"test_002.png"],[UIImage imageNamed:#"test_001.png"],nil];
animTime =3.0;
[animatedImageView setAnimationImages:testArray] ;
animatedImageView.animationDuration = animTime;
animatedImageView.animationRepeatCount = 1;
[self.view addSubview: animatedImageView];
[animatedImageView startAnimating];

Can not adjust UIPopupController to display images

In my application (code listed below), I use a popover to display a series of colors that the user can choose. These colors are used for the color of the drawing they are completing above. I am trying to modify the popover to work the same way, except for this time I would want to display images (the images are saved in the application's documents folder as png files) instead of blocks of color. Listed below is the working code for the color selector popover. ColorGrid is a UIview which contains an NSArray Colors, as well as two NSUIntegers columnCount and rowCount. I have tried to replace the items in the colors array with UIImages of the png files, as well as UIImageViews but I have not been able to get a successful result (or a compilable one). Listed below is the working code. Could anyone show me how I can change the UIColor items to the images to show them in the grid?
- (IBAction)popoverStrokeColor:(id)sender {
StrokeColorController *scc = [[[StrokeColorController alloc] initWithNibName:#"SelectColorController" bundle:nil] autorelease];
scc.selectedColor = self.strokeColor;
[self doPopoverSelectColorController:scc sender:sender];
}
- (void)doPopoverSelectColorController:(SelectColorController*)scc sender:(id)sender {
[self setupNewPopoverControllerForViewController:scc];
scc.container = self.currentPopover;
self.currentPopover.popoverContentSize = scc.view.frame.size;
scc.colorGrid.columnCount = 2;
scc.colorGrid.rowCount = 3;
scc.colorGrid.colors = [NSArray arrayWithObjects:
//put the following below back in after testing
[UIColor blackColor],
[UIColor blueColor],
[UIColor redColor],
[UIColor greenColor],
[UIColor yellowColor],
[UIColor orangeColor],
//[UIColor purpleColor],
// [UIColor brownColor],
// [UIColor whiteColor],
// [UIColor lightGrayColor],
//[UIColor cyanColor],
//[UIColor magentaColor],
nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(colorSelectionDone:) name:ColorSelectionDone object:scc];
[self.currentPopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; //displays the popover and anchors it to the button
}
Thanks for your help. I am new to objective-c.
edit - heres the function with my attempt to insert the images instead of the colors
- (void)doPopoverSelectColorController:(SelectColorController*)scc sender:(id)sender {
[self setupNewPopoverControllerForViewController:scc];
scc.container = self.currentPopover;
self.currentPopover.popoverContentSize = scc.view.frame.size;
// these have to be set after the view is already loaded (which happened
// a couple of lines ago, thanks to scc.view...
scc.colorGrid.columnCount = 2;
scc.colorGrid.rowCount = 3;
//here we need to get the UIImage items to try to put in the array.
NSArray *pathforsave = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [pathforsave objectAtIndex:0];
//here we need to add the file extension onto the file name before we add the name to the path
//[fileName appendString:#".hmat"];
NSString *strFile = [documentDirectory stringByAppendingPathComponent:#"test.png"];
NSString *strFile1 = [documentDirectory stringByAppendingPathComponent:#"test1.png"];
NSString *strFile2 = [documentDirectory stringByAppendingPathComponent:#"test2.png"];
NSString *strFile3 = [documentDirectory stringByAppendingPathComponent:#"test3.png"];
NSString *strFile4 = [documentDirectory stringByAppendingPathComponent:#"test4.png"];
NSString *strFile5 = [documentDirectory stringByAppendingPathComponent:#"test5.png"];
//now for the Images
UIImage *image = [ UIImage imageWithContentsOfFile: strFile];
UIImage *image1 = [ UIImage imageWithContentsOfFile: strFile1];
UIImage *image2 = [ UIImage imageWithContentsOfFile: strFile2];
UIImage *image3 = [ UIImage imageWithContentsOfFile: strFile3];
UIImage *image4 = [ UIImage imageWithContentsOfFile: strFile4];
UIImage *image5 = [ UIImage imageWithContentsOfFile: strFile5];
UIImageView *imageview = [[[UIImageView alloc] initWithImage:image] autorelease];
[self.view addSubview:imageview];
UIImageView *imageview1 = [[[UIImageView alloc] initWithImage:image1] autorelease];
[self.view addSubview:imageview1];
UIImageView *imageview2 = [[[UIImageView alloc] initWithImage:image2] autorelease];
[self.view addSubview:imageview2];
UIImageView *imageview3 = [[[UIImageView alloc] initWithImage:image3] autorelease];
[self.view addSubview:imageview3];
UIImageView *imageview4 = [[[UIImageView alloc] initWithImage:image4] autorelease];
[self.view addSubview:imageview4];
UIImageView *imageview5 = [[[UIImageView alloc] initWithImage:image5] autorelease];
[self.view addSubview:imageview5];
imageview.image = image;
imageview1.image = image1;
imageview2.image = image2;
imageview3.image = image3;
imageview4.image = image4;
imageview5.image = image5;
scc.colorGrid.colors = [NSArray arrayWithObjects:
// When attempting to add the images like this - get the error identified expected
// after the e in image, at the end bracket. Putting a * does nothing to change the error
[image],
// When adding one of the Imageviews, i get the same error as above
//below is how I attempted to add it
[imageView],
//
nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(colorSelectionDone:) name:ColorSelectionDone object:scc];
[self.currentPopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; //displays the popover and anchors it to the button
}
Remove your square brackets around image and/or imageView :
scc.colorGrid.colors = [NSArray arrayWithObjects:
// Not : [image] but
image,
// or
imageView,
// Not : [imageView],
nil];

Save multiple custom UIImageViews

I was recently examining the project "Demo Photo Board" found here.
This is a simple demonstration of adding UIImageViews to the screen that have UIGestureRecognizers added to them...allowing the user to manipulate the various UIImageViews.
I add the view like so:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
imageview = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
imageview.userInteractionEnabled = YES;
[imageview setImage:image];
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scale:)];
[pinchRecognizer setDelegate:self];
[imageview addGestureRecognizer:pinchRecognizer];
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotate:)];
[rotationRecognizer setDelegate:self];
[imageview addGestureRecognizer:rotationRecognizer];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[panRecognizer setDelegate:self];
[imageview addGestureRecognizer:panRecognizer];
[self.view addSubview:imageview]; }
I can even save the view like so:
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[NSKeyedArchiver archivedDataWithRootObject:imageview] forKey:#"imageViewSaved"];
Now my question: The following method saves only the last imageview added to the screen. Anyone know how to save all of the imageviews that are on the screen...if the user adds more than one?
I really don't think you want to be saving the entire UIImageView object to the user defaults. Instead, try saving a list of UIImage objects, which will be much more lightweight. (And which make much more sense to serialize.)
You can do this like so:
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
NSArray *savedArray = [defs objectForKey:#"SAVED_IMAGES"];
// Create a mutable version in case the serialized copy is an NSArray
NSMutableArray *mutableImages = savedArray ? [NSMutableArray arrayWithArray:savedArray] : [NSMutableArray array];
[mutableImages addObject:image];
[defs setObject:mutableImages forKey:#"SAVED_IMAGES"];
[defs save];
To distinguish the UIImageViews on the screen you can do the following.
Define the start ImageView Tag number
#define kImageViewTag 3000
Define an instance var for number of images added to the screen.
NSUInteger numberOfImage = 0
Whenever you create a new UIImageView, increase the count and add it with the kImageViewTag and assign it to the tag property.
imageview = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
imageview.userInteractionEnabled = YES;
[imageview setImage:image];
numberOfImage += 1;
imageView.tag = kImageViewTag + numberOfImage;
Whenever you enumerate the screen subviews, if the class is UIImageView with the tag >= kImageViewTag, you know those are the images added to the screen from the UIImagePickerController.

Difficulty with accessing list of URLs in XML file

I am trying to make an app that plays MP3 songs. My program flow is like this:
I have an XML file here in my website: http://jeewanaryal.web44.net/SongsXML/songsListXML.xml. It has song titles and the actual URL of those songs on the Internet. I have the following code for my Pop songs section:
NSString *urlString = #"http://jeewanaryal.web44.net/SongsXML/songsListXML.xml";
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
NSDictionary *dict = [XMLReader dictionaryForXMLData:data error:nil];
NSArray *arrayOfSongs = [[NSArray alloc] initWithArray:[[[dict objectForKey:#"list"] objectForKey:#"songs"] objectForKey:#"song"]];
StartStopSound = [UIButton buttonWithType:UIButtonTypeRoundedRect];
StartStopSound.frame = CGRectMake(60, 360, 200, 30);
[StartStopSound setTitle:#"बजाउनुहोस" forState:UIControlStateNormal];
[StartStopSound addTarget:self action:#selector(playSong) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:StartStopSound];
back = [UIButton buttonWithType:UIButtonTypeRoundedRect];
back.frame = CGRectMake(20, 320, 100, 30);
[back setTitle:#"पछाडीको गीत " forState:UIControlStateNormal];
[back addTarget:self action:#selector(playSong) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:back];
next = [UIButton buttonWithType:UIButtonTypeRoundedRect];
next.frame = CGRectMake(200, 320, 100, 30);
[next setTitle:#"अगाडीको गीत" forState:UIControlStateNormal];
[next addTarget:self action:#selector(playSong) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:next];
NSData *myData = [[NSData alloc] init ];
NSString *urlString1 = [[NSString alloc] init];
for (NSDictionary *fruitDict in arrayOfSongs) {
UILabel *songTitle = [[UILabel alloc] initWithFrame:CGRectMake(40, 200, 300, 40)];
songTitle.text = [NSString stringWithFormat:#"%#",[[fruitDict objectForKey:#"title"] objectForKey:#"text"]];
[self.view addSubview:songTitle];
urlString1 = [NSString stringWithFormat:#"%#",[[fruitDict objectForKey:#"url"] objectForKey:#"text"]];
//NSLog(#"\n\n -- URL STRING : %# \n\n",urlString);
}
myData = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString1]];
player = [[AVAudioPlayer alloc] initWithData:myData error:nil];
[player play];
[player numberOfLoops];
[player currentTime];
This works fine for a single song; that is, it only plays the last URL of my XML file. I want to make all songs to be played one by one, making a "Next" and "Previous" button on my app.
Will you please tell me how I can implement that? I am using XMLReader.h and XMLReader.m file to parse the data from XML into my app.
You would need to store arrayOfSongs somewhere in the class. The "back" and "next" buttons would need separate actions (e.g. playPreviousSong, playNextSong). These methods would then look something like this:
-(void) playPreviousSong
{
NSString *url = [[self songs] objectAtIndex:[self songIndex] - 1];
[self playSong:url];
[self setSongIndex:[self songIndex - 1];
}
This is a crude implementation just to show how it'd fit together. Basically you need to store the list of songs and keep track of which song is "selected"/playing, then just select the next/previous one.
Edit: To answer your question in the comments, you have already extracted the array of song URLs, you simply need to keep a reference to it in the class. E.g.
#interface AudioPlayer {
NSArray *_songs;
NSUInteger *_songIndex;
}
Then in the #implementation instead of creating a arrayOfSongs variable, simply reference the array from the instance variable:
_songs = [[NSArray alloc] initWithArray:[[[dict objectForKey:#"list"] objectForKey:#"songs"] objectForKey:#"song"]];
Then in, for example, the playPreviousSong method:
-(void) playPreviousSong
{
NSString *url = [_songs objectAtIndex:_songIndex - 1];
[self playSong:url];
_songIndex--;
}