Swift 포함기존 UIKit 응용 프로그램의 UI 보기
Swift로 뷰 작성 가능UI는 기존 UIKit 애플리케이션과 나란히 있습니까?
Objective-C로 작성된 기존 어플리케이션이 있습니다.스위프트 5로 이주를 시작했어스위프트를 사용할 수 있는지 궁금합니다.UI와 기존 UIKit .xib 보기를 함께 사용합니다.
즉, Swift로 뷰를 만들고 싶다.UI 및 기타 뷰는 같은 앱에서 UIKit으로 빌드됩니다.물론 둘 다 섞지 않는다.
SomeObjCSwiftProject/
SwiftUIViewController.swift
SwiftUIView.xib
UIKitViewController.swift
UIKitView.xib
서로 연계하여 작업하다
edit 06/19: 답변에서 @Departmento B가 제안한 UI Hosting Controller에 대한 정보를 추가했습니다.크레딧은 그에게 돌아간다!
Swift 사용UIKit 내의 UI
수 SwiftUI
, 컴포넌트UIKit
: ★★★★★★★★★★★★★★★★★★★★★★★★」SwiftUI
View
UIHostingController
음음음같 뭇매하다
let swiftUIView = SomeSwiftUIView() // swiftUIView is View
let viewCtrl = UIHostingController(rootView: swiftUIView)
또, 이 기능을 무효로 할 수도 있습니다.UIHostingController
제작할 수 있습니다. 맞춤 할 수 .예예 、 를를 、 ,를 、preferredStatusBarStyle
하지 않는 으로, 「」를 사용해 .SwiftUI
역시나
UIHostingController
는 여기에 기재되어 있습니다.
Swift 내에서 UIKit 사용UI
의 「」의 .UIKit
는 「」로 가 있습니다.SwiftUI
,,,UIViewRepresentable
프로토콜이 도움이 됩니다!여기에 기재되어 있으며, Apple의 공식 튜토리얼에서 실제로 동작하고 있는 것을 확인할 수 있습니다.
호환성.
, 사용하실 수 .SwiftUI
버전에서는, 、、< 、、 。SwiftUI
는 iOS 13 이상에서만 사용할 수 있습니다.상세한 것에 대하여는, 이 투고를 참조해 주세요.
「 」를 사용하고 SwiftUI
이하의 에서는, 「iOS 13」에를 붙일 필요가 .SwiftUI
「」가 붙은 @available(iOS 13.0.0, *)
기여하다.
Swift를 포함하려면UI를 UEKit 보기 컨트롤러로 변환하고 컨테이너 보기를 사용합니다.
class ViewController: UIViewController {
@IBOutlet weak var theContainer: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let childView = UIHostingController(rootView: SwiftUIView())
addChild(childView)
childView.view.frame = theContainer.bounds
theContainer.addSubview(childView.view)
childView.didMove(toParent: self)
}
}
UI Hosting 컨트롤러
수업 시간에 대한 문서가 작성되지 않았지만 재 업 성 았 료 지 되 although at has,ation않 the만 the, class작지 the written been자수 not moment for는 document현 has although atUIHostingController<Content>
찾고 계신 것 같습니다.https://developer.apple.com/documentation/swiftui/uihostingcontroller
방금 앱에서 다음 코드 행으로 시도했습니다.
let vc = UIHostingController(rootView: BenefitsSwiftUIView())
디 어디 있죠?BenefitsSwiftUIView
is just the default "Hello World" 기본 "Hello World" 입니다.View
부에서SwiftUI
. 이것은 당신이 기대만큼 잘해요.이것은 당신이 예상한 대로 작동합니다.로도 합니다.UIHostingController
.
제가 아직 본 적이 없는 아이템 중 하나는 Xcode 11 beta 5 (11M382q)와 관련된 것으로, 앱의 info.plist 파일을 갱신하는 것입니다.
시나리오에서는 기존 Swift 및 UIKit 기반 애플리케이션을 iOS 13 및 순수 Swift로 완전히 이행합니다.UI 앱이기 때문에 이전 버전과의 호환성은 신경 쓰지 않습니다.
AppDelegate에서 필요한 변경을 한 후:
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions) -> UISceneConfiguration {
return UISceneConfiguration(name: "Default Configuration",
sessionRole: connectingSceneSession.role)
}
SceneDelegate 클래스에 추가:
import UIKit
import SwiftUI
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: HomeList())
self.window = window
window.makeKeyAndVisible()
}
}
}
SceneDelegate가 호출되지 않는 문제가 발생했습니다.이 문제는 다음 사항을 info.plist 파일에 추가함으로써 해결되었습니다.
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string></string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneStoryboardFile</key>
<string>LaunchScreen</string>
</dict>
</array>
</dict>
</dict>
스크린샷은 다음과 같습니다.
동기화 상태를 유지하는 주요 항목은 다음과 같습니다.
- 클래스 이름을 위임하여 Xcode가 검색 위치를 알 수 있도록 합니다.
SceneDelegate
파일 - AppDelegate 콜이 올바른 콜을 로드할 수 있도록 설정 이름
UISceneConfiguration
이렇게 하면 새로 만든 HomeList 뷰(A Swift)를 로드할 수 있었습니다.UI 오브젝트)
레이아웃에 문제가 있는 경우 UI Hosting Controller 뷰에 제약을 추가해야 합니다.
class ViewController: UIViewController {
@IBOutlet weak var theContainer: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let childView = UIHostingController(rootView: SwiftUIView())
addChild(childView)
childView.view.frame = theContainer.bounds
theContainer.addConstrained(subview: childView.view)
childView.didMove(toParent: self)
}
}
다음 확장자를 사용합니다.
extension UIView {
func addConstrained(subview: UIView) {
addSubview(subview)
subview.translatesAutoresizingMaskIntoConstraints = false
subview.topAnchor.constraint(equalTo: topAnchor).isActive = true
subview.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
subview.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
subview.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
}
}
방법은 다음과 같습니다.
Swift 만들기UI 어댑터
/**
* Adapts a SwiftUI view for use inside a UIViewController.
*/
class SwiftUIAdapter<Content> where Content : View {
private(set) var view: Content!
weak private(set) var parent: UIViewController!
private(set) var uiView : WrappedView
private var hostingController: UIHostingController<Content>
init(view: Content, parent: UIViewController) {
self.view = view
self.parent = parent
hostingController = UIHostingController(rootView: view)
parent.addChild(hostingController)
hostingController.didMove(toParent: parent)
uiView = WrappedView(view: hostingController.view)
}
deinit {
hostingController.removeFromParent()
hostingController.didMove(toParent: nil)
}
}
다음과 같이 뷰 컨트롤러에 추가합니다.
class FeedViewController: UIViewController {
var adapter : SwiftUIAdapter<FeedView>!
override required init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
adapter = SwiftUIAdapter(view: FeedView(), parent: self)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
/** Override load view to load the SwiftUI adapted view */
override func loadView() {
view = adapter.uiView;
}
}
래핑된 뷰의 코드
래핑 뷰는 자동 레이아웃이 아닌 수동 레이아웃(layoutSubViews)을 사용합니다.이 경우는 매우 간단합니다.
class WrappedView: UIView {
private (set) var view: UIView!
init(view: UIView) {
self.view = view
super.init(frame: CGRect.zero)
addSubview(view)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func layoutSubviews() {
super.layoutSubviews()
view.frame = bounds
}
}
를 작성하려면SwiftUI
기존 Objective C 프로젝트의 뷰는 이 기술이 나에게 완벽하게 적용되었습니다.
'Swift 추가'UI에서 Objective-C 애플리케이션으로
그 글을 쓴 친구에게 찬사를 보냅니다.
스토리보드 포함
사용할 수 있습니다.HotingViewController
컴포넌트:
그럼 심플한 게 있으면HotingController
다음과 같습니다.
class MySwiftUIHostingController: UIHostingController<Text> {
required init?(coder: NSCoder) {
super.init(coder: coder, rootView: Text("Hello World"))
}
}
컨트롤러의 커스텀클래스로 설정할 수 있습니다.
코드 포함
let mySwiftUIHostingController = UIHostingController(rootView: Text("Hello World"))
그리고 보통처럼 사용할 수 있습니다.UIViewController
중요사항
Import하는 것을 잊지 마세요.SwiftUI
필요한 곳이면 언제든지UIHostingController
이러한 순서는, 간단하게 실행할 수 있습니다.
mainStoryBoard에 표시되는 viewController에 버튼을 만들고 Swift를 가져옵니다.UI
mainStoryboard에 hostingViewController를 추가하고 버튼에서 hostingViewController로 Segue(Segue 표시)를 드래그합니다.storyBoard에서 Swift로 segue 끌기UI
mainStoryBoard에 표시되는 segueAction 폼 segue를 viewController에 추가합니다.
segueAction에 코드 폴링 라인 쓰기...
@IBSegueAction func ActionMe(_ coder: NSCoder) -> UIViewController? {
return UIHostingController(coder: coder, rootView: SWIFTUI())
}
같이 쓰셔도 돼요.전송 할 수 있습니다.UIView
로.View
타고UIViewRepresentable
준거성자세한 내용은 공식 튜토리얼에서 확인할 수 있습니다.
그러나 호환성도 고려해야 합니다.
여기 프로토콜의 코드 조각이 있습니다.View
Swift의UI:
///
/// You create custom views by declaring types that conform to the `View`
/// protocol. Implement the required `body` property to provide the content
/// and behavior for your custom view.
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
public protocol View : _View {
/// The type of view representing the body of this view.
///
/// When you create a custom view, Swift infers this type from your
/// implementation of the required `body` property.
/// ...
}
따라서 역호환성이 없습니다.
- iOS 13.0 이상
- MacOS 10.15 이상
- 감시 OS 6.0+
import Foundation
#if canImport(SwiftUI)
import SwiftUI
internal final class SomeRouter {
fileprivate weak var presentingViewController: UIViewController!
function navigateToSwiftUIView() {
if #available(iOS 13, *) {
let hostingController = UIHostingController(rootView: contentView())
presentingViewController?.navigationController?.pushViewController(hostingController, animated: true)
return
}
//Keep the old way when not 13.
}
#endif
언급URL : https://stackoverflow.com/questions/56433826/include-swiftui-views-in-existing-uikit-application
'programing' 카테고리의 다른 글
bash 스크립트에서 파일 이름 확장자를 확인하는 방법 (0) | 2023.04.10 |
---|---|
어레이의 각 루프에 대해를 사용하려면 어떻게 해야 합니까? (0) | 2023.04.10 |
오브젝트 속성을 기반으로 오브젝트 목록을 정렬하려면 어떻게 해야 합니까? (0) | 2023.04.10 |
Git에서 이전(마지막이 아님) 커밋에 변경된 파일을 추가하는 방법 (0) | 2023.04.10 |
현재 시각에 분수를 빠르게 추가하는 방법 (0) | 2023.04.10 |