MPMoviePlayerController in iOS 8 navigationBar remain visible after exiting Full Screen - objective-c

For playing Video I am using MPMoviePlayerController,my app supports only portrait mode but For playing Video I need to support Landscape too. Every thing is working fine till iOS 7.x. In iOS 8.0, After exiting Full screen there remains a navigation bar. Please refer below image.
In App delegate, under supportedInterfaceOrientationsForWindow, following is used.
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if (self.forceLandscapeRight) {
return UIInterfaceOrientationMaskAll;
}
return UIInterfaceOrientationMaskPortrait;
}
Noe in my controller class for initiating MPMoviePlayerController:
[self.mpMoviePlayerContr setContentURL:object];
[theMoviPlayer prepareToPlay];
self.mpMoviePlayerContr.controlStyle = MPMovieControlStyleEmbedded;
self.mpMoviePlayerContr.scalingMode = MPMovieScalingModeAspectFit;
[self.mpMoviePlayerContr play];
self.mpMoviePlayerContr.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
self.mpMoviePlayerContr.shouldAutoplay = YES;
[theMoviPlayer setFullscreen:false animated:YES];
Also, I have some notification for entering and exiting Full screen.
- (void) moviePlayerWillEnterFullscreenNotification:(NSNotification*)notification {
ED_APPDelegate.forceLandscapeRight = YES;
[self.mpMoviePlayerContr setFullscreen:YES animated:YES];
[self.mpMoviePlayerContr play];
}
- (void) moviePlayerWillExitFullscreenNotification:(NSNotification*)notification {
ED_APPDelegate.forceLandscapeRight = NO;
[self.mpMoviePlayerContr setFullscreen:NO animated:YES];
[self.mpMoviePlayerContr play];
}
- (void)orientationChanged:(NSNotification *)notification
{
UIDeviceOrientation currentOrientation = [[UIDevice currentDevice] orientation];
ED_APPDelegate.forceLandscapeRight = NO;
if (currentOrientation == UIDeviceOrientationLandscapeLeft ||currentOrientation == UIDeviceOrientationLandscapeRight ) {
[self.mpMoviePlayerContr setFullscreen:YES animated:YES];
[self.mpMoviePlayerContr play];
ED_APPDelegate.forceLandscapeRight = YES;
} else {
if (self.mpMoviePlayerContr.playbackState == MPMoviePlaybackStatePaused) {
[self.mpMoviePlayerContr play];
}
[self.mpMoviePlayerContr setFullscreen:NO animated:YES];
ED_APPDelegate.forceLandscapeRight = NO;
}
}
Above code is working fine in iOS 7.x, but have issue in iOS 8.0.

Related

self.splitViewController.navigationController pushViewController can't work

UIsplitViewController can't pushViewController, only the master view or only detail view can pushViewController inside it's view. I wan't to push a new view int the current UIsplitViewController. The UIsplitViewController is in a UITabBarController.
How to solve it?
self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryHidden;
[MLTool pushView:self newView:USER_VIEW];
+(id)pushView:(UIViewController*)view newView:(NSString*)newView{
UIViewController *svc = [view.storyboard instantiateViewControllerWithIdentifier:newView];
//NSAssert(svc, #"pushView nil");
[view.navigationController pushViewController:svc animated:YES];
return svc;
}
- (void)viewWillAppear:(BOOL)animated{
SplitProductView* split=(SplitProductView* )self.splitViewController;
[split resetSplit: [[UIApplication sharedApplication] statusBarOrientation]];
//self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay
}
-(void)resetSplit :(UIInterfaceOrientation)toInterfaceOrientation {
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
//TODOX:iphone
if (isPad)
{
if(UIInterfaceOrientationIsPortrait(toInterfaceOrientation)){
self.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;
}
else{
//if (self.displayMode == UISplitViewControllerDisplayModePrimaryOverlay)
{//ios的bug,必须这三行,不然左边有黑边
// if (SYSTEM_VERSION_MORE_THAN(#"8.0"))
{
self.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryHidden;
self.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;
self.preferredDisplayMode = UISplitViewControllerDisplayModeAutomatic;
}
}
}
}
}
}

SLComposeViewController cancel doesn't close the VC from one tap

I have problem with the attached codе. It have to close the currently displayed modalViewController when the user tap once on the cancel button instead of twice as it do now.
Code
- (BOOL)isIOS6 {
BOOL native = YES;
if([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0f){
native = NO;
}
return native;
}
- (void)twitterShare {
DLog(#"is ios6: %d", [self isIOS6]);
if ([self isIOS6]) {
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter])
{
NSString *textToShare = #"Test";
SLComposeViewController *twitterComposeViewController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
twitterComposeViewController.completionHandler = ^(SLComposeViewControllerResult result){
DLog(#"result: %d", result);
if (result == 1) {
Dlog(#"Shared");
[[NSNotificationCenter defaultCenter] postNotificationName:#"notitificationName" object:nil];
DLog(#"Sended provide bonus notification");
[self disableButtonWithTag:GrowthButtonTwitterConnectTag];
DLog(#"disable that button.");
} else {
Dlog(#"canceled...");
}
};
[twitterComposeViewController setInitialText:textToShare];
[self presentViewController:twitterComposeViewController animated:YES completion:nil];
} else {
DLog(#"Twitter not available");
}
} else {
// iOS 5 not supported message
[[[[UIAlertView alloc] initWithTitle:NSLocalizedString(#"ATTENTION", nil)
message:NSLocalizedString(#"IOS6_OR_ABOVE_FEATURE", nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(#"OK", nil)
otherButtonTitles:nil, nil] autorelease] show];
}
}
I've manage to fix that issue with the following code:
tweetSheet.completionHandler = ^(SLComposeViewControllerResult result) {
switch(result) {
// This means the user cancelled without sending the Tweet
case SLComposeViewControllerResultCancelled:
break;
// This means the user hit 'Send'
case SLComposeViewControllerResultDone:
[[NSNotificationCenter defaultCenter] postNotificationName:#"kGrowthProvideTwitterBonus" object:nil];
DLog(#"Sended provide bonus notification");
[self disableButtonWithTag:TTGrowthButtonTwitterConnectTag];
break;
}
// dismiss the Tweet Sheet
dispatch_async(dispatch_get_main_queue(), ^{
[self dismissViewControllerAnimated:NO completion:^{
NSLog(#"Tweet Sheet has been dismissed.");
}];
});
};

AVQueuePlayer is pausing but play icon won't disappear

I'm building an application that uses an AVQueuePlayer to stream audio. I have my AVAudioSession set up with the category AVAudioSessionCategoryPlayback and I'm able to receive events from remoteControlReceivedWithEvent:. However, when I pause my audio session, the icon in the status bar does not disappear, nor does the pause/play button in the App Switcher change to play. The audio pauses, but the icons never change. Do you know why this might be happening?
I also use an MPMusicPlayerController to play music from the iPod music player. Both players are always initialized, however only one plays at a time. When the app opens, if I play something from the MPMusicPlayerController first, the AVQueuePlayer doesn't have this pause conflict anymore. It only has this problem when you play from the AVQueuePlayer first. I included the code to show you what I'm doing.
FYI- My MPMusicController is self.musicPlayer. My AVQueuePlayer is self.radioPlayer. After pausing, the status of my AVQueuePlayer is AVPlayerStatusReadyToPlay.
- (void)viewDidLoad {
[super viewDidLoad];
self.musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
self.musicPlayer.nowPlayingItem = self.currentSong;
self.musicPlayer.shuffleMode = MPMusicShuffleModeSongs;
self.musicPlayer.repeatMode = MPMusicRepeatModeAll;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:nil error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(radioItemDidReachEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:[_radioPlayer currentItem]];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}
- (void)viewWillDisappear:(BOOL)animated
{
[self resignFirstResponder];
if (self.source == LIBRARY)
{
[self.parentDelgate reloadInformation];
}
}
- (void)viewDidAppear:(BOOL)animated
{
if (self.source == RADIO)
{
// Code that sets the URLs for the AVQueuePlayer
[self initializeMusicPlayer];
[self prepareRadioPlayer];
}
else if ( self.source == LIBRARY ) {
if ( self.currentSong != self.musicPlayer.nowPlayingItem || self.playlist != nil)
{
[self initializeMusicPlayer];
self.musicPlayer.nowPlayingItem = self.currentSong;
}
}
}
- (void)initializeMusicPlayer {
if ( self.source == LIBRARY )
{
[self.musicPlayer setQueueWithItemCollection:[MPMediaItemCollection collectionWithItems:(NSArray *)self.tracks]];
if ([self.radioPlayer rate] != 0.0)
[self.radioPlayer pause];
[self.musicPlayer play];
self.status = PLAYING;
}
else if ( self.source == RADIO )
{
if ( self.musicPlayer.playbackState == MPMusicPlaybackStatePlaying )
[self.musicPlayer pause];
}
}
- (IBAction)pausePressed:(UIButton *)sender {
if ( self.source == LIBRARY )
{
[self.musicPlayer pause];
}
else if (self.source == RADIO)
{
[self.radioPlayer pause];
}
[self onStatePaused];
}
- (void)onStatePaused {
// UI Stuff
}
- (void)endSession {
[self.musicPlayer stop];
[self.radioPlayer pause];
[self.radioPlayer removeAllItems];
// Present different view
}
Any ideas?
I figured out the problem. I was adding multiple instances of observers to the AVQueuePlayer/AVPlayerItems which was interfering with this.

UISplitViewController: How to present popover?

I've a UISplitViewController which is a UISplitViewControllerDelegate with the following delegate method:
splitViewController:willHideViewController:withBarButtonItem:forPopoverController:
When the iPad is started in Portrait, I would like the Popover from the SplitView to be visible. How can I do that?
I've tried the following code:
- (void)splitViewController:(UISplitViewController *)svc
willHideViewController:(UIViewController *)aViewController
withBarButtonItem:(UIBarButtonItem *)barButtonItem
forPopoverController:(UIPopoverController *)pc
{
//setting the barButtonItem in the toolbar in the detail view.
[pc presentPopoverFromBarButtonItem:barButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:NO];
}
But the above code gives me the following error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIPopoverController presentPopoverFromRect:inView:permittedArrowDirections:animated:]: Popovers cannot be presented from a view which does not have a window.'
there only one problem, wrong place to call presentPopover method, splitViewController:*WillHide*ViewController....... so, barButtonItem exist but not present on screen. i used next code and it worked for me.
For handle all cases u need to use 2 methods.
- (void)viewDidAppear:(BOOL)animated
{
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) {
if (self.view.window != nil) {
[_masterPopoverController presentPopoverFromRect:CGRectMake(0, 0, 1, 1) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:NO];
}
}
[super viewDidAppear:animated];
}
and
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
if (fromInterfaceOrientation == UIDeviceOrientationLandscapeLeft || fromInterfaceOrientation == UIDeviceOrientationLandscapeRight) {
if (self.view.window != nil) {
[_masterPopoverController presentPopoverFromRect:CGRectMake(0, 0, 1, 1) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:NO];
}
}
}

how to remove prev next button from virtual keyboard IOS

i have use a UIWebview in IOS 5. I try to set contenteditable="true" to make uiwebview editable.
The screenshoot of my app is similar to an image in this link How do you remove the Next and Prev buttons from virtual keyboard in Sencha Touch / Phonegap application,
my problem is i want to remove this prev & next button from the keyboard, but i dont know how. Can some body help me?
thank you
This is an old answer and is no longer working on iOS 9. For an updated solution, see my answer here.
It is a gray-area, but certainly possible.
See here: http://ios-blog.co.uk/iphone-development-tutorials/rich-text-editing-a-simple-start-part-1/
Register for notification on keyboard showing:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
Then:
- (void)keyboardWillShow:(NSNotification *)note {
[self performSelector:#selector(removeBar) withObject:nil afterDelay:0];
}
- (void)removeBar {
// Locate non-UIWindow.
UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
if (![[testWindow class] isEqual:[UIWindow class]]) {
keyboardWindow = testWindow;
break;
}
}
// Locate UIWebFormView.
for (UIView *possibleFormView in [keyboardWindow subviews]) {
// iOS 5 sticks the UIWebFormView inside a UIPeripheralHostView.
if ([[possibleFormView description] rangeOfString:#"UIPeripheralHostView"].location != NSNotFound) {
for (UIView *subviewWhichIsPossibleFormView in [possibleFormView subviews]) {
if ([[subviewWhichIsPossibleFormView description] rangeOfString:#"UIWebFormAccessory"].location != NSNotFound) {
[subviewWhichIsPossibleFormView removeFromSuperview];
}
}
}
}
}
Remove the empty area.
- (void)removeBar {
// Locate non-UIWindow.
UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
if (![[testWindow class] isEqual:[UIWindow class]]) {
keyboardWindow = testWindow;
break;
}
}
// Locate UIWebFormView
for (UIView *possibleFormView in [keyboardWindow subviews]) {
if ([[possibleFormView description] hasPrefix:#"<UIPeripheralHostView"]) {
for (UIView* peripheralView in [possibleFormView subviews]) {
// hides the backdrop (iOS 7)
if ([[peripheralView description] hasPrefix:#"<UIKBInputBackdropView"]) {
//skip the keyboard background....hide only the toolbar background
if ([peripheralView frame].origin.y == 0){
[[peripheralView layer] setOpacity:0.0];
}
}
// hides the accessory bar
if ([[peripheralView description] hasPrefix:#"<UIWebFormAccessory"]) {
// remove the extra scroll space for the form accessory bar
UIScrollView *webScroll;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0) {
webScroll = [[self webView] scrollView];
} else {
webScroll = [[[self webView] subviews] lastObject];
}
CGRect newFrame = webScroll.frame;
newFrame.size.height += peripheralView.frame.size.height;
webScroll.frame = newFrame;
// remove the form accessory bar
[peripheralView removeFromSuperview];
}
// hides the thin grey line used to adorn the bar (iOS 6)
if ([[peripheralView description] hasPrefix:#"<UIImageView"]) {
[[peripheralView layer] setOpacity:0.0];
}
}
}
}
}
It's the inputAccessoryView for UIWebBrowserView (inner UIWebView), you can hack it.
Here is an example: https://gist.github.com/bjhomer/2048571
I found the solution for iOS 8. You can check it here:
-(void) removeKeyboard {
UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
if (![[testWindow class] isEqual : [UIWindow class]]) {
keyboardWindow = testWindow;
break;
}
}
// Locate UIWebFormView.
for (UIView *possibleFormView in [keyboardWindow subviews]) {
if ([[possibleFormView description] hasPrefix : #"<UIInputSetContainerView"]) {
for (UIView* peripheralView in possibleFormView.subviews) {
for (UIView* peripheralView_sub in peripheralView.subviews) {
// hides the backdrop (iOS 8)
if ([[peripheralView_sub description] hasPrefix : #"<UIKBInputBackdropView"] && peripheralView_sub.frame.size.height == 44) {
[[peripheralView_sub layer] setOpacity : 0.0];
}
// hides the accessory bar
if ([[peripheralView_sub description] hasPrefix : #"<UIWebFormAccessory"]) {
for (UIView* UIInputViewContent_sub in peripheralView_sub.subviews) {
CGRect frame1 = UIInputViewContent_sub.frame;
frame1.size.height = 0;
peripheralView_sub.frame = frame1;
UIInputViewContent_sub.frame = frame1;
[[peripheralView_sub layer] setOpacity : 0.0];
}
CGRect viewBounds = peripheralView_sub.frame;
viewBounds.size.height = 0;
peripheralView_sub.frame = viewBounds;
}
}
}
}
}
}
You may try and improve this. try call this function inside Your UIKeyboardDidShowNotification event handler.
Hope this helps...
This is the level of views in accessory:
(UIWebFormAccessory) -> (UIToolbar) -> (UIImageView,UIToolbarButton,UIToolbarButton)