How do I stop the background music in another view in Xcode? - objective-c

So I have a background music playing in one view, then I press the button and go to another view, the background music in another view run as well.
Then I have two background music playing. I want to stop music from the previous view.
So here is the .h code for the first view:
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface ViewController : UIViewController<AVAudioPlayerDelegate>{
AVAudioPlayer *startingMusic;
}
-(IBAction)StartGame:(id)sender;
So here is the .m code for the first view:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
-(IBAction)StartGame:(id)sender{
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *music = [[NSBundle mainBundle] pathForResource:#"Morning_Walk" ofType:#"mp3"];
startingMusic=[[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:music] error:NULL];
startingMusic.delegate=self;
startingMusic.numberOfLoops=-1;
[startingMusic play];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
here is the .h code for the second view:
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface StageOne : UIViewController<AVAudioPlayerDelegate>
AVAudioPlayer *gameMusic;
}
here is the .m code for the second view:
#import "StageOne.h"
#interface StageOne ()
#end
#implementation StageOne
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSString *music = [[NSBundle mainBundle] pathForResource:#"Green_Hills" ofType:#"mp3"];
gameMusic=[[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:music] error:NULL];
gameMusic.delegate=self;
gameMusic.numberOfLoops=-1;
[gameMusic play];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Thanks You so much!

This is normal behavior, as your first controller are still loaded
Try this:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear: animated];
NSString *music = [[NSBundle mainBundle] pathForResource:#"Green_Hills" ofType:#"mp3"];
gameMusic=[[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:music] error:NULL];
gameMusic.delegate=self;
gameMusic.numberOfLoops=-1;
[gameMusic play];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear: animated];
gameMusic.delegate = nil;
[gameMusic stop];
gameMusic = nil;
}

Related

Passing data between two viewcontrollers in xcode using storyboard

I am super new to programming in general. I am trying to make a very simple app.
I am trying to pass data from one viewcontroller to another using a storyboard. On my first screen I have a text field and a button then after you press the button i want the second screen's label to be updated with whatever text you put in the text field.
Here is some of my code:
#import "FirstViewController.h"
#import "SecondViewController.h"
#interface FirstViewController ()
#end
#implementation FirstViewController
#synthesize secondviewData;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)passData:(UIButton *)sender {
// SecondViewController *second = [[SecondViewController alloc] initWithNibName:nil bundle:nil];
self.secondviewData = secondviewData;
secondviewData.passedValue = input.text;
// [self presentViewController:second animated:YES completion:nil];
homeLabel.text = input.text;
}
#end
#import "SecondViewController.h"
#import "FirstViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
#synthesize passedValue;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
label.text = passedValue;
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Here's a link to my code: http://oberober.com/passingData/
So far the label on the second screen keeps going blank no matter what I enter on the first screen's text field.
I feel like I am missing an important concept? Any tips or tutorials I can look at?
Thanks ahead of time,
Casper
You pass the data by using the prepareForSegue method of the first controller. Here's an example from one of my apps that shows a vehicle object being passed to the second controller.
CHRBodyViewController is the class of the second controller.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
CHRBodyViewController *body = [segue destinationViewController];
body.vehicle = _vehicle;
body.updated = YES;
}

Missing context for method declaration?

I am trying to create an app and when I added this IBAction, it gave me the error Missing context for method declaration. I have looked up how to fix this but I am a bit confused since I am a beginner. The errors appear in my .m file:
#import "QRscannerSecondViewController.h"
#end
#interface QRscannerSecondViewController ()
#end
#implementation QRscannerSecondViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"Info", #"Info");
self.tabBarItem.image = [UIImage imageNamed:#"second"];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
-(IBAction)button1
{
[input resignFirstResponder];
l11 = input.text;
line11.text = [[NSString alloc] initWithFormat:#"%2.f", l11];
}
but I though that it would help if I included my .h file, also.
#import <UIKit/UIKit.h>
#interface QRscannerSecondViewController : UIViewController
#end
#interface TextGameViewController : UIViewController
{
IBOutlet UITextField *input;
IBOutlet UILabel *line11;
NSString *l11;
}
-(IBAction)button1;
You need to put the code:
-(IBAction)button1
{
[input resignFirstResponder];
l11 = input.text;
line11.text = [[NSString alloc] initWithFormat:#"%2.f", l11];
}
before the #end.

Custom delegate iOS 6 using ARC not working

I am a begginer with Objective-C programming.
I searched here and in other websites to a way to solve my problem but i did not find.
I want to create an login view before the system load. Then, after login i want to dismiss it.
On my project i use ARC and not use Storyboards.
When i debug and look into the function "efetuarLogin" the value of property delegate is 0x000000. I think it is blank, is not?
According to the tutorials and other tips i found on the internet, this is the right way to code delegate. Can you check this for me?
Here is the code:
Login.h
#import <UIKit/UIKit.h>
#class Login;
#protocol LoginDelegate <NSObject>
#required
- (void)loginDidFinish: (Login *)login;
#end
#interface Login : UIViewController{
__weak id<LoginDelegate> delegate;
}
#property (nonatomic, weak) id <LoginDelegate> delegate;
- (IBAction)efetuarLogin:(id)sender;
#end
Login.M
#import "Login.h"
#implementation Login
#synthesize delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)efetuarLogin:(id)sender {
[delegate loginDidFinish:self];
}
#end
MainController.h
#import <UIKit/UIKit.h>
#import "Login.h"
#interface MainController : UITabBarController <LoginDelegate>
#end
MainController.m
#import "MainController.h"
#import "Login.h"
#import "ModalViews.h"
#import "Alerts.h"
#import "ViewPadrao.h"
#import "TableView.h"
#implementation MainController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
ModalViews *modalViews = [[ModalViews alloc] initWithNibName:#"ModalViews" bundle:nil];
Alerts *alerts = [[Alerts alloc] initWithNibName:#"Alerts" bundle:nil];
ViewPadrao *viewPadrao = [[ViewPadrao alloc] initWithNibName:#"ViewPadrao" bundle:nil];
TableView *tableView = [[TableView alloc] initWithNibName:#"TableView" bundle:nil];
self.viewControllers = #[modalViews, alerts, viewPadrao, tableView];
}
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
Login *login = [[Login alloc] initWithNibName:#"Login" bundle:nil];
[login setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
[self presentViewController:login animated:NO completion:nil];
}
- (void)loginDidFinish: (Login *)login{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Sua mensagem aqui" message:#"Mensagem" delegate:self cancelButtonTitle:#"Fechar" otherButtonTitles:nil];
[alert show];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
And the method didFinishLaunchingOptions of AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
mainController = [[MainController alloc] init];
window.rootViewController = mainController;
[window makeKeyAndVisible];
return YES;
}
Sorry for the high quantity of code. I am thankful since already!!
I am using the ViewDidAppear method to show Login to users. But when i dismiss and the MainController appears, the method viewdidapper creates the Login again.
How i do to show login once? When i tried to do this on viewdidload it did not work. The login did not appear.
In your MainViewController.m when you create login object
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
Login *login = [[Login alloc] initWithNibName:#"Login" bundle:nil];
login.delegate = self; //add this line
[login setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
[self presentViewController:login animated:NO completion:nil];
}
EDIT : After seeing OP's edit in the question (which should have been a different thread)
Your view Controller hierarchy is wrong. The ideal flow should be
1) Show Login controller directly from App delegate.
2) After successfull login, show MainViewController from Login Controller.

Can't override a simple method

I've created a new project with two ViewControllers and imported a class that pushes ViewController from right to left instead LTR but can't manage to use it. I can see that pushViewController inside UIRightToLeft.m is not being called and I don't understand why.
My main goal is to get that working with RTL aniamtion.
#import "UIRightToLeft.h"
#implementation UIRightToLeft
- (id)initWithRootViewController:(UIViewController *)rootViewController
{
self = [super initWithRootViewController:rootViewController];
if (!self)
return nil;
return self;
}
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
NSLog(#"pushViewController");
// Add the viewController and a fake controller without animation. Then pop the fake controller with animation.
UIViewController *fakeController = [[UIViewController alloc] init] ;
[super setViewControllers:[[self viewControllers] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:viewController, fakeController, nil]] animated:NO];
[super popViewControllerAnimated:animated];
}
- (void)popViewControllerAnimatedStep2:(UIViewController *)viewController
{
// Push the new top controller with animation
[super pushViewController:viewController animated:YES];
// Remove the view that should have been popped
NSMutableArray *arr = [NSMutableArray arrayWithArray:[self viewControllers]];
[arr removeObjectAtIndex:[[self viewControllers] count]-2];
[super setViewControllers:[NSArray arrayWithArray:arr] animated:NO];
}
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
NSLog(#"popViewControllerAnimated");
if (animated)
{
// Save the controller that should be on top after this pop operation
UIViewController *newTopController = [[self viewControllers] objectAtIndex:[[self viewControllers] count]-2];
// Remove it from the stack. Leave the view that should be popped on top
NSMutableArray *arr = [NSMutableArray arrayWithArray:[self viewControllers]];
[arr removeObjectAtIndex:[[self viewControllers] count]-2];
[super setViewControllers:[NSArray arrayWithArray:arr] animated:NO];
// Schedule the next step
[self performSelector:#selector(popViewControllerAnimatedStep2:) withObject:newTopController afterDelay:0];
return [arr objectAtIndex:[arr count]-1];
}
return [super popViewControllerAnimated:NO];
}
#end
ViewController.m:
#import "ViewController.h"
#import "UIRightToLeft.h"
#import "SecondViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)pressMe:(UIButton *)sender {
SecondViewController *next = [[SecondViewController alloc]init];
[self.navigationController pushViewController:next animated:YES];
}
#end
ViewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
- (IBAction)pressMe:(UIButton *)sender;
#end
(In my ViewController there's only one button draged to the second ViewController with push)
After looking at your error log I think you actually need to have your navigation controller subclass UIRightToLeft.
If you are using a Storyboard, select your navigation controller and set Custom Class to UIRightToLeft.

EXC_BAD_ACCESS when am try to open subview i put sound in the background

i make subviewcontroller with three files .h .m .nib
the .h content :-
#interface du3a : UIViewController <AVAudioPlayerDelegate> {
}
the .m one is:-
#import "du3a.h"
#implementation du3a
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (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
- (void)viewDidLoad
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"jaber" ofType:#"mp3"];
AVAudioPlayer *theAudio; [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
the problem come from the mainview .m specially in this line :-
-(IBAction)du3a:(id)sender {
du3a *du3 = [[du3a alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:du3 animated:YES];
}
Any help appreciated
First: Do the [super viewDidLoad]; at the beginning of the viewDidLoad method.
Second: Use the naming conventions.
Third: Your code seams to have leaks.