SwiftUI Catalyst drag and drop - swift

I'm struggling with implementing drag'n'drop for my SwiftUI catalyst app. This is my code:
Text("Drag your files here")
.onDrop(of: ["public.url","public.file-url"], isTargeted: nil) { providers -> Bool in
print("dropped")
print(providers)
return true
}
If I drag a file from the finder on the Label, I'm getting the green plus icon. If I drop it, the output is:
dropped
[]
What am I doing wrong?

Related

SetFocusFilterIntent macOS system extension doesn't run perform() function

I am writing a Focus system extension (sandboxed, Cocoa, entitlements set) for macOS 13/Ventura using Xcode 14.2
I have the extension loading it's UI into the macOS system settings > Focus pane.
so here are the issues:
Even though it is loaded, it doesn't seem to ever run the perform() function when the UI is changed by the user or the user invokes Focus > Do Not Disturb.
What can be done in the perform() function? Like, what is supposed to go there? Nothing seems to work.
import AppIntents
struct MacOSFocus: SetFocusFilterIntent {
static var title: LocalizedStringResource {
return "Focus Settings"
}
// The description as it appears in the Settings app
static var description: LocalizedStringResource? = "Focus Settings" // name under Minus icon in options list
// How a configured filter appears on the Focus details screen
var displayRepresentation: DisplayRepresentation {
return DisplayRepresentation(stringLiteral: "Focus Settings") // name under filter once added to Foucs
}
#Parameter(title: "Show Task Bar", default: false)
var showDefaultTaskBar: Bool
#Parameter(title: "Start Timer")
var startTimer: Bool
func perform() async throws -> some IntentResult {
// This doesnt seem to run
// What can I put here?
// I need to write string data to a text file somewhere or communicate with the host app in some way.
return .result()
}
}
Just trying to get unstuck. Thanks for any help.
Tried adding an NSLog() call in the perform() function for debugging. Even tried using NSSound.beep() just to check that it is getting called. Didn't work.

SwiftUI - Dynamic Edit Button on Nav Bar

I'm fairly new to Swift/SwiftUI - I'm working on a simple to-do list app and trying to make a Nav bar button that changes from the built-in Edit button to a custom button depending on a state variable.
I attempted this using a ternary operator like below
#State var addingItems: Bool = false
...
}.navigationBarItems(trailing: self.addingItems ? Button("Done", action: submitItems) : EditButton())
Each of the buttons work here individually, but Swift will not let me mix them like this. I get a mismatched types error
Result values in '? :' expression have mismatching types 'Button<Text>' and 'EditButton'
Is there a way to make this work outside of writing a custom Edit button?
Thanks
If you are ok with just supporting iOS 14+ you should use the toolbar api
.toolbar {
ToolbarItem(placement: .primary) {
if self.addingItems {
Button("Done", action: submitItems)
} else {
EditButton()
}
}
}

How can I have auto fill functionality as default in my custom codes?

As you know we can just type Button( in SwiftUI and chose (action:label) on options and press Enter key, then Xcode make us a ready default code for start editing, it would be like this:
Button(action: {}, label: { Text("Button") })
I want same functionality in my code, therefore I just tried to re-create Button, but I do not know how could I possibly make it happen, I am getting this code after pressing Enter as default, which missing {} for action and { Text("Button") } for label:
CustomButton(action: () -> Void, label: () -> _)
My Goal: Which I would like get autofilled default like this:
CustomButton(action: {}, label: { Text("CustomButton") })
How could I make it possible? also I know about code Snippet, I do not want use that, I like my codes have default value from start, for editing them.
my used code:
struct CustomButton<Content: View>: View {
var action: () -> Void
var label: () -> Content
var body: some View {
return label()
.foregroundColor(Color.blue)
.onTapGesture { action() }
}
}
I know you said you didn't want to use code snippets, but I think that's the only way. You can get very close to the default behavior though. The trick is to use /*#START_MENU_TOKEN#*/ and /*#END_MENU_TOKEN#*/. These tell Xcode that everything between them should be autofilled.
So I assume you want something like this?
Original Xcode Button
Custom Button
First, let's see what Xcode does for a normal Button. Type in Button(, then copy what Xcode autofills into a text editor:
Button(action: /*#START_MENU_TOKEN#*/{}/*#END_MENU_TOKEN#*/, label: {
/*#START_MENU_TOKEN#*/Text("Button")/*#END_MENU_TOKEN#*/
})
As you can see, there are /*#START_MENU_TOKEN#*/ and /*#END_MENU_TOKEN#*/ surrounding the autofill text. You can customize this to your need, like this:
Button(action: /*#START_MENU_TOKEN#*/{}/*#END_MENU_TOKEN#*/, label: {
/*#START_MENU_TOKEN#*/Text("CustomButton")/*#END_MENU_TOKEN#*/
})
Try pasting this back into Xcode. It will look just as expected!
Now you can make this into a code snippet. Highlight the button text, right click, then click Create Code Snippet.
Then, enter something into the Completion field. This will be what Xcode will replace with your autofilled button code.
Finally, you can use it!
1. Type CustomBut
2. Press Enter

Selecting a picker value to lead to a text field, SwiftUI

Im trying to implement a feature in my app.
When I click on my picker:
Picker(selection: $profileViewModel.education,
label: Text("Education Level")) {
ForEach(Education.levels, id: \.self) { level in
Text(level).tag(level)
}
}
This takes me to a screen and then I select the value (this is fine - it works as expected)
How could I select the value which then takes my to let's say another screen so I can fill in more details regarding the selected value.
For example the above picker has a values to select eduction level, after selecting it, how could I get an action sheet/another screen appear so I can have a text field there to save this extra data to or once the selection is made, a text field appears for me to save some extra data, and then clicking a button which would take me to the original screen of the picker (hope that makes sense)?
I've tried researching online for a problem similar to this but can't seem to find one/or if you can point me in the direction of what I should be looking into?.
Tried the following:
If I correctly understood your scenario here is a possible approach (replication tested with Xcode 12 / iOS 14)
Picker(selection: $profileViewModel.education,
label: Text("Education Level")) {
ForEach(Education.levels, id: \.self) { level in
Text(level).tag(level)
}
}
.onChange(of: profileViewModel.education) { _ in
DispatchQueue.main.async {
self.showSheet = true
}
}
.sheet(isPresented: $showSheet) {
// put here your text editor or anything
Text("Editor for \(profileViewModel.education)")
}

NavigationLink not working if label is conditional

I have created a scroll bar with a list of folders created by the user like in the picture
a simple navigation link navigates inside the folder.
in order to give the option to the user to delete the folder, on the navigation view label I put an IF that change the icon of the folder base if the editing mode is on or off.
my issue is, when I'm changing the icon setting the var isEditFolderModeON = true with a long press gesture.
all working fine, problem is since I put the long press gesture in the Navigation link label it stop to work.
any solution?
where I can move the long pressure gesture,
thanks
NavigationLink(destination: FolderViewAirport(fm: self.fm, dm: self.dm, folders: folder)
.onAppear(perform: {
self.fm.updateFolderData(dm: self.dm) {
}
})
) {
if self.isEditFolderModeON {
FolderBarEdit( folder: folder)
.onTapGesture {
self.fm.delateFolderTouch(nameFolder: folder)
}
}
else if self.isEditFolderModeON == false {
FolderBar(folder: folder)
.onLongPressGesture {
self.isEditFolderModeON = true
}
}
}
if I remove the .onLongPressGesture {} it works, but where I can put the self.isEditFolderModeON = true