Search code examples
xcodeswiftuiipad-playgrounds

How do you render Text("Content") in SwiftUI on an iPad in Swift Playgrounds vs. Xcode on a Mac?


The above code works on a Mac, using the Xcode editor. However, the same code returns: abort() called on an iPad using Swift Playground's editor. How do I render Text() on the iPad?

I followed the directions in this video:

https://developer.apple.com/videos/play/wwdc2020/10643/

I found a similar question in Apple's developer forums, but no real solution:

https://developer.apple.com/forums/thread/667357

I tried decreasing the size, but that didn't help:

"I would assume based on the other question with Abort(), that Abort() is called if it is about to crash, and it seems that the view isn't getting the bounds of the screen in the live view, so it doesn't know how/where to render the view."

import SwiftUI
import PlaygroundSupport

struct ProgressView: View {
   
   var body: some View {
       ZStack {
           Circle()
           .stroke(lineWidth: 40)
           .foregroundColor(.blue)
               Text("25%")
       }
   }
   
}

PlaygroundPage.current.setLiveView(ProgressView().padding(150))


Solution

  • This is most likely a bug — I filed feedback #FB9092837. But until Apple fixes it, adding a hardcoded .frame works as a hacky fix.

    .frame(width: 500, height: 500)
    

    However, it takes a while to load... it first renders in the top-left corner, and after a couple seconds, moves to the center.

    GIF of the long loading time

    I found that if you put your ProgressView inside another container view, and set the frame there, it's much faster.

    GIF of the much faster loading time

    Here's the code:

    import SwiftUI
    import PlaygroundSupport
    
    struct ProgressView: View {
        var body: some View {
            ZStack {
                Circle()
                    .stroke(lineWidth: 40)
                    .foregroundColor(.blue)
                Text("25%")
            }
        }
    }
    
    struct ContainerView: View {
        var body: some View {
            ProgressView()
                .frame(width: 500, height: 500)
        }
    }
    
    PlaygroundPage.current.setLiveView(ContainerView())