Posts

Post not yet marked as solved
1 Replies
255 Views
I have an issue that is a timing issue. The issue is I have a list: List(sidebars[0].childrenSorted!, id:\.id, children: \.childrenSorted, selection: $selected) { sidebar in It works great for me., as is. I am now implementing add, delete, and move (drag and drop) functionality to the list. The data is persisted in SwiftData, so the order of the array is not maintained, and I have a field called "index," which allows it to be sorted correctly for each display. That also works. If I insert or move an item in the list, I must update the index of all the elements after the insertion point in that "child" (folder) to the new order/sequence number. Here is the code for dropping a row item onto another row item in the same child/folder. (Note: indexes are incremented by 2 to allow for the insertion of new items and reindexing) The dropped item should be placed after the target item: func dropOnSidebarItem(dropped: Sidebar, target: Sidebar) { if target.parent_?.id != dropped.parent_?.id { // moving to new parent dropped.parent_?.children_?.removeAll(where: {$0.id == dropped.id}) dropped.parent_ = target.parent_ target.parent_?.children_?.append(dropped) } dropped.index = target.index + 1 var ix = 0 target.parent_?.childrenSorted?.forEach { child in child.index = ix ix += 2 } } If I run this as is, it will crash at the List statement with a nil access to the sidebars[0]. If I add this after the reindexing loop (above), it runs correctly: target.parent_?.childrenSorted?.forEach { child in print("\(child.title)") } All this addition does is to put a slight delay before returning. That is an obvious HACK doomed to failure at some point. The issue appears to be that the list is updated before the reindexing is complete. I have tried placing the reindexing into a function with a tempModelContext that does not autosave. I then manually save the temporary context once the loop is done - the same failure occurs, and the same "delay" makes it work. Do you have any suggestions on what I am doing wrong? It appears to be associated with autosaving the SwiftData changes. TIA, Frank
Posted
by franc.
Last updated
.
Post not yet marked as solved
1 Replies
396 Views
Does anyone KNOW if SwiftUI now supports drag and drop in a list? It seems like it was only working in ForEach before the latest version. Now, this tries to work, but hangs. List(sidebars.sorted{$0.index < $1.index}[0].children!, id:\.id, children: \.children, selection: $selected) { sidebar in NavigationLink { SidebarDetailSelectorView(sidebar: sidebar) } label: { rowLabel(sidebar: sidebar) //.background(Color.random()) } .onChange(of: selected) { currentSidebar.sidebar = sidebars.first{ $0.id == selected } currentSidebar.editSidebar = currentSidebar.sidebar } .draggable(sidebar) .dropDestination(for: Sidebar.self) { sidebars, location in print("\(sidebars[0].title) -> \(sidebar.title)") return true } } I want a hierarchical sidebar (like finder or mail) to be able to drag and drop within the list to reorder it. I can get it working with DisclosureGroups. The parent items can be dragged or dropped on but are not selectable - which I need. Here is an example of my recursive DisclusureGroup implementation using ForEach loops. struct MenuItemView: View { let item: MenuItem var body: some View { if let children = item.children, children.isEmpty == false { DisclosureGroup(item.text) { ForEach(children, id: \.id) { childItem in MenuItemView(item: childItem) .draggable(childItem) .dropDestination(for: MenuItem.self) { items, location in print("\(items[0].text) -> \(childItem.text)") return true } isTargeted: { isTargeted in item.isTargeted = isTargeted } } } } else { VStack { NavigationLink(item.text, destination: Text(item.text)) .foregroundColor(item.isTargeted ? .teal : Color(.selectedTextColor )) .draggable(item) .dropDestination(for: MenuItem.self) { items, location in print("\(items[0].text) -> \(item.text)") return true } isTargeted: { isTargeted in item.isTargeted = isTargeted } } } } }
Posted
by franc.
Last updated
.
Post marked as solved
2 Replies
431 Views
I see this "new" NavigationLink in Apples documentation: Apple NavigationLink I am upgrading my working code from a depreciated NavigationLink with "destination" to a NavigationStack with a value. But, I can not get XCode to accept any syntax I can come up with using a Label (). Here is what I have tried (along with other variations). XCode chokes on this and says it is too complex. NavigationLink( value: sidebar, { Label(sidebar.title, systemImage: SFSymbolsModel.icon[sidebar.type] ?? "questionmark" ) }) I need a Label (I think - it is what I used before) because I want to format the displayed text with an Icon. All of the examples I can find use a string to provide the label. Does "Label" in the documentation not mean an actual Label, like we have in the depreciated version? Can anyone provide me a one- or two-line example of the correct syntax?
Posted
by franc.
Last updated
.
Post not yet marked as solved
2 Replies
404 Views
I am registered developer. I have a MacBook Pro that I use for dev on the road and it is showing me the Sonoma Dev Beta, and updated with no problem. I recently got a M2 Mac mini Pro and thought I have it setup but it only shows the public beta. What do I need to have the dev beta show up? TIA
Posted
by franc.
Last updated
.
Post not yet marked as solved
1 Replies
579 Views
I am trying to get NSFontPanel/NSFontManager to work in a SwiftUI Document Template app. I have the following defined, a customize version of this I found on GitHub. This lets me pick the size, face, style, etc. Interestingly, a color picker is included in the FontPanel. The documentation doesn't seem to say this. Is this something new? Anyway, I would like to either be able to use the color picker to let the user select a color, or if not I would like to hide the color picker - at is not "critical" to this application. I am using this to allow customization of text in a sidebar, so color is nice, but not necessary. Any help would be appreciated. public struct FontPicker: View{     let labelString: String     @Binding var font: NSFont     @State var fontPickerDelegate: FontPickerDelegate?     public init(_ label: String, selection: Binding<NSFont>) {         self.labelString = label         self._font = selection     }    let fontManager = NSFontManager.shared     let fontPanel = NSFontPanel.shared     @AppStorage("setSidebarFont") var setSidebarFont = "System"     @AppStorage("setSidebarFontSize") var setSidebarFontSize = 24     @AppStorage("setSidebarFontColor") var setSidebarFontColor = "gray"     public var body: some View {         HStack {             Text(labelString)             Button {                 if fontPanel.isVisible {                     fontPanel.orderOut(nil)                     return                 }                 self.fontPickerDelegate = FontPickerDelegate(self)                 fontManager.target = self.fontPickerDelegate                 fontManager.action = #selector(fontPickerDelegate?.changeAttributes)                 fontPanel.setPanelFont(self.font, isMultiple: false)                 fontPanel.orderBack(nil)             } label: {                 Text("Font Selection: \(setSidebarFont)")                     .font(.custom(setSidebarFont, size: CGFloat(setSidebarFontSize)))             }         }     }          func fontSelected() {         self.font = fontPanel.convert(self.font)         setSidebarFont = self.font.displayName ?? "System"         setSidebarFontSize = Int(self.font.pointSize)         var newAttributes = fontManager.convertAttributes([String : AnyObject]())         newAttributes["NSForegroundColorAttributeName"] = newAttributes["NSColor"]         newAttributes["NSUnderlineStyleAttributeName"] = newAttributes["NSUnderline"]         newAttributes["NSStrikethroughStyleAttributeName"] = newAttributes["NSStrikethrough"]         newAttributes["NSUnderlineColorAttributeName"] = newAttributes["NSUnderlineColor"]         newAttributes["NSStrikethroughColorAttributeName"] = newAttributes["NSStrikethroughColor"]         print("\(newAttributes["NSForegroundColorAttributeName"]!)")     } }
Posted
by franc.
Last updated
.
Post marked as solved
1 Replies
680 Views
I am rewriting my app with goodies from WWDC 2022. This is for MacOS only, it is based on the Document Template from Xcode 14 beta 2. When I try to add the Settings scene as shown below I get two errors, with or without my SettingsView referenced.
Posted
by franc.
Last updated
.
Post not yet marked as solved
0 Replies
478 Views
I have decided to make a change in my app. My app is arranged around “projects”. Each project is a set of work someone does. Previously, I kept all projects in a single CoreData instance. That works fine but has some disadvantages. Mainly I want the user to be able to open and close projects much like they would open or close a document with a word processor. I am working on giving the user the ability to specify a Core Data instance (sqllite) to open, save, backup, etc. So far the user can create a new project - the program will create a “bundle/package” folder at the location chosen by NSSavePanel. Inside the bundle are the SQLLite files needed by Core Data, and open that Core Data instance and display the user interface. To do this requires that it delays dealing with the CoreData instance from the app startup. When the users decides to open a recent project or create a new one I need to ensure the previous (if any) Persistent Store is closed and no data is lost - (save context, reset?). Each project will have its own set of SQLLite files in the bundle (it appears as a single file instead of a folder).  I need to close one instance and then open/create a new one while the program is running. I am making some progress, but it is complicated (to me - being a newbie). For instance, the standard method of initialization of the PersistenceController/PersistenceContainer at startup and placing those in the environment works well - it seems they are singletons and immutable. So, I am working on using a class that contains those and publishing it, then I can update them.  What I am asking for is if ANYONE has any suggestions on best practices when an app switches open/close/create etc Core Data instances on the fly, I would appreciate it. If anyone has any links to projects that actually do this, it would be great to see what someone else came up with.
Posted
by franc.
Last updated
.
Post not yet marked as solved
1 Replies
930 Views
I want to layout a window that works how Xcode works. By this I mean it has a sidebar on both sides and a document view in the middle. The left sidebar will be the "master" and the document and right sidebar will display data based on the master item selected. That all works, and the user can adjust the size of the two side bars. The problem is the size of the side bars as set by the user dragging is overridden when a new master item is selected or when the window is resized by the user. The left side bar is working as expected, the right side bar is self adjusting when the window size is changed by the user. I have implemented it with a NavigationView on the left side bar and a second navigation view on the center document view and the left sidebar displayed in it. And I have tried using a NavigationView around the left sidebar with HSplitview around the Document and right side view. How do I get the window width adjustment to ONLY affect the document view, and the size of the sidebars to be adjustable by the User only. TIA, Frank
Posted
by franc.
Last updated
.
Post not yet marked as solved
0 Replies
407 Views
I am looking for confirmation of a problem before I file a bug report with Apple. I am on XCode Version 12.3 (12C33), on Big Sur (beta). It appears this update of XCode has a bug when using dianostic print statements that contain Bindings of NSAttributedStrings. I am totally new to NSAttributedString and I am incorporating that into an NSRepresentable NSTextView for formatted text editing. So, being able to print is crucial to understanding what I am doing. Could someone at the same level of release verify they can (or can't) print a @Binding<NSAttrributedString>, I would appreciate it. Simple test: struct ARepresentableView: NSViewRepresentable { &#9;&#9; &#9;&#9;@Binding var aString: NSAttributedString? &#9;&#9; &#9;&#9;func updateNSView(_ view: AnNSView, context: Context) { &#9;&#9;&#9;&#9;print("updateNSView: [\(aString)]") &#9;&#9;&#9;&#9;view.aString = aString &#9;&#9;} This works with the passed in value of aString. When the value of aString is changed within ARepresentableView, and the udpateNSView is called to refresh it the print state crashes with this: 2020-12-15 09:32:52.030427-0500 Hermes[77309:1627758] [General] *** -[NSBigMutableString substringWithRange:]: Range {27, 49} out of bounds; string length 60
Posted
by franc.
Last updated
.