I have the NSTimer that needs to be run in the background as you navigate around to different pages, but when I had that in the view controller files, id move to another page and it would essentially destroy the timer. so I made a singleton class and attempted to put the code in there and just call it from there. at this point the code runs, but it doesn't continue to run the timer when I navigate to another page. any ideas are greatly appreciated, please ask for more info!
Code:
Viewcontroller.h
#import <UIKit/UIKit.h>
#import "ApplicationManager.h"
#interface ViewController : UIViewController{
IBOutlet UILabel *time;
NSTimer *ticker;
}
- (IBAction)start;
- (IBAction)reset;
- (void)showActivity;
#end
//
// ViewController.m
// License
//
// Created by Connor Gosell on 7/2/13.
// Copyright (c) 2013 Connor Gosell. All rights reserved.
//
#import "ViewController.h"
#import "ApplicationManager.h"
#interface ViewController ()
#end
#implementation ViewController
-(IBAction) start
{
ticker:[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(showActivity) userInfo:nil repeats:YES];
}
-(IBAction)reset
{
[ticker invalidate];
time.text = #" 0:00";
}
-(void) showActivity
{
int currentTime = [time.text intValue];
int newTime = currentTime + 1;
time.text = [NSString stringWithFormat:#"%d", newTime];
}
- (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) start
{
[[ApplicationManager instance] setTicker:[NSTimer scheduledTimerWithTimeInterval:1.0 target:self ``selector:#selector(showActivity) userInfo:nil repeats:YES]];
}
-(IBAction) reset
{
[[[ApplicationManager instance] ticker] invalidate];
time.text = #" 0:00";
}
-(void) showActivity
{
int currentTime = [time.text intValue];
int newTime = currentTime + 1;
time.text = [NSString stringWithFormat:#"%d", newTime];
}
*/
//
// ApplicationManager.h
// License
//
// Created by Connor Gosell on 7/31/13.
// Copyright (c) 2013 Connor Gosell. All rights reserved.
//
#import <Foundation/Foundation.h>
#interface ApplicationManager : NSObject{
}
+(ApplicationManager*) instance;
#end
//
// ApplicationManager.m
// License
//
// Created by Connor Gosell on 7/31/13.
// Copyright (c) 2013 Connor Gosell. All rights reserved.
//
#import "ApplicationManager.h"
#implementation ApplicationManager
static ApplicationManager* appMgr = nil;
+(ApplicationManager*) instance
{
#synchronized([ApplicationManager class])
{
if(!appMgr)
{
appMgr = [[self alloc] init];
}
return appMgr;
}
return nil;
}
+(id) alloc
{
#synchronized([ApplicationManager class])
{
NSAssert((appMgr == nil), #"Only one instance of singleton class may be instantiated.");
appMgr = [super alloc];
return appMgr;
}
}
-(id) init
{
if(!(self = [super init]))
{
[self release];
return nil;
}
return self;
}
I'll make some assumptions, but you can calculate the time based on the system time instead of by incrementing a var. The start time can be stored as a property in the app delegate if it is reused by the entire app. If the time is calculated this way, timers can be started as each view controller appears and stopped when disappearing, and may benefit from a quicker interval if accuracy is desired. I use a similar technique to this in the Pace Clock Mac and iOS apps.
Put the timer in your AppDelegate, have the timer tick send a notification, have your view controllers each enable a listener for the notification, so they can do their updates.
Related
There are lots of questions and answers about how to change the UISlider value with NsTimer but i need to create the reverse condition i need to change the NSTimer interval per UISlider value change, and want the slider value work in reverse manner. so can anyone help to achieve this?
Thanks for your approaches and time :)
you can set Timer set again interval value at the IBAction of UISlier Method like:-
.h class:-
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
{
IBOutlet UILabel *lblTimer;
IBOutlet UISlider *timeSlider;
}
#property(nonatomic,strong)NSTimer *timer;
.m class:-
- (void)viewDidLoad
{
[super viewDidLoad];
_timer=[[NSTimer alloc]init];
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(updateLable) userInfo:nil repeats:YES];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
int i=0;
-(IBAction)changeSlider:(UISlider*)sender
{
NSLog(#"%d",(int)sender.value);
[_timer invalidate];
_timer=[[NSTimer alloc]init];
_timer=nil;
_timer = [NSTimer scheduledTimerWithTimeInterval:(int)sender.value target:self selector:#selector(updateLable) userInfo:nil repeats:YES];
// i=0;
//text_field .text= [[NSString alloc] initWithFormat:#" Value %d ", (int)slider.value];
}
-(void)updateLable
{
[lblTimer setText:[NSString stringWithFormat:#"%d",i]];
i++;
}
OUTPUT OF CODE
I have been having this issue from last couple of hours and did all the search that i could but unfortunately, i didnt find anything that resolves my issue....
Scenario: i have a CountDownTimer in TimerViewController, NSTimer and other methods are set up in AppDelegate which is suppose to update TimerViewController's Label... as per label's setter, i'm getting the value correctly and its showing in the NSLog HOWEVER, the label is not updating on the screen... this setter is being called from AppDelegate every second and the Label is suppose to show the Timer,
- (void)setMainTimerLabel:(UILabel *)mainTimerLabel
{
_mainTimerLabel = mainTimerLabel;
NSLog(#"ValueUpdated %#",_mainTimerLabel);
}
I have double checked the label, it hooked up with interface correctly, i tried to update the label from ViewDidLoad with test String, the label was showing me the string...
Help please!
EDIT:
AppDelegate Code:
AppDelegate.h
#property (nonatomic, strong) TimerViewController *TimerVC;
- (void)fireTimer;
AppDelegate.m
- (void)fireTimer
{
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(countDownTimer) userInfo:nil repeats:YES];
}
- (void) countDownTimer
{
.......
TimerVC = [[TimerViewController alloc]init];
self.TimerVC.mainTimerLabel = [NSString stringWithFormat:#"%02d:%02d:%02d",hours,minutes,seconds];
.......
}
I resolved this issue following the below code by jabobadilla
I actually solved it by performing a method that will go and retrieve the value that the NSTimer is updating in my AppDelegate, since the method firing the NSTimer is no longer in the main thread when I leave the view and come back to it. This method will loop as long as my NSTimer is valid. I also placed a delay, allowing for the UI to update the value, and then perform the method again. Here is the code in case it helps someone running into a similar issue. I got this idea from the suggestion provided by chandan, thanks!!
AppDelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate> {
}
#property (nonatomic, retain) NSTimer *countdownTimer;
#property (nonatomic, retain) NSString *timeString;
CountdownTimerViewController.h
#interface CountdownTimerViewController : UIViewController {
AppDelegate *appdelegate;
}
#property (strong, nonatomic) IBOutlet UILabel *labelCountdownTimer;
#property (strong, nonatomic) IBOutlet UIButton *buttonStartTimer;
#property (strong, nonatomic) IBOutlet UIButton *buttonStopTimer;
- (IBAction)startTimer:(id)sender;
- (IBAction)stopTimer:(id)sender;
CountdownTimerViewController.m
#implementation CountdownTimerViewController
#synthesize labelCountdownTimer;
- (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.
//Instatiating Appdelegate
if(!appdelegate)
appdelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
- (void) viewDidAppear:(BOOL)animated {
if ([appdelegate.countdownTimer isValid]) {
[self updateLabel];
} else {
labelCountdownTimer.text = #"00:00:00";
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Button Action Methods
- (IBAction)startTimer:(id)sender {
[self updateCounter];
}
- (IBAction)stopTimer:(id)sender {
[appdelegate.countdownTimer invalidate];
labelCountdownTimer.text = #"00:00:00";
}
int countLimit=30; //seconds
NSDate *startDate;
- (void)updateCounter {
labelCountdownTimer.text = #"00:00:00";
startDate = [NSDate date];
appdelegate.countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:#selector(countDown)
userInfo:nil
repeats:YES];
}
- (void)countDown {
if([[NSDate date] timeIntervalSinceDate:startDate] >= countLimit) {
[appdelegate.countdownTimer invalidate];
return;
}
else {
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = -([currentDate timeIntervalSinceDate:startDate]);
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
appdelegate.timeString = [dateFormatter stringFromDate:timerDate];
labelCountdownTimer.text = appdelegate.timeString;
}
}
- (void) updateLabel {
if ([appdelegate.countdownTimer isValid]) {
labelCountdownTimer.text = appdelegate.timeString;
[self performSelector:#selector(updateLabel) withObject:nil afterDelay:0.05];
}
}
There may be problem in your IBOutlet....
Try to create a programatic UILabel and pass the _mainTimerLabel value to that label....
This may help you..
In iPhone every UIContrrol has predefined delegate methods but how we will create our own custom delegate methods
In your header file, before #interface, insert
#protocol YourDelegate <NSObject>
#optional
- (void) anOptionalDelegateFunction;
#required
- (void) aRequiredDelegateFunction;
#end
and under #interface
#property (nonatomic, assign) id<YourDelegate> delegate;
// Remember to synthesize in implementation file
Now you can call in your .m file
[delegate aRequiredDelegateFunction];
and in the delegate
include <YourDelegate> as usual in the .h file
in .m, assign the delegate property of the class with your custom delegate to self
To Create Custom Delegate and Protocol iOS | Swift & Objective-C
Protocols
A protocol is a list of methods that specify an interface that your delegate will implement. There are two kinds of delegates we can use: Option and Required. They are pretty self explanatory but the difference is Required will throw an error letting you know your class is not conforming to the protocol. Also protocol methods are required by default so if you want it optional don’t forget that optional keyword. If you are using swift you will also need to add the #objc prefix if you want an optional method.
Swift
//
// MyTimer.swift
// SwiftProtocol
//
// Created by Barrett Breshears on 10/11/14.
// Copyright (c) 2014 Sledge Dev. All rights reserved.
//
import UIKit
// set up the MyTimerDelegate protocol with a single option timer function
#objc protocol MyTimerDelegate{
optional func timerFinished()
}
class MyTimer: UIViewController {
// this is where we declare our protocol
var delegate:MyTimerDelegate?
// set up timer variables and labels
var timer:NSTimer! = NSTimer()
var labelTimer:NSTimer! = NSTimer()
var timerLabel:UILabel! = UILabel()
var timerCount = 0
var duration = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
timerLabel = UILabel(frame: self.view.frame)
timerLabel.textAlignment = NSTextAlignment.Center
self.view.addSubview(timerLabel)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func startTimer(timerDuration:Double){
self.duration = Int(timerDuration)
timerLabel.text = String(format: "%d", duration)
timer = NSTimer.scheduledTimerWithTimeInterval(timerDuration, target: self, selector: Selector("timerFired:"), userInfo: nil, repeats: false)
labelTimer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("updateLabel:"), userInfo: nil, repeats: true)
}
timer.invalidate()
}
if(labelTimer.valid){
labelTimer.invalidate()
}
// ************************************** \\
// ************************************** \\
// This is the important part right here
// we want to call our protocol method
// so the class implementing this delegate will know
// when the timer has finished
// ************************************** \\
// ************************************** \\
delegate?.timerFinished!()
}
func updateLabel(timer:NSTimer){
duration = duration - 1
timerLabel.text = String(format: "%d", duration)
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
This is a pretty simple example but here is what is going on. The UIViewController has a start timer method that sets up the two timers: one that will fire when the overall time is complete and one that fires every second to update the timer label. When the total duration timer is finished the timerFired method is called, and thats where we run the delegate’s timerFinished method. Now lets do the same thing but with Objective-C.
Objective-C
//
// MyTimer.h
// ObjectIveCProtocol
//
// Created by Barrett Breshears on 10/11/14.
// Copyright (c) 2014 Sledge Dev. All rights reserved.
//
#import
// set up the MyTimerDelegate protocol with a single option timer finished function
#protocol MyTimerDelegate
#optional
-(void)timerFinished;
#end
#interface MyTimer : UIViewController
// this is where we declare our protocol
#property (nonatomic, strong) id delegate;
// set up timer variables and labels
#property (nonatomic, strong) NSTimer *timer;
#property (nonatomic, strong) NSTimer *labelTimer;
#property (nonatomic, strong) UILabel *timerLabel;
#property (nonatomic, assign) int timerCount;
#property (nonatomic, assign) int duration;
- (void)startTimer:(float)duration;
#end
//
// MyTimer.m
// ObjectIveCProtocol
//
// Created by Barrett Breshears on 10/11/14.
// Copyright (c) 2014 Sledge Dev. All rights reserved.
//
#import "MyTimer.h"
#interface MyTimer ()
#end
#implementation MyTimer
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_timer = [[NSTimer alloc] init];
_labelTimer = [[NSTimer alloc] init];
_timerCount = 0;
_duration = 0;
_timerLabel = [[UILabel alloc] initWithFrame:self.view.frame];
[self.view addSubview:_timerLabel];
[_timerLabel setTextAlignment:NSTextAlignmentCenter];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)startTimer:(float)duration{
_duration = (int)duration;
_timerLabel.text = [NSString stringWithFormat:#"%d", _duration];
_timer = [NSTimer scheduledTimerWithTimeInterval:duration target:self selector:#selector(timerFired:) userInfo:nil repeats:NO];
_labelTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateLabel:) userInfo:nil repeats:YES];
}
- (void)timerFired:(NSTimer *)timer {
if ([_timer isValid]) {
[_timer invalidate];
}
_timer = nil;
if ([_labelTimer isValid]) {
_labelTimer invalidate];
}
_labelTimer = nil;
// ************************************** \\
// This is the important part right here
// we want to call our protocol method here
// so the class implementing this delegate will know
// when the timer has finished
// ************************************** \\
[_delegate timerFinished];
}
- (void)updateLabel:(NSTimer *)timer{
_duration = _duration - 1;
_timerLabel.text = [NSString stringWithFormat:#"%d",
_duration];
}
#end
So same thing just different syntax. The UIViewController has a start timer method that sets up the two timers: one that will fire when the overall time is complete and one that fires every second to update the timer label. When the total duration timer is finished the timerFired method is called, and thats where we run the delegate’s timerFinished method.
Delegates
Now that we have our protocols all set up all we have to do is implement them. We are going to do this by creating a delegate. A delegate is a variable that complies to a protocol, which a class typically uses to notify of events, in this case the timer finishing. To do this we add our protocol to our class declaration, to let our class know it must comply with the delegate. Then we add our delegate method to our class.
Swift
//
// ViewController.swift
// Swift-Protocol
// Created by Barrett Breshears on 10/11/14.
// Copyright (c) 2014 Sledge Dev. All rights reserved.
import UIKit
// add our MyTimerDelegate to our class
class ViewController: UIViewController, MyTimerDelegate {
var timer:MyTimer = MyTimer()
override func viewDidLoad() {
super.viewDidLoad()
timer.view.frame = self.view.frame
// ************************ \\
// This is where we let the delegate know
// we are listening for the timerFinished method
// ************************ \\
timer.delegate = self
self.view.addSubview(timer.view)
timer.startTimer(10.0)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// ************************ \\
// This is where our delegate method is fired
// ************************ \\
func timerFinished(){
timer.startTimer(10.0)
println("Hey my delegate is working")
}
}
So the important thing here is we set the timer.delegate to self so the ViewController’s method timerFinished() class is called.
Objective-C
//
// ViewController.h
// ObjectIveCProtocol
//
// Created by Barrett Breshears on 10/10/14.
// Copyright (c) 2014 Sledge Dev. All rights reserved.
#import
#import "MyTimer.h"
// add our MyTimerDelegate to our class
#interface ViewController : UIViewController
#property (nonatomic, strong) MyTimer *timer;
#end
// ViewController.m
// ObjectIveCProtocol
// Created by Barrett Breshears on 10/10/14.
// Copyright (c) 2014 Sledge Dev. All rights reserved.
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_timer = [[MyTimer alloc] init];
_timer.view.frame = self.view.frame;
_timer.delegate = self;
[self.view addSubview:_timer.view];
[_timer startTimer:10.0];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)timerFinished{
[_timer startTimer:10.0];
NSLog(#"Hey my delegate is working!");
}
#end
When we run the code we see the timer label is added and set to a 10 second timer. It counts down, and when it reaches 0 it notifies the viewcontroller, restarts the timer and prints the “Hey my delegate is working in the console”.
If you have any questions about the code or found this tutorial helpful let me know in the comments below! I appreciate feedback. Also don’t forget to follow me on twitter. I am always looking for iOS developers to tweet with.
If you want to follow allow you can download the projects from GitHub here:
https://github.com/barrettbreshears/objective-c-protocol
or,
https://github.com/barrettbreshears/swift-protocol
In your class create an id object delegate. Create a getter and setter so other classes can set themselves as delegates.
In your class add this:
#interface MyClass (Private)
-(void)myDelegateMethod;
#end
Then in what ever function you want to call back to the class that is the delegate do something like this:
if ( [delegate respondsToSelector:#selector(myDelegateMethod)] ) {
[delegate myDelegateMethod];
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Making the iPhone vibrate
I have two buttons. One button adds up, one button adds down. The question is when I certain number such as lets say 22 is in the text area, the phone vibrates for a certain mount of time. Here is my code for it:
What I am trying to say is IF Label Displays "22" THEN VIBRATE PHONE... The question is how do i go about writing this.. I'm still learning so any help regarding this would be much appreciated! Here is my code so far:
#import "StartCountViewController.h"
#import "AudioToolbox/AudioServices.h"
#implementation StartCountViewController
int Count=0;
-(void)awakeFromNib {
startCount.text = #"0";
}
- (IBAction)addNumber {
if(Count >= 999) return;
NSString *numValue = [[NSString alloc] initWithFormat:#"%d", Count++];
startCount.text = numValue;
[numValue release];
}
- (IBAction)vibrate {
}
- (IBAction)subtractNumber {
if(Count <= -35) return;
NSString *numValue = [[NSString alloc] initWithFormat:#"%d", Count--];
startCount.text = numValue;
[numValue release];
}
- (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.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
This is basically a duplicate of Programmatically make the iPhone vibrate
Having said that, I think your code is still going to have errors, and the syntax seems deprecated.
Here's an example. I didn't try this on an actual iphone which would be required to test the vibration, but it should work provided you add the AudioToolbox framework to your project, and of course your XIB file has the necessary connections:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (retain, nonatomic) IBOutlet UILabel *numberLabel;
- (IBAction)addNumber:(id)sender;
- (IBAction)subtractNumber:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#import "AudioToolbox/AudioServices.h"
#interface ViewController ()
{
int count;
}
#end
#implementation ViewController
#synthesize numberLabel;
- (void)viewDidLoad
{
count = 0;
[self updateCount];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setNumberLabel:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)dealloc
{
[numberLabel release];
[super dealloc];
}
- (IBAction)addNumber:(id)sender
{
if(count >= 999) {
return [self vibrate];
}; // ignore numbers larger than 999
count++;
[self updateCount];
}
- (IBAction)subtractNumber:(id)sender
{
if(count <= -35) {
return [self vibrate];
}; // ignore numbers less than -35
count--;
[self updateCount];
}
-(void)updateCount
{
NSString *countStr = [[NSString alloc] initWithFormat:#"%d",count];
[self.numberLabel setText:countStr];
[countStr release];
}
-(void)vibrate
{
NSLog(#"I'm vibrating");
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
#end
Hi i am designing a basic iPhone/iPad app that has a UINavigationController. The user clicks on the table row and it opens up a video in full screen. This works well and plays the video. however when you click on the navigation bar to go back to the table on the rootViewController the video keeps playing the audio in the background. Any ideas?
// RevoLix_HDAppDelegate.h
// RevoLix HD
//
// Created by Rob Hartley on 8/6/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import <UIKit/UIKit.h>
#class UrologyViewController;
#interface RevoLix_HDAppDelegate : NSObject <UIApplicationDelegate> {
UrologyViewController *urologyViewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
RevoLix_HDAppDelegate.m
// RevoLix HD
//
// Created by Rob Hartley on 8/6/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "RevoLix_HDAppDelegate.h"
#import "PlayerViewController.h"
#import "UrologyViewController.h"
#implementation RevoLix_HDAppDelegate
#synthesize window=_window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
//PlayerViewController *vc = [[PlayerViewController alloc] init];
//[[self window]setRootViewController:vc];
urologyViewController = [[UrologyViewController alloc] init];
//create an instance of a UINavigationController, its stack contains only itemsViewController
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:urologyViewController];
[urologyViewController release];
[[self window]setRootViewController:navController];
[navController release];
[_window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
/*
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
*/
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
/*
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
*/
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
/*
Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
*/
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/
}
- (void)applicationWillTerminate:(UIApplication *)application
{
/*
Called when the application is about to terminate.
Save data if appropriate.
See also applicationDidEnterBackground:.
UrologyViewController.h
// RevoLix HD
//
// Created by Rob Hartley on 8/7/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "PlayerViewController.h"
# class PlayerViewController;
#interface UrologyViewController : UITableViewController {
NSMutableArray *allVideos;
}
#end
UrologyViewController.m
// RevoLix HD
//
// Created by Rob Hartley on 8/7/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "UrologyViewController.h"
#import "UrologyVideos.h"
#import "PlayerViewController.h"
#implementation UrologyViewController
- (id)init
{
self = [super initWithStyle:UITableViewStyleGrouped];
if (self) {
[[self navigationItem] setTitle:#"Urology"];
}
allVideos = [[NSMutableArray alloc] init];
[allVideos addObject:[UrologyVideos fieldVideo]];
[allVideos addObject:[UrologyVideos strictureVideo]];
return self;
}
/*- (id)initWithStyle:(UITableViewStyle)style
{
return [self init];
}*/
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
int numberOfRows = [allVideos count];
return numberOfRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//create an instance of UITableViewCell, with default appearance
UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"UITableViewCell"] autorelease];
//set the text on the cell with the title of the video that is at the nth idex of possessions, where n = row this cell will appear in on the tableview
[[cell textLabel] setText:[[allVideos objectAtIndex:[indexPath row]] videoTitle]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
PlayerViewController *playerViewController = [[[PlayerViewController alloc] init] autorelease];
// Give detail view controller a pointer to the possession object in this row
[playerViewController setSelectVideo:[allVideos objectAtIndex:[indexPath row]]];
// Push it onto the top of the navigation controller's stack
[[self navigationController] pushViewController:playerViewController
animated:YES];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
-(void)dealloc
{
[allVideos release];
[super dealloc];
}
#end
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#class UrologyVideos;
#interface PlayerViewController : UIViewController {
MPMoviePlayerViewController *moviePlayer;
UrologyVideos *selectVideo;
}
#property (nonatomic,retain) UrologyVideos *selectVideo;
#end
PlayerViewController.m
// RevoLix HD
//
// Created by Rob Hartley on 8/6/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "PlayerViewController.h"
#import "UrologyVideos.h"
#implementation PlayerViewController
#synthesize selectVideo;
- (id)init
{
return [super initWithNibName:#"PlayerViewController" bundle:nil];
}
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle
{
return [self init];
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[self navigationItem] setTitle:[selectVideo videoTitle]];
}
- (void) viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *moviePath = [[NSBundle mainBundle] pathForResource:[selectVideo videoFileName] ofType:#"m4v"];
NSURL *movieURL = [NSURL fileURLWithPath:moviePath];
moviePlayer = [[MPMoviePlayerViewController alloc] initWithContentURL:movieURL];
[[self view] addSubview:[moviePlayer view]];
float halfHeight = [[self view]bounds].size.height;
float width = [[self view] bounds].size.width;
[[moviePlayer view] setFrame:CGRectMake(0, 0, width, halfHeight)];
}
- (void)dealloc
{
[selectVideo release];
[moviePlayer release];
[MPMoviePlayerViewController release];
[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)viewDidUnload
{
[super viewDidUnload];
[selectVideo release];
selectVideo = nil;
[moviePlayer release];
moviePlayer = nil;
[MPMoviePlayerViewController release];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
#end
Apple explains that video playback may be set to use "your application’s audio session by default, but can be configured to use a system-supplied audio session."
If you check the audio documentation, you will find you can setup behavior to stop or keep playing music if application goes to background (typically, to obtain the iPod player behavior). That's where you should set the proper application variable.