Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

lloyddean

macrumors 65816
Original poster
May 10, 2009
1,047
19
Des Moines, WA
I'm looking into porting an old classic Mac OS game written in 68K assembler to run on the current version of macOS using SwiftUI and SpriteKit.

My current implementation is a Cocoa based shell written in Swift that I wish to change to use SwiftUI in an attempt to target Mac, iPhone, iPad and Apple TV.

There are a great number of tutorials and example code based on SwiftUI targeting iPhone/iPad but very little targeting macOS or Apple TV.

Is anyone aware of any SwiftUI macOS example code on forcing a macOS SwiftUI SpriteView to resize while keeping a set aspectRatio?

Something equivalent to my existing shell's working code -

Code:
class GameViewController: NSViewController {
    ...
    override func viewDidAppear() {
        super.viewDidAppear()

        if let window = view.window {
            window.contentAspectRatio = NSSize(width: 4, height: 3)
            window.update()
        }
    }
}
 

casperes1996

macrumors 604
Jan 26, 2014
7,593
5,764
Horsens, Denmark
I never got all that good at SwiftUI (yet), but I do know that there is presently no way of accessing the window itself without going out to UIKit/AppKit.

However, since you're working with SpriteKit, my first instinct would be to set the scaleMode to .aspectFill on the scene itself rather than trying to change it in the window, and I would assume with the way SwiftUI works that the view and thus the window would be tightly bound to the scene's borders if it's the only thing presented

 

prime17569

macrumors regular
May 26, 2021
207
524
Is anyone aware of any SwiftUI macOS example code on forcing a macOS SwiftUI SpriteView to resize while keeping a set aspectRatio?

The .scaledToFill(), .scaledToFit(), or aspectRatio() view modifiers could help, and are available on macOS too.

From Apple's documentation:
func scaledToFill() -> some View
func scaledToFit() -> some View
func aspectRatio(CGFloat?, contentMode: ContentMode) -> some View (btw, you can also provide this a plain old Float and it will work)
func aspectRatio(CGSize, contentMode: ContentMode) -> some View

IMHO, in my experience, native SwiftUI support on macOS is pretty poor compared to that on iOS/iPadOS. If you're familiar with iOS development, you might want to consider using Mac Catalyst with Optimized for Mac mode enabled to build the Mac app, which would allow you to make use of the large library of iOS-targeted code samples on the Mac.

This blog post by Steve Troughton-Smith has some great examples of Mac UI patterns in Catalyst made with SwiftUI and UIKit (occasionally dipping into AppKit).

edit: fixed a link
 
Last edited:

lloyddean

macrumors 65816
Original poster
May 10, 2009
1,047
19
Des Moines, WA
Guys, thanks for taking the time and effort to respond.

I've explored both your suggestions already and for various reason rejected them.

casperes1996 as well as prime17569's first suggestion displays the games content distorted and floating in the center of black rectangle with some contents hanging past the view edges depending on the users Window resizing efforts.

prime17569's suggestion of Catalyst I considered and then rejected as unlikely to be supported in the future and is unavailable last I checked on Apple TV.

If anyone come across something more palatable please keep this thread request in mind.

Thanks again!
 

casperes1996

macrumors 604
Jan 26, 2014
7,593
5,764
Horsens, Denmark
Guys, thanks for taking the time and effort to respond.

I've explored both your suggestions already and for various reason rejected them.

casperes1996 as well as prime17569's first suggestion displays the games content distorted and floating in the center of black rectangle with some contents hanging past the view edges depending on the users Window resizing efforts.

prime17569's suggestion of Catalyst I considered and then rejected as unlikely to be supported in the future and is unavailable last I checked on Apple TV.

If anyone come across something more palatable please keep this thread request in mind.

Thanks again!

Does what I suggested work well for non-macOS platforms like the AppleTV? Last I tried messing with SwiftUI I concluded it wasn’t yet a good fit for window-based systems like macOS, but systems where the view does not live inside a traditional window seemed much more suited for it.
That may still be the case, and if so my recommendation would be AppKit for the Mac and SwiftUI elsewhere.
Besides, if your AppKit/SwiftUI code is just there to host the SpriteKit scene(s) then it’s not that much code around it that can’t be shared, right?
 

prime17569

macrumors regular
May 26, 2021
207
524
Guys, thanks for taking the time and effort to respond.

I've explored both your suggestions already and for various reason rejected them.

casperes1996 as well as prime17569's first suggestion displays the games content distorted and floating in the center of black rectangle with some contents hanging past the view edges depending on the users Window resizing efforts.

prime17569's suggestion of Catalyst I considered and then rejected as unlikely to be supported in the future and is unavailable last I checked on Apple TV.

If anyone come across something more palatable please keep this thread request in mind.

Thanks again!

Out of curiosity, what happened when you tried .scaledToFit()? Would you be able to post some screenshots or code?

With regards to Catalyst, whether you choose to use it or not, you're probably still going to need a separate target for Apple TV. Catalyst just allows you to merge your iOS and macOS targets into one. And you can use SwiftUI in all of these cases, even in a Catalyst app.

Considering that several of Apple's default apps are now Catalyst apps (most notably Messages, Maps, Podcasts, and Books), I would argue that Apple will support Catalyst for years to come.

Ultimately, it comes down to which framework suits your requirements best.
 
Last edited:

szymczyk

macrumors regular
Mar 5, 2006
187
17
Is there a reason you need to use SwiftUI? If you create a multiplatform game project in Xcode, you can create a SpriteKit game that runs on iOS, Mac and tvOS. You will also get better backward compatibility by using SpriteKit without SwiftUI.
 

lloyddean

macrumors 65816
Original poster
May 10, 2009
1,047
19
Des Moines, WA
Well it's certainly possible to get a reference to Window in an SwiftUI based SpriteKit app.

Anyone want to weigh-in on doing a bit of an end-run and setting the windows contentAspectRatio member in this manner.

Code:
class SceneTileMap: SKScene {
    var window: NSWindow!

//  override func didMove(to view: SKView) {
//  }

    override func update(_ currentTime: TimeInterval) {
        if window == nil {
            if let w = self.view?.window {
                window = w
                window.contentAspectRatio = NSSize(width: 4, height: 3)
                print("\(#function) Window found: \(w)")
            }
        }
    }

    override func mouseDown(with event: NSEvent) {
        print("\(#function) Squeek!.")
    }
}


struct ContentView: View {

    let dxView = 640.0
    let dyView = 400.0

    var scene: SceneTileMap {
        let scene = SceneTileMap()
        scene.size = CGSize(width: dxView, height: dyView)
        scene.scaleMode = .aspectFit
        return scene
    }

    var body: some View     {
        SpriteView(scene: scene)
            .frame(minWidth: 320.0, idealWidth: 1280.0, maxWidth: 1280.0, minHeight: 200.0, idealHeight: 800.0, maxHeight: 800.0, alignment: .center)
    }
}
 
Last edited:

casperes1996

macrumors 604
Jan 26, 2014
7,593
5,764
Horsens, Denmark
You just escaped SwiftUI. NSWindow is part of AppKit and this won't be a single codebase across platforms anymore since NSWindow doesn't exist on non-macOS systems like iOS and tvOS
 

lloyddean

macrumors 65816
Original poster
May 10, 2009
1,047
19
Des Moines, WA
A conditional indeed, but it is the only case (thus far) where there is really a case, given the platform. where the user is likely to want to change and place the game window. All other platforms are full screen only.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.