Post

Replies

Boosts

Views

Activity

SwiftUI Scrollview with both axes enabled produces layout mess
The Problem In our brand new SwiftUI project (Multiplatform app for iPhone, iPad and Mac) we are using a ScrollView with both .horizontal and .vertical axes enabled. In the end it all looks like a spreadsheet. Inside of ScrollView we are using LazyVStack with pinnedViews: [.sectionHeaders, .sectionFooters]. All Footer, Header and the content cells are wrapped into a LazyHStack each. The lazy stacks are needed due to performance reasones when rows and columns are growing. And this exactly seems to be the problem. ScrollView produces a real layout mess when scrolling in both axes at the same time. Tested Remedies I tried several workarounds with no success. We built our own lazy loading horizontal stack view which shows only the cells whose indexes are in the visible frame of the scrollview, and which sets dynamic calculated leading and trailing padding. I tried the Introspect for SwiftUI packacke to set usesPredominantAxisScrolling for macOS and isDirectionalLockEnabled for iOS. None of this works as expected. I also tried a workaround to manually lock one axis when the other one is scrolling. This works fine on iOS but it doesn't on macOS due to extreme poor performance (I think it's caused by the missing NSScrollViewDelegate and scroll events are being propagated via NotificationCenter). Example Screen Recordings To give you a better idea of what I mean, I have screenshots for both iOS and macOS. Example Code And this is the sample code used for the screenshots. So you can just create a new Multiplatform project and paste the code below in the ContentView.swift file. That's all. import SwiftUI let numberOfColums: Int = 150 let numberOfRows: Int = 350 struct ContentView: View { var items: [[Item]] = { var items: [[Item]] = [[]] for rowIndex in 0..<numberOfRows { var row: [Item] = [] for columnIndex in 0..<numberOfColums { row.append(Item(column: columnIndex, row: rowIndex)) } items.append(row) } return items }() var body: some View { Group { ScrollView([.horizontal, .vertical]) { LazyVStack(alignment: .leading, spacing: 1, pinnedViews: [.sectionHeaders, .sectionFooters]) { Section(header: Header()) { ForEach(0..<items.count, id: \.self) { rowIndex in let row = items[rowIndex] LazyHStack(spacing: 1) { ForEach(0..<row.count, id: \.self) { columnIndex in Text("\(columnIndex):\(rowIndex)") .frame(width: 100) .padding() .background(Color.gray.opacity(0.2)) } } } } } } .edgesIgnoringSafeArea([.top]) } .padding(.top, 1) } } struct Header: View { var body: some View { LazyHStack(spacing: 1) { ForEach(0..<numberOfColums, id: \.self) { idx in Text("Col \(idx)") .frame(width: 100) .padding() .background(Color.gray) } Spacer() } } } struct Item: Hashable { let id: String = UUID().uuidString var column: Int var row: Int } Can You Help? Okay, long story short... Does anybody knows a real working solution for this issue? Is it a known SwiftUI ScrollView bug? If there were a way to lock one scrolling direction while the other is scrolled, then I could deal with that. But at the moment, unfortunately, it is not usable for us. So any solution is highly appreciated! Ideally an Apple engineer can help. 😃 NOTE: Unfortunately Apple does not allow URLs to anywhere. I also have two screen recordings for both iOS and macOS. So, if you would like to watch them, please contact me.
5
3
4.1k
Jun ’22
Xcode Cloud: How to configure Xcode for both local and remote dependencies?
The Situation Our SwiftUI project uses three Swift packages (hosted on GitHub in private repositories): a custom UIKit package a custom BackendKit package a custom ApplicationKit package From the filesystem perspective it looks like this: OurApplication/ CustomUIKitPackage/ CustomBackendKitPackage/ CustomApplicationKitPackage/ I added all three packages as local dependencies (because we need to edit them constantly) by dragging their folders into the project workspace. In the Xcode project navigator they are now under a Packages group. I also added remote dependencies for all three packages to the Xcode project by using their git@github.com:... URL. Access to these three private repos are already granted. The Problem With this configuration I can work on the project and on all three packages as well. I can make changes, run tests, all the stuff - No problem. Triggering an Xcode Cloud build it will always fail saying something weird of: an out-of-date resolved file was detected at /Volumes/workspace/repository/MY_PROJECT.xcworkspace/xcshareddata/swiftpm/Package.resolved, which is not allowed when automatic dependency resolution is disabled; please make sure to update the file to reflect the changes in dependencies. Running resolver because the following dependencies were added: 'CustomBackendKitPackage' (git@github.com:MY_COMPANY/CustomBackendKitPackage.git)xcodebuild: error: Could not resolve package dependencies: Removing all three local dependencies out of MY_PROJECT/Packages/*, pushing everthing to GitHub and running an Xcode Cloud build again, it works as expected. All three remote dependencies with its git@github.com:... URLs are being used correctly and the Xcode Cloud build turns green. The Question How do I configure Xcode correctly so that I have my local packages for development at the same time as Xcode Cloud uses the remote references?
1
2
1.4k
Jun ’22