2

Goal:

Create a splash screen ("LaunchScreen") for a ".Net 8 for iOS" C# app (successor to "Xamarin Native / iOS").

The splash screen contains an image (a logo) scaled to fill (maintaining aspect ratio) the screen, with a small margin.

Requirement:

  • Don't rely on any Microsoft tools on mac (e.g. VS Code + .Net extension). On the mac, only use Xcode.

Rationale: As much as possible, work on the PC. Minimize reliance on installing/learning/maintaining tools on the Mac.


Related question:

Led Machine's answer to xamarin.ios - How to change splash screen is similar to the LaunchScreen.storyboard I have. I was unable to get that .storyboard to work either.

There have been fundamental changes since then.

Given that the technology is no longer "Xamarin", and that all the involved tools and targets (both Microsoft and Apple) have changed, it seems appropriate to start a new question.

Especially since Visual Studio no longer has an Xcode-like storyboard editor for iOS.


What I have done:

Apple Doc: Specifying your app's launch screen.

  • Use Xcode to create a native app (Objective-C or Swift). Specify LaunchScreen as storyboard. Set background color to Blue. Add a .png image file to project. Add a UIImageView to the LaunchScreen, and select that .png. Run native app.

Success: See .png on blue background, then main view of app.

Testing on iOS (17.2 and 18.1) Simulator on mac.
Some testing on iPad with iOS 18.3.2 attached to the mac.

Xcode 16.1. [There doesn't appear to be any Xcode problem; I doubt upgrading or downgrading would help.]


Where I am stuck:

Get that same LaunchScreen.storyboard + .png file to work in .Net 8 C# project in Visual Studio 2022, deployed from Windows to mac via "Pair to mac".


What I have tried:

I can copy launchimage.png, and LaunchScreen.storyboard from (working) native Apple Swift project back to the C# project.

info.plist contains:

    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>

However, when the LaunchScreen should appear, there is simply a black screen. I don't even see the Blue background color I set, let alone the image. [After the black screen, the app's main screen appears.]

  • I have tried setting various "Build" options in VS Solution Explorer Properties. For LaunchScreen.storyboard and launchimage.png. However, since this is not a Maui project, I haven't found any setting that works. Also note that Main.storyboard does not require any .csproj build action. [I presume the files are all sent to Xcode on the mac, with a build script that does what is needed for storyboards.]

NOTE: If this were a MAUI cross-platform app, this would be straightforward. There is a MAUI option to create a simple launch screen with logo. That works for me, in a different app test. But that isn't applicable to this update of a "Xamarin Native / iOS" app.

0

1 Answer 1

2

Short answer:

It is easier to get .Net iOS Splash Screen (LaunchScreen) to work on an actual device, rather than on Simulator.

REASON: Simulator won't show Splash Screen for an unsigned app; e.g. a Debug build.

I discovered this via .Net Maui / iOS not show splash screen:

... as of iOS ~16.4 you will NOT be able to see your splash screen on an IOS simulator

(...BUT keep reading, there is a solution below for Simulator...)

Although I am not developing a Maui app, I am using .Net 8 for iOS, which has similar issue.

UPDATE A later section of this answer shows what to add to .csproj, to enable code-signing, so can see Splash Screen in simulator with a Debug build.


Long answer:

These steps worked:

  1. Create LaunchScreen.storyboard in Xcode on mac in a simple native (Objective C or Swift) project. If using Swift, be sure to specify that LaunchScreen is via "Storyboard".

  2. Use Xcode to modify LaunchScreen as desired. As a first simple test, add a View and set its Background Color (no Image yet).

  3. Verify this native app shows LaunchScreen.

  4. Copy LaunchScreen.storyboard into C# ".Net for iOS" project's Resources folder.

  5. Add to info.plist:

  <key>UILaunchStoryboardName</key>
  <string>LaunchScreen</string>
  1. Deploy Debug build to an ios device attached to the mac. [Testing Debug build on Simulator didn't show the LaunchScreen.]

Result: The LaunchScreen color appears, then app's Main screen appears.


For Step (6.) above, Splash Screen can be tested on Simulator by adding code-signing to .csproj file:

<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
    <EnableCodeSigning>true</EnableCodeSigning>
    <CodesignRequireProvisioningProfile>true</CodesignRequireProvisioningProfile>
    <DisableCodesignVerification>true</DisableCodesignVerification>
</PropertyGroup>

[It might be necessary to restart Simulator on mac, to see this change.]

Credit: Based on a comment in
dotnet / macios / Enable codesigning by default in the simulator.

NOTE: I tested in an iOS-only project. If targetting multiple platforms, change first line to:

<PropertyGroup Condition="$(TargetFramework.Contains('-ios')) And '$(Configuration)' == 'Debug'">

Troubleshooting:

  • Make a change, but previous version of Launch Screen is still seen.

    Launch Screen apparently is cached on device.

    restart (power off, then back on) the device or (quit) Simulator.

    If still not seeing the change, quit Visual Studio, delete bin and obj folders. After this, restart device/Simulator again.

    I've had situations where change still was not seen. Perhaps some cache on mac not updated. Quit Xcode if it is running.

    Delete app from device/Simulator.

    If all else fails: Power off pc and mac. Repeat the above steps, before running Visual Studio again. Perhaps edit LaunchScreen.Storyboard again in an external text editor, so it has a new modified date.

  • Add an image, but it is not seen.

    FIRST get it working in a native (Swift or Objective C) app in Xcode. Then copy needed files to C# project. NOTE: Image can either be a single .png or an asset catalog (containing a content.json and one or more versions of image).

    Place relevant files (LaunchScreen.Storyboard, yourimagename.png) in C# project's folder "Resources".

    Asset catalog(s) go in project folder "Assets.xcassets". This seems to work whether inside "Resources", or as its own folder in project root.

    No build actions needed on the files: these files are sent to Xcode, which processes appropriately.

  • Launch Screen not appearing on Simulator.

    Test it on a physical device. If it works there, double-check the code-sign properties described above.

  • If using ".Net for iOS" (but NOT Maui), the place to report bugs is:

    https://github.com/dotnet/macios/issues

    (Consider first posting a StackOverflow question, in case it isn't actually a bug.)

    If you are using .Net Maui, and encounter issues on iOS, report bugs here:

    https://github.com/dotnet/maui/issues


Contents of LaunchScreen.storyboard:

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
    <device id="retina6_12" orientation="portrait" appearance="light"/>
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <capability name="System colors in document resources" minToolsVersion="11.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--View Controller-->
        <scene sceneID="EHf-IW-A2E">
            <objects>
                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
                        <rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="iosLaunchImage.png" translatesAutoresizingMaskIntoConstraints="NO" id="KEL-HK-vdv">
                                <rect key="frame" x="16" y="59" width="361" height="759"/>
                            </imageView>
                        </subviews>
                        <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
                        <color key="backgroundColor" red="0.0" green ="0.0" blue="1.0" alpha="1" colorSpace="custom" customColorSpace="sRGB" />
                        <constraints>
                            <constraint firstItem="KEL-HK-vdv" firstAttribute="bottom" secondItem="6Tk-OE-BBY" secondAttribute="bottom" id="BvB-83-3Ty"/>
                            <constraint firstItem="KEL-HK-vdv" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leadingMargin" id="F7Y-zg-6OF"/>
                            <constraint firstItem="KEL-HK-vdv" firstAttribute="trailing" secondItem="Ze5-6b-2t3" secondAttribute="trailingMargin" id="NfD-Qh-mDE"/>
                            <constraint firstItem="KEL-HK-vdv" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" id="kVK-62-x1g"/>
                        </constraints>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="52.671755725190835" y="374.64788732394368"/>
        </scene>
    </scenes>
    <resources>
        <image name="iosLaunchImage.png" width="722" height="409.69015502929688"/>
    </resources>
</document>

Adapting to different device sizes:

  • imageView .. contentMode="scaleAspectFit"
  • autoresizingMask .. Yes
  • constraints for the 4 edges of view. There must NOT be constraints that set Width/Height to constant values.

color key="backgroundColor" ... blue="1.0" set background color to blue, so I could tell the storyboard was being used, even before I added an image. Useful in case image is somehow not being found.

Sign up to request clarification or add additional context in comments.

1 Comment

I followed your approach but I keep getting error "Could not find any available provisioning profiles for TestProject on iOS"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.