mirror of
https://github.com/ivanvorobei/SwiftUI.git
synced 2026-03-30 06:02:11 +02:00
Add iPadOS Scenes
This commit is contained in:
62
Examples/iPadOS Scenes/BehindTheScenes/AppDelegate.swift
Executable file
62
Examples/iPadOS Scenes/BehindTheScenes/AppDelegate.swift
Executable file
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// AppDelegate.swift
|
||||
// BehindTheScenes
|
||||
//
|
||||
// Created by Simeon Saint-Saens on 4/6/19.
|
||||
// Copyright © 2019 Two Lives Left. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
var sceneCount = 0
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
// Override point for customization after application launch.
|
||||
return true
|
||||
}
|
||||
|
||||
func applicationWillTerminate(_ application: UIApplication) {
|
||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||
}
|
||||
|
||||
// MARK: UISceneSession Lifecycle
|
||||
|
||||
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
|
||||
// Called when a new scene session is being created.
|
||||
// Use this method to select a configuration to create the new scene with.
|
||||
sceneCount += 1
|
||||
|
||||
connectingSceneSession.userInfo = ["SceneCount" : sceneCount ]
|
||||
|
||||
var sceneDelegateClass: AnyClass = SceneDelegate.self
|
||||
|
||||
if let activity = options.userActivities.first,
|
||||
let sceneType = SceneType(rawValue: activity.activityType) {
|
||||
|
||||
switch sceneType {
|
||||
case .uikitScene:
|
||||
sceneDelegateClass = SceneDelegate.self
|
||||
case .swiftuiScene:
|
||||
sceneDelegateClass = SwiftUISceneDelegate.self
|
||||
}
|
||||
}
|
||||
|
||||
let config = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
|
||||
config.sceneClass = UIWindowScene.self
|
||||
config.delegateClass = sceneDelegateClass
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
|
||||
// Called when the user discards a scene session.
|
||||
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
|
||||
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "83.5x83.5",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ios-marketing",
|
||||
"size" : "1024x1024",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
6
Examples/iPadOS Scenes/BehindTheScenes/Assets.xcassets/Contents.json
Executable file
6
Examples/iPadOS Scenes/BehindTheScenes/Assets.xcassets/Contents.json
Executable file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
25
Examples/iPadOS Scenes/BehindTheScenes/Base.lproj/LaunchScreen.storyboard
Executable file
25
Examples/iPadOS Scenes/BehindTheScenes/Base.lproj/LaunchScreen.storyboard
Executable file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" 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="13104.12"/>
|
||||
<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"/>
|
||||
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||
</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>
|
||||
21
Examples/iPadOS Scenes/BehindTheScenes/ContentView.swift
Executable file
21
Examples/iPadOS Scenes/BehindTheScenes/ContentView.swift
Executable file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// ContentView.swift
|
||||
// BehindTheScenes
|
||||
//
|
||||
// Created by Simeon Saint-Saens on 4/6/19.
|
||||
// Copyright © 2019 Two Lives Left. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct ContentView : View {
|
||||
let count: Int
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Text("Scene \(count)")
|
||||
Text("This is a SwiftUI View 🚀")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
62
Examples/iPadOS Scenes/BehindTheScenes/Info.plist
Executable file
62
Examples/iPadOS Scenes/BehindTheScenes/Info.plist
Executable file
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIApplicationSceneManifest</key>
|
||||
<dict>
|
||||
<key>UIApplicationSupportsMultipleScenes</key>
|
||||
<true/>
|
||||
<key>UISceneConfigurations</key>
|
||||
<dict>
|
||||
<key>UIWindowSceneSessionRoleApplication</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UISceneConfigurationName</key>
|
||||
<string>Default Configuration</string>
|
||||
<key>UISceneDelegateClassName</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
64
Examples/iPadOS Scenes/BehindTheScenes/SceneDelegate.swift
Executable file
64
Examples/iPadOS Scenes/BehindTheScenes/SceneDelegate.swift
Executable file
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// SceneDelegate.swift
|
||||
// BehindTheScenes
|
||||
//
|
||||
// Created by Simeon Saint-Saens on 4/6/19.
|
||||
// Copyright © 2019 Two Lives Left. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
|
||||
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
||||
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
|
||||
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
|
||||
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
|
||||
guard let windowScene = (scene as? UIWindowScene) else { return }
|
||||
|
||||
let count = session.userInfo?["SceneCount"] as? Int ?? 0
|
||||
|
||||
window = UIWindow(windowScene: windowScene)
|
||||
window?.rootViewController = ViewController(count: count)
|
||||
window?.makeKeyAndVisible()
|
||||
}
|
||||
|
||||
func sceneDidDisconnect(_ scene: UIScene) {
|
||||
// Called as the scene is being released by the system.
|
||||
// This occurs shortly after the scene enters the background, or when its session is discarded.
|
||||
// Release any resources associated with this scene that can be re-created the next time the scene connects.
|
||||
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
|
||||
}
|
||||
|
||||
func sceneDidBecomeActive(_ scene: UIScene) {
|
||||
// Called when the scene has moved from an inactive state to an active state.
|
||||
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
|
||||
}
|
||||
|
||||
func sceneWillResignActive(_ scene: UIScene) {
|
||||
// Called when the scene will move from an active state to an inactive state.
|
||||
// This may occur due to temporary interruptions (ex. an incoming phone call).
|
||||
}
|
||||
|
||||
func sceneWillEnterForeground(_ scene: UIScene) {
|
||||
// Called as the scene transitions from the background to the foreground.
|
||||
// Use this method to undo the changes made on entering the background.
|
||||
}
|
||||
|
||||
func sceneDidEnterBackground(_ scene: UIScene) {
|
||||
// Called as the scene transitions from the foreground to the background.
|
||||
// Use this method to save data, release shared resources, and store enough scene-specific state information
|
||||
// to restore the scene back to its current state.
|
||||
}
|
||||
|
||||
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
|
||||
print("Continuing \(userActivity.userInfo?["count"])")
|
||||
}
|
||||
|
||||
func scene(_ scene: UIScene, didUpdate userActivity: NSUserActivity) {
|
||||
print("Updating user activity")
|
||||
}
|
||||
}
|
||||
|
||||
27
Examples/iPadOS Scenes/BehindTheScenes/SwiftUISceneDelegate.swift
Executable file
27
Examples/iPadOS Scenes/BehindTheScenes/SwiftUISceneDelegate.swift
Executable file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// SwiftUISceneDelegate.swift
|
||||
// BehindTheScenes
|
||||
//
|
||||
// Created by Simeon Saint-Saens on 4/6/19.
|
||||
// Copyright © 2019 Two Lives Left. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SwiftUI
|
||||
|
||||
class SwiftUISceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
var window: UIWindow?
|
||||
|
||||
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
||||
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
|
||||
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
|
||||
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
|
||||
guard let windowScene = (scene as? UIWindowScene) else { return }
|
||||
|
||||
let count = session.userInfo?["SceneCount"] as? Int ?? 0
|
||||
|
||||
window = UIWindow(windowScene: windowScene)
|
||||
window?.rootViewController = UIHostingController(rootView: ContentView(count: count))
|
||||
window?.makeKeyAndVisible()
|
||||
}
|
||||
}
|
||||
86
Examples/iPadOS Scenes/BehindTheScenes/ViewController.swift
Executable file
86
Examples/iPadOS Scenes/BehindTheScenes/ViewController.swift
Executable file
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// ViewController.swift
|
||||
// BehindTheScenes
|
||||
//
|
||||
// Created by Simeon Saint-Saens on 4/6/19.
|
||||
// Copyright © 2019 Two Lives Left. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
enum SceneType: String {
|
||||
case uikitScene
|
||||
case swiftuiScene
|
||||
}
|
||||
|
||||
class ViewController: UIViewController {
|
||||
|
||||
let count: Int
|
||||
|
||||
init(count: Int) {
|
||||
self.count = count
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("NO THANKS XCODE")
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
print("Loading view controller")
|
||||
|
||||
super.viewDidLoad()
|
||||
|
||||
view.backgroundColor = UIColor(white: 0.9, alpha: 1)
|
||||
|
||||
let button = UIButton(type: .system)
|
||||
button.addTarget(self, action: #selector(openScene(_:)), for: .touchUpInside)
|
||||
button.setTitle("Request New Scene", for: .normal)
|
||||
|
||||
view.addSubview(button)
|
||||
button.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
|
||||
button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
|
||||
|
||||
let swiftUIbutton = UIButton(type: .system)
|
||||
swiftUIbutton.addTarget(self, action: #selector(openSwiftUIScene(_:)), for: .touchUpInside)
|
||||
swiftUIbutton.setTitle("Request Swift UI Test Scene", for: .normal)
|
||||
|
||||
view.addSubview(swiftUIbutton)
|
||||
swiftUIbutton.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
swiftUIbutton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
|
||||
swiftUIbutton.topAnchor.constraint(equalTo: button.bottomAnchor, constant: 16).isActive = true
|
||||
|
||||
let countLabel = UILabel()
|
||||
countLabel.text = "\(count)"
|
||||
countLabel.textAlignment = .center
|
||||
countLabel.textColor = .black
|
||||
countLabel.font = UIFont.systemFont(ofSize: 144, weight: .heavy)
|
||||
|
||||
view.addSubview(countLabel)
|
||||
countLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
countLabel.bottomAnchor.constraint(equalTo: button.topAnchor, constant: -30).isActive = true
|
||||
countLabel.centerXAnchor.constraint(equalTo: button.centerXAnchor).isActive = true
|
||||
}
|
||||
|
||||
@objc private func openScene(_ sender: Any) {
|
||||
let activity = NSUserActivity(activityType: SceneType.uikitScene.rawValue)
|
||||
|
||||
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: activity, options: nil, errorHandler: {
|
||||
print($0)
|
||||
})
|
||||
}
|
||||
|
||||
@objc private func openSwiftUIScene(_ sender: Any) {
|
||||
let activity = NSUserActivity(activityType: SceneType.swiftuiScene.rawValue)
|
||||
|
||||
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: activity, options: nil, errorHandler: {
|
||||
print($0)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user