I have a specific function on an app that is intended to work on iPhone 4 and iPad. I don't have an iPad yet (because Apple forgot my country), so I have to test it on simulator.
I have a method that needs to grab the contents of the main screen as a CGImageRef.
I have this method:
- (CGImageRef)takeScreenshot {
UIWindow *theScreen = [[UIApplication sharedApplication].windows objectAtIndex:0];
UIGraphicsBeginImageContext(theScreen.frame.size);
[[theScreen layer] renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return screenshot.CGImage;
}
When I compile and test the iPhone version of my app for the iPhone, it works perfectly. But when I compile and test the iPad version on iPad simulator, it returns a black screen.
For it to work, I have to change the "objectAtIndex:0" to "objectAtIndex:1" on the second line.
Is there any logic for this or it is just a simulator bug? As far as I know, index 0 is always the main screen.
Is there any other way to capture the main screen content from another class?
thanks in advance.
Maybe use the keyWindow to get the correct window directly?
UIWindow *theScreen = [[UIApplication sharedApplication] keyWindow];
For the country problem - consider ordering one from another country. ;-)
Related
I believe that I did everything necessary to change my app for ipad (was for iphone at start). I can toggle the build status to either iphone (only), ipad (only) or iphone/ipad - and the app launches either in ipad or iphone simulator. I can do that forth and back at will.
I added the idiom to check for ipad and basically for one of my xib, instead of using the string of my xib to create the controller, I use the one for the ipad. So it is a new xib for ipad with all same graphical objects ( enlarged ;-) ) . I added the callbacks to function correctly with IB.
I can see everything fine and arrive on my new ipad view BUT when I click on one of my buttons... nothing happened like if my callbacks don't work. It is very surprising and actually I have no idea where to look as I compared most of the parameters between my iphone and ipad view and they are identical as far as I can see.
It must be something damn obvious so if one of you had the same issue and it was a very simple answer ... I guess that would be what I missed!
Thanks for your help in advance
Cheers,
geebee
EDIT1: Some code as requested
at start I have that to decide either way:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
examTFVC_NIB=#"ExamTFViewController-iPad";
}
else
{
examTFVC_NIB=#"ExamTFViewController";
}
Then to go to the right view:
ExamTFViewController *examTFViewController = [[ExamTFViewController alloc]
initWithNibName:globals.examTFVC_NIB bundle:nil];
But I have no problem loading the correct XIB. The issue is really the callback functions not being called...
Thanks for the help.
EDIT2:
I also realised that calling the extension of the xib xxx~ipad allows to avoid the example code above. And it works - but still no function can be called.
EDIT3:
IMPORTANT FINDING: if I move my buttons higher and on the left of the screen: they work! So it seems that the functions are called if the event are in the region of an iphone screen although I am on an ipad screen. I guess know it would be more obvious to find the issue! thanks for any help – geebee just now
ANSWER
iPad touch detected only in 320x480 region
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// to correct region size
CGRect rect = [[UIScreen mainScreen] bounds];
[window setFrame:rect];
// now, display your app
[window addSubview:rootController.view];
[window makeKeyAndVisible];
}
** OR OTHER SOLUTION **
Check the full screen at launch checkbox - only present in the ipad xib MainWindow
finally solved - with 2 methods - programmatically or via IB - in the edited section of the post.
I have downloaded ray wenderlich's code for apns application from this link
http://www.raywenderlich.com/3525/apple-push-notification-services-tutorial-part-2
now i converted that project of ray's to tab bar application project, now i am having a problem with tab bar image. i added x and 2x resolution images in my images folder of project, and doing this in view will appear
AppDelegate *delegate2 =(AppDelegate *) [[UIApplication sharedApplication] delegate];
for(UIView *view in delegate2.tabBarControler.tabBar.subviews) {
if([view isKindOfClass:[UIImageView class]]) {
[view removeFromSuperview];
}
}
[delegate2.tabBarControler.tabBar insertSubview:[[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"home.png"]] autorelease] atIndex:0];
the 2x resolution image which is home#2x.png, it is not being picked by ios 5 device (ipod 4) i know that the operating system (ios 5) automatically senses the 2x image and pick it, but in my case its not happening, rather its picking the x resolution image and there is a white line showing under tab bar, i am stuck here , please guide me thanx and regards Saad.
Lets run through some basics to see where something may have gone wrong;
Put the following line in your code, just after that and see what it prints out;
NSLog(#"Image scale : %f",[[UIImage imageNamed:#"home.png"] scale]);
If it prints out 'Image scale : 2.000000', that means the #2x image has been correctly identified and loaded by the app.
Also;
Delete both images, clean the project, add them and try rebuilding
Make sure the case of home.png and home#2x.png match exactly
If you're trying this on a simulator, Reset the simulator and try again.
If you already have a previous build on your device, delete it and try again.
Hi I have an app and I have two *.pngs for default splash screen:
Default-Landscape.png
Default-Portrait.png
What I want is to animate this default splash screen away when my app is loaded and ready to go.
To achieve this I would normally present an UIImageView with either default-landscape or default-portrait (depending on the device orientation), keep it on screen for a certain time and then animate it away.
My problem is that if I call [[UIDevice currentDevice] orientation] in
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
The answer is always that the device is in portrait orientation even if I clearly have it in landscape. I tried this in simulator and on the device as well and the behaviour is the same.
Does anyone know a fix for this or maybe some other approach?
Thanks!
I had troubles with this and I solved it by making one image 1024x1024 and setting the contentMode of the UIImageView to UIViewContentModeTop, then using left and right margin autoresizing. So long as your portrait and landscape default images are the same layout then this will work fine.
Just to clarify here's what I used:
bgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:SplashImage]];
bgView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
bgView.contentMode = UIViewContentModeTop;
To get around this problem I installed the splash image view inside of a view controller that allowed both orientations. Even though the device reported the wrong orientation at startup, the view controller seems to get the right one.
You can use UIApplication statusBarOrientation as follows:
if ( UIDeviceOrientationIsLandscape( [[UIApplication sharedApplication] statusBarOrientation] ))
{
// landscape code
}
else
{
// portrait code
}
Maybe you could show a blank view with black background at start time and place [[UIDevice currentDevice] orientation] into this view's viewDidAppear and start your splash screen from there?
Another solution would be to read the accelerometer data and determine the orientation yourself.
To know at start what is the orientation (UIDevice orientation don't work until user have rotate the device) intercept shouldAutorotateToInterfaceOrientation of your View Controller, it is called at start, and you know your device orientation.
There are certainly times when you want to transition from the loading image to something else before the user gets control of your app. Unless your app is really simple, going from loading image to landing page probably won't be sufficient without making the app experience really suck. If you ever develop a large app, you'll definitely want to do that to show progress during setup, loading xibs, etc. If an app takes several seconds to prepare with no feedback, users will hate it. IMO, there's nothing wrong with a nice transition effect either. Almost nobody uses loading screens the way Apple suggests to. I don't know which apps you looked at that showed the "empty UI" type loading screens they suggest. Heck, even Apple doesn't do that except in their sample code and none of my clients would find that acceptable. It's a lame design.
Only the first view added to the window is rotated by the OS. So if you want your splash screen to automatically rotate AND your main view is rotatable then just add it as a child of that view.
Here is my code for fading out the appropriate splash screen image:
// Determine which launch image file
NSString * launchImageName = #"Default.png";
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
if (UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation])) {
launchImageName = #"Default-Portrait.png";
} else {
launchImageName = #"Default-Landscape.png";
}
}
// Create a fade out effect
UIImageView* whiteoutView = [[[UIImageView alloc] initWithFrame:self.window.frame] autorelease];
whiteoutView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
whiteoutView.autoresizesSubviews = YES;
whiteoutView.image = [UIImage imageNamed:launchImageName];
[[[self.window subviews] objectAtIndex:0] addSubview:whiteoutView];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
whiteoutView.alpha = 0.0;
[UIView commitAnimations];
Note: You'll have to update it to support hi-res screens.
It sounds like you're not using the launch image the way Apple recommends in the iOS HIG. It specifically calls out that you should not use it as a splash screen, but rather as a skeleton version of your actual UI. The net effect is that your app appears to be ready just that much faster.
The suggestions that you could draw a splash screen yourself after the app has launching in viewDidAppear or similar also are missing the basic purpose of a launch image. It's not a splash screen. If your app is ready, let the user interact with it, don't waste their time drawing a splash screen.
From my five minute survey of Apple apps and third-party apps, everyone showed a portrait launch image, loaded the portrait version of the UI, and then rotated to landscape. It's been a while since programming on iOS, but I think this mirrors the order of the method calls -- first your app gets launched, then it is told to rotate to a particular orientation.
It might be a nice enhancement request to file with Apple though :)
My app is landscape. I would like to launch the in-app email composer in landscape and restrict it as such. Can anyone advise how to do this? I created a view controller with the proper auto-rotate settings to keep my app in landscape but am unsure how to tell the MFMailComposeViewController to please launch in landscape and stay there (and stop making the keyboard rotate).
Help?
This is answering his comment and not the original question.
I had this problem as well and this snippet seems to work for me:
[[UIApplication sharedApplication] setStatusBarOrientation: UIInterfaceOrientationLandscapeLeft];
First Add following property in info.plist file
Supported interface orientations
"Landscape (right home button)"
than use presentModalViewController
-(void)displayComposerSheet
{
MFMailComposeViewController *picker4 = [[[MFMailComposeViewController alloc]init]autorelease];
picker4.mailComposeDelegate = self;
[picker4 setSubject:result];
CGRect rect = CGRectMake(0,0,480,320);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
// Fill out the email body text
[self presentModalViewController:picker4 animated:NO];
}
I need to capture a screen shot of a video playing in mpmovieplayer controller, but all I get is a red screen (I made the coverView with red background and 0.5 alpha).
Here is the code:
NSArray *windows = [[UIApplication sharedApplication] windows];
if ([windows count] > 1)
{
UIWindow *moviePlayerWindow = [[UIApplication sharedApplication] keyWindow];
UIView *coverView = [[UIView alloc] initWithFrame:moviePlayerWindow.bounds];
[mainController.moviePlayer pause]; //Without that it won't work either!
coverView.backgroundColor = [UIColor redColor];
coverView.alpha = 0.5;
[moviePlayerWindow addSubview:coverView];
UIGraphicsBeginImageContext(coverView.bounds.size);
[coverView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenShot;
screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(screenShot, self, nil, nil);
}
Any ideas???
Thanks
I was curious about his myself. I believe there are similar issues with taking screenshots of OpenGL stuff too.
If you look at this blog post http://getsetgames.com/2009/07/30/5-ways-to-take-screenshots-of-your-iphone-app/, they have a method that works for an EAGLView, it might be worth giving it a go for your issue.
Follow up to the question:
Recently I have a project that requires the functionality that was asked in this thread again, and I am glad to say there is already an apple provided solution to this. I am posting this so that people that visit this thread can get an answer.
MPMoviePlayerController now has a method that return a UIImage of the moment you want to capture.
- (UIImage *)thumbnailImageAtTime:(NSTimeInterval)playbackTime timeOption:(MPMovieTimeOption)option
Just put in the playbackTime you want to capture, and bingo, UIImage.
Looking at your codes, I would like to advise that you should look for an alternative method of getting the image rather than from the mpmovieplayer itself. The reason being that the method you are using is a private framework code, and second, getting screenshots off a video is highly prone to crashes.
Instead of getting a screenshot from the video, how about tagging the video beforehand? The codes looks highly vulnerable to an app rejection by apple.
Sounds like you're taking a shot of the video overlay mask
http://en.wikipedia.org/wiki/Hardware_overlay