I want the splash screen to be displayed each time app becomes active. I have created a function showSplash which I call in applicationDidBecomeActive:
-(void)showSplash
{
UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: #"Default.png"]];
[self.window.rootViewController.view addSubview: splashScreen];
[self.window makeKeyAndVisible];
NSLog(#"begin splash");
[UIView animateWithDuration: 4.2
delay: 0.5
options: UIViewAnimationOptionCurveEaseOut
animations: ^{
splashScreen.alpha = 0.0;
}
completion: ^ (BOOL finished) {
[splashScreen removeFromSuperview];
NSLog(#"end splash");
}
];
}
This is how I call this function :
- (void)applicationDidBecomeActive:(UIApplication *)application {
[self showSplash];
}
But no splash screen appears. Please correct me.
If you want the application to have a fresh start every time you get back to it, you could also disable background execution, as stated in the Apple Documentation (last section titled "Opting Out of Background Execution"):
If you do not want your app to run in the background at all, you can
explicitly opt out of background by adding the
UIApplicationExitsOnSuspend key (with the value YES) to your app’s
Info.plist file.
after adding the splash view - bring it to front
change
UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: #"Default.png"]];
[self.window.rootViewController.view addSubview: splashScreen];
[self.window makeKeyAndVisible];
to
UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: #"Default.png"]];
[self.window addSubview: splashScreen];
[self.window bringSubviewToFront: splashScreen]; //!
[self.window makeKeyAndVisible];
Please, ensure your window root view controller main view is the top most view in your App in the moment you want to show splash...
Check frame of splashScreen (UIImageView). Set its frame to bounds of your root view controller.
You can try to hunt the top view controller with a recursion like this:
- (UIViewController *)findTopViewController {
return [self topViewControllerFrom:self.window.rootViewController];
}
- (UIViewController *)topViewControllerFrom:(UIViewController *)vc {
if (vc.navigationController.visibleViewController != nil) {
return [self topViewControllerFrom:vc.navigationController.visibleViewController];
}
if (vc.tabBarController.selectedViewController != nil) {
return [self topViewControllerFrom:vc.tabBarController.selectedViewController];
}
return vc;
}
Now calling [self findTopViewController] should hopefully return the currently visible/top VC of your app, and you can do:
[[self findTopViewController].view addSubview:splashScreen];
...
you can do something like:
#import "AppDelegate.h"
#define kSplashScreen (UIScreen.mainScreen.bounds.size.height == 568) ? #"Default-568h" \
: (UIScreen.mainScreen.bounds.size.height == 667) ? #"Default-667" \
: (UIScreen.mainScreen.bounds.size.height == 736) ? #"Default-Portrait" \
: #"Default"
#interface AppDelegate ()
#property (nonatomic) UIWindow *splashWindow;
#property (nonatomic) UIWindow *keyWindow;
#property (nonatomic, getter=isSplashConfigured) BOOL splashConfigured;
#property (nonatomic, getter=isShowingSplash) BOOL showingSplash;
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self animateSplash];
return YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
[self showOrHideSplash];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[self showOrHideSplash];
}
- (void)showOrHideSplash
{
[self.splashWindow setHidden:[self isShowingSplash]];
if ([self isShowingSplash])
{
[self.keyWindow makeKeyAndVisible];
}
else
{
[self.splashWindow makeKeyAndVisible];
[self animateSplash];
}
self.showingSplash = !self.showingSplash;
}
- (void)animateSplash
{
if ([self isSplashConfigured])
{
[self.window.rootViewController.view addSubview:self.splashWindow];
[self.window makeKeyAndVisible];
}
else
{
self.keyWindow = [[UIApplication sharedApplication] keyWindow];
self.splashWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.splashWindow.rootViewController = [[UIViewController alloc] init];
self.splashWindow.rootViewController.view.frame = self.splashWindow.bounds;
UIImageView *splashImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:kSplashScreen]];
splashImage.frame = self.splashWindow.bounds;
[self.splashWindow.rootViewController.view addSubview:splashImage];
[self.splashWindow makeKeyAndVisible];
[self.splashWindow setHidden:YES];
self.splashConfigured = YES;
}
NSLog(#"begin splash");
__weak AppDelegate* weakSelf = self;
[UIView animateWithDuration:4.2 delay:0.5 options:UIViewAnimationOptionCurveEaseOut animations: ^{
weakSelf.splashWindow.alpha = 1.0;
weakSelf.splashWindow.alpha = 0.0;
} completion: ^(BOOL finished) {
[weakSelf.splashWindow removeFromSuperview];
NSLog(#"end splash");
}];
}
#end
This is a bit cumbersome solution, but it works fine. The idea is add new UIWindow on top of all controllers
- (void)showSplash {
id <UIApplicationDelegate> appDelegate = [[UIApplication sharedApplication] delegate];
UIWindow *window = [[UIWindow alloc] initWithFrame:[appDelegate window].frame];
UIViewController *splashController = [UIViewController new];
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Default.png"]];
splashController.view = imgView;
window.rootViewController = splashController;
window.windowLevel = UIWindowLevelAlert;
window.hidden = NO;
[window makeKeyAndVisible];
[UIView animateWithDuration:4.2 delay:0.5 options:UIViewAnimationOptionCurveEaseOut animations:^{
window.alpha = 0.0;
} completion:^(BOOL finished) {
window.hidden = YES;
window.rootViewController = nil;
[[appDelegate window] makeKeyAndVisible];
[[appDelegate window] setNeedsDisplay];
}];
}
Please find below a solution for this problem.
Split the splash screen code into two methods; showSplash and hideSplash.
Call showSplash in the method applicationWillResignActive. In the method, create and add the imageView to rootViewController; set it's alpha to 0.0f and then animate it to alpha 1.0f. This is to make sure that the user doesn't see the imageView when the app is going to background.
Now call hideSplash in applicationDidBecomeActive. In hideSplash remove the imageView with animation. See the code below;
-(void)showSplash
{
_splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: #"Default"]];
[self.window.rootViewController.view addSubview:_splashScreen];
_splashScreen.alpha = 0.0f;
[UIView animateWithDuration:0.3f animations:^{
_splashScreen.alpha = 1.0f;
}];
}
- (void)hideSplash
{
[UIView animateWithDuration: 4.2
delay: 0.5
options: UIViewAnimationOptionCurveEaseOut
animations: ^{
_splashScreen.alpha = 0.0;
}
completion: ^ (BOOL finished) {
[_splashScreen removeFromSuperview];
NSLog(#"end splash");
}
];
}
- (void)applicationWillResignActive:(UIApplication *)application {
[self showSplash];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[self hideSplash];
}
I hope this helps! :-)
Add
splashScreen.frame = self.window.rootViewController.view.frame;
below
UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: #"alertBg.png"]];
example
-(void)showSplash
{
UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed: #"Default.png"]];
splashScreen.frame = self.window.rootViewController.view.frame;
[self.window.rootViewController.view addSubview: splashScreen];
[self.window makeKeyAndVisible];
NSLog(#"begin splash");
[UIView animateWithDuration: 4.2
delay: 0.5
options: UIViewAnimationOptionCurveEaseOut
animations: ^{
splashScreen.alpha = 0.0;
}
completion: ^ (BOOL finished) {
[splashScreen removeFromSuperview];
NSLog(#"end splash");
}
];
}
The best way to achieve this is to add the image in AppDelegate's window.
In the below code statusView is one of the view, which consist of some image. So add it to your AppDelegate's window as a subView
[[[[UIApplication sharedApplication] delegate] window] addSubview:statusView];
Now whenever you want it to appear for some amount of time, you show this view, but same time bring it to front.
-(void)showStatusView{
[UIView animateWithDuration:0.5 animations:^{
[[[[UIApplication sharedApplication] delegate] window] bringSubviewToFront:statusView];
statusView.alpha = 1;
}];
}
Better Call the above method on the AppDelegate's method didBecomeActive.
Also, show the splash screen as soon as application is going to resign active. This way, iOS will take the snapshot of the screen, which will be shown for fraction of seconds when the app is about to become active.
- (void)applicationDidEnterBackground:(UIApplication *)application {
[self showStatusView];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[self showStatusView];
}
Once the app is active, you can show the actual splash screen for some duration & then your usual app state.
First create your launch screen or image in didFinishLaunchingWithOptions function.
After this write your code like this-
Root view controller is not always the presented view controller. This can cause your splash screen to be hidden under bunch of other view controllers. Try using something like (swift syntex):
func getTopViewController() -> UIViewController?{
if var topController = UIApplication.sharedApplication().keyWindow?.rootViewController{
while ((topController.presentedViewController) != nil) {
topController = topController.presentedViewController!
}
return topController
}
return nil
}
And add your splash view to the top view controller
launch your application normally every-time, call your method in applicationBecomeActive, and add you image view on Appdelegate.window and remove it after some time by timer.
[self.window addSubview: splashScreen];
You should use the following line:
[self.window addSubview: splashScreen];
instead of
[self.window.rootViewController.view addSubview: splashScreen];
You can reuse your launchScreen to show up instead of showing imageview. This comes handdy when you have complex launchscreen instead of single image as a splash screen.
func applicationWillResignActive(_ application: UIApplication) {
guard let window = UIApplication.shared.windows.last,
let launchScreen = UIStoryboard(name: "LaunchScreen", bundle: nil).instantiateInitialViewController(),
let launchView = launchScreen.view else {return}
launchView.tag = 8888
launchView.frame = window.bounds
launchView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
window.addSubview(launchView)
window.makeKeyAndVisible()
}
func applicationDidBecomeActive(_ application: UIApplication) {
guard let window = UIApplication.shared.windows.last,
let view = window.viewWithTag(8888) else {return}
view.removeFromSuperview()
}
Related
I want to show alert in status bar for small duration with animation and hide systems status bar for that duration
I have referred this but enable to hide system's status bar for that particular time,failed to add animation
Here is my code
NSString *status=#"welcome..";
UIView *notificationView= [JDStatusBarNotification showWithStatus:(NSString *)status styleName:JDStatusBarStyleDark];
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
notificationView.frame=statusBarFrame;
[self.view addSubview:notificationView];
UIView *dismissNotificationView=[JDStatusBarNotification showWithStatus:(NSString *)status
dismissAfter:(NSTimeInterval)5.0f styleName:JDStatusBarStyleDark];
[self.view addSubview:dismissNotificationView]; `
also tried this but it moves another window then shows and turns back
here is the code used
MTStatusBarOverlay *overlay = [MTStatusBarOverlay sharedInstance];
overlay.animation = MTStatusBarOverlayAnimationFallDown; // MTStatusBarOverlayAnimationShrink
overlay.detailViewMode = MTDetailViewModeHistory; // enable automatic history-tracking and show in detail-view
overlay.delegate = self;
overlay.progress = 0.0;
[overlay postImmediateFinishMessage:#"welcome" duration:2.0 animated:YES];
overlay.progress = 1.0;
please help..thanks in advance
I'm not sure when you want the alert to appear, so I will assume just after loading the view. I didn't use the two frameworks, but tested it with a generic red UIView and it worked with the code below:
#import "ViewController.h"
#interface ViewController () {
BOOL animating;
CGRect aimFrame;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
animating = YES; //To set if we are showing the alert or not
aimFrame = [[UIApplication sharedApplication] statusBarFrame];
[self setNeedsStatusBarAppearanceUpdate];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UIView *notificationView = [[UIView alloc] init];
[notificationView setFrame:aimFrame];
[notificationView setBackgroundColor:[UIColor redColor]];
[self.view addSubview:notificationView];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[notificationView removeFromSuperview];
animating = NO;
[self setNeedsStatusBarAppearanceUpdate];
});
}
- (BOOL)prefersStatusBarHidden {
// Toggle based upon if we are showing the alert
if (animating) {
return YES;
} else {
return NO;
}
}
#end
I hope this helps, let me know if it still doesn't work or if I miss understood something :)
Try my code to complete hide the status bar:
-(BOOL)prefersStatusBarHidden{
return YES;
}
Ive seen similar question asked already so apologies if there were a correct answer I missed.
My app has to be in portrait mode all the time except when it shows media player which has to be in landscape full screen mode.
Here is how its done:
AppDelegate.m
#implementation HCAAppDelegate
+(void) landscapeLock {
HCAAppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
appDelegate.screenIsLandscapeOnly= true;
appDelegate.screenIsPortraitOnly = false;
}
+(void) portraitLock
{
HCAAppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
appDelegate.screenIsPortraitOnly = true;
appDelegate.screenIsLandscapeOnly = false;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
[HCAAppDelegate portraitLock];
}
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
NSUInteger orientations = UIInterfaceOrientationMaskPortrait;
if (self.screenIsPortraitOnly) {
return UIInterfaceOrientationMaskPortrait;
} else if (self.screenIsLandscapeOnly) {
return UIInterfaceOrientationMaskLandscape;
} else {
if(self.window.rootViewController) {
UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return orientations;
}
}
Media player is created as
-(void) _initPlayer
{
[HCAAppDelegate landscapeLock];
_moviePlayer = [[HCAMoviePlayerController alloc]init];
[_moviePlayer setControlStyle:MPMovieControlStyleDefault];
_moviePlayer.shouldAutoplay = YES;
[self.view addSubview:_moviePlayer.view];
[_moviePlayer setFullscreen:YES animated:YES];
}
and dismissed as
- (void) _finishPlay
{
...
[_moviePlayer.view removeFromSuperview];
[HCAAppDelegate portraitLock];
}
When player is initialized it goes to landscape, but when its dismissed it still remains in the landscape mode , why the portraitLock method did not work ?
Thanks!
After looking more into this issue I understood where the bug is. Will post the answer here to close the case and provide a working example of subj.
Adding mediaPlayer view to the existing view controller
[self.view addSubview:_moviePlayer.view];
works but after removing it
[_moviePlayer.view removeFromSuperview];
the portraitLock does not affect self.view
The working way is to create a new controller and present / dismiss it:
here is the code:
Presenting the view for FullScreen playback. Note that height/width is switched in the
line _moviePlayer.view setFrame:
UIViewController *movieVC = (UIViewController*) [storyboard instantiateViewControllerWithIdentifier:#"MoviePlayer"];
movieVC.view = [[UIView alloc] initWithFrame:CGRectMake(0,
0,
[[UIScreen mainScreen] applicationFrame].size.width,
[[UIScreen mainScreen] applicationFrame].size.height)];
[HCAAppDelegate landscapeLock];
[_moviePlayer.view setFrame:CGRectMake(0,
0,
movieVC.view.frame.size.height,
movieVC.view.frame.size.width)];
[movieVC.view addSubview:_moviePlayer.view];
[self.navigationController presentViewController:movieVC animated:YES completion:nil];
Dismissing the view:
[_moviePlayer stop];
[HCAAppDelegate portraitLock];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
I am subclassing a UINavigationController to serve as the main root controller of my application. The purpose of the view controller is to present a custom splash screen that allows for a swipe action from (right to left) to enter the main application. The custom transition fades the splash view during the swipe and reveals the main application underneath (a UITabBarController). Most of my code is following the objc.io article on custom view controller transitions in iOS7: http://www.objc.io/issue-5/view-controller-transitions.html.
Everything seems to work as expected. However, very rarely, I am getting reports of a black screen appearing once the splash screen disappears, instead of the main screen. I have been unable to reproduce the behavior. Here is the code:
First, setting up the main root view controller in the custom app delegate:
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.rootViewController = [[CustomRootViewController alloc] initWithNavigationBarClass:nil toolbarClass:nil];
self.window.rootViewController = self.rootViewController;
[self.window makeKeyAndVisible];
}
Important portions from CustomRootViewController (note I'm hiding the navigation bar):
- (instancetype) initWithNavigationBarClass:(Class)navigationBarClass toolbarClass:(Class)toolbarClass
{
self = [super initWithNavigationBarClass:navigationBarClass toolbarClass:toolbarClass];
if (self) {
self.navigationBarHidden = YES;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.delegate = self;
// This is the main UI for the app
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]];
CustomTabBarControllerViewController *mainViewController = [mainStoryboard instantiateInitialViewController];
self.mainViewController = mainViewController;
UIStoryboard *splashStoryboard = [UIStoryboard storyboardWithName:#"Splash" bundle:[NSBundle mainBundle]];
SplashViewController *splashViewController = [splashStoryboard instantiateInitialViewController];
self.splashViewController = splashViewController;
// Initialize the navigation controller to have the main app sitting under the splash screen
self.viewControllers = #[self.mainViewController, self.splashViewController];
}
// In the public interface, called from the Splash screen when the user can perform the action
- (void)allowSwipeToDismiss
{
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
panGestureRecognizer.delegate = self;
[self.view addGestureRecognizer:panGestureRecognizer];
}
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC
{
if (operation == UINavigationControllerOperationPop) {
return [[CustomRootViewControllerAnimator alloc ] init];
}
return nil;
}
- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController
{
return self.interactiveController;
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
// Only enable swiping when on the Swipe To Enter screen
// After we are in the main app, we don't want this gesture recognizer interfering with the rest of the app
if (self.topViewController == self.splashViewController) {
return true;
} else {
return false;
}
}
- (void)handlePan:(UIPanGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateBegan) {
self.interactiveController = [[UIPercentDrivenInteractiveTransition alloc] init];
[self popViewControllerAnimated:YES];
} else if (recognizer.state == UIGestureRecognizerStateChanged) {
CGPoint translation = [recognizer translationInView:self.view];
CGFloat viewWidth = self.view.bounds.size.width;
CGFloat percentDone = -translation.x / viewWidth;
[self.interactiveController updateInteractiveTransition:percentDone];
} else if (recognizer.state == UIGestureRecognizerStateEnded) {
if (self.interactiveController.percentComplete < 0.5) {
[self.interactiveController cancelInteractiveTransition];
} else {
[self.interactiveController finishInteractiveTransition];
}
self.interactiveController = nil;
}
}
And here is the code for the CustomRootViewControllerAnimator being returned by my custom UINavigationController:
#implementation CustomRootViewControllerAnimator
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
return 1;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
[[transitionContext containerView] insertSubview:toViewController.view
belowSubview:fromViewController.view];
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
CGFloat screenWidth = [[UIScreen mainScreen] bounds].size.width;
fromViewController.view.transform = CGAffineTransformMakeTranslation(-screenWidth, 0);
fromViewController.view.alpha = 0;
} completion:^(BOOL finished) {
fromViewController.view.transform = CGAffineTransformIdentity;
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
#end
Was finally able to replicate the problem, but only in iOS 7.0. By starting the interactive transition, then canceling it, I was able to get the black screen on the next start of the transition. In the completion block, I needed to set the alpha value of the fromViewController back to 1. Again, this is only necessary in iOS 7.0. It does not happen in 7.1.
I have a problem with an app that won't set frames outside -init and -viewWillLayoutSubviews methods. What should happen when one taps the editButton is an animation that will hide the editor view. Nonetheless, nothing happens as I test it. The problem doesn't come from the animation method since the -setFrame method as it - not included in the block - doesn't work neither.
Here is the code :
-(id)init {
if (self = [super init]) {
editButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(editButtonTapped)];
doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneButtonTapped)];
editor = [[UIView alloc] init];
[editor setBackgroundColor:[UIColor yellowColor]];
editor.clipsToBounds = YES;
editorIsOpen = YES;
portraitRegularModeEditorRect = CGRectMake(15, 59, 738, 100);
portraitClosedEditorEditorRect = CGRectMake(15, 59, 738, 0);
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[[self view] addSubview:editor];
[[self view] setBackgroundColor:[UIColor blueColor]];
}
-(void)viewDidAppear:(BOOL)animated {
[self setForRegularMode];
}
-(void)viewWillLayoutSubviews {
UIInterfaceOrientation io = [[UIApplication sharedApplication] statusBarOrientation];
if (io == UIInterfaceOrientationPortrait || io == UIInterfaceOrientationPortraitUpsideDown) {
//portrait
[editor setFrame:portraitRegularModeEditorRect];
} else {
//landscape
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(void)editButtonTapped {
[self setForScenarioLinesEditingMode];
}
-(void)doneButtonTapped {
[self setForRegularMode];
}
-(void)setForRegularMode {
editingMode = CPRegularMode;
if (!editorIsOpen) {
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationCurveEaseOut animations:^(void){
[editor setFrame:portraitRegularModeEditorRect];
} completion:^(BOOL finished) {
editorIsOpen = YES;
}];
}
[[self navigationItem] setRightBarButtonItems:[[NSArray alloc] initWithObjects:editButton,nil]];
}
-(void)setForScenarioLinesEditingMode {
editingMode = CPScenarioLinesEditingMode;
if (editorIsOpen) {
[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationCurveEaseOut animations:^(void){
[editor setFrame:portraitClosedEditorEditorRect];
} completion:^(BOOL finished) {
editorIsOpen = NO;
}];
}
[[self navigationItem] setRightBarButtonItems:[[NSArray alloc] initWithObjects:doneButton,nil]];
}
If anyone can help, thanks in advance ;)
I think that the problem in your case is the fact that in -(void)viewWillLayoutSubviews method you set, lets say the default frame of your view, if you try to change the frame in other methods after the setFrame is called on your view, the -(void)viewWillLayoutSubviews will also be called and the frame of the view will be the default one. Try to remove the setFrame from your -(void)viewWillLayoutSubviews.
Is your view controller set up in storyboards, and are you using Autolayout (which is on by default?) If so, setFrame won't work and you need to edit constraints after creating outlets to them from the storyboard.
Alternatively, you can turn off Autolayout in your storyboard, as shown here.
My client wants his splash image to fade out and then show the UI. I am not sure how to do this. As of right now it just appears once it loads. Is there a simple way to do this ?
UIImageView *splash=[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"splash"]];
[UIView animateWithDuration:1
animations:^{
splash.alpha = 0.0;
}
completion:^(BOOL finished)
{
[splash release];
}];
I was looking at this tutorial but decided not to implement it so I cant vouch as to whether it works or not but everything looks in check
http://www.dobervich.com/2010/10/22/fade-out-default-ipad-app-image-with-proper-orientation/
Beware though adding to much to your app startup is grounds for app rejection.
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.
Source: Apple Developer Site
As I just explained on a closely related question, don't use splash screens! Please relate this to your client, who might not be familiar with the Human Interface Guidelines.
That said, if you can't convince you client otherwise, you can just fade out the UIImageView that I mentioned in my other response.
You can implement your own UIViewController as a splash screen:
#interface SplashScreenViewController : UIViewController {
UIImageView *splashView;
}
#end
//
#import "SplashScreenViewController.h"
#implementation SplashScreenViewController
#pragma mark - View lifecycle
- (void)loadView {
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
splashView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[splashView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
[self.view addSubview:splashView];
}
- (void)viewWillAppear:(BOOL)animated {
if (isIPad) {
if (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))
splashView.image = [UIImage imageNamed:#"Default-Portrait~ipad.png"];
else
splashView.image = [UIImage imageNamed:#"Default-Landscape~ipad.png"];
}
else
splashView.image = [UIImage imageNamed:#"Default.png"];
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (isIPad) {
if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation))
splashView.image = [UIImage imageNamed:#"Default-Portrait~ipad.png"];
else
splashView.image = [UIImage imageNamed:#"Default-Landscape~ipad.png"];
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (isIPad ? YES : UIInterfaceOrientationIsPortrait(interfaceOrientation));
}
#end
Then, after showing, you can hide this UIViewController with any transition you want.