Positioning MPMoviePlayerController view - ios

I got a little problem when trying to position the view of a MPMoviePlayerController. Here is my code so far.
MPMoviePlayerController *moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:[[NSURL alloc] initFileURLWithPath:URL]];
moviePlayerController.shouldAutoplay = NO;
[moviePlayerController.view setFrame:CGRectMake((CGFloat)vidX, (CGFloat)vidY, (CGFloat)vidWidth, (CGFloat)vidHeight)];
//Find ApplicationWindow
id delegate = [[UIApplication sharedApplication] delegate];
UIWindow * win= [delegate window];
[win addSubview:moviePlayerController.view];
The code works fine and the movie is shown. However the positioning is making me crazy. When I change the width or the height of the view I expect the view to stay at the exact x and y position and only width and height should change. But this is not the case. When I change vidWidth or vidHeight and leave vidX and vidY untouched the origin of the view jumps to another point, which makes it extremely hard to position the video view.
Any help will be appreciated.
Best Regards,
Rambazamba

Related

iOS - MPMoviePlayerController resets view transform on repeat

Using an MPMoviePlayerController.view as a background (think spotify). A user can tap login or signup and they are taken to the appropriate viewController, which has a clear background so that the moviePlayer.view remains as the background (i.e., user continues to see the video regardless of the currently active viewController) throughout the flow.
On some viewControllers the form needs to be lifted up so that the keyboard doesn't cover the field. I'm doing this using a transform.
The background video of the moviePlayer is set to repeat, so the video is on a continuous loop. Each time the video resets (video status goes from 1 to 2 - paused to playing) the transform resets in the child viewControllers. My initial thought was that the view was being redrawn, but this doesn't appear to be the case based on logs (I put nslogs in the drawRect of the views but it's only ever called once at instantiation).
Has anyone come across this?
My setup in the root viewController:
// lazy load moviePlayer
-(MPMoviePlayerController *)moviePlayer
{
if (_moviePlayer) return _moviePlayer;
NSURL *videoURL = [[NSBundle mainBundle] URLForResource:#"resources.bundle/videos/auth_bg" withExtension:#"mp4"];
_moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
_moviePlayer.controlStyle = MPMovieControlStyleNone;
_moviePlayer.scalingMode = MPMovieScalingModeAspectFill;
_moviePlayer.repeatMode = MPMovieRepeatModeOne;
_moviePlayer.shouldAutoplay = true;
return _moviePlayer;
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.moviePlayer.view.frame = self.view.frame;
self.moviePlayer.view.hidden = false;
// 'still' is an imageView of the first frame to show while video loading
[self.navigationController.view insertSubview:self.moviePlayer.view aboveSubview:still];
}
I suspect this has to do with Autolayout -- I found a few other questions where views were being reset (one example here: https://stackoverflow.com/a/17849584/1542275) ... My solution was to adjust the layout constraint constants as opposed to transforming the view coordinates. Things are now staying put.
All of that said, I'm still not sure why the video restart is resetting the transforms.

Key-Frame Animation appears fuzzy when moving Frames?

I use JazzHands to create a key frame based animation in a UIScrollView.
Here is an example. Look at the view at the top. When you move from page to page. While the animation is running the view at the top is slightly moving from left to right. The animation appears a bit fuzzy.
Here is the code taken from the example here:
IFTTTFrameAnimation *titleView1FrameAnimation = [IFTTTFrameAnimation new];
titleView1FrameAnimation.view = self.titleView1;
[self.animator addAnimation:titleView1FrameAnimation];
[titleView1FrameAnimation addKeyFrame:[[IFTTTAnimationKeyFrame alloc] initWithTime:timeForPage(1)
andFrame:self.titleView1.frame]];
[titleView1FrameAnimation addKeyFrame:[[IFTTTAnimationKeyFrame alloc] initWithTime:timeForPage(2)
andFrame:CGRectOffset(self.titleView1.frame, timeForPage(2), 0)]];
[titleView1FrameAnimation addKeyFrame:[[IFTTTAnimationKeyFrame alloc] initWithTime:timeForPage(3)
andFrame:CGRectOffset(self.titleView1.frame, timeForPage(3), 0)]];
[titleView1FrameAnimation addKeyFrame:[[IFTTTAnimationKeyFrame alloc] initWithTime:timeForPage(4)
andFrame:CGRectOffset(self.titleView1.frame, timeForPage(4), 0)]];
When running the demo take a look at the part marked with red in the following screenshot:
Edit: Here is the code containing this problem: https://github.com/steffimueller/Intro-Guide-View-for-Talk.ai
How can I make the animation running smooth and less fuzzy?
This is due to the frame rate in the JazzHands IFTTTAnimatedScrollViewController being set for non-retina displays. You need to double the number in timeForPage, and also use double the number of the contentOffset in animate, but use the original non-doubled values of timeForPage in places where you were using that for laying out the positions of views instead of using it for the animation time.
Here's a Gist of the changes you'd have to make to your example to get it working. Fixed Demo Gist
You need this method for setting the animation times:
#define timeForPage(page) (NSInteger)(self.view.frame.size.width * (page - 1) * 2.0)
And this one for setting the centers of your views based on the page dimensions:
#define centerForPage(page) (NSInteger)(self.view.frame.size.width * (page - 1))
Then you need to override the scrollViewDidScroll: method in IFTTTAnimatedScrollViewController to use double the numbers it's currently using.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
[self.animator animate:(NSInteger)(scrollView.contentOffset.x * 2)];
}
We'll work on getting the JazzHands demo updated!
Before you start your animation call:
view.layer.shouldRasterize = YES; (seems that you are using objective-c so I put YES here, for swift should be true)
As soon as the animation is finished call
view.layer.shouldRasterize = NO; (seems that you are using objective-c so I put NO here, for swift should be false)
You should always use it when you animating a view
You can see more details about it in the WWDC 2012 Polishing Your Interface Rotations video (paid developer subscription needed)
I hope that helps you!
[EDIT]
Every Time you call the method animate set shouldRasterize to YES before it, like in the example bellow:
titleView1FrameAnimation.view.layer.shouldRasterize = YES;
[self. titleView1FrameAnimation animate:scrollView.contentOffset.x];
I've messed around a bit with the code and it seems that keeping those top views in place while the scrollview is scrolling made it jiggle left and right.
What I did is take out the title view from the scroll view and add it to the view controller view.
You can see it in action here
Later edit:
To actually see what I've changed you can check the file differences in Git. Basically I moved your titleViews (titleView1, titleView2, etc) from the scrollView to the view controller's view (so basically I've replaced all the lines that were like this:
[self.scrollView addSubView:self.titleView1]
to something like this:
[self.view addSubView:self.titleView1]
After that I've also took out the keyframe animations that were keeping your title views in place since they were not moving with the scrollview anymore. Practically I've deleted all the lines that were adding a frame animation to your titleviews from each configurePageXAnimation.
2nd question answer:
Say your screenshot view is called screenshotView. You can go ahead and create it like this:
UIImageView *screenshotView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"ScreenshotImage"]];
[self.view addSubview:screenshotView];
self.screenshotView = screenshotView;
[self.screenshotView setCenter:CGPointMake(self.view.center.x + self.view.bounds.size.width, <#yourDesiredY#>)];
And animate it like this:
//screenshotView frame animation
IFTTTFrameAnimation *screenshotViewFrameAnimation = [IFTTTFrameAnimation new];
screenshotViewFrameAnimation.view = self.screenshotView;
[self.animator screenshotViewFrameAnimation];
[screenshotViewFrameAnimation addKeyFrame:[[IFTTTAnimationKeyFrame alloc] initWithTime:timeForPage(1) andFrame:self.screenshotView.frame]];
[screenshotViewFrameAnimation addKeyFrame:[[IFTTTAnimationKeyFrame alloc] initWithTime:timeForPage(2) andFrame:CGRectOffset(self.screenshotView.frame, -self.scrollView.bounds.size.width, 0.0)]];
[screenshotViewFrameAnimation addKeyFrame:[[IFTTTAnimationKeyFrame alloc] initWithTime:timeForPage(3) andFrame:CGRectOffset(self.screenshotView.frame, -self.scrollView.bounds.size.width, 0.0)]];
[screenshotViewFrameAnimation addKeyFrame:[[IFTTTAnimationKeyFrame alloc] initWithTime:timeForPage(4) andFrame:CGRectOffset(self.screenshotView.frame, -self.scrollView.bounds.size.width * 2, 0.0)]];

bad orientation in screen with multiple viewcontrollers/ views in iOS 7, landscape only (iOS 8 is fine)

I'm using TheSidebarController to implement add a sliding menu into an iOS application. This is the library I'm using, but I've found the same issue in other libraries, like ECSlidingViewController, etc. They essentially work by adding multiple view controllers onto a containing view controller, nothing too crazy.
The issue is, when you make the app a landscape app, all the screens in the container- the menu, the content screen- seem to think they're in portrait mode, and get cut off half way. You can see the issue in this screenshot where the table is cut off:
http://imgur.com/xD5MUei
I've been trying to get this to work in any way I can, and no luck.
The library I'm using + example project can be found here:
https://github.com/jondanao/TheSidebarController
Any help is greatly appreciated :)
EDIT: people are saying I can stretch the table out to make it look normal, but this just masks the underlying problem, which is the app and/or the screens still think they're in portrait orientation. As a quick example, if I take the example project, and in LeftViewController substitute the following code:
- (void)dismissThisViewController
{
UIViewController* vc = [[UIViewController alloc] init];
UINavigationController* pulldown = [[UINavigationController alloc] initWithRootViewController:vc];
pulldown.view.frame = CGRectMake(pulldown.view.frame.origin.x, -[[UIApplication sharedApplication] delegate].window.frame.size.height,
pulldown.view.frame.size.width, pulldown.view.frame.size.height);
[[[UIApplication sharedApplication] delegate].window addSubview:pulldown.view];
[UIView animateWithDuration:.5 animations:^{
pulldown.view.frame = CGRectMake(pulldown.view.frame.origin.x, 0,
pulldown.view.frame.size.width, pulldown.view.frame.size.height);
} completion:^(BOOL finished) {
;
}];
}
The viewcontroller comes in sideways, not from the top.
This was a strange one... I had to set the frame of the content view controller, which made sense, but then I had to reset it every time the content was refreshed:
- (void)setContentViewController:(UIViewController *)contentViewController
{
// Old View Controller
UIViewController *oldViewController = self.contentViewController;
[oldViewController willMoveToParentViewController:nil];
[oldViewController.view removeFromSuperview];
[oldViewController removeFromParentViewController];
// New View Controller
UIViewController *newViewController = contentViewController;
[self.contentContainerViewController addChildViewController:newViewController];
[self.contentContainerViewController.view addSubview:newViewController.view];
[newViewController didMoveToParentViewController:self.contentContainerViewController];
_contentViewController = newViewController;
if ([DeviceDetection isDeviceiPad]) {
_contentViewController.view.frame = CGRectMake(0, 0, 1024, 768);
}
}
Did you check if it's has something to do with the new interface orientation?
https://developer.apple.com/library/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS8.html
chapter -> Supporting New Screen Sizes and Scales
In CenterViewController.h make the class a subclass of a UITableViewController instead.
Then comment out [self.view addSubview:self.tableView]; in CenterViewController.m.
Done!
In centerViewController.m, when you create the tableview, add this line:
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth;

iOS : How to Full screen video when change device orientation to Landscape in MPMoviePlayerController?

I am developing an application with MPMoviePlayerController. The application supports Portrait mode only. But I want to change the video in full Screen when I change the device orientation to landscape and back to half screen when change device orientation to Portrait.
if in Landscape and Full Screen mode and movie finishes then also go to half screen mode.
I have tried different codes and options but could not succeed. please help.
My Source code
#property (nonatomic,strong) MPMoviePlayerController* moviePlayer;
-(void)PlayVideoContent
{
CGFloat x = 0;
CGFloat y = 70;
CGRect mpFrame = CGRectMake(x, y, SCREEN_WIDTH, 200);
NSString * introVideoFileName = #"video_5.mp4";
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:introVideoFileName ofType:#""]];
MPMoviePlayerController *controller = [[MPMoviePlayerController alloc] initWithContentURL:url];
controller.scalingMode = MPMovieScalingModeAspectFill;
self.moviePlayer = controller; //Super important
// controller.view.frame = self.view.bounds; //Set the size
controller.view.frame = mpFrame; //Set the size
// [self.moviePlayer setFullscreen:YES animated:YES];
[self.view addSubview:self.moviePlayer.view]; //Show the view
[self.moviePlayer play]; //Start playing
}
U must give the UIViewController(s) of your application to decide whether it's in landscape or portrait.
After that, set all the rest to portrait except the one u want in landscape (the MPMoviePlayerController)
In your project settings (App Target > General > Deployment Info > Device Orientation), select Portrait, Landscape Left and Landscape Right.
In your root view controller, add:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
If everything gets loaded into this view controller, that should be all you have to do. If you find that some views are rotating when they shouldn't, add this same code to their view controllers.
The controller for the fullscreen video will use the supported orientations specified in the target settings, and so will allow rotation to landscape. When you close the video, the view will rotate back to portrait.

Adding subviews on UIWindow covers the keyboard called by textfields

I am trying to imitate an alert view and i show a view with two text fields above a view with a translucent background. The problem is that when i try to tap on the text fields , the keyboard is shown behind my translucent view and i can't tap it no more. Is there a solution?
Here is my code:
if (_grayView==nil) {
_grayView = [[UIView alloc]init];
_grayView.frame = [[UIScreen mainScreen]bounds];
_grayView.backgroundColor = [UIColor blackColor];
_grayView.alpha = 0.7;
[[[[UIApplication sharedApplication] windows] lastObject] addSubview:_grayView];
}
//Show the dimensions view when choosing an image
_dimensionsView.hidden = NO;
[[[[UIApplication sharedApplication] windows] lastObject] addSubview:_dimensionsView];
In the _dimensionsView i have the textfileds.
What you're doing isn't a very good idea to begin with. Also be aware that you can't count on windows.lastObject to always be the window you expect. iOS 7 and 8 are more and more liberal with creating new windows for keyboards and modals. You might not be adding your subview to the window you're expecting.

Resources