Hello,
I added the following code in my .m file :
- (void)viewDidLoad
{
[imageA setHidden:YES];
[scrollView setScrollEnabled:YES];
[scrollView setContentSize:CGSizeMake(320, 3420)];
NSString *path = [[NSBundle mainBundle] pathForResource:@"MyMusic" ofType:@"mp3"];
AVAudioPlayer* musicLoop=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
//musicLoop.delegate = self;
musicLoop.numberOfLoops = -1;
musicLoop.volume = 0.5;
[musicLoop play];
[super viewDidLoad];
}
it’s a background music, how can I add a button to stop it ? because each time I’m trying to do that,
xcode says:
[musicLoop stop]; Use of undeclared identifier ‘musicLoop’
any help please ??
Where are you putting the stop code? I assume it is outside the viewDidLoad function.
You need to have it as a property in you .h file and synthesize it in your .m
@property (nonatomic, retain) AVAudioPlayer *musicLoop;
Then in your viewDid load function you set the property like this:
musicLoop=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
Then you should be able to stop it from any method. Also, remember to release it in your dealloc function.
thanks NightStalker-DNS for your help, please check my code:
-------------- .h ----------------------
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@interface ABC2ViewController : UIViewController <AVAudioPlayerDelegate> {
IBOutlet UIScrollView *scrollView;
IBOutlet UIImageView *imageA;
IBOutlet UIImageView *imageB;
AVAudioPlayer* musicLoop;
AVAudioPlayer* AudioC;
AVAudioPlayer* AudioB;
}
- (IBAction)letterA:(id)sender;
- (IBAction)letterB:(id)sender;
- (IBAction)musicStop:(id)sender;
@property(nonatomic, retain) IBOutlet UIImageView *imageA;
@property(nonatomic, retain) IBOutlet UIImageView *imageB;
@end
---------------- .m ---------------------
#import "ABC2ViewController.h"
#import <AVFoundation/AVFoundation.h>
@implementation ABC2ViewController
@synthesize imageA;
@synthesize imageB;
- (IBAction)letterA:(id)sender{
NSString *path = [[NSBundle mainBundle] pathForResource:@"A" ofType:@"m4a"];
AudioC=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
if (imageA.hidden == TRUE) {
[imageA setHidden:FALSE];
[AudioC play];
}
else {
[imageA setHidden:TRUE];
[AudioC play];
}
}
- (IBAction)letterB:(id)sender{
NSString *path = [[NSBundle mainBundle] pathForResource:@"A" ofType:@"m4a"];
AudioB=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
AudioB.delegate = self;
//[imageB setHidden:NO];
if (imageB.hidden == TRUE) {
[imageB setHidden:FALSE];
[AudioB play];
//[self performSelector:@selector(hideagain)withObject:nil afterDelay:2];
}
else {
[imageB setHidden:TRUE];
[AudioB play];
}
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[imageA setHidden:YES];
[imageB setHidden:YES];
[scrollView setScrollEnabled:YES];
[scrollView setContentSize:CGSizeMake(320, 3420)];
NSString *path = [[NSBundle mainBundle] pathForResource:@"MusicLoop3a3" ofType:@"mp3"];
musicLoop=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
musicLoop.delegate = self;
musicLoop.numberOfLoops = -1;
musicLoop.volume = 0.5;
[musicLoop play];
[super viewDidLoad];
}
- (IBAction)musicStop:(id)sender{
[musicLoop stop];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)dealloc
{
[UIScrollView release];
[scrollView release];
[musicLoop release];
[AudioC release];
[AudioB release];
[super dealloc];
}
@end
and tell me why I still have a problem, my problem is when I click on button ( letterA ) first time, if ok, second time the application crash, I don’t know why and give me the following :
[AudioC play]; Thread1: Stopped ay breakpoint1
Hello,
Everything work fine now, but just one question to be sure about dealloc section, it’s right ?
- (void)dealloc
{
[UIScrollView release];
[scrollView release];
[musicLoop release];
[AudioC release];
[AudioB release];
[super dealloc];
}
thanks in advance
Ok, well you need to set your musicLoop as a retain property and synthesize it. The release it in your dealloc as you are doing.
Also remember to set all your IBOutlet properties to nil in the viewDidUnload method:
self.scrollView = nil;
Then you also need to release all those items in the dealloc
Hello NightStalker-DNS,
I did all what you asked me for, and this is my script now
.h file
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@interface ABC2ViewController : UIViewController <AVAudioPlayerDelegate> {
IBOutlet UIScrollView *scrollView;
IBOutlet UIImageView *imageA;
IBOutlet UIImageView *imageB;
AVAudioPlayer* musicLoop;
AVAudioPlayer* AudioC;
AVAudioPlayer* AudioB;
}
- (IBAction)letterA:(id)sender;
- (IBAction)letterB:(id)sender;
- (IBAction)musicStop:(id)sender;
- (IBAction)musicPlay:(id)sender;
@property(nonatomic, retain) IBOutlet UIScrollView *scrollView;
@property(nonatomic, retain) IBOutlet UIImageView *imageA;
@property(nonatomic, retain) IBOutlet UIImageView *imageB;
@property(nonatomic, retain) AVAudioPlayer* musicLoop;
@property(nonatomic, retain) AVAudioPlayer* AudioC;
@property(nonatomic, retain) AVAudioPlayer* AudioB;
@end
.m
#import "ABC2ViewController.h"
#import <AVFoundation/AVFoundation.h>
@implementation ABC2ViewController
@synthesize scrollView;
@synthesize imageA;
@synthesize imageB;
@synthesize musicLoop;
@synthesize AudioC;
@synthesize AudioB;
- (IBAction)letterA:(id)sender{
NSString *path = [[NSBundle mainBundle] pathForResource:@"A" ofType:@"m4a"];
AudioC=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
AudioC.delegate = self;
if (imageA.hidden == TRUE) {
[imageA setHidden:FALSE];
[AudioC play];
//[self performSelector:@selector(hideagain)withObject:nil afterDelay:2];
}
else {
[imageA setHidden:TRUE];
[AudioC play];
}
}
- (IBAction)letterB:(id)sender{
NSString *path = [[NSBundle mainBundle] pathForResource:@"A" ofType:@"m4a"];
AudioB=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
AudioB.delegate = self;
//[imageB setHidden:NO];
if (imageB.hidden == TRUE) {
[imageB setHidden:FALSE];
[AudioB play];
//[self performSelector:@selector(hideagain)withObject:nil afterDelay:2];
}
else {
[imageB setHidden:TRUE];
[AudioB play];
}
}
- (IBAction)musicStop:(id)sender{
[musicLoop pause];
}
- (IBAction)musicPlay:(id)sender{
[musicLoop play];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[imageA setHidden:YES];
[imageB setHidden:YES];
[scrollView setScrollEnabled:YES];
[scrollView setContentSize:CGSizeMake(320, 3420)];
NSString *path = [[NSBundle mainBundle] pathForResource:@"MusicLoop3a3" ofType:@"mp3"];
musicLoop=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
musicLoop.delegate = self;
musicLoop.numberOfLoops = -1;
//musicLoop.volume = 0.5;
[musicLoop play];
[super viewDidLoad];
}
- (void)viewDidUnload
{
self.scrollView = nil;
self.imageA = nil;
self.imageB = nil;
self.musicLoop = nil;
self.AudioC = nil;
self.AudioB = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)dealloc
{
[scrollView release];
[imageA release];
[imageB release];
[musicLoop release];
[AudioC release];
[AudioB release];
[super dealloc];
}
@end
First of all, THANK YOU so much, really I appreciate your help, and I have 2 small questions:
1: is my code above is clean as you want ?
2: what is mean ( self.scrollView = nil; ) ? just to understand what is happen when I do it.
Yes, everything looks good to me. I cannot see any problems there.
You should set all properties to nil that get set in viewDidLoad or that is an IBOutlet. Setting it to nil is basically clearing the object from memory. The pointer is then pointing to an empty memory block. Then you can still release a nil object without problems. It will also clear all the retain counts.
viewDidUnload gets called when memory becomes critical, so you must clear all memory you can that can get re-created with viewDidLoad and IB.
Hello NightStalker-DNS,
Thanks for your help, I understand better now.
I’m gonna to change the view ( all what you have seen before, I used to make a simple application for kids, one image includes the letters Alphabet ), I’m going now to add 2 or 3 pages( credits, info, … and by the way I will need your name to thank you in the finale application ) so just to be sure, which one of the following solutions is better:
A: Add more view and each view includes a page.
B: Add a new XIB file, with new controller .h and .m files for each page.
In fact, it will be amazing if I will make a turn page effect between pages, from right to left, like a real book, so I don’t know which solution is better ?
Best regards.
I think be is the better option. Or you xib file could get quite bloated. Separating them will be better. You can use a navigation controller for slide animations, but there are also a few built in animations you could use. Curl down, Curl up, flip, etc. Nothing built in though for page turning like you want, so that will have to be custom. You could look at the following open source solutions on GitHub:
Leaves
EPGLTransitionView
I hope that helps.
PS. There is no need to thank me in the app. I appreciate the gesture though. Thank you
Hello NightStalker-DNS,
Thank you all time for your support, and for your adives. I’m discovering now the links that you have sent, they are interesting, but how could I integrate them in my script, this is my new adventure now
so be waiting my feedback very soon.
PS: I will not accept to finish the app without saying thanks to you, if not to your company with its logo, and if not also, than I wiill thanks Sitepoint.
Hi
Ok, no problem. I will help with that as much as I can. But it can be a rather tricky process and might not be that easy to help with. My company is currently also looking into this, but has still not got it 100%.
If you are so adamant about the thanks, then I will suggest you just thank sitepoint, because had it not been for sitepoint, I would not have been able to help you.
Good luck with your project
Hi,
You will not imagine how much hours I spend to find solution, in fact I found the way to do an effect as the following:
YouTube - Tiffany Page Curl Effect on Android
this one is a page curl effect on Android, but how it’s possible to do it on iPhone / iPad, it’s the hard mission.
By the way, I found the following the ( The anatomy of a page curl ) on the following link :
Chris Luke » Blog Archive » The anatomy of a page curl
maybe it’s interesting for you too.
The closest solution code available till now is one ( High Caffeine Content: Apple’s iBooks Dynamic Page Curl ) but there is a small bug, when you turn the page and leave it, it will not return to its place, or turn to show another page, also the shadow on the page above, not pasting properly ( I can add a capture later if this is interesting for you )
Really it’s hard to get the same effect as Apple iBook, but I saw many applications included the same effect ( the corner of the page following your finger as iBook ) but how they did that ? I don’t know.
Anyway my adventure not finish yet, I will do my best to get the solution, if you get it before me, let me know, and thanks again for your help.