I want to add a Logo (UIImageView) to a fullscreen MPMoviePlayerController.
It works fine when the MPMoviePlayerController is not in fullscreen Mode. When i switch to full screen all added views on the MPMoviePlayerController removed(hidden).
Here is my code:
- (void)setupMPMoviePlayer{
[self.moviePlayer.view removeFromSuperview];
[self removeNotifications];
self.moviePlayer = nil;
self.moviePlayer = [[MPMoviePlayerController alloc] init];
[self addNotifications];
[self.moviePlayer.view setFrame:self.view.bounds];
self.moviePlayer.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.moviePlayer.fullscreen = NO;
[self.view addSubview:self.moviePlayer.view];
if ([self.moviePlayer respondsToSelector:#selector(setAllowsAirPlay:)])
[self.moviePlayer setAllowsAirPlay:YES];
[self.moviePlayer setContentURL:[NSURL URLWithString:urlString]];
[self.moviePlayer setFullscreen:YES animated:YES];
[self addLogoViewAtView:self.moviePlayer.view];
}
- (void)addLogoViewAtView:(UIView *)view{
UIView *theView = [view viewWithTag:101];
if (theView.superview) {
[theView removeFromSuperview];
}
UIImageView *logoView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"logo_weiss.png"]];
logoView.tag = 101;
logoView.frame = CGRectMake( logoView.image.size.width - 100.0,
100.0,
logoView.image.size.width,
logoView.image.size.height);
logoView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin;
[view addSubview:logoView];
[view bringSubviewToFront:logoView];
}
Now my question is there an alternate way to add an subview to MPMoviePlayerController?
I can add the logo to the application's window but this ist not so clean.
Anyone have any idea on how I could do this?
Most propably fullscreen mode add MPMoviePlayerController view at keyWindow for an application or present a modal view controller above. So, you can try looking for the view in window.subviews or modal view controllers for moviePlayer.
Related
Here're some view controller I have: tabBarController, navigationBarController, viewController, and imageView.
The hierarchy is that: tabBarController is the root controller, it includes navigationBarController. And the viewController(which is include the imageView) is pushed in by navigationBarController.
So the question is, when I touched the imageView, how to resize it to fullscreen with smooth animation. Note, I don't want to hide NavigationBar & TabBar.
I tried it by setFrame, however, it is covered by navigationBarController and tabBarController.
I tried presentModalViewController: but it lose continuity.
I also tried to reset rootViewController to viewController, but the resulted with a broken animation. :(
Thanks for any suggestion!
Test code
UIViewController * viewController = [[UIViewController alloc] init];
[viewController.view setFrame:CGRectMake(0.0f, 0.0, 320.0f, 480.0f)];
[viewController.view setBackgroundColor:[UIColor redColor]];
UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 480.0f)];
[imageView setBackgroundColor:[UIColor yellowColor]];
[imageView setUserInteractionEnabled:YES];
[viewController.view addSubview:imageView];
[imageView release];
UINavigationController * navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
[viewController release];
UIViewController * anotherTabViewController = [[UIViewController alloc] init];
[anotherTabViewController.view setFrame:CGRectMake(0.0f, 0.0, 320.0f, 480.0f)];
[anotherTabViewController.view setBackgroundColor:[UIColor blueColor]];
UITabBarController * tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = [NSArray arrayWithObjects:navigationController, anotherTabViewController, nil];
[navigationController release];
[anotherTabViewController release];
[self.window setRootViewController:tabBarController];
Here I write a simple code for testing. Now don't care about the touch action. I wonder how to set the imageView to totally fullscreen(width:320, height:480). But it's clipped by navigation bar and tab bar. I know the frame is relative to its super view. How to deal with this issue?
try to add img to you window, when you need to resize it to full screen:
UIImageView *img; //create new image
img = yourImageView;
[img setOrigin:CGPointMake(yourImageView.frame.origin.x, yourImageView.frame.origin.y+90)];
//window size is bigger, so to set an image frame visionary at same place, you need to set origin point lower
MOEAppDelegate *sharedAppDelegate = (MOEAppDelegate *)[[UIApplication sharedApplication] delegate];
[sharedAppDelegate.window addSubview:img];
[UIView animateWithDuration:1
animations:^{
[img setFrame:CGRectMake(0,
0,
320,
480)];
}];
Note, that your self.view's frame automatically resized when you adding tabBar or navigationBar, and in -(void)viewDidLoad it is NOT resized jet!
I have implemented UITapGestureRecognizer on UIImageView, It is working on first tap. On First Tap, I am hiding that image and starting animation. Once the animations are completed, i am showing the image again. But After setting setHidden:FALSE, I am not getting the Tap event of that UIImageView.
Following is the code I am using :
- (void)viewDidLoad{
[super viewDidLoad];
defaultDogView= [[UIImageView alloc] initWithFrame:CGRectMake(3, 270, 110, 210)];
[defaultDogView setImage:[UIImage imageNamed:#"dog1.png"]];
defaultDogView.userInteractionEnabled = YES;
[self addGestureRecognizersToPiece:defaultDogView];
[self.view addSubview:defaultDogView];
}
- (void)addGestureRecognizersToPiece:(UIImageView *)piece
{
NSLog(#"in Gesture");
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapPiece:)];
[tapGesture setDelegate:self];
[piece addGestureRecognizer:tapGesture];
[tapGesture release];
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressPiece:)];
[piece addGestureRecognizer:longPressGesture];
[longPressGesture release];
NSLog(#"%#", [piece gestureRecognizers]);
}
- (void)singleTapPiece:(UITapGestureRecognizer *)gestureRecognizer
{
NSLog(#"Image Tapped");
/** Hide the default Image and start the animation ***/
[defaultDogView setHidden:TRUE];
/***Animating the Dog***/
[dogArray addObject:[SpriteHelpers setupAnimatedDog:self.view numFrames:69 withFilePrefix:#"dog" withDuration:(12) ofType:#"png" withValue:0]];
dogView = [dogArray objectAtIndex:0];
//[self addGestureRecognizersToPiece:dogView];
[self performSelector:#selector(callBubbleUpdater) withObject:nil afterDelay:5.5];
}
-(void)showDogFrame{
NSLog(#"%#",[defaultDogView gestureRecognizers]);
[defaultDogView setHidden:FALSE];
defaultDogView.userInteractionEnabled = YES;
}
When view is hidden or its alpha component is zero that view won't receive any UIGestureRecognizers.
I can suggest to use next approach if you need to hide some view (let's name it touchableView) but want it to respond to gestures:
Create backgroundView with the same frame as touchableView:
UIView *backgroundView = [[UIView alloc] initWithFrame:touchableView.frame];
Set background color of backgroundView to clearColor:
backgroundView.backgroundColor = [UIColor clearColor];
Reset position of touchableView:
CGRect frame = touchableView.frame;
frame.origin.x = 0;
frame.origin.y = 0;
Disable user interaction of touchableView:
touchableView.userInteractionEnabled = NO;
Add touchableView as subview to backgroundView:
[backgroundView addSubview:touchableView];
Add appropriate gesture recognizers to backgroundView.
Add backgroundView to view that you want.
Now you can hide touchableView but you will still receive gesture recognizers.
I don't test this but I think it should work.
sure
when UIImageView is hidden. it does not receive any touch events
set alpha zero for uiimageview
I need to add UIImagePickerController in camera mode using addSubView. I have written code for it but it leaves white space at the top of the view.
-(void)viewDidAppear:(BOOL)animated{
NSLog(#"ViewDidAppear");
OverlayView *overlay = [[OverlayView alloc]
initWithFrame:CGRectMake(0,0,SCREEN_WIDTH,SCREEN_HEIGTH)];
//create a new image picker instance
picker = [[UIImagePickerController alloc]init];
self.picker.delegate = self;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
//set source to video!
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
//hide all controls
picker.showsCameraControls = NO;
picker.navigationBarHidden = NO;
picker.toolbarHidden = YES;
picker.editing = NO;
//make the video preview full size
picker.wantsFullScreenLayout = YES;
slider.value = 1;
picker.cameraViewTransform = CGAffineTransformScale(picker.cameraViewTransform,slider.value, slider.value);
//set our custom overlay view
picker.cameraOverlayView = overlay;
[picker.view addSubview:slider];
//show picker
[picker.view addSubview:capture];
[picker.view addSubview:library];
//[picker.view addSubview:multicapture];
[capture addTarget:self action:#selector(takepicture) forControlEvents:UIControlEventTouchUpInside];
[library addTarget:self action:#selector(goToLibrary) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:picker.view];
[picker viewWillAppear:YES];
[picker viewDidAppear:YES];
}else{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Test Text" message:#"Camera is Not Availble" delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
[overlay release];
}
Can anyone please help me.
Thanks.
As kante0 says, that white margin is the status bar disappeared. If you want to show the status bar, use kante0's solution:
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
[self.view addSubview:picker.view];
If you don't want to show the status bar (typically when you show the camera preview), use this piece of code:
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
[self.view setFrame: [[UIScreen mainScreen] bounds]];
// Place your overlay view here
[self.view addSubview:picker.view];
But you have to remember that when the pickerview is removed, if you want to show again the status bar, you'll need to do this:
[picker.view removeFromSuperview];
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
[self.view setFrame: [[UIScreen mainScreen] applicationFrame]];
// If you need to place elements programmatically, do it here
Look into NSScreen for getting accurate dimensions. Double check that you have the height value correct. For example, you could do this:
int width = [[NSScreen mainScreen] frame].size.width;
int height = [[NSScreen mainScreen] frame].size.height;
Is not a white margin, is status bar disappearing.
I solved the problem with:
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
I have a view controller which includes a MPMoviePlayer inside. I hide the navigation bar, and want it to be shown when the video paused.
When the video is loaded, it works just fine. After i paused the video navigation bar appears but it pushes the whole player view to a little bit down. How can i make navigation bar appear without affecting the player view.
here is the code i used:
In ViewDidLoad():
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(videoPlayerPlaybackStateChanged:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:nil];
[self setWantsFullScreenLayout:YES];
[moviePlayer prepareToPlay];
//For viewing partially.....
moviePlayer.view.backgroundColor = [UIColor blackColor];
//[moviePlayer.view setFrame:CGRectMake(0, 0, 320, 410)];
[moviePlayer.view setFrame:[self.view bounds]];
moviePlayer.fullscreen = YES;
moviePlayer.scalingMode = MPMovieScalingModeAspectFill;
[self.view addSubview:moviePlayer.view];
[moviePlayer play];
- (void) videoPlayerPlaybackStateChanged:(NSNotification*) aNotification
{
MPMoviePlayerController *player = [aNotification object];
if(player.playbackState == MPMoviePlaybackStatePaused){
self.navigationController.navigationBar.tintColor = [UIColor blackColor];
self.navigationController.navigationBarHidden = NO;
}
else if(player.playbackState == MPMoviePlaybackStatePlaying){
self.navigationController.navigationBarHidden = YES;
}
[player autorelease];
}
Thank you in advance...
In your condition
if(player.playbackState == MPMoviePlaybackStatePaused)
{
self.navigationController.navigationBar.tintColor = [UIColor blackColor];
self.navigationController.navigationBarHidden = NO;
}
Try using
[self.navigationController.navigationBar setTranslucent:YES];
I have a UIViewController that I'm using to control a "pop-up" view for viewing images throughout my application. It supports autorotation, as it automatically sizes the image to fit properly regardless of orientation. This works perfectly, but only the first time I initialize and display the view controller. When it closes, I am removing the UIView from my view hierarchy and releasing the view controller - but the next time I instantiate and add it to my view hierarchy, it stops receiving the -shouldAutorotateToInterfaceOrientation messages when the phone is rotated.
This is how I instantiate and display it:
popupVC = [[PopupVC alloc] init];
[popupVC viewWillAppear:NO];
[[[UIApplication sharedApplication] keyWindow] addSubview:popupVC.view];
[popupVC viewDidAppear:NO];
this is how I remove/release it when it's finished:
[popupVC viewWillDisappear:NO];
[popupVC.view removeFromSuperview];
[popupVC viewDidDisappear:NO];
[popupVC release];
popupVC = nil;
I've tried looping through [[UIApplication sharedApplication] keyWindow] subviews to see if somehow my popup view isn't on top, but it always is. And it has a different address each time so I do know that it's a different instance of the view controller class.
As requested, here is the complete loadView method from PopupVC:
- (void)loadView {
UIView *myView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
myView.backgroundColor = self.overlayColor;
myView.autoresizesSubviews = NO;
myView.hidden = YES;
myView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.view = myView;
[myView release];
_isVisible = NO;
UIView *myMaskView = [[UIView alloc] initWithFrame:self.view.bounds];
myMaskView.backgroundColor = [UIColor clearColor];
myMaskView.clipsToBounds = YES;
myMaskView.hidden = YES;
myMaskView.autoresizesSubviews = NO;
myMaskView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:myMaskView];
self.imageMaskView = myMaskView;
[myMaskView release];
UIImageView *myImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
myImageView.center = self.view.center;
myImageView.hidden = NO;
myImageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleHeight;
[self.imageMaskView addSubview:myImageView];
self.imageView = myImageView;
[myImageView release];
UIButton *myImageButton = [UIButton buttonWithType:UIButtonTypeCustom];
myImageButton.frame = self.view.frame;
myImageButton.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleHeight;
[myImageButton addTarget:self action:#selector(clickImage:) forControlEvents:UIControlEventTouchUpInside];
[self.imageMaskView addSubview:myImageButton];
self.imageButton = myImageButton;
UIActivityIndicatorView *myActivityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
myActivityView.hidden = YES;
[self.view addSubview:myActivityView];
myActivityView.center = self.view.center;
self.activityView = myActivityView;
[myActivityView release];
}
The shouldAutorotateToInterfaceOrientation handler isn't the place for custom code to respond to rotation events. It's purpose is just to tell the OS that your view controller can rotate. If you want to have custom code to handle the rotation events you should overide - didRotateFromInterfaceOrientation or one of the other similar callback methods depending on your needs:
willRotateToInterfaceOrientation:duration:
willAnimateRotationToInterfaceOrientation:duration:
didRotateFromInterfaceOrientation:
willAnimateFirstHalfOfRotationToInterfaceOrientation:duration:
didAnimateFirstHalfOfRotationToInterfaceOrientation:
willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration:
See Autorotating Views in the developer docs.
I think that might be a bug in the new OS 3.0. A workaround to this would be to use NSNotificationCenter after turning on beginGeneratingDeviceOrientationNotifications.
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(receivedRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];
}
-(void) receivedRotate: (NSNotification *) notification {
DebugLog(#"ORIENTATION CHANGE");
UIDeviceOrientation interfaceOrientation = [[UIDevice currentDevice] orientation];
if(interfaceOrientation == UIDeviceOrientationPortrait) {
self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(0));
self.view.bounds = CGRectMake(0, 0, 320, 480);
}
else if(interfaceOrientation == UIDeviceOrientationLandscapeLeft) {
self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
self.view.bounds = CGRectMake(0, 0, 480, 320);
}
else if(interfaceOrientation == UIDeviceOrientationLandscapeRight) {
self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(-90));
self.view.bounds = CGRectMake(0, 0, 480, 320);
}
}
My problem is that I get the rotation event for my rootViewController, but as soon as I launch my second viewController, it won't get any signals except motion (shaking) and touch. Is that the same issue as the original post -- it is certainly similiar??
I followed-up with above recommendation and I don't have the selector coded correctly so it throws an exception as soon as I try to rotate. Meanwhile, I found this other discussion on the web which confirms that the problem was introduced in 3.0.
link text