I have a App works well on iOS 4.3.3. But I found there are some problems on iOS 5. This App plays mp3 files by avaudioplayer and the remote control does not work well on iOS 5.
There are four view controllers in this App. I add following codes on each view controller in order to realize the function of remote control. The problem is, when the view controller is first time to open. The remote control button works well, even the app run in background or lock the screen. But when I click anther view controller and go back the previous on, the remote controller does not work anymore. But canBecomeFirstResponder function was called every time.
I even try to put
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
in delegate function
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
It not work.
I don't understand why this is happening. It tortured me for few days.
Is there better way to realize remote control function in multiple view controllers?
BTW, I added the UIBackgroundModes audio key to the info.plist. And this App works well well in background.
Any help will be appreciated.
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}
- (void)viewWillAppear:(BOOL)animated {
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];
}
- (BOOL) canBecomeFirstResponder {
NSLog(#"Can be first responder!");
return YES;
}
- (void)remoteControlReceivedWithEvent:(UIEvent *)event
{
if (event.subtype == UIEventSubtypeRemoteControlTogglePlayPause) {
NSLog(#"UIEventSubtypeRemoteControlTogglePlayPause");
[self playAndpause:nil];
}
}
Related
I'm having problem to control the iPhone controls with my avplayer.
if I put the function
- (void)remoteControlReceivedWithEvent:(UIEvent *)event
in the view controller that responsible for playing the function called but only if I i'm going to background in the current view controller.
if i'm going to background from other view controller the function never called.
that's why i want to put it in the app delegate.
I tried Becomefirstresponse and to put the function in every view controller but it did help.
also I call
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
in the
-(void)applicationWillResignActive:(UIApplication *)application
thanks
I have used below code to iPhone Control -
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
Used to get register for listening the remote control.
Once done remove it -
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];
make the App canBecomeFirstResponder-
- (BOOL)canBecomeFirstResponder {
return YES;
}
Used delegate method to handle iPhone control, like play and pause while doble tap on the home button
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
//if it is a remote control event handle it correctly
if (event.type == UIEventTypeRemoteControl) {
if (event.subtype == UIEventSubtypeRemoteControlPlay) {
[audioPlayer play];
NSLog(#"play");
} else if (event.subtype == UIEventSubtypeRemoteControlPause) {
[audioPlayer stop];
NSLog(#"pause");
} else if (event.subtype == UIEventSubtypeRemoteControlTogglePlayPause) {
NSLog(#"toggle");
}
}
}
In my case i am able to handle play and pause.Please let know if any thing wrong.
You can move the function up the responder chain, to UIApplication subclass. This way, it will always be there to catch the event.
This kind of event is ignored in common UI and controller classes, so it travels up to the bottom of responder chain, where your app delegate and the the application itself reside.
As noted here, UIApplication's delegate is not part of responder chain (I was wrong here). UIApplication is there, so is root UIWidow, all the views in chain and corresponding UIViewControllers.
Hint: becomeFirstResponder must be called from within viewDidAppear, not viewWillAppear...
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self becomeFirstResponder];
}
just to test it I enabled the activity indicator of the status bar as follows:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible: TRUE];
//...
}
I never disable the indicator so it should always be visible, but it isn't. It is visible in the iPhone Simulator but not on the device. Why?
Please not that the application is not active when a call is made to didFinishLaunchingWithOptions. You should move this to the viewDidLoad method instead. Thus the code should look like this:
- (void)viewDidLoad {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
// Some other code goes here...
[super viewDidLoad];
}
Or you could put this code anywhere else where the view has been loaded. Do not forget to stop it once the data has been loaded.
I want to show the status bar in my app in all views but one. I have tried modifying the 'status bar is initially hidden' in the plist, i have tried:
[[UIApplication sharedApplication] setStatusBarHidden:YES];
That hides the bar but leaves an ugly blue box where the status bar was (which isn't part of my view, there's nothing blue on there).
I have also tried altering the layout wants full screen and status bar settings in the 'interface builder' bit of Xcode 4.2.
Any suggestions?
EDIT - SORT OF SOLUTION:
I have done it by including:
-(void)viewWillDisappear:(BOOL)animated{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
-(void)viewDidAppear:(BOOL)animated{
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}
on every single page that I want the status bar to be on.
It still looks choppy and rubbish because the tab bar appears and reappears each time you switch a view. But i've had enough, worked on this stupid problem for about 5 hours now so this will have to do.
SECOND EDIT -
Fixed the choppyness by including setStatusBarHidden=NO in viewWillAppears. God knows how everything works but it does.
Try This one It will Run perfectly..
[[UIApplication sharedApplication] setStatusBarHidden:YES];
And in XIB set none option for the status bar.
for iOS 7.
Go to info.plist and add two attributes if not present. set "Status bar is initially hidden" to "YES" and set "UIViewControllerBasedStatusBarAppearance" to "NO". This will hide status bar for your app.
#pragma mark - Hide statusbar
-(void)hideStatusBar {
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
// iOS 7.0 or later
[self setNeedsStatusBarAppearanceUpdate];
#else
// less than 7
[[UIApplication sharedApplication] setStatusBarHidden:YES];
#endif
}
- (BOOL)prefersStatusBarHidden {
return YES;
}
If there is anyone looking for a solution where the above solution does not work (and there is still an annoying blue 20px gap at the top), try putting this in the viewWillAppear on the implementation file of the view controller that you would like the status bar to be hidden.
self.navigationController.navigationBar.frame = CGRectOffset(self.navigationController.navigationBar.frame, 0.0, -20.0);
That literally took me 12 hours or so to fix, and that was the solution, so now i'm spreading the word in case anyone else has this annoying issue.
Kartik's solution worked for me.
[[UIApplication sharedApplication] setStatusBarHidden:YES];
I added this to viewWillAppear: instance method.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
self.webView.scalesPageToFit = YES;
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.google.co.uk"]]];
}
And I spent ages on this too. Using Xcode 4.2, iOS5 sim.
But when I first implemented it, the annoying "space" at the top was there. I selected the View Controller in the storyboard and set the properties as follows:
Size: Full Screen
StatusBar: None
everything else inferred.
I checked wants full screen.
Voila, it all worked fine.
I know this is an old question but none of this answers works for me, so this is how it works for me to hide the status bar in a single viewController
First in your parentViewController you have to set:
- (UIViewController *)childViewControllerForStatusBarHidden {
if ( hideStatusBarViewController ) {
return hideStatusBarViewController;
}
return nil
}
It only returns the child view controller when its created otherwise nil is the default. When you add your hideStatusBarViewController you must call
[self setNeedsStatusBarAppearanceUpdate];
on the parentViewController, this function forces to read childViewControllerForStatusBarHidden. Finally in hideStatusBarViewController you must set
- (BOOL)prefersStatusBarHidden {
return YES;
}
Its the only solution that works for me. I hope it help somebody.
I would suggest you a different approach: insert that view onto the application's window:
YourUIAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate.window insertSubview:self.yourView atIndex:([[appDelegate.window subviews]count])];
That way it will show over the status bar
I hope it helps you
This is solution if you want to hide status bar on a single view
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[self.view sizeToFit];
}
Here is a snippet of code that might help. When the view loads show the status bar, when you leave the view hide it again.
-(void)viewWillAppear:(BOOL)animated {
if([[UIApplication sharedApplication] respondsToSelector:#selector(setStatusBarHidden: withAnimation:)])
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
else
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:YES];
}
-(void)viewWillDisappear:(BOOL)animated {
if([[UIApplication sharedApplication] respondsToSelector:#selector(setStatusBarHidden: withAnimation:)])
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];
else
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];
}
The [[UIApplication sharedApplication] setStatusBarHidden:BOOL]; is enough, but:
Remember to set it back to NO before leaving the view or the page you return to will likely have the Nav Bar under the status bar.
Make sure that you set both status bar hide and show in the view in which you want the status bar hidden. I did the switch off in the viewDidLoad method, and - crucially - the switch back on in the viewWillDisappear:animated method. Any later and you're in for trouble.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
remoteControlReceivedWithEvent in AVAudio is not being called
I am trying to get remote control events to start/stop some audio my app is playing, but -remoteControlReceivedWithEvent: is not getting called. My app has a tab bar that switches among multiple views, if that makes any difference.
The view controller for each view implements the setup per Apple docs on using remote control events (https://developer.apple.com/iphone/library/documentation/EventHandling/Conc
eptual/EventHandlingiPhoneOS/RemoteControl/RemoteControl.html#//apple_ref/d
oc/uid/TP40009541-CH7-SW1). I have copied those bits below for reference.
Any ideas on why -remoteControlReceivedWithEvent: is not getting called? Should I be implementing it on another object in the responder chain?
steve
- (BOOL) canBecomeFirstResponder
{
return YES;
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}
- (void) viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];
}
Did you add the UIBackgroundModes audio key to the info.plist? See the docs.
I need to hide something on the screen when the user has activates the application by switching it to the foreground.
I have tried inserting my code within applicationDidBecomeActive or applicationWillEnterForeground and although it runs OK the old screen with the text I want to hide is displayed momentarily.
How can I hide the field before the screen is redrawn?
Thanks
iphaaw
I think the problem is, iOS will capture a screenshot from your app in the moment it goes to the background, so the animation will work in an instant.
The only way in my opinion to do this is to hide / cover your view in moment the app goes to the background.
Write some code in applicationWillResignActive: to 'hide' whatever you need to hide.
I faced a similar situation but, instead of hiding, I wanted to show a block code screen to grant access. Anyway I think that the solution also applies to your needs.
I often implement a custom base view controller in my iOS applications. So instead of dealing with applicationDidBecomeActive: or applicationWillResignActive: I setup this view controller to listen for the equivalent notifications:
#interface BaseViewController : UIViewController
- (void)prepareForGrantingAccessWithNotification:(NSNotification *)notification;
- (void)grantAccessWithNotification:(NSNotification *)notification;
#end
#implementation BaseViewController
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self addNotificationHandler:#selector(grantAccessWithNotification:)
forNotification:UIApplicationDidBecomeActiveNotification];
[self addNotificationHandler:#selector(prepareForGrantingAccessWithNotification:)
forNotification:UIApplicationWillResignActiveNotification];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)prepareForGrantingAccessWithNotification:(NSNotification *)notification {
// Hide your views here
myCustomView.alpha = 0;
// Or in my case, hide everything on the screen
self.view.alpha = 0;
self.navigationController.navigationBar.alpha = 0;
}
- (void)grantAccessWithNotification:(NSNotification *)notification {
// This is only necessary in my case
[self presentBlockCodeScreen];
self.view.alpha = 1;
self.navigationController.navigationBar.alpha = 1;
...
}
#end