stackotter / swift-cross-ui

A cross-platform declarative UI framework, inspired by SwiftUI.
https://stackotter.github.io/swift-cross-ui/documentation/swiftcrossui/
MIT License
652 stars 36 forks source link

[AppKitBackend] Fix VStack and HStack layout #87

Closed stackotter closed 2 months ago

stackotter commented 7 months ago

VStack and HStack are the building blocks of basically all layouts, so it's very obvious when they don't have very sensible default layouts.

I've run GreetingGeneratorExample with SwiftCrossUI's AppKitBackend, and run an equivalent app built with SwiftUI. Some of the differences in layout are due to padding not being implemented for AppKitBackend yet, but the major differences are due to VStack having terrible automatic layout.

Since SwiftCrossUI expands the root view to fill the window (to make NavigationSplitView work properly), the NSStackView that represents the root VStack is constrained to fill the window. This would be fine except that stack views seem to want to use all available space for laying out their children instead of maintaining a consistent constant spacing between views (e.g. 8 pixels). This still occurs even when the children all get their 'gravity' set to center (which I assumed would make the stack view lay them out closely together and centered at the center). I've looked around for a property to achieve the desired behaviour, to no avail.

I reckon we should implement our own NSStackView from scratch (which essentially just involves writing code to correctly set up constraints between children of the stack). This would both help solve this specific problem and give us the flexibility to fine tune stuff in the future.

SwiftCrossUI (at time of writing)

Screenshot 2024-04-10 at 12 17 50 am Screenshot 2024-04-10 at 12 18 05 am Screenshot 2024-04-10 at 12 18 16 am

SwiftUI

Screenshot 2024-04-10 at 12 15 15 am

Screenshot 2024-04-10 at 12 15 28 am

Screenshot 2024-04-10 at 12 15 45 am

Once the history list appears, it fills the remaining space because it's a ScrollView. SwiftCrossUI gets that part right.

stackotter commented 2 months ago

The new layout system fixes this. SwiftCrossUI now replicates SwiftUI's layout behaviour in this scenario.