Ternary Operator Inside Navigationlink Swiftui

Ternary operator inside NavigationLink SwiftUI

This is because the types of CampaignDetailsView and Text don't match. You need to use a @ViewBuilder (or just a Group, VStack etc).

Here is a solution with the destination view as a @ViewBuilder computed property:

@ViewBuilder
var destinationView: some View {
if cardCampaigns.count > 0 {
CampaignDetailsView(viewModel: CampaignDetailsViewModel(campaign: cardCampaigns[self.count].campaign))
} else {
Text("No Campaign found")
}
}

Which you can use like this:

NavigationLink(destination: destinationView) { ... }

Using ternary operator in SwiftUI causes mismatching types error, why?

Besides what @Don said about the extra ), CinderDarkButtonStyle and CinderLightButtonStyle are different structs. They aren't the same type.

What you can do is make a custom function that returns an opaque type, as said in this answer. Try something like this:

struct ContentView: View {
@State var colorScheme = ColorScheme.dark

var body: some View {
GeometryReader { geometry in
Button("Create Account", action: {
//DO SOME ACTION
})
.buttonStyle(for: colorScheme, geometry: geometry) /// use custom buttonStyle function
}
}
}

extension Button {
@ViewBuilder
func buttonStyle(for colorScheme: ColorScheme, geometry: GeometryProxy) -> some View {
switch colorScheme {
case .light:
buttonStyle(CinderDarkButtonStyle(geometry: geometry))
case .dark:
buttonStyle(CinderLightButtonStyle(geometry: geometry))
}
}
}

The above switches between a buttonStyle(CinderDarkButtonStyle(geometry: geometry)) and buttonStyle(CinderLightButtonStyle(geometry: geometry)) modifier, based on the colorScheme.

Ternary operator issue SwiftUI

Break body construction for smaller components, like below

ForEach (expenses.items) { item in
self.listRow(for: item) // << extract !!
}
.onDelete(perform: removeItem)

,say, to private row generator function

private func listRow(for item: Item) -> some View { // << your item type here
HStack {
VStack(alignment: .leading) {
Text(item.name)
.font(.headline)
Text(item.type)
}
Spacer()
Text("€\(item.amount)")
Circle()
.frame(width: 10, height: 10)
.foregroundColor(item.amount < 10 ? Color.green : (item.amount < 100 ? Color.orange : Color.red))
}
}

SwiftUI - Ternary operator on padding modifier crashes program

Try this:

ForEach(0..<arr.count) { i in
ZStack {
...
}
.padding(.top, getPadding(i))

// I use i later in this code
...
}
func getPadding(_ i: Int) -> CGFloat {
if i == 0 {
return CGFloat(70)
}

return CGFloat(0)
}

How to do nothing in ternary operator in SwiftUI?

.overlay expects some View type as a parameter.

If you want to use a ternary operator, it has to return the same type. For a "do nothing" view, use EmptyView(), but since it has to be the same type, one way to do this would be by wrapping each conditional view with AnyView:

Image("shape0")
.overlay(clicked1
? AnyView(RoundedRectangle(cornerRadius:10)
.stroke(Color.yellow, lineWidth: 7))
: AnyView(EmptyView())
)

EDIT:
Actually - Optional<Wrapped: View> also conforms to View, so this is a better approach than above - i.e. just return the view you want or nil:

Image("shape0")
.overlay(clicked1 ? RoundedRectangle(cornerRadius:10)
.stroke(Color.yellow, lineWidth: 7) : nil)

Another approach would be to use computed property which returns a conditional view:

var body: some View {
Image("shape0")
.overlay(overlayView)
}

@ViewBuilder
var overlayView: some View {
if clicked1 {
RoundedRectangle(cornerRadius:10)
.stroke(Color.yellow, lineWidth: 7)
}
}

How can I have more than one destination for one Navigation link in SwiftUI?

Here is possible solution (just to be aware):

    NavigationLink(
destination: isSignUpView ? AnyView(SetupPassView()) : AnyView(ForgetView()),
isActive: $showSetupPassView,
...

Button with NavigationLink and function call SwiftUI

The answer from Yodagama works if you were trying to present a sheet (because you called your navigation destination SheetView), but if you were trying to navigate to SheetView instead of present a sheet, the following code would do that.

struct LoginView: View {
@State var check = false
@State var answer = false

var body: some View {
NavigationView {
VStack{
Text("it doesn't work")
NavigationLink(destination: SheetView(), isActive: $answer, label: {
Button(action: {
answer = test(value: 2)
}, label: {
Text("Calculate")
})
})



}
}
}

func test(value: Int) -> Bool {

if value == 1 {
check = false
} else {
print("Succes")
check = true
}

return check
}

}

struct SheetView: View {

var body: some View {
NavigationView {
VStack{
Text("Test")
.font(.title)
}
}
}
}

NavigationLink inside LazyVGrid cycles all entries on back, SwiftUI

It is Form/List feature to auto-detect links in rows, but you have several in row, so the effect. The solution would be to separate cell view and hide link from auto-detection.

Tested with Xcode 12.0 / iOS 14

struct ContentView: View {
@State var images:[String] = ["plus", "minus"]
var body: some View {
NavigationView {
Form {
Section {
LazyVGrid(columns: [GridItem(.adaptive(minimum:100))]){
ForEach(images){
ImageCellView(image: $0)
}
}
}
}
}
}
}

struct ImageCellView: View {
var image: String
@State private var isActive = false
var body: some View {
Image(uiImage: UIImage(systemName: image)!)
.resizable()
.scaledToFit()
.onTapGesture {
self.isActive = true
}
.background(
NavigationLink (
destination: ImageDetail(image: image), isActive: $isActive,
label: {
EmptyView()
}
))
}
}


Related Topics



Leave a reply



Submit