I have a two-view app where the main view is a procedural animation and a secondary view controls settings for the animation. I want to use Play/Pause to toggle between the views, but can't figure out how to do this.
Ideally the main view does not have any visible control and the whole screen can be dedicated to the animation view. Attaching onPlayPauseCommand to the main view does not work. I've also tried managing focus using onFocus without success.
I'm open to other ways to toggle between the main and settings views, it's just that Play/Pause seems the most intuitive.
Post
Replies
Boosts
Views
Activity
I'm trying to write a unit test for a SwiftData migration. In the teardown function I delete the SQLite container files, but then the underlying sqlite library complains.
There must be a way to gracefully terminate the SwiftData container before I delete the files, but I don't see how. Simplying nil-ifying the references doesn't work. I don't see any obvious close functions, so I hope someone knows a non-obvious function.
override func tearDownWithError() throws {
// Cleanup resources
// -- DOES NOT CLOSE UNDERLYING SQLITE ACCESS --
self.container = nil
self.context = nil
// Delete database
do {
try FileManager.default.removeItem(at: self.url)
}
catch {
// Ignore file not found, report everything else.
let nserror = error as NSError
if nserror.domain != "NSCocoaErrorDomain" && nserror.code == 4 {
throw error
}
}
try? FileManager.default.removeItem(at: self.url.deletingPathExtension().appendingPathExtension("store-shm"))
try? FileManager.default.removeItem(at: self.url.deletingPathExtension().appendingPathExtension("store-wal"))
}
I get these errors for .store, store-shm, and .store-wal:
BUG IN CLIENT OF libsqlite3.dylib: database integrity compromised by API violation: vnode unlinked while in use: /Users/(ME)/Library/Developer/XCTestDevices/C52F4E12-EB4F-4639-9866-C3A7126155FA/data/Containers/Data/Application/B0EE90C6-B95D-4185-890D-6F20766B9B3B/tmp/test1.store
invalidated open fd: 11 (0x11)
If the worst comes to the worst, I'll work around it by using a differently-named container for each test, but as they're in tmp they'll get cleaned up for me eventually.
When I save an item which is a FileRepresentation to the File system/Files app, TWO files are saved: the shared file, and simple text file containing the message text. I don't want the user to get the message in a text file when they save that way. Sure I can just leave out the message parameter, but then it's useful if they want to email the file somewhere? Is there a way to have a message text that isbn't saved in a file?
ShareLink(item: ...,
subject: Text("..."),
message: Text("..."), //⬅ this text gets saved in a 2nd file
preview: SharePreview("...", image: ...)) {
Label { Text("...") } icon: { Image(systemName: "square.and.arrow.up") }
}
How can I tell List to animate row height changes?
I have a list whose rows may grow or shrink with user actions. When that happens the List is redrawn with the new heights instantly but the contents slide to their new position. It'd be better if the row heights were animated. Since I don't know what a row's height is I can't use the usual .frame(height: self.animate ? 60 : 90)
This code demonstrates the problem.
struct ContentView: View {
@State private var numbers: [Int] = [0,1,2,3]
var body: some View {
VStack {
List {
Item(numbers: $numbers)
Item(numbers: .constant([9,8,7]))
}
.font(.largeTitle)
HStack {
Button { withAnimation { addNumber() }}
label: { Text("Add") }
Spacer()
Button { withAnimation { removeNumber() }}
label: { Text("Remove") }
}
}
.padding()
}
private func addNumber() {
numbers.append(numbers.count)
}
private func removeNumber() {
numbers = numbers.dropLast()
}
}
struct Item: View {
@Binding var numbers: [Int]
var body: some View {
VStack {
ForEach(numbers, id:\.self) { n in
Text("\(n)")
}
}
}
}
I haven’t done any work for Intents so I don’t know why iOS is making Siri suggestions for my app.
Every now and then, maybe especially in the morning, my iPhone will show a button at the bottom of the Lock Screen with my app icon, the title of a data record from inside my app, and the caption “Siri suggestion”. Tapping it launches my app but that’s it. The app doesn’t show the record.
Why is iOS doing this? Is this some half-baked effect of using iCloud data or Swift Data?
I can’t release the app with iOS doing this, and adding proper Intent support would delay the release.
I want to access to a small number of Markdown text files. It looks like the asset catalog feature "Folder with Namespace" might do well, as I could store these small files in a folder that the asset catalog contains. How would I go about getting the string contents of a particular file if I know its name?
How do I make iCloud optional when using SwiftData? Not all users will have an iCloud account, or allow my app to use iCloud. I want it to gracefully, silently use a local store instead of iCloud if iCloud isn't available. It should also silently handle when the user switches iCloud on or off.
.modelContainer(for: MyMode.self, isUndoEnabled: true)
This may work for single model containers, but I have a number of models. I don't see how to enable undo for multiple model containers.
The keyboard shortcut Control + Command + F normally toggles a window's full screen mode. It's assigned to the menu command View / Enter Full Screen. Well, if you make a multiplatform document-based app, create a new document, the shortcut does not work. The menu command works just fine.
Does anyone have a workaround for this?
ScrollViewReader doesn't seem to work reliably with an animated alignmentGuide view as the target. If I scroll by hand then SVR will track the animated guide. Rescaling the content often breaks the behavior and requires another manual scroll to reconnect the animation to scrolling.
In my test I have a media player-like timeline. I'd like to keep the elapsed time cursor centered, no matter the length of the timeline rectangle.
struct ContentView: View {
@State private var zoom: Double = 10
let start = Date.now
let duration: TimeInterval = 60
var body: some View {
VStack(alignment: .leading) {
TimelineView(.periodic(from: start, by: 1)) { context in
let elapsed = context.date.timeIntervalSince(start)
ScrollViewReader { proxy in
ScrollView(.horizontal) {
Text("\(elapsed.formatted(.number.precision(.fractionLength(0)))) / \(duration.formatted(.number.precision(.fractionLength(0))))")
let barWidth: CGFloat = max(300, duration * zoom)
ZStack(alignment: Alignment(horizontal: .marker, vertical: .bottom)) {
ZStack(alignment: .leading) {
// The bar representing the duration.
Rectangle().fill(Color.gray)
// The bar representing the elapsed time.
Rectangle().fill(Color.accentColor)
.frame(width: barWidth * (elapsed / duration))
.alignmentGuide(.marker) { d in d[.trailing] }
}
.frame(width: barWidth, height: 20)
Rectangle().fill(Color.primary).frame(width: 3)
.alignmentGuide(.marker) { d in d[HorizontalAlignment.trailing] }
.id(1)
}
.frame(height: 30)
.onChange(of: elapsed, perform: { _ in proxy.scrollTo(1, anchor: .center) })
}
.onChange(of: elapsed, perform: { newValue in if newValue > duration { exit(0) } })
}
}
Slider(value: $zoom, in: 0.5...40, label: { Text("Zoom") })
let s = zoom.formatted(.number.precision(.fractionLength(1)))
Text("\(s)")
}
.padding()
}
}
I am writing a document-based app for macOS using SwiftUI. I want the File menu's New Document command to show a template picker/wizard, and then let the wizard create the document.
How do I structure this? Is there documentation? Examples?
I tried this pattern
@main struct DocDemoApp: App {
var body: some Scene {
WindowGroup { NewDocWizard() }
DocumentGroup(newDocument: { DocDemoDocument() }) {
ContentView(document: $0.document)
}
}
}
The NewDocWizard calls newDocument({ DocDemoDocument() }). But the WindowGroup makes a File > New Window command while DocumentGroup makes the File > New Document command. I need just New Document and it should show the NewDocWizard.
Similarly to this old post [https://developer.apple.com/forums/thread/130969] I am getting a "ThreadSanitizer: CHECK failed" before my code seems to have launched. Is this something I should spend time trying to reproduce in a small project or is it an Xcode bug others are getting too?
Turning off the sanitizer is my dirty workaround for now.
I want to present a table using SwiftUI. I've gotten most of the way using LazyVGrid.
Problem 1 is the last row's frame paints below the LazyVGrid frame when the last cell is taller than the others.
Problem 2 is the last column shows multiline text. All cells on that row should be aligned using VerticalAlignment.firstTextbaseline. What happens is all of the cells end up vertically aligned.
private var columns: [GridItem] = [
GridItem(.fixed(25)),
GridItem(.fixed(25)),
GridItem(.fixed(30), alignment: .trailing),
GridItem(.flexible())
]
var body: some View {
LazyVGrid(columns: columns, alignment: .leading) {
ForEach(rows) { row in
Text(row.a)
Text("#\(row.b)")
Text("(\(row.c))")
Text(row.d)
.multilineTextAlignment(.leading)
.lineLimit(nil)
}
}
}
I explored using custom alignment guides istead of LazyVGrid, but I don't know how to apply more than one guide to achieve the effect of tab stops for each column.
I've been building my app on Xcode 13 when suddenly it doesn't know about the iOS 15 APIs. Here are a couple error examples:
self.modified = Date.now
// Type 'Date' has no member 'now'
and
operation.modifySubscriptionsResultBlock = { result in
// Value of type 'CKModifySubscriptionsOperation' has no member 'modifySubscriptionsResultBlock'
I can take the exact same code and build it on my other Mac and it builds properly. Both Macs are using Xcode Version 13.0 (13A233) and running macOS 11.6 (20G165). I checked the deployment info for project and target (iOS 15.0), but of course using git I know I have the exact same code base on both machines.
Is there an Xcode preference or system file that got hosed? I tried reinstalling Xcode, but it didn't help.
This looks like a refresh of an old question. I'm using iOS 15 beta 7 and have presented a UIActivityViewController from a SwiftUI app. I get a ton of these errors when trying to share a two-item list containing String and UISimpleTextPrintFormatter.
[default] LaunchServices: store (null) or url (null) was nil: Error Domain=NSOSStatusErrorDomain Code=-54 "process may not map database" UserInfo={NSDebugDescription=process may not map database, _LSLine=264, _LSFunction=-[_LSDReadClient getServerStoreWithCompletionHandler:]}
[default] Attempt to map database failed: permission was denied. This attempt will not be retried.
[db] Failed to initialize client context with error Error Domain=NSOSStatusErrorDomain Code=-54 "process may not map database" UserInfo={NSDebugDescription=process may not map database, _LSLine=264, _LSFunction=-[_LSDReadClient getServerStoreWithCompletionHandler:]}
[default] -imageForImageDescriptor: can do IO please adopt -imageForDescriptor: for IO free drawing or -prepareImageForDescriptor: if IO is allowed. (This will become a fault soon.)
[default] LaunchServices: store (null) or url (null) was nil: Error Domain=NSOSStatusErrorDomain Code=-54 "process may not map database" UserInfo={NSDebugDescription=process may not map database, _LSLine=264, _LSFunction=-[_LSDReadClient getServerStoreWithCompletionHandler:]}
It looks as if the API is checking for entitlements I haven't requested, but I am not trying to share images. I just want to share text as plaintext or a nicely formatted printable attributed string.