Reputation: 12004
Objective-C drives me slightly crazy. I know that it is not a language which processes every command after the other, but what if I need to do this?
For instance, my problem is that I would like to:
Right now, the app will take a screenshot of all the views added in the method (completely ignoring my order of the events) and will not HIDE the added view BENEATH my screenshot. Whatever I try to do, everything will always happen at once and this sucks.
This is my code:
- (void)takeScreenShot
{
screenShotView = [[UIImageView alloc] initWithImage:[self screenshot]];
[screenShotView setFrame:CGRectMake(0, -20, 320, 480)];
accessoryView.hidden = YES;
[self.view addSubview:accessoryView]; // which is hidden beneath and about to be revealed
[self.view addSubview:screenShotView];
[self.view bringSubviewToFront:screenShotView];
[self startAnimation];
}
- (void)startAnimation
{
[UIView animateWithDuration:0.0
delay:0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
accessoryView.hidden = NO;
}
completion:^(BOOL finished){
[UIView animateWithDuration:3.0
delay:0
options:UIViewAnimationOptionCurveLinear
animations:^{
screenShotView.transform = CGAffineTransformMakeTranslation(-320, 0);
}
completion:^(BOOL finished){
}
];
}];
}
- (UIImage*)screenshot
{
// Create a graphics context with the target size
// On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration
// On iOS prior to 4, fall back to use UIGraphicsBeginImageContext
CGSize imageSize = [[UIScreen mainScreen] bounds].size;
if (NULL != UIGraphicsBeginImageContextWithOptions)
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
else
UIGraphicsBeginImageContext(imageSize);
CGContextRef context = UIGraphicsGetCurrentContext();
// Iterate over every window from back to front
for (UIWindow *window in [[UIApplication sharedApplication] windows])
{
if (![window respondsToSelector:@selector(screen)] || [window screen] == [UIScreen mainScreen])
{
// -renderInContext: renders in the coordinate space of the layer,
// so we must first apply the layer's geometry to the graphics context
CGContextSaveGState(context);
// Center the context around the window's anchor point
CGContextTranslateCTM(context, [window center].x, [window center].y);
// Apply the window's transform about the anchor point
CGContextConcatCTM(context, [window transform]);
// Offset by the portion of the bounds left of and above the anchor point
CGContextTranslateCTM(context,
-[window bounds].size.width * [[window layer] anchorPoint].x,
-[window bounds].size.height * [[window layer] anchorPoint].y);
// Render the layer hierarchy to the current context
[[window layer] renderInContext:context];
// Restore the context
CGContextRestoreGState(context);
}
}
// Retrieve the screenshot image
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
Upvotes: 2
Views: 570
Reputation: 47241
This is no real answer but comments don't offer enough space.
I just recreated a simple project to see if the order of adding the views does any difference to the screenshot.
I used a view based application template. The nib has two buttons, connected to properties btn1 and btn2. See screenshot 1. The upper button btn1 is connect to an action to start taking the screenshot and adding it below the buttons to see a difference. The second button is hidden initially.
screenshot 1
Here is my code of the viewController. myView is your accessory view, which will be created on viewWillAppear. This view contains a label as you'll see later.
Header
...
@interface ScreenshotviewsViewController : UIViewController
{
UIButton *btn1;
UIButton *btn2;
UIView *myView;
}
@property (nonatomic ,retain) IBOutlet UIButton *btn1;
@property (nonatomic ,retain) IBOutlet UIButton *btn2;
@property (nonatomic ,retain) UIView *myView;
- (IBAction)doTheThings;
@end
I'll skip your screenshot method: nothing changed, works like a charm :). Result in screenshot 2
As you can see, the screenshot does not show the other views. I just added it below the buttons to see the differences.
Implementation: case 1
- (void)viewWillAppear:(BOOL)animated
{
self.myView = [[[UIView alloc] initWithFrame:CGRectMake(0, 20, 320, 50)] autorelease];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(5, 5, 200, 40)];
myView.backgroundColor = [UIColor greenColor];
[myView addSubview:label];
label.text = @"fooo";
[label release];
}
- (IBAction)doTheThings
{
UIImageView *screenShotView = [[UIImageView alloc] initWithImage:[self screenshot]];
[screenShotView setFrame:CGRectMake(0, 230, 320, 480)];
btn2.hidden = NO;
[self.view addSubview:myView];
[self.view addSubview:screenShotView];
[screenShotView release];
}
screenshot 2
case two would be
add screenshot as subview
(IBAction)doTheThings { btn2.hidden = NO; [self.view addSubview:myView];
UIImageView *screenShotView = [[UIImageView alloc] initWithImage:[self screenshot]]; [screenShotView setFrame:CGRectMake(0, 230, 320, 480)];
[self.view addSubview:screenShotView]; [screenShotView release]; }
screenshot 3
As you can see the order is recognized. I've left out the animation though. Remove the animation and see if works then. Else try this in a seperate project like I did and see if it works in isolation. If yes we'll have to dig down into you app more.
Upvotes: 1