From e0116013b28ee9dd670d80260d42702fdb06159c Mon Sep 17 00:00:00 2001 From: Muukii Date: Wed, 8 May 2024 12:45:49 +0900 Subject: [PATCH] WIP --- .../Development.xcodeproj/project.pbxproj | 8 ++- .../Development/Book/BookHosting.swift | 53 +++++++++++++++++++ Development/Development/ContentView.swift | 20 ++++--- Development/Development/Util.swift | 10 ++++ .../SwiftUIHosting/HostingController.swift | 22 ++++++++ .../SwiftUIHosting/SwiftUIHostingView.swift | 10 ++-- 6 files changed, 109 insertions(+), 14 deletions(-) create mode 100644 Development/Development/Book/BookHosting.swift diff --git a/Development/Development.xcodeproj/project.pbxproj b/Development/Development.xcodeproj/project.pbxproj index 973afd5..c51e45b 100644 --- a/Development/Development.xcodeproj/project.pbxproj +++ b/Development/Development.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 4B7DF0652BEA8D7A00C59107 /* BookHosting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7DF0642BEA8D7900C59107 /* BookHosting.swift */; }; 4B7E762429B9A1EF009DE246 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7E762329B9A1EF009DE246 /* ContentView.swift */; }; 4B7E762629B9A1F0009DE246 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4B7E762529B9A1F0009DE246 /* Assets.xcassets */; }; 4B7E762929B9A1F0009DE246 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4B7E762829B9A1F0009DE246 /* Preview Assets.xcassets */; }; @@ -18,6 +19,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 4B7DF0642BEA8D7900C59107 /* BookHosting.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookHosting.swift; sourceTree = ""; }; 4B7E761E29B9A1EF009DE246 /* Development.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Development.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4B7E762329B9A1EF009DE246 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 4B7E762529B9A1F0009DE246 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -87,6 +89,7 @@ isa = PBXGroup; children = ( 4B7E763729B9B105009DE246 /* BookSizing.swift */, + 4B7DF0642BEA8D7900C59107 /* BookHosting.swift */, ); path = Book; sourceTree = ""; @@ -174,6 +177,7 @@ files = ( 4B7E763029B9A214009DE246 /* AppDelegate.swift in Sources */, 4B7E762429B9A1EF009DE246 /* ContentView.swift in Sources */, + 4B7DF0652BEA8D7A00C59107 /* BookHosting.swift in Sources */, 4B7E763829B9B105009DE246 /* BookSizing.swift in Sources */, 4B7E763B29B9B143009DE246 /* Util.swift in Sources */, ); @@ -312,7 +316,7 @@ INFOPLIST_KEY_UILaunchStoryboardName = "Launch Screen.storyboard"; INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -342,7 +346,7 @@ INFOPLIST_KEY_UILaunchStoryboardName = "Launch Screen.storyboard"; INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/Development/Development/Book/BookHosting.swift b/Development/Development/Book/BookHosting.swift new file mode 100644 index 0000000..7217187 --- /dev/null +++ b/Development/Development/Book/BookHosting.swift @@ -0,0 +1,53 @@ +import SwiftUI +import SwiftUIHosting + +@available(iOS 14.0, *) +struct BookHosting: View, PreviewProvider { + var body: some View { + ContentView() + } + + static var previews: some View { + Self() + } + + private struct ContentView: View { + + @State var text: String = "" + + var body: some View { + HostingViewHost { + VStack { + Color.purple.frame(width: 100, height: 100) + TextField("Text", text: $text) + Color.purple.frame(width: 100, height: 100) + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .ignoresSafeArea(.keyboard) + .background(Color(white: 0.1)) + } +// .ignoresSafeArea() +// .background(Color(white: 0.1)) + } + } +} + +private struct HostingViewHost: UIViewRepresentable { + + let content: () -> Content + + init(@ViewBuilder content: @escaping () -> Content) { + self.content = content + } + + func makeUIView(context: Context) -> UIView { +// _UIHostingView(rootView: AnyView(content())) + SwiftUIHostingView { + content() + } + } + + func updateUIView(_ uiView: UIView, context: Context) { + // Nothing + } +} diff --git a/Development/Development/ContentView.swift b/Development/Development/ContentView.swift index 80d2504..8655b7d 100644 --- a/Development/Development/ContentView.swift +++ b/Development/Development/ContentView.swift @@ -9,13 +9,19 @@ import SwiftUI struct ContentView: View { var body: some View { - NavigationView { - List { - NavigationLink("Content") { - BookSizing() - } - } - } +// NavigationView { +// List { +// NavigationLink("Content") { +// BookSizing() +// } +// if #available(iOS 14.0, *) { +// NavigationLink("Hosting") { +// BookHosting() +// } +// } +// } +// } + BookHosting() } } diff --git a/Development/Development/Util.swift b/Development/Development/Util.swift index e22737d..eb0d345 100644 --- a/Development/Development/Util.swift +++ b/Development/Development/Util.swift @@ -4,6 +4,16 @@ import SwiftUIHosting func measureSize(content: some View, targetSize: CGSize) { + do { + if #available(iOS 15.0, *) { + let a = _makeUIHostingController(AnyView(content), tracksContentSize: true, secure: false) + print(a) + } else { + // Fallback on earlier versions + } + + } + do { let size = UIHostingController(rootView: content).sizeThatFits(in: targetSize) print("System SizeThatFits:", size) diff --git a/Sources/SwiftUIHosting/HostingController.swift b/Sources/SwiftUIHosting/HostingController.swift index f5c7156..0569893 100644 --- a/Sources/SwiftUIHosting/HostingController.swift +++ b/Sources/SwiftUIHosting/HostingController.swift @@ -15,6 +15,28 @@ final class HostingController: UIHostingController { #else _disableSafeArea = disableSafeArea #endif + + if true { + guard let viewClass = object_getClass(view) else { return } + + let viewSubclassName = String(cString: class_getName(viewClass)).appending("_IgnoresKeyboard") + if let viewSubclass = NSClassFromString(viewSubclassName) { + object_setClass(view, viewSubclass) + } + else { + guard let viewClassNameUtf8 = (viewSubclassName as NSString).utf8String else { return } + guard let viewSubclass = objc_allocateClassPair(viewClass, viewClassNameUtf8, 0) else { return } + + if let method = class_getInstanceMethod(viewClass, NSSelectorFromString("keyboardWillShowWithNotification:")) { + let keyboardWillShow: @convention(block) (AnyObject, AnyObject) -> Void = { _, _ in } + class_addMethod(viewSubclass, NSSelectorFromString("keyboardWillShowWithNotification:"), + imp_implementationWithBlock(keyboardWillShow), method_getTypeEncoding(method)) + } + objc_registerClassPair(viewSubclass) + object_setClass(view, viewSubclass) + } + } + } @MainActor required dynamic init?(coder aDecoder: NSCoder) { diff --git a/Sources/SwiftUIHosting/SwiftUIHostingView.swift b/Sources/SwiftUIHosting/SwiftUIHostingView.swift index 8dd9332..d3e720e 100644 --- a/Sources/SwiftUIHosting/SwiftUIHostingView.swift +++ b/Sources/SwiftUIHosting/SwiftUIHostingView.swift @@ -48,7 +48,7 @@ open class SwiftUIHostingView: UIView { } } - private let hostingController: HostingController + private let hostingController: UIHostingController public let configuration: Configuration @@ -93,10 +93,10 @@ open class SwiftUIHostingView: UIView { hostingController.view.leftAnchor.constraint(equalTo: leftAnchor), ]) - hostingController.onViewDidLayoutSubviews = { controller in - // TODO: Reduces number of calling invalidation, it's going to be happen even it's same value. - controller.view.invalidateIntrinsicContentSize() - } +// hostingController.onViewDidLayoutSubviews = { controller in +// // TODO: Reduces number of calling invalidation, it's going to be happen even it's same value. +// controller.view.invalidateIntrinsicContentSize() +// } } @available(*, unavailable)