Невозможно правильно определить размер SKScene при работе с SwiftUI - PullRequest
0 голосов
/ 07 октября 2019

Я пытаюсь использовать SpriteKit с интерфейсом на основе SwiftUI, но столкнулся с проблемой при инициализации моего SKScene.

Во-первых, мой UIViewRepresentable, содержащий SKView, имеетвзято из аналогичного вопроса :

struct SpriteKitContainer: UIViewRepresentable {
    let scene: SKScene

    func makeUIView(context: Context) -> SKView {
        return SKView(frame: .zero)
    }

    func updateUIView(_ view: SKView, context: Context) {
        view.presentScene(scene)
    }
}

Ключевым моментом здесь является то, что требуется инициализация SKScene до инициализации SpriteKitContainer.

В настоящее время у меня есть следующий сокращенный фрагмент кода:

import SwiftUI
import SpriteKit

struct GameView: View {
    @State private var isEnabled = true

    var body: some View {
        let tapGesture = TapGesture()
            .onEnded { value in }

        // This size is obviously wrong
        let size = UIScreen.main.bounds.size
        let scene = Scene(size: size)
        scene.scaleMode = .resizeFill

        return SpriteKitContainer(scene: scene)
            .disabled(!isEnabled)
            .frame(maxWidth: .infinity,
                   maxHeight: .infinity,
                   alignment: .center)
            .gesture(tapGesture)
            .padding(.all, 30)
    }
}

Я только включаю TapGesture, чтобы показать, почему структура body такова, как она есть. С включенным кодом все будет работать так, как ожидается, но размер, используемый для сцены, явно неправильный (он не учитывает отступы и элементы навигации).

Однако я не нашел другого способачтобы получить размер или фрейм на этом этапе, и отправка размером .zero для вызова Scene(size:) также не изменит его размер правильно.

Я предполагаю, что я пропускаю какой-то шаг предшественника, поскольку явсе еще нарастает с SwiftUI. В противном случае я мог бы вычислить новое CGSize с учетом того, что я знаю, но это кажется мне неправильным подходом.

1 Ответ

1 голос
/ 08 октября 2019

В SwiftUI вам нужно использовать GeometryReader в качестве прокси для получения текущего размера представления (это происходит каждый раз, когда представление перестраивается). Затем вы хотите изменить размер вашего UIViewRepresentable на основе размера его родительского элемента , только если размер фактически изменился . У меня есть пример GeometryReader: https://github.com/joshuajhomann/SwiftUI-Spirograph

...