summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2021-07-15 16:20:20 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2022-02-16 05:14:24 +0100
commite5b3436255ce095af58608b03b913fc9bcb8e61f (patch)
tree98695671fc913f0a81436512332b68ed6d339795
parenta1fb3971f222afa01583e41f4d8f0e037d2c7892 (diff)
CMake: Add default launch screen storyboard for iOS apps
Bundle a default LaunchScreen.storyboard file for an iOS app and make sure it's referenced in the generated Info.plist file. When launching Qt examples, it ensures the app uses the whole screen space on the device rather than just a square-ish part of it. The storyboard file is a copy of the qmake one, which qmake adds to the Xcode projects it generates. A custom launch screen can be provided either by setting the QT_IOS_LAUNCH_SCREEN variable or by setting the QT_IOS_LAUNCH_SCREEN target property. The value must be an absolute path to the launch screen file. The automatic addition of the launch screen entry in the Info.plist file can be prevented by setting the QT_NO_SET_IOS_LAUNCH_SCREEN variable to TRUE. The automatic bundling of the launch screen file in the application bundle can be prevented by setting the QT_NO_ADD_IOS_LAUNCH_SCREEN_TO_BUNDLE variable to TRUE. The current implementation has a limitation that only one launch screen storyboard and one iOS executable can exist within a project. If there are multiple executables in the project, all of them will use the launch screen that is specified last (the last qt_add_executable call). Because of this limitation, the API is marked as Technical Preview, to be improved upon in the future. For now it simply serves as an improvement to the out-of-the-box experience of iOS apps built with CMake. Amends 4d838dae5a821e9e5f013ba1d5a494ece1b5180e Pick-to: 6.2 6.3 Fixes: QTBUG-95837 Change-Id: I6b067d703d635122959a1ef17fcca713da694a86 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
-rw-r--r--cmake/QtBaseGlobalTargets.cmake1
-rw-r--r--cmake/QtConfig.cmake.in3
-rw-r--r--cmake/ios/LaunchScreen.storyboard48
-rw-r--r--cmake/ios/MacOSXBundleInfo.plist.in10
-rw-r--r--src/corelib/Qt6CoreMacros.cmake82
5 files changed, 141 insertions, 3 deletions
diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake
index e9d9370510..3696ddd958 100644
--- a/cmake/QtBaseGlobalTargets.cmake
+++ b/cmake/QtBaseGlobalTargets.cmake
@@ -362,6 +362,7 @@ if(MACOS)
elseif(IOS)
qt_copy_or_install(FILES
cmake/ios/MacOSXBundleInfo.plist.in
+ cmake/ios/LaunchScreen.storyboard
DESTINATION "${__GlobalConfig_install_dir}/ios"
)
endif()
diff --git a/cmake/QtConfig.cmake.in b/cmake/QtConfig.cmake.in
index 011970ed1e..1d32c94e3d 100644
--- a/cmake/QtConfig.cmake.in
+++ b/cmake/QtConfig.cmake.in
@@ -44,7 +44,8 @@ if(APPLE AND (NOT CMAKE_SYSTEM_NAME OR CMAKE_SYSTEM_NAME STREQUAL "Darwin"))
list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}/macos")
elseif(APPLE AND CMAKE_SYSTEM_NAME STREQUAL "iOS")
# Add module directory to pick up custom Info.plist template for iOS
- list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}/ios")
+ set(__qt_internal_cmake_ios_support_files_path "${_qt_import_prefix}/ios")
+ list(APPEND CMAKE_MODULE_PATH "${__qt_internal_cmake_ios_support_files_path}")
endif()
set(QT_ADDITIONAL_PACKAGES_PREFIX_PATH "" CACHE STRING
diff --git a/cmake/ios/LaunchScreen.storyboard b/cmake/ios/LaunchScreen.storyboard
new file mode 100644
index 0000000000..cfe5d26eba
--- /dev/null
+++ b/cmake/ios/LaunchScreen.storyboard
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13142" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
+ <dependencies>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12042"/>
+ <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
+ <capability name="Safe area layout guides" minToolsVersion="9.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="375" height="667"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <subviews>
+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="obG-Y5-kRd">
+ <rect key="frame" x="0.0" y="626.5" width="375" height="20.5"/>
+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="@QT_IOS_LAUNCH_SCREEN_TEXT@" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="GJd-Yh-RWb">
+ <rect key="frame" x="0.0" y="202" width="375" height="43"/>
+ <fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ <nil key="highlightedColor"/>
+ </label>
+ </subviews>
+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ <constraints>
+ <constraint firstItem="Bcu-3y-fUS" firstAttribute="centerX" secondItem="obG-Y5-kRd" secondAttribute="centerX" id="5cz-MP-9tL"/>
+ <constraint firstItem="Bcu-3y-fUS" firstAttribute="centerX" secondItem="GJd-Yh-RWb" secondAttribute="centerX" id="Q3B-4B-g5h"/>
+ <constraint firstItem="obG-Y5-kRd" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" constant="20" symbolic="YES" id="SfN-ll-jLj"/>
+ <constraint firstAttribute="bottom" secondItem="obG-Y5-kRd" secondAttribute="bottom" constant="20" id="Y44-ml-fuU"/>
+ <constraint firstItem="GJd-Yh-RWb" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="bottom" multiplier="1/3" constant="1" id="moa-c2-u7t"/>
+ <constraint firstItem="GJd-Yh-RWb" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" constant="20" symbolic="YES" id="x7j-FC-K8j"/>
+ </constraints>
+ <viewLayoutGuide key="safeArea" id="Bcu-3y-fUS"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="53" y="375"/>
+ </scene>
+ </scenes>
+</document>
diff --git a/cmake/ios/MacOSXBundleInfo.plist.in b/cmake/ios/MacOSXBundleInfo.plist.in
index 616abe9f10..5b15af1302 100644
--- a/cmake/ios/MacOSXBundleInfo.plist.in
+++ b/cmake/ios/MacOSXBundleInfo.plist.in
@@ -28,10 +28,16 @@
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
- <key>LSRequiresIPhoneOS</key>
+ <key>LSRequiresIPhoneOS</key>
<true/>
- <key>UISupportedInterfaceOrientations</key>
+ <key>NOTE</key>
+ <string>This file was generated by Qt's default CMake support.</string>
+
+ <key>UILaunchStoryboardName</key>
+ <string>${QT_INTERNAL_IOS_LAUNCH_SCREEN_PLIST_ENTRY}</string>
+
+ <key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake
index 436bda645d..ea7f0bcda1 100644
--- a/src/corelib/Qt6CoreMacros.cmake
+++ b/src/corelib/Qt6CoreMacros.cmake
@@ -685,6 +685,87 @@ function(qt6_finalize_target target)
endif()
endfunction()
+function(_qt_internal_handle_ios_launch_screen target)
+ # Check if user provided a launch screen path via a variable.
+ set(launch_screen "")
+
+ # This variable is currently in Technical Preview.
+ if(QT_IOS_LAUNCH_SCREEN)
+ set(launch_screen "${QT_IOS_LAUNCH_SCREEN}")
+ endif()
+
+ # Check if user provided a launch screen path via a target property.
+ if(NOT launch_screen)
+
+ # This property is currently in Technical Preview.
+ get_target_property(launch_screen_from_prop "${target}" QT_IOS_LAUNCH_SCREEN)
+ if(launch_screen_from_prop)
+ set(launch_screen "${launch_screen_from_prop}")
+ endif()
+ endif()
+
+ # If user hasn't provided a launch screen path, use a copy of the one qmake uses.
+ # It needs to be a copy because configure_file can't handle all the escaped double quotes.
+ if(NOT launch_screen AND NOT QT_NO_SET_IOS_LAUNCH_SCREEN)
+ set(launch_screen "LaunchScreen.storyboard")
+ set(launch_screen
+ "${__qt_internal_cmake_ios_support_files_path}/${launch_screen}")
+ endif()
+
+ # Save the name of the launch screen in an internal cache var, so it is added as a
+ # UILaunchStoryboardName entry in the generated Info.plist.
+ # This is the only sensible but dirty way to set up a variable, so that CMake's internal
+ # configure_file call for Info.plist picks it up.
+ # Unfortunately CMake does not provide a way of setting a regular non-cache variable in a
+ # directory scope from within a nested function call.
+ # This means that the behavior below will only work if there's one single executable in the
+ # project.
+ # FIXME: Figure out if there's a better way of doing this.
+ # Perhaps we should give up on using CMake's Info.plist mechanism and just call
+ # configure_file ourselves.
+ if(launch_screen)
+ if(NOT IS_ABSOLUTE "${launch_screen}")
+ message(FATAL_ERROR
+ "Provided launch screen value should be an absolute path: '${launch_screen}'")
+ endif()
+
+ if(NOT EXISTS "${launch_screen}")
+ message(FATAL_ERROR
+ "Provided launch screen file does not exist: '${launch_screen}'")
+ endif()
+
+ get_filename_component(launch_screen_name "${launch_screen}" NAME)
+ set(QT_INTERNAL_IOS_LAUNCH_SCREEN_PLIST_ENTRY "${launch_screen_name}" CACHE INTERNAL "")
+ endif()
+
+ if(launch_screen AND NOT QT_NO_ADD_IOS_LAUNCH_SCREEN_TO_BUNDLE)
+ # Configure the file and place it in the build dir.
+ set(launch_screen_in_path "${launch_screen}")
+
+ string(MAKE_C_IDENTIFIER "${target}" target_identifier)
+ set(launch_screen_out_dir
+ "${CMAKE_CURRENT_BINARY_DIR}/qt_story_boards/${target_identifier}")
+
+ set(launch_screen_out_path
+ "${launch_screen_out_dir}/${launch_screen_name}")
+
+ file(MAKE_DIRECTORY "${launch_screen_out_dir}")
+
+ set(QT_IOS_LAUNCH_SCREEN_TEXT "${target}")
+ configure_file(
+ "${launch_screen_in_path}"
+ "${launch_screen_out_path}"
+ @ONLY
+ )
+
+ # Add it as a source file, otherwise CMake doesn't consider it a resource.
+ target_sources("${target}" PRIVATE "${launch_screen_out_path}")
+
+ # Ensure Xcode copies the file to the app bundle.
+ set_property(TARGET "${target}" APPEND PROPERTY RESOURCE "${launch_screen_out_path}")
+ endif()
+endfunction()
+
function(_qt_internal_find_ios_development_team_id out_var)
get_property(team_id GLOBAL PROPERTY _qt_internal_ios_development_team_id)
get_property(team_id_computed GLOBAL PROPERTY _qt_internal_ios_development_team_id_computed)
@@ -846,6 +927,7 @@ function(_qt_internal_finalize_ios_app target)
endif()
endif()
+ _qt_internal_handle_ios_launch_screen("${target}")
_qt_internal_set_placeholder_apple_bundle_version("${target}")
endfunction()