A Launch Storyboard or Xib Must Be Provided Unless the App Requires Full Screen

A launch storyboard or xib must be provided unless the app requires full screen

Starting from iOS9 and Xcode 7 you are required to provide a LaunchScreen.storyboard for your launch screen in order to support the new multitasking feature on iPad.

To opt out of being eligible to participate in Slide Over and Split View, add the UIRequiresFullScreen key to your Xcode project’s Info.plist file and apply the Boolean value YES.

Find out more on Apple's reference (check last paragraph) or watch session 205 Getting Started with Multitasking on iPad in iOS 9 @ 10:35.

Launch Screen not working on iOS 14 with Xcode 12

So here are a lot of good ideas, but I was able to finally solve the issue - it is more like a workaround. I needed to store the picture outside the Images.xcassets folder and then it started to work again. This is a very weird issue.

iOS 9 Splash screen is black

Same problem here after I updated to iOS 9. Re-installing the app from the App Store seems to solve the problem. I guess, it's an iOS 9 glitch.

iOS Launch Screen storyboard changes constraints on rest of user interface

It's unfortunate that your app was designed for one specific device...

I played around a bit with (essentially) putting your entire app into a "container" view, with not-great results.

If you want to see the general idea - you might be able to get it to work for you...

Add a RootContainerViewController:

RootContainerViewController.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface RootContainerViewController : UIViewController

@property (nonatomic, strong) UIView *container;

@end

NS_ASSUME_NONNULL_END

RootContainerViewController.m

#import "RootContainerViewController.h"

@interface RootContainerViewController ()

@end

@implementation RootContainerViewController

- (void)viewDidLoad {
[super viewDidLoad];

self.view.backgroundColor = [UIColor blackColor];

self.container = [UIView new];
self.container.backgroundColor = [UIColor redColor];
[self.container setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:self.container];

UILayoutGuide *g = [self.view safeAreaLayoutGuide];

[NSLayoutConstraint activateConstraints:@[

[self.container.topAnchor constraintEqualToAnchor:g.topAnchor constant:0.0],
[self.container.bottomAnchor constraintEqualToAnchor:g.bottomAnchor constant:0.0],
[self.container.widthAnchor constraintEqualToAnchor:self.container.heightAnchor multiplier:1024.0 / 768.0],
[self.container.centerXAnchor constraintEqualToAnchor:g.centerXAnchor],

]];

}

- (UIStatusBarStyle)preferredStatusBarStyle {
if (@available(iOS 13.0, *)) {
return UIStatusBarStyleLightContent;
} else {
// Fallback on earlier versions
}
}

@end

and change your ApplicationDelegate_Pad.m to this:

#import "ApplicationDelegate_Pad.h"
#import "MPRootViewController.h"
#import "MPDetailViewController.h"

#import "RootContainerViewController.h"

@implementation ApplicationDelegate_Pad

@synthesize tabBarController;
@synthesize splitViewController;
@synthesize rootViewController;
@synthesize detailViewController;
@synthesize splitViewControllerD;

-(void) makeSplitViewController {

// Create an array of controllers that will correspond to each tab in the tab bar vc.
NSMutableArray *controllers = [NSMutableArray arrayWithArray:self.tabBarController.viewControllers];

int index = 0;
for (UIViewController *controller in self.tabBarController.viewControllers) {

// Set the split vc in the Presentation tab to hold the playlist in the root vc and the presenter controls in the detail vc.
if (index == 0) {
// Set up a storyboard for the root vc and initialize the root vc.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"PlaylistVC" bundle:nil];
self.rootViewController = [storyboard instantiateInitialViewController];

// Initialize the detail vc and assign it to the root vc.
detailViewController = [[MPDetailViewController alloc] initWithNibName:@"MPDetailViewController" bundle:nil];
self.rootViewController.detailViewController = self.detailViewController;

// Set up a split vc to hold the root vc and detail vc we just created.
splitViewController = [[UISplitViewController alloc] init];
self.splitViewController.tabBarItem = controller.tabBarItem;
self.splitViewController.viewControllers = @[self.rootViewController, self.detailViewController];

// Set the split vc's delegate.
self.splitViewController.delegate = self.detailViewController;

// Other.
self.splitViewController.presentsWithGesture = NO;

// limit Primary Column Width to 320
[self.splitViewController setMaximumPrimaryColumnWidth:320.0];

// Add the split vc to the list of controllers that will correspond to each tab in tab bar vc).
controllers[index] = self.splitViewController;
}

// Set the split vc in the Datasets tab.
if (index == 1) {
// Set up a storyboard for the root vc and initialize the root vc.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"DatasetsVC" bundle:nil];
self.splitViewControllerD = [storyboard instantiateViewControllerWithIdentifier:@"DatasetsVC"];

// Set the title and icon of the Datasets tab bar item. Tried to do this in Interface Builder, but it would
// always show up blank.
self.splitViewControllerD.tabBarItem.title = @"Data Catalog";

// Add the split vc to the list of controllers that will correspond to each tab in tab bar vc.
controllers[index] = self.splitViewControllerD;
}

index++;
}

// Set the tab bar's array of vc's with the split vc's controllers we just created.
self.tabBarController.viewControllers = controllers;
self.tabBarController.delegate = self;
self.tabBarController.viewControllers = controllers;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// Override point for customization after application launch.
[super application:application didFinishLaunchingWithOptions:launchOptions];

// This helps us to get a split view controller inside a tab.
[self makeSplitViewController];

// setup a new Root controller with a "container" view
if (YES) {

// instantiate RootContainerViewController
RootContainerViewController *vc = [RootContainerViewController new];

[vc loadViewIfNeeded];

// add tabBarController as child of RootContainerViewController
[vc addChildViewController:self.tabBarController];

// add tabBarController's view to container
[vc.container addSubview:self.tabBarController.view];
// resizing mask
[self.tabBarController.view setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
// set frame to container bounds
[self.tabBarController.view setFrame:vc.container.bounds];
// finsish child load
[self.tabBarController didMoveToParentViewController:vc];

// window rootViewController is now RootContainerViewController instead of tabBarController
self.window.rootViewController = vc;

} else {

// Set the window view to the tab bar vc.
self.window.rootViewController = self.tabBarController;
[self.window addSubview:self.tabBarController.view];

}

// Make the receiver the main window and display it in front of other windows.
[self.window makeKeyAndVisible];

// iOS 15 added a default vertical content offset (i.e., padding) for table views that is non-zero that
// pushes the table view down. Force this offset to be zero for all table views.
if (@available(iOS 15.0, *)) {
UITableView.appearance.sectionHeaderTopPadding = 0;
}



return YES;
}

#pragma mark - Memory management

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
/*
Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
*/
}

@end

The results...

First, using your original App Delegate code without LaunchScreen:

Sample Image

Then, *using LaunchScreen with modified App Delegate code:

Sample Image

At first glance, it looks like it might work, however... the Secondary pane of the split view controller is not sizing correctly (note that the "Overlays" button is not visible, because it is outside the bounds of the view).

Worth mentioning -- Apple's docs state:

Although it’s possible to install a split view controller as a child in some other container view controllers, doing so is not recommended in most cases.

So, using a split view controller as a tab in a Tab Bar Controller is throwing another wrench into the process.

You might want to play around with the container idea, but I don't have high hopes for it (no idea what else might be affected in your actual app).

I think you're just going to have to "bite the bullet" and restructure your app to run on modern devices.

iOS Xcode LaunchScreen Storyboard not displaying

In case anyone else runs into this issue, I resolved it by simply deleting the ViewController on my LaunchScreen storyboard (leaving me with an empty storyboard), creating a new ViewController and resetting the Storyboard entry point to that new ViewController. There may be some sort of bug with XCode 7.2 with respect to the LaunchScreen storyboard and default entry point into the auto-created View Controller, but then again, I've tried replicating this 3 times and it hasn't ever repeated itself, so maybe not.

Updated to Xcode 7.0.1 and Project now has problems

If your app supports multi tasking you need to support all orientations (Portrait up, Portrait Down, Landscape Left, Landscape Right) and a also Launch Screen xib/storyboard.

If you are not interested, you can opt-out by specifying UIRequiresFullScreen key in your info.plist and setting the boolean value to YES. (Read this answer for more about this option)

ios - Is LaunchScreen required in SwiftUI apps for the AppStore?

A launchscreen is still needed for your application, so the Apple docs are correct.

For SwiftUI applications you can configure your launchscreen through the info.plist provided for your application alternatively you could probably retrofit the storyboard back in.

For guidance on how to configure your launchscreen through the plist file I'd suggest taking a look at this article.



Related Topics



Leave a reply



Submit