I’m fairly new to Swift and Xcode. I’ve been following along with Apple’s SwiftUI tutorials and haven’t had much problem, until I got to here: Interfacing with UIKit (https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit)
When I get to step 5, the build is successful but there is no preview. The error I receive is:
“ RemoteHumanReadableError: Failed to update preview.
The preview process appears to have crashed.
Error encountered when sending 'render' message to agent.
==================================
| RemoteHumanReadableError: The operation couldn’t be completed. (BSServiceConnectionErrorDomain error 3.)
|
| BSServiceConnectionErrorDomain (3):
| ==BSErrorCodeDescription: OperationFailed”
Any help on what I’m doing wrong, and why it’s wrong would be great help :)
Edit: code added
import SwiftUI
struct PageView<Page: View>: View {
var viewControllers: [UIHostingController<Page>]
init(_ views: [Page]) {
self.viewControllers = views.map { UIHostingController(rootView: $0) }
}
var body: some View {
PageViewController(controllers: viewControllers)
}
}
struct PageView_Previews: PreviewProvider {
static var previews: some View {
PageView(features.map { FeatureCard(landmark: $0) })
.aspectRatio(3/2, contentMode: .fit)
}
}
SwiftUI works seamlessly with the existing UI frameworks on all Apple platforms. For example, you can place UIKit views and view controllers inside SwiftUI views, and vice versa.
Compatibility with different iOS versions SwiftUI is limited and works better with iOS 14 and iOS 15. On the contrary, UIKit enables you to support even iOS version 9.0. This makes UIKit more flexible. It surely wins against SwiftUI when it comes to backward compatibility.
SwiftUI is more than ready for simple applications, but at the time of this writing (iOS 15, beta 4), I don't think SwiftUI is production-ready yet for complex applications, mainly due to the issues with ScrollViews and the heavy reliance on UIViewRepresentable .
For example, you can place UIKit views and view controllers inside SwiftUI views, and vice versa. This tutorial shows you how to convert the featured landmark from the home screen to wrap instances of UIPageViewController and UIPageControl.
Learn how to use SwiftUI to compose rich views out of simple ones, set up data flow, and build the navigation while watching it unfold in Xcode’s preview. Discover how to draw shapes and paths to create a badge that you’ll animate, while also creating seamless transitions between views.
Let’s begin by starting a new Xcode project in Xcode 11. Remember to check “Use SwiftUI” in the project creation window. 2. Xcode Tour Now, let’s take a look at the ContentView.swift file.
If you’re used to using UIKit, this is similar to the ViewController.swift file which is created by default when you start a new Xcode project. Once your project is created, you should see a screen that looks like this: Take note of the editor pane, preview pane, object library, and live preview button in the preview pane.
Using this page as inspiration, I was able to make this work in XCode 12 using the following code:
import SwiftUI
struct PageView<Page: View>: View {
var viewControllers: [UIHostingController<Page>]
init(viewControllers: [UIHostingController<Page>]) {
self.viewControllers = viewControllers
}
init(_ views: [Page]) {
self.viewControllers = views.map { UIHostingController(rootView: $0) }
}
var body: some View {
PageViewController(controllers: viewControllers)
}
}
struct PageView_Previews: PreviewProvider {
// the static in the following line is critical to it working...
static let controllers = features.map { UIHostingController(rootView: FeatureCard(landmark: $0)) }
static var previews: some View {
PageView(viewControllers: controllers).aspectRatio(3/2, contentMode: .fit)
}
}
It appears that you need to pass a fully constructed UIHostingController
array from within Preview, so I created an extra init
overload to be used for preview mode. The [Page]
-based init
is to keep the code compatible with the downstream steps in the tutorial. As to why it works with the static let
, sadly, I have no clue (i.e. if you put the let
statement inside of previews
as a non-static let
, it will fail to generate the preview.
this worked for me. added the @State & $currentPage to make the Preview along with the swipe to change images in the Active Preview finally work!
you need to finish Section 3 of Interfacing With UIKit before it works because you have to add the necessary lines in the PageViewController.swift. keep the Preview pinned to see it finally work once you assign the coordinator as the delegate in Section 3 - step 6.
// PageView.swift
import SwiftUI
struct PageView<Page: View>: View {
@State var currentPage = 1
var viewControllers: [UIHostingController<Page>]
init(viewControllers: [UIHostingController<Page>]) {
self.viewControllers = viewControllers
}
init(_ views: [Page]) {
self.viewControllers = views.map { UIHostingController(rootView: $0) }
}
var body: some View {
VStack {
PageViewController(controllers: viewControllers, currentPage: $currentPage)
Text("Current Page: \(currentPage)")
}
}
}
struct PageView_Previews: PreviewProvider {
static let controllers = features.map { UIHostingController(rootView: FeatureCard(landmark: $0)) }
static var previews: some View {
PageView(viewControllers: controllers).aspectRatio(3/2, contentMode: .fit)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With