SwiftUI cannot show SpriteView in live activities

189 Views Asked by At

I am trying to show a sprite view in an app. I already have it showing as a view on the main app and it works perfectly fine. The problem comes when I try and add it as a view using

var characterView: some View {
        SpriteView(scene: characterScene)
            .frame(width: 50, height: 50)
    }

and just showing that view.

Here is some minimal code:

// Character Animation
import Foundation
import SpriteKit

class CharacterScene: SKScene {
    let characterName: String
    init(characterName: String) {
        self.characterName = characterName
        super.init(size: CGSize(width: 300, height: 400))
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    var textures: [SKTexture] = []
    override func didMove(to view: SKView) {
        let atlas = SKTextureAtlas(named: characterName)
        textures = atlas.textureNames.sorted().map { atlas.textureNamed($0) }
        
        let sprite = SKSpriteNode(texture: textures[0])
        let maxSize: CGFloat = 200
        let aspectRatio = sprite.size.height / sprite.size.width
        sprite.size = CGSize(width: min(sprite.size.width, maxSize), height: min(sprite.size.height, maxSize * aspectRatio))
        sprite.position = CGPoint(x: frame.midX, y: frame.midY)
        addChild(sprite)
        
        let animation = SKAction.animate(with: textures, timePerFrame: 0.5)
        sprite.run(SKAction.repeatForever(animation))
    }
}

//Widget

import WidgetKit
import SwiftUI
import ActivityKit
import SpriteKit

struct CharacterIslandWidget: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(
            for: CharacterIslandAttributes.self,
            content: { context in
                CharacterIslandWidgetView(context: context)
            },
            dynamicIsland: { context in
                DynamicIsland(
                    expanded: {
                        DynamicIslandExpandedRegion(.center) {
                            Text(context.state.CharacterName)
                        }
                        DynamicIslandExpandedRegion(.leading) {
                            SpriteView(scene: CharacterScene(characterName: context.state.CharacterImage))
                                .frame(width: 50, height: 50)
                        }
                    },
                    compactLeading: {
                        SpriteView(scene: CharacterScene(characterName: context.state.CharacterImage))
                            .frame(width: 50, height: 50)
                    },
                    compactTrailing: {
                    },
                    minimal: {
                        SpriteView(scene: CharacterScene(characterName: context.state.CharacterImage))
                            .frame(width: 50, height: 50)
                    })
            }
    )}
}
struct CharacterIslandWidgetView: View {
    let context: ActivityViewContext<CharacterIslandAttributes>
    var body: some View {
        SpriteView(scene: CharacterScene(characterName: context.state.CharacterImage))
            .frame(width: 50, height: 50)
        Text(context.state.CharacterImage)
    }
}

I don't get any executable errors in the logs, so I don't exactly know the problem, but the image looks like this (I don't have previews set up for the widgets yet).

image error

The atlas name is given below the image and is correct as it is running perfectly fine in the app.

A few extra things:

  • The asset folder is shared between the widget and app, and it works because it shows up on the app.
  • context.state.CharacterImage is the atlas "folder" name which has all the sprites.

How do I go about this from here? Are sprite views not allowed in Live Activities (Dynamic Island)?

I tried hardcoding names, and reading error logs, but nothing showed.

1

There are 1 best solutions below

1
On BEST ANSWER

Widgets only support a subset of SwiftUI views and live activities are a special kind of widget. Apple documents the SwiftUI views that can be used in widgets.

The red no entry symbol seems to be displayed when trying to use an unsupported SwiftUI view (Why do some views appear as a red no entry sign in widgets?)