Circumvent screenshot for iOS 4 - iphone

I would like to clear a view before an application is switched away from, to change the launch image so that the next time the app is entered it will not display some insecure data.
iOS 4 provides applicationDidEnterBackground and applicationWillResignActive...however, neither of these seem to be able to prevent the screenshot from being taken before I have a chance to clear the view.

-applicationDidEnterBackground does get called before the screenshot. Turns out I was simply hiding my view improperly.
A simple way to clear the view was to set the hidden property on my UIView.

Just to add a snippet of code for a fast solution to this problem using a full background image declared on the initialization and hiding it.
You can do a more sofisticated hide of the particular contents of each view by registering to the notification, and in the views hide the particular views (labels) you want to hide.
Another solution is to check which viewcontroller is showing and switch between differente screenshots of the view of this viewcontroller without the data shown.
The easiest way:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIImageView *backgroundView_ = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Default.png"]];
self.backgroundView = backgroundView_;
[backgroundView_ release];
// Add other controllers views
// ...
[self.window bringSubviewToFront:self.backgroundView];
self.backgroundView.hidden = YES;
[self.window makeKeyAndVisible];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
self.backgroundView.hidden = YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
self.backgroundView.hidden = NO;
}

Related

I get two of the same root view

I am testing my app on iphone and the software version is 4.2.1. I find some problems happened when switching from a customer launchview controller to the rootview controller. The code is as below:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
....
launchViewController = [[[LaunchImageTransition alloc] initWithNibName:#"LaunchView_iphone" bundle:nil controller:self.viewController animation:UIModalTransitionStyleCrossDissolve] autorelease];
self.window.rootViewController = launchViewController;
....
}
In the "LaunchImageTransition.m":
//do some initial work
[self presentModalViewController:self.rootViewController animated:YES];
The rootViewController is initialed in the "MainWindow.xib".
When I test on the iphone simulator, everything is ok. But when I test on the real device, I find that the viewDidAppear method of the rootViewController is called twice while the viewDidload method is called once. This result in two of the same view。
I want to know why this only happened on real device and how to fix it?
I think that the problem is that you are using the view system in a way that it is not the way it has been thought it should be used. My advice is to change the way you present your views.
I don't know if you have to do this exactly this way, but I think that a better way to go is to let the rootViewController as it should be, like the mainViewController.
At the end of the - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method you can present the launchView as modal on the mainViewController.
[mainViewController presentModalViewController: launchViewController animated:YES];
And on the viewWillAppearMethod or viewDidAppearMethod of the mainViewController you can dismiss the launchViewController.
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self dismissModalViewControllerAnimated:YES];
}
I hope it helps...

display a modal view on ipad application startup

I want to conditionally display a login screen on launch of an ipad app. I don't want to make it part of a default segue, since they only need to login periodically, not every time.
There are numerous examples of my question, but they all seem to predate ios5. When I use storyboards, however, nothing seems to work.
To reduce this to its essence,
* create a new single view application, using storyboard
* add a new viewcontroller to the storyboard, give it an identifier of "loginScreen"
* put a text label on each view to visually distinguish them.
* in the appDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard *storyboard = [self.window.rootViewController storyboard];
UIViewController *loginController = [storyboard instantiateViewControllerWithIdentifier:#"loginScreen"];
[self.window.rootViewController presentModalViewController:loginController animated:TRUE];
return YES;
}
From what I've seen of the examples, that should work. But it still consistently displays the original rootViewController's view. No errors though.
Can anyone point out the (probably small) thing I'm missing?
It turns out that the app isn't in an active state in the didFinishLaunching method.
The proper place to put this is
- (void)applicationDidBecomeActive:(UIApplication *)application
{
UIStoryboard *storyboard = self.window.rootViewController.storyboard;
UIViewController *loginController = [storyboard instantiateViewControllerWithIdentifier:#"loginScreen"];
[self.window.rootViewController presentModalViewController:loginController animated:NO];
}
#deafgreatdane: Your solution would present the view controller modally each time the application becomes active from being in a background state (which may be desirable).
In my case (using this to show a one-time only launch screen) I would add a dispatch_once to that solution to make sure that the modal launch screen will only show up once:
- (void)applicationDidBecomeActive:(UIApplication*)application
{
static dispatch_once_t onceToken;
dispatch_once( &onceToken, ^
{
SomeLaunchViewController* launchViewController = [[SomeLaunchViewController alloc] init];
[self.window.rootViewController presentViewController:launchViewController animated:NO completion:NULL];
} );
}
This code snippet uses ARC.

UISearchDisplayController not showing

I've been doing everything programmatically in the past, but now I'm trying to learn to use Interface Builder. An experience in and of itself.
My problem is with UISearchDisplayController. Just dropping it on top of my UITableViewController (see figure 1) should set up all relevant connections (and I think add it to the tableView header), and as such it should (?) show up when I run the app. But no! Nothing shows up (see figure 2). Has anyone had any similar experiences, or know what the problem might be?
Figure 1
Figure 2
It's a navigation based app - if that makes any difference - with the navigation part of the app set up programmatically like so:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
bookmarksController = [[BookmarksViewController alloc] init];
bookmarksController.managedObjectContext = [self managedObjectContext];
navController = [[UINavigationController alloc] initWithRootViewController:bookmarksController];
[bookmarksController release];
[self.window addSubview:navController.view];
[self.window makeKeyAndVisible];
return YES;
}
Turns out I had to explicitly point out which NIB to load:
bookmarksController = [[BookmarksViewController alloc] initWithNibName:#"BookmarksViewController" bundle:nil];
in the ViewDidLoad method:
self.searchDisplayController.searchBar.hidden = NO;
if that dosen't help then check all the connections in IB.
This a screenshot of the connections of the Files Owner in my tableview xib.
If even this dosen't help, please comment and I will try to figure out something else.

Show a view as a splash screen in didFinishLaunchingWithOptions

I have a Tab Bar Application and I want to simply display a view (splash screen) once the didFinishLaunchingWithOptions method loads up the tab bar controller. Why is this so hard? Please show me how I'd load up and show a Xib file called SplashView.xib below and display it:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Add the tab bar controller's view to the window and display.
[window addSubview:tabBarController.view];
[window makeKeyAndVisible];
// Load up and show splash screen Xib here
return YES;
}
First thing I'd mention is that splash screens are specifically frowned upon in the HIG. Especially ones that only serve to make the user wait & stare at some logo they don't care about.
Now that rant is out of the way, I'll assume that you probably have some loading going on that you'd like to have happen before the tabs are displayed.
In this case I don't load up a tab bar in the MainWindow.xib. Instead I launch my single view (with XIB) that does the loading. The reason is this: You'll pay for the loading of all of those views before you can even see your splash screen.
In the case of loading data, sometimes these tabs depend on this data being loaded, so it makes more sense to wait to load up the tab bar controller.
The app delegate ends up looking like this:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window makeKeyAndVisible];
[window addSubview:splashController.view]; //this assumes MainWindow.xib defines your splash screen, otherwise....
UIViewController *splashController = [[SplashController alloc] initWithNibName:#"SplashController" bundle:nil];
splashController.delegate = self;
[window addSubview:splashController.view];
//hang on to it in an ivar, remember to release in the dealloc
}
Then in the splash screen controller, when I'm done loading, I do this:
-(void)doneLoading {
[self.delegate performSelector:#selector(splashScreenDidFinishLoading)];
}
Of course self.delegate doesn't exist, and it can be added simply like this:
//header
#property (nonatomic, assign) id delegate;
//implementation
#synthesize delegate;
Then just make sure and implement that method on the app delegate:
-(void)splashScreenDidFinishLoading {
//load up tab bar from nib & display on window
//dispose of splash screen controller
}
I've used this pattern in a handful of apps and is simple and works well. You could also choose to do a nice transition animation in the method above.
Hope this helps.
In your app delegate's header file:
#interface AppDelegate {
...
IBOutlet UIView *splash; // add this line
}
In IB open the SplashView.xib, set the File Owner's class to the class of your app delegate, connect the splash outlet. Add this to show a splash view:
[[NSBundle mainBundle] loadNibNamed: #"SplashView" owner: self options: nil];
[window addSubview: splash];
You will possibly want to hide the splash view too:
[splash removeFromSuperview];
[splash release];
splash = nil;
You could use UIView animation block to fade out the splash view to be extra-cool. That said, splash screens are evil.
I think the app delegate is indeed a better place for this kind of stuff.
I would do something like:
UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"Splash.png"]];
[imageView setCenter:CGPointMake(240, 160)];
self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[self.view addSubview:imageView];
[imageView retain];
[NSTimer scheduledTimerWithTimeInterval:3.0 target:self //display for 3 secs
selector:#selector(continueLoadingWhatever:)
userInfo:nil
repeats:NO];
And then...
- (void)continueLoadingWhatever:(id)sender {
//do whatever comes after here
}
I probably wouldn't do this in the app delegate, but in the root view controller. You should never have to add anything unnecessary directly to the window, especially if it contains interaction (I know this doesn't).

UIView underneath Status Bar

Hi i have a strange issue after adding my UIViewController.view to my Application Window.
I created a window based app and added my view in my appDelegates didFinishLaunchingWithOptions method.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
overviewViewController *overView = [[overviewViewController alloc] initWithNibName:#"overviewViewController" bundle:nil];
//overView.view.bounds = CGRectMake(0.0f, 20.0f, 320.0f, 460.0f);
[window addSubview:overView.view];
//[overView release];
[window makeKeyAndVisible];
return YES;
}
clicking the "add" button presents a model view controller. after dismissing this modelViewController the main view fits perfectly.
as you can see, i also tried to set the bounds before adding my subview, without any success.
does anybody have some hints for me please, how to solve this problem?
You can fix this by setting this in your viewDidLoad method or even the viewWillAppear:
self.view.frame = [[UIScreen mainScreen] applicationFrame];
Also, I'm guessing you are hiding your status bar initially? Or do you have it always showing?
in your nib, check to make sure the simulated interface status bar is turned on so that it shows up when your editing your nib's view.
if this does not work, try setting the frame instead of bounds before you add it to the window.