是否可以将 ViewController 分配给 SwiftUI 视图?
Is it possible to assign a ViewController to a SwiftUI view?
我正在使用 SwiftUI 应用程序协议构建 SwiftUI 应用程序。
我需要访问一些 UIKIt 函数,尤其是控制 NavigationView 的函数,如下所示:.
显然,要做到这一点,我需要将我的 SwiftUI 视图与 ViewController 绑定。
我已尝试执行以下操作:
ContentView.swift
struct ContentView: View {
var body: some View {
ZStack {
ContentViewIntegratedController() // <- here
NavigationView{
ScrollView {
Text("Content View")
.navigationTitle("Content View")
}
}
}
}
}
class ContentViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
struct ContentViewIntegratedController: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> some UIViewController {
return ContentViewController()
}
func updateUIViewController(_ uiViewController: UIViewControllerType,
context: UIViewControllerRepresentableContext<ContentViewIntegratedController>) {}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
但是调用 ContentViewIntegratedContoller
(第 5 行)似乎创建了一个新的预览而不是修改现有的。
有没有集成一个ViewController来修改SwiftUI视图?
我不想做的事:
- 创建一个包含 SwiftUI 视图的 Storyboards 应用程序
- 为
ContentViewIntegratedViewController
创建故事板视图。
有没有其他方法可以在不向我的 SwiftUI 视图添加 ViewController 的情况下访问这些功能?
TIA。
纯 SwiftUI 无法直接检测 large
和 inline
显示模式之间的变化。但是,使用 SwiftUI-Introspect,你可以下降到 UIKit 来解决这个问题。
我通过获取大标题的视图并检测 alpha
属性 何时更改来解决此问题。这在标题从 large
变为 inline
或 vice-versa.
的确切时刻发生变化
代码:
struct ContentView: View {
@State private var observer: NSKeyValueObservation?
@State private var title: String = "Large Title"
var body: some View {
NavigationView {
ScrollView {
Text("Hello world!")
}
.navigationTitle(title)
}
.introspectNavigationController { nav in
let largeTitleView = nav.navigationBar.subviews.first { view in
String(describing: type(of: view)) == "_UINavigationBarLargeTitleView"
}
observer = largeTitleView?.observe(\.alpha) { view, change in
let isLarge = view.alpha == 1
title = isLarge ? "Large Title" : "Inline title"
}
}
}
}
结果:
struct ContentView: View {
var body: some View {
ContentViewIntegratedController(view: YourView())
.ignoresSafeArea()
}
}
--------------------------------------------------------------
struct YourView: View {
var body: some View {
ScrollView{
Text("Hello, World!")
}
}}
------------------------------------------------------
import Foundation
import SwiftUI
struct ContentViewIntegratedController :UIViewControllerRepresentable{
var view: YourView
init(view:YourView) {
self.view = view
}
func makeUIViewController(context: Context) -> UINavigationController{
let childView = UIHostingController(rootView: view)
let controller = UINavigationController(rootViewController:childView)
let appearance = UINavigationBarAppearance()
let searchController = UISearchController()
searchController.searchBar.barStyle = .black
appearance.backgroundColor = UIColor(Color(.red))
appearance.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
controller.navigationBar.topItem?.compactAppearance = appearance
controller.navigationBar.topItem?.scrollEdgeAppearance = appearance
controller.navigationBar.topItem?.standardAppearance = appearance
controller.navigationBar.topItem?.title = "navigation bar"
controller.navigationBar.prefersLargeTitles = true
searchController.searchBar.searchTextField.attributedPlaceholder = NSAttributedString(string: "Rechercher...", attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])
searchController.searchBar.setValue("Annuler", forKey: "cancelButtonText")
searchController.searchBar.showsBookmarkButton = true
searchController.searchBar.searchTextField.leftView?.tintColor = .white
let sfConfiguration = UIImage.SymbolConfiguration(pointSize: 30)
let barCodeIcon = UIImage(systemName: "barcode.viewfinder")?.withTintColor(.white, renderingMode: .alwaysOriginal).withConfiguration(sfConfiguration)
searchController.searchBar.setImage(barCodeIcon, for: .bookmark, state:.normal)
searchController.obscuresBackgroundDuringPresentation = false
let attributes = [NSAttributedString.Key.foregroundColor : UIColor.white]
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes(attributes, for: .normal)
controller.navigationBar.topItem?.hidesSearchBarWhenScrolling = false
controller.navigationBar.topItem?.searchController = searchController
return controller
}
func updateUIViewController(_ uiViewController: UINavigationController, context: Context) {
}}
我正在使用 SwiftUI 应用程序协议构建 SwiftUI 应用程序。
我需要访问一些 UIKIt 函数,尤其是控制 NavigationView 的函数,如下所示:
显然,要做到这一点,我需要将我的 SwiftUI 视图与 ViewController 绑定。
我已尝试执行以下操作:
ContentView.swift
struct ContentView: View {
var body: some View {
ZStack {
ContentViewIntegratedController() // <- here
NavigationView{
ScrollView {
Text("Content View")
.navigationTitle("Content View")
}
}
}
}
}
class ContentViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
struct ContentViewIntegratedController: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> some UIViewController {
return ContentViewController()
}
func updateUIViewController(_ uiViewController: UIViewControllerType,
context: UIViewControllerRepresentableContext<ContentViewIntegratedController>) {}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
但是调用 ContentViewIntegratedContoller
(第 5 行)似乎创建了一个新的预览而不是修改现有的。
有没有集成一个ViewController来修改SwiftUI视图?
我不想做的事:
- 创建一个包含 SwiftUI 视图的 Storyboards 应用程序
- 为
ContentViewIntegratedViewController
创建故事板视图。
有没有其他方法可以在不向我的 SwiftUI 视图添加 ViewController 的情况下访问这些功能?
TIA。
纯 SwiftUI 无法直接检测 large
和 inline
显示模式之间的变化。但是,使用 SwiftUI-Introspect,你可以下降到 UIKit 来解决这个问题。
我通过获取大标题的视图并检测 alpha
属性 何时更改来解决此问题。这在标题从 large
变为 inline
或 vice-versa.
代码:
struct ContentView: View {
@State private var observer: NSKeyValueObservation?
@State private var title: String = "Large Title"
var body: some View {
NavigationView {
ScrollView {
Text("Hello world!")
}
.navigationTitle(title)
}
.introspectNavigationController { nav in
let largeTitleView = nav.navigationBar.subviews.first { view in
String(describing: type(of: view)) == "_UINavigationBarLargeTitleView"
}
observer = largeTitleView?.observe(\.alpha) { view, change in
let isLarge = view.alpha == 1
title = isLarge ? "Large Title" : "Inline title"
}
}
}
}
结果:
struct ContentView: View {
var body: some View {
ContentViewIntegratedController(view: YourView())
.ignoresSafeArea()
}
}
--------------------------------------------------------------
struct YourView: View {
var body: some View {
ScrollView{
Text("Hello, World!")
}
}}
------------------------------------------------------
import Foundation
import SwiftUI
struct ContentViewIntegratedController :UIViewControllerRepresentable{
var view: YourView
init(view:YourView) {
self.view = view
}
func makeUIViewController(context: Context) -> UINavigationController{
let childView = UIHostingController(rootView: view)
let controller = UINavigationController(rootViewController:childView)
let appearance = UINavigationBarAppearance()
let searchController = UISearchController()
searchController.searchBar.barStyle = .black
appearance.backgroundColor = UIColor(Color(.red))
appearance.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
controller.navigationBar.topItem?.compactAppearance = appearance
controller.navigationBar.topItem?.scrollEdgeAppearance = appearance
controller.navigationBar.topItem?.standardAppearance = appearance
controller.navigationBar.topItem?.title = "navigation bar"
controller.navigationBar.prefersLargeTitles = true
searchController.searchBar.searchTextField.attributedPlaceholder = NSAttributedString(string: "Rechercher...", attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])
searchController.searchBar.setValue("Annuler", forKey: "cancelButtonText")
searchController.searchBar.showsBookmarkButton = true
searchController.searchBar.searchTextField.leftView?.tintColor = .white
let sfConfiguration = UIImage.SymbolConfiguration(pointSize: 30)
let barCodeIcon = UIImage(systemName: "barcode.viewfinder")?.withTintColor(.white, renderingMode: .alwaysOriginal).withConfiguration(sfConfiguration)
searchController.searchBar.setImage(barCodeIcon, for: .bookmark, state:.normal)
searchController.obscuresBackgroundDuringPresentation = false
let attributes = [NSAttributedString.Key.foregroundColor : UIColor.white]
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes(attributes, for: .normal)
controller.navigationBar.topItem?.hidesSearchBarWhenScrolling = false
controller.navigationBar.topItem?.searchController = searchController
return controller
}
func updateUIViewController(_ uiViewController: UINavigationController, context: Context) {
}}