Can I Animate an image iOS8 LaunchScreen.xib - ios

Question:
Are there ways to animate anything within the LaunchScreen.xib file of an Xcode 6 Project targeted to deploy for iOS 8.1+ ?
Context:
I'm looking to make simple animations to convey activity or serve as a distraction to the user while they wait...
Examples:
A Loading Bar
Activity Indicator
Animated GIF
Move a UIImage across the Screen
Rotate an Image

Nope.
The Launch Image is shown only during the time period between when the user chooses to launch your app and when your app has actually started running. During this period, your app can't take any actions such as performing an animation — it's not running yet. The Launch Image is just a static image that, when well designed, helps give the user the impression that your app is ready quickly.
(Some developers ignore the HIG and use the launch image to provide a splash screen, sometimes with an animated presentation. But in those cases, the launch screen is still a static image, and the animation happens once the app begins running — it's just that the first frame of animation drawn by the running app matches the appearance of the static launch image.)
This behavior didn't change with the LaunchScreen.xib feature in iOS 8 — it still appears only before your app is actually running, so it's still a static image. What the LaunchScreen.xib feature gets you is the ability to adaptively produce a launch image for many different device sizes and styles without having to separately design, render, and ship in your app bundle different images for each size/orientation/etc.
If your app isn't actually ready to use by the time it gains control, think about whether the "loading" tasks you're doing at that time really need to be done immediately, or if you can let the user start doing some things right away and do more setup work on a background thread or defer it until it's actually needed.

I don’t use splash screens often but when I do, I want them to open like a book.
In all truth, I’m not a big fan of splash screens and even Apple recommends using a default.png that shows the controls (with no text) of the application:
Display a launch image that closely resembles the first screen of the application. This practice decreases the perceived launch time of your application.
Avoid displaying an About window or a splash screen. In general, try to avoid providing any type of startup experience that prevents people from using your application immediately.
from HIG Guidelines
However, some people love them and one app in particular has a nice implementation splash screen — Path 2.0. When you open Path, you’re greeted with their logo on a red version of the Apple linen texture that animates open like a book (or journal as that’s what Path considers themselves to be).
You can get the source for this project here: https://github.com/jaysonlane/OpenBook
Before we begin, let me preface this with a disclaimer: I am very new to animations in Cocoa so bear with me. If you spot unnecessary or inefficient code, please leave a comment and I’ll tidy it up.
If you haven’t seen the animation, hop on the app store and pick up a copy to see what we’re trying to accomplish. I’ve created a default png that we can use cleverly titled Math (like a Math book that opens, right?) You can download that here (retina) and here.
To get started, let me explain “the trickery” behind what we’ll be doing: we’re going to use the normal default splash system in place to display our default.png. In the App Delegate, once the application has finished launching, we’re going to create a UIImageView on top of our view of that same default.png. We’ll then animate that UIImageView, to rotate open to reveal our view.
So let’s go:
Create a new project, I created one using the single view template but this will work with whatever. Go ahead and set your default.png and default#2x.png to the images supplied. You can do this by clicking the project in the navigation pane on the left, click the Target and scroll down to launch images:
Open your AppDelegate.m and add the following code to your application didFinishLaunching or application didFinishLaunchingWithOptions function:
//1. add the image to the front of the view...
UIImageView *splashImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[splashImage setImage: [UIImage imageNamed:#"Default"]];
[self.window addSubview:splashImage];
[self.window bringSubviewToFront:splashImage];
//2. set an anchor point on the image view so it opens from the left
splashImage.layer.anchorPoint = CGPointMake(0, 0.5);
//reset the image view frame
splashImage.frame = CGRectMake(0, 0, 320, 480);
//3. animate the open
[UIView animateWithDuration:1.0
delay:0.6
options:(UIViewAnimationCurveEaseOut)
animations:^{
splashImage.layer.transform = CATransform3DRotate(CATransform3DIdentity, -M_PI_2, 0, 1, 0);
} completion:^(BOOL finished){
//remove that imageview from the view
[splashImage removeFromSuperview];
}];
Three things are happening here…
1) We create a new UIImageView and add it to the top of the view
2) We set an anchor point on the left side of the image to make it open from the left and then reset the frame to the full size of the view
3) We animate the UIImageView and remove it from the view on completion
That’s it, it’s that simple.
Source: http://jaysonlane.net/tech-blog/2012/03/path-2-0-style-animated-splash-screen-default-png/

You can create the LaunchScreen.xib and then create a perfect replica that you can put code on and have a class like LaunchScreenAnimator that you can call form your delegate and that has a delegate to tell you when the animation is over
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
LaunchScreenAnimator *la=[LaunchScreenAnimator createWithDelegate:self];
self.window.rootViewController=la;
[self.window makeKeyAndVisible];
[la startAnimation];
return YES;
}
-(void) splashAnimationFinished:(LaunchScreenAnimator*)view
{
[self startWithDashboardWindow]; // replace the current rootViewController with whatever you want
}

Related

iOS white screen debugging

Sometimes, when I run app, I got white screen. But I know app is still running (coz I need to play sound).
Somehow, the view hierarchy mess up I guess. Problem is that I never see white screen if I run from Xcode. If I see, I will know how is the hierarchy.
dispatch_async(dispatch_get_main_queue(), ^{ //need to run in main thread.
self.window.rootViewController = self.defaultVC;
[self.window makeKeyWindow];
self.window.hidden = NO;
});
Is it because of view hierarchy? Or any other reason which can produce white screen?
There is an awesome little tool called PonyDebugger which enables view-based debugging. You just throw it all in your project and start it in your AppDelegate and you can see at anytime exactly what view is displayed.
You can basically step through the hierarchy like in "chrome F12".
This helped me solve WhiteScreen-problems in the past.
Check your Copy Bundle Resources (found within Build Phases) and make sure that all of your .xib files are correctly listed (e.g. that they are indeed there).
Also is there a specific reason you are creating that window programmatically instead of using setRootViewController?

Unable to configure launch screen appearance using view controller file

I have a LaunchScreen.storyboard which serves as the launch screen file. In this storyboard is a view controller with the class LaunchViewController.
In my LaunchViewController.m file I changed the view's background color and added a label with the FB shimmering effect (https://github.com/facebook/Shimmer).
_shimmeringView = [[FBShimmeringView alloc] init];
_shimmeringView.shimmering = YES;
_shimmeringView.shimmeringBeginFadeDuration = 0.3;
_shimmeringView.shimmeringOpacity = 0.3;
[self.view addSubview:_shimmeringView];
_logoLabel = [[UILabel alloc] initWithFrame:_shimmeringView.bounds];
_logoLabel.text = #"Shimmer";
_logoLabel.font = [UIFont fontWithName:#"HelveticaNeue-UltraLight" size:60.0];
_logoLabel.textColor = [UIColor whiteColor];
_logoLabel.textAlignment = NSTextAlignmentCenter;
_logoLabel.backgroundColor = [UIColor clearColor];
_shimmeringView.contentView = _logoLabel;
But when I ran it there's only an empty white background displayed as the launch screen. Also I find that he LaunchViewController looks fine when used as a regular view controller. How to make it display the same effect when used as launch screen?
You can't use code inside a launch view controller nib. Whether it is a storyboard or a separate nib. The code is not executed. The only thing that works is what is in InterfaceBuilder like auto layout and stuff. No code is loaded. This would defeat the purpose of using a launch file. The launcfile is loaded before the app has had chance to load.
No app, no code. Only the launch file.
I've had similar problems, and based on your code, it may be similar to mine. First off, I don't understand your question as much as I would like to. You said, "The LaunchViewController works fine when not used as launch screen." Does that mean that it looks the way you want it to look like when viewing on Xcode, but not on the simulator? I will try to provide possible solutions, and some trouble-shooting tips.
It could be something as simple as your background(or something) is at the front of the screen, blocking the rest. If so, you have to reconfigure the order of your items on your launch screen in your xib file in your application.
It could be an error on your part. Some of my programmer friends develop their launch screens using the Xcode interface: I find that easier to use, and it may have less errors.
It could be an issue with the iOS simulator. This is not likely to be true, but it could be. Try running the app on your device and see if it is fine there.
Troubleshooting: In order to trouble shoot your code, comment out your code, and load in all the elements of your launch screen one at a time, checking the iOS simulator and the console in between. You will eventually find the problematic code, and be able to fix it. From looking at your code, I don't see anything wrong (but don't take my word on it, I'm not familiar with coding the launchscreen/storyboard in swift. Good luck, and I hope my tips work. Also, if your launch screen is appearing fine inside Xcode, it is a programming error or an error on the iOS simulator. A picture or a description of your launch screen could also help future people who will answer this question.

Display 3D-Object with COCOS3D on top of AR-View

I work on an app, which scans an image and shows you a 3D-Object or a video on top of the image target. Normal AR-App. For that AR stuff I usw the Vuforia SDK. The problem is, that the Vuforia SDK don't support animated 3D-Objects and for that I use cocos3d.
So I created a basic cocos3d app and included my vuforia stuff for the AR. This works good and the app displays normal 3D-Objects and videos. This was the background, now the problem.
The first view I have is my camera view, which scans the images. If I scan now a specified target, I want to show an animated 3D-Object. For that, I display the cocos3d view on top of the AR-View. The cocos3d view is transparent and is displayed on top of the AR-View (tested this with a simple button in the cocos3d view).
The problem is, that I'am not able to display a animated 3D-Object. I tested some options but none of them worked because I don't really have an idea how to do that. My current code:
CCDirector *director = CCDirector.sharedDirector;
EAGLViewCC *glView = [EAGLViewCC viewWithFrame:[window bounds] pixelFormat:kEAGLColorFormatRGBA8 depthFormat:GL_DEPTH_COMPONENT16_OES];
[director setOpenGLView:glView];
[window addSubview:director.openGLView];
After that I have a layer and add the test scene to my layer (Standard from the example). But than I don't know how to display it. It tried this:
[director pushScene:scene];
but no luck. In the example, they use this code to show the object (viewController is of type "CC3DeviceCameraOverlayUIViewController").
[viewController runSceneOnNode: mainLayer];
Why don't I use the viewController? Because I couldn't get the view transparent. So how do I get the 3D-Object displayed in my view? What do I have to do? Am I completely wrong?

iOS Duration of Splash Screen (Default.png)

im using a Default.png file for my iPad-app. It appears correctly but i could'nt find a way to modify the duration of the splash screen. Has somebody any suggestions? Google has many sites that show how to setup the startscreen but could'nt find a solution for my problem.
The first rule of Human Interface Guidelines for Splash Screens is: don't use splash screens. The second rule is: don't use splash screens!:
Supply a launch image to improve user experience.
Avoid using your launch image as an opportunity to provide:
An “application entry experience,” such as a splash screen
An About window
Branding elements, unless they are a static part of your application’s first screen
If you absolutely must include a long-duration splash screen, and have darn good reasons for doing so, the usual approach is to throw up a UIImageView containing a copy of you launch image in, e.g., application:didFinishLaunchingWithOptions: - which should provide the illusion of a lengthy splash screen.
But please don't.
Using a "splash screen" (Logo, etc) is not the idea of the Default.png!
Read the HIG from Apple.
The (splash) screen (named loading screen) is not for a Logo showing or something like this.
When having multitasking enabled, the "splash screen" shows up really rare.
The splash screen should, like the apple apps does, only show the interface coming up in the first application screen without any localized strings, etc.
Also keep in mind:
The faster the iOS Device get, the shorter you can see the Default.png. So avoid using it for any important CI/CD content.
The Default image is displayed while the app is loading and will be dismissed as soon as the app is ready. And there is no API to control that duration.
You can't technically modify the duration that the "Default" image stays there; it is designed to just be a temporary image "foreshadowing" the app actually starting up and isn't specifically designed as a splash screen.
I recommend that you keep the "splash screen effect" by adding an image view to the screen as the app starts in the -application:didFinishLaunchingWithOptions: method. You can then set a timer which calls a method to animate the splash off after the designated time you want it to be. It will be there for a little longer than you specify depending on how long it actually took the app to load up, but it will give the effect you're after.
You can set the image view's image to [UIImage imageNamed:#"Default"] and it will access that Default artwork for you.
You can't change the duration. If you want it be shown longer though, you can add the same image to a view that you show while you're loading your data!
There is a good blog post here on how to create a splash screen using a UIImageView with a timer:
http://nullpointr.wordpress.com/2012/02/19/iphone-dev-how-to-implement-a-splash-screen/
Useful for beginners, who are still learning the best way to do things in iOS.
As #Conrad Shultz answered, splash screen should be used only via the supplied LaunchScreen.storyboard file by Xcode.
However, in rare situations you do want to prolong the splash screen:
Download A LOT of files before the app starts since the app depends on them.
Other reason...
This is the way to do it:
Inside AppDelegate, under didFinishLaunchingWithOptions you should:
Create a VC that has the same splash image and the same constraints
Present it
Dismiss it after a given time
The code:
let splashVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "splash")
window?.makeKeyAndVisible()
if let root = window?.rootViewController
{
root.present(splashVC, animated: false, completion: nil)
let dispatchTime = DispatchTime.now() + 3
// didFinishLaunchingWithOptions will return and this block will be executed afterwards, hence, async..
DispatchQueue.main.asyncAfter(deadline: dispatchTime, execute: {
root.presentedViewController?.dismiss(animated: false, completion: nil)
})
}
}

iPhone app in landscape mode, 2008 systems

Please note that this question is from 2008 and now is of only historic interest.
What's the best way to create an iPhone application that runs in landscape mode from the start, regardless of the position of the device?
Both programmatically and using the Interface Builder.
Historic answer only. Spectacularly out of date.
Please note that this answer is now hugely out of date/
This answer is only a historical curiosity.
Exciting news! As discovered by Andrew below, this problem has been fixed by Apple in 4.0+.
It would appear it is NO longer necessary to force the size of the view on every view, and the specific serious problem of landscape "only working the first time" has been resolved.
As of April 2011, it is not possible to test or even build anything below 4.0, so the question is purely a historic curiosity. It's incredible how much trouble it caused developers for so long!
Here is the original discussion and solution. This is utterly irrelevant now, as these systems are not even operable.
It is EXTREMELY DIFFICULT to make this work fully -- there are at least three problems/bugs at play.
try this .. interface builder landscape design
Note in particular that where it says "and you need to use shouldAutorotateToInterfaceOrientation properly everywhere" it means everywhere, all your fullscreen views.
Hope it helps in this nightmare!
An important reminder of the ADDITIONAL well-known problem at hand here: if you are trying to swap between MORE THAN ONE view (all landscape), IT SIMPLY DOES NOT WORK. It is essential to remember this or you will waste days on the problem. It is literally NOT POSSIBLE. It is the biggest open, known, bug on the iOS platform. There is literally no way to make the hardware make the second view you load, be landscape. The annoying but simple workaround, and what you must do, is have a trivial master UIViewController that does nothing but sit there and let you swap between your views.
In other words, in iOS because of a major know bug:
[window addSubview:happyThing.view];
[window makeKeyAndVisible];
You can do that only once. Later, if you try to remove happyThing.view, and instead put in there newThing.view, IT DOES NOT WORK - AND THAT'S THAT. The machine will never rotate the view to landscape. There is no trick fix, even Apple cannot make it work. The workaround you must adopt is having an overall UIViewController that simply sits there and just holds your various views (happyThing, newThing, etc). Hope it helps!
From the Apple Dev Site:
To start your application in landscape
mode so that the status bar is in the
appropriate position immediately, edit
your Info.plist file to add the
UIInterfaceOrientation key with the
appropriate value
(UIInterfaceOrientationLandscapeRight
or
UIInterfaceOrientationLandscapeLeft),
as shown in Listing 2.
Listing 2: Starting your application
in landscape mode
<key>UIInterfaceOrientation</key>
<string>UIInterfaceOrientationLandscapeRight</string>
Summary and integration from all the posts, after testing it myself; check the update for 4.x, 5.x below.
As of 3.2 you cannot change the orientation of a running application from code.
But you can start an application with a fixed orientation, although doing so this is not straightforward.
Try with this recipe:
set your orientation to UISupportedInterfaceOrientations in the Info.plist file
in your window define a 480x320 "base view controller". Every other view will be added as a subview to its view.
in all view controllers set up the shouldAutorotateToInterfaceOrientation: method (to return the same value you defined in the plist, of course)
in all view controllers set a background view with
self.view.frame = CGRectMake(0, 0, 480, 320)
in the viewDidLoad method.
Update (iOS 4.x, 5.x): the Apple iOS App Programming Guide has a "Launching in Landscape Mode" paragraph in the "Advanced App Tricks" chapter.
References:
interface builder landscape design
interface builder landscape design-1
First I set in info.plist
<key>UIInterfaceOrientation</key>
<string>UIInterfaceOrientationLandscapeRight</string>
then I put this code in applicationDidFinishLaunching:
CGAffineTransform rotate = CGAffineTransformMakeRotation(1.57079633);
[window setTransform:rotate];
CGRect contentRect = CGRectMake(0, 0, 480, 320);
window.bounds = contentRect;
[window setCenter:CGPointMake(160.0f, 240.0f)];
This way I can work on the view in Interface Builder in landscape mode.
sasb's and michaelpryor's answer appears to be correct, but if it's not working for you, try this alternative:
- (void)applicationDidFinishLaunchingUIApplication *)application {
application.statusBarOrientation = UIInterfaceOrientationLandscapeRight;
}
Or this one:
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
Or this one:
[application setStatusBarOrientation: UIInterfaceOrientationLandscapeRight animated:NO];
You may also have to call window makeKeyAndVisible; first.
A few links: Developing in landscape mode, iPhone SDK: How to force Landscape mode only?
#Robert: please refer to The iPhone SDK, NDA, and Stack Overflow.
I'm surprised no one has come up with this answer yet:
In all my tests when a dismissing a modal view controller the parent view controller's preferred orientation set in shouldAutorotateToInterfaceOrientation is honored even when part of a UINavigationController. So the solution to this is simple:
Create a dummy UIViewController with a UIImageView for a background. Set the image to the default.png image your app uses on startup.
When viewWillAppear gets called in your root view controller, just present the dummy view controller without animation.
when viewDidAppear gets called in your dummy view controller, dismiss the view controller with a nice cross dissolve animation.
Not only does this work, but it looks good! BTW, just for clarification i do the root view controller's viewWillAppear like this:
- (void)viewWillAppear:(BOOL)animated
{
if ( dummy != nil ) {
[dummy setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentModalViewController:dummy animated:NO];
[dummy release];
dummy = nil;
}
...
}
The latest iPhone OS Programming Guide has a full section on this, with sample code. I am sure this is a recent addition, so maybe you missed it. It explains all the conditions you have to comply with; basically...
set the Info.plist properties (this changes the position of the status bar, but not the view)
rotate your view manually around its center, on either your UIViewController viewDidLoad: method or your applicationDidFinishLaunching: method or implement auto rotation ("Autoresizing behaviors", page 124)
Look for "Launching in Landscape Mode", page 102.
See this answer: Landscape Mode ONLY for iPhone or iPad
add orientation to plist
shouldAutorotateToInterfaceOrientation = YES in all files
Although if you're using mixed modes, you might be better off with
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];

Resources