Issue with giving a title to a menu - swift

I want to give a text name for this menu but it won't let me saying there's an Extra argument in call what's wrong ? PS: I'm a beginner in coding
Divider()
Menu("\(buttonTitle)" ) {
Button("Riyadh",action: {SelectRiyadh()})
Button("Dammam",action: {SelectDammam()})
Button("Jeddah",action: {SelectJeddah()})
Button("Mecca",action: {SelectMecca()})
}

We need to see the ContentView page, but try to wrap all that code in some group or into stack, for example VStack.
Anyway, read this article first: How to show a menu when a button is pressed
VStack{
Divider()
Menu("\(buttonTitle)" ) {
Button("Riyadh",action: {option()})
}
}

Related

Exclude button from disabling

I have custom view with different content inside including Button.
For example:
VStack {
Text("Some text")
Button() // 1-th
Button() // 2-th
.disabled(false) // This doesn't help, despite it logical
}
.disabled(true) // Line with disabling
I want 2-th button to be always enabled no matter what is set in "Line with disabling".
According to the documentation this does not work that way. It works the other way around. As you allready discovered the .disable on the parent overrides the value set in the child.
Possible solution would be to not use the parent .disable instead use it on each child element.

SwiftUI on Mac: Help Text Always Visible Even within View with Zero Opacity

I have run into some unexpected behavior while using SwiftUI in a macOS app. I filed a Feedback with Apple in case it's a bug, but it might actually be designed to work this way, so I'm looking for a workaround.
I rely heavily on the use of .opacity() to show and hide different sections of my app with tabs. I don't use if clauses because each time the user changes the tab, you have to wait for the entire view to rebuild and that is pretty slow.
Here's a basic example that demonstrates the problem:
struct ContentView: View {
#State var viewAVisible = false
var body: some View {
VStack{
ZStack{
Text("View A Visible")
.frame(width: 500, height: 500)
.background(Color.blue)
.help("This is View A's help text. It should be invisible when View A is invisible.")
.opacity(viewAVisible ? 1 : 0)
Text("View B Visible")
.frame(width: 500, height: 500)
.background(Color.gray)
.opacity(viewAVisible ? 0 : 1)
}
Button("Toggle"){
viewAVisible.toggle()
}
}.padding()
}
}
The default app state is to hide the "View A" Text() and only show the "View B" Text(). But if you hover over View B, you still see View A's .help text:
In my opinion, if a view has .opacity(0) then its help text shouldn't show up. But regardless, I need to find a way around this.
I thought about doing something like this:
.help(viewAVisible ? "This is View A's help text..." : "")
...but that doesn't scale across dozens of views in my app--particularly among child views that don't know if their parent view is shown or hidden. As I mouse across my app, I see the help text of tons of views all over the place even though they are invisible. 😅
Has anyone run into this or have any suggestions on how to handle it?
Looks like a bug (they do not remove tracking rects), here is a demo of workaround - move help tag into background and remove it manually (tested with macOS 12.0.1)
Text("View A Visible")
.frame(width: 500, height: 500)
.background(Group {
if viewAVisible {
Color.blue.help("This is View A's help text. It should be invisible when View A is invisible.")
} else {
Color.clear
}
})
.opacity(viewAVisible ? 1 : 0)

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)")
}

SwiftUI pick a value from a list with ontap gesture

i'm try to pick some value from a swiftUI list with the ontapGesture.
I have a Searchlist of item, the user need to choose one item and then the app will send the choice to an array that later will be use for other info.
now my problem is how do I do that? how can do it?
as you can see from the code below, I want to pick the value of the item.icaoAirport corresponding to that raw and pass to an array.
List(dm.vettoreAeroporti.filter{
// $0.icaoCode.contains(searchTerm)
$0.icaoAirport.localizedCaseInsensitiveContains(searchTerm)
}) { item in
HStack {
Text(item.icaoAirport).bold()
Spacer()
Text(item.nameAirport)
}
}
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.dm.openFileJson(fileName: "data")
}
}
.onTapGesture {
// ?? I need to take the value of the item.icaoAirport corresponding to that raw
}
thanks in advance for the help.
While your, Damiano, answer is right it works only on tap on the Text.
Sometimes it is needed to have the whole row tappable, so here is the solution for this case:
List(items) { item in
HStack {
Text(item.icaoAirport).bold()
Spacer()
Text(item.nameAirport)
}
.contentShape(Rectangle())
.onTapGesture {
print("touched item \(item)")
}
}
Thanks Paul for this (https://www.hackingwithswift.com/quick-start/swiftui/how-to-control-the-tappable-area-of-a-view-using-contentshape)
Note, that if you have content only on one side of the HStack e.g:
HStack {
Text("Some text") // This text will be on the left side
}
then the .contentShape(Rectange()) will work only for the width of the text. So to enable it for the whole width just add a trailing Spacer() like this:
HStack {
Text("Some text")
Spacer() // This will take all the space from the end of the text up to the end of the whole row
}
.contentShape(Rectangle())
I solved my issue:
HStack {
Text(item.icaoAirport).bold()
Spacer()
Text(item.nameAirport)
.onTapGesture {
print("touched item \(item.icaoAirport)")
}
}
List {
ForEach(Type.allCases, id: \.self) { type in
FilterRow(Color: type.Color,
title: type.Title)
.contentShape(Rectangle())
.onTapGesture {
print("Ammu type:\(type)")
}
}
}
This one is quite old but the accepted answers are pretty strange. I was able to achieve this effect in a much simpler way. Consider:
List {
ForEach(myItems) { item in
Button {
// action
} label: {
Text(item.name)
}
}
}
Now doing it this way, the button is edge-to-edge in the row. However, the button is now the accent color of your app. That's probably not what you want! So I tried adding:
Button(...)
.buttonStyle(PlainButtonStyle())
The text of the button is now the primary foreground color, great! But there's a different problem now! The button no longer goes edge-to-edge, it's only the text. To fix this, i instead:
Button(...)
.foregroundColor(.primary)
This is edge-to-edge with primary color text and custom actions. No need to create HStacks with spacers and an onTap, it's all just handled. OP's post has text on both sides so likely still needs an HStack for their specific usecase but a Button is still probably a better choice.

SwiftUI - NavigationView Error message - Argument passed to call that takes no arguments

I am trying to implement a really basic NavigationView in SwiftUI. When I try the sample code that I have seen on other websites it generates an error message in Xcode. I am not sure why or how to fix this.
I have tried to clean the project, quit Xcode-Beta and restart it but that did not work.
struct ContentView : View {
var body: some View {
NavigationView {
Text("This is a great app")
}
}
}
I thought the code above should work but the error I get says:
"Argument passed to call that takes no arguments."
Any ideas or suggestions?
VStack can only take 10 argument.
If more, there will be error, so you should make it nested.
from
VStack{
}
to
VStack{
VStack{
}
VStack{
}
}
I had this same error message too and figured out what I did wrong and then kind of felt like an idiot. Ha ha.
Take a look:
It took me a while to figure out that my struct was the same name as a previously defined struct VStack. Whoops!
So I'm wondering if you had a file in your project that did this too.
check-in your app is there any Swifui class with the name NavigationView.
also when you jump to the definition from NavigationView it should refer to:
#available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 7.0, *)
public struct NavigationView<Content> : View where Content : View {
public init(#ViewBuilder content: () -> Content)
/// The type of view representing the body of this view.
///
/// When you create a custom view, Swift infers this type from your
/// implementation of the required `body` property.
public typealias Body = Never
}
Testing Xcode 11.2.1 and it's still buggy. I noticed when I keep adding primitive views to my ContentView, I start getting errors like
"Argument passed to call that takes no arguments",
"Type of expression is ambiguous without more context" etc. on primitive views which worked before.
When I replaced, for example,
ScrollView {
VStack {
Text
Button
Image
Text
Button
Image
Text
Button
Image
...
}
}
with
ScrollView {
VStack {
VStack {
Text
Button
Image
}
VStack {
Text
Button
Image
}
VStack {
Text
Button
Image
}
...
}
my code started to compile and run again.
I found this problem when I accidentally try to redefine Text struct. Check if you naming your custom class the same as those in SwiftUI.
#Matteo Pacini helped me find the answer. When I started a new Xcode Project just to test the code above everything worked. I had a lot of files and was testing a lot of different code while experimenting with SwiftUI in my other project and for some reason XCode was always generating this error.
When I tried everything in a new project it worked. Something to be aware of while testing. Hope this helps others avoid similar problems.
Embed the 'Text("This is a great app")' in a VStack
struct ContentView : View {
var body: some View {
NavigationView {
Stack {
Text("This is a great app")
}
}
}
}