buttonswiftuiswiftui-navigationlink

Swifui button image is stretching across the entire streen


I am not sure how to get the image to stay in a reasonable size, being new to SwiftUI I have no doubt that this is completely my fault.

Screen Shot of button

The code is as follows:

import SwiftUI

struct AnimalsView: View {
    var body: some View {
        NavigationStack {
            ZStack {
                VStack(spacing: 20) {
                    HStack {
                        Text("Hello")
                    }
                    HStack {
                            NavigationLink(destination: ManagementView()) {
                                ZStack {
                                    Image("Button-Normal")
                                        .resizable()
                                        .frame(width: 150, height: 50)
                                    Text("Breeding")
                                        .font(.title3)
                                        .foregroundColor(.black)
                                        .fontWeight(.medium)
                                }
                            }
                            NavigationLink(destination: AnimalsView()) {
                                ZStack {
                                    Image("Button-Normal")
                                        .resizable()
                                        .padding()
                                
                                    
                                    
                                    Text("Animals")
                                        .font(.title3)
                                        .foregroundColor(.black)
                                        .fontWeight(.medium)
                                }
                            }
                        }
                    HStack {
                        
                    }
                    HStack {
                        
                    }
                }
                
                .toolbar {
                    Button("Logout") {
                        Task {
                            let Signout = SignOutLocally()
                            await Signout.signOutLocally()
                        }
                    }
                }
            }
            .background {
                Image("Rancher1")
                    .resizable()
                    .scaledToFill()
                    .ignoresSafeArea()
            }
        }
    }
}


#Preview {
    AnimalsView()
}

The first button has a frame defined with height and width but I know that Apple strongly suggests staying away from that.

I know some developers prefer to use the NavigationLink as the button itself, and I have tried that as well but it never acts correctly. Any assistance would be appreciated.


Solution

  • You need a better grasp on SwiftUI basics, like layout, combining views and defining structs. ZStacks are fun but they're not the answer to everything.

    Everything inside the NavigationLink in your case should be a struct that accepts a text parameter, or a styled Button.

    You don't need a trillion ZStacks for this layout. See how I did it below and compare. Notice the use of only two stacks to achieve the intended layout. I left the background as yellow, you can set your own image as an exercise.

    import SwiftUI
    
    struct FarmView: View {
        
        @State private var path = NavigationPath()
        
        enum Destination: Hashable {
            case red
            case orange
        }
        var body: some View {
            NavigationStack(path: $path){
                VStack{
                    Text("Select an interest:")
                    HStack {
                        Button("Breeding"){
                            path.append(Destination.orange)
                        }
                        .buttonStyle(OrangeButtonStyle())
                        
                        Button("Animals"){
                            path.append(Destination.red)
                        }
                        .buttonStyle(OrangeButtonStyle())
                    }
                }
                .toolbar {
                    Button("Logout") {
                        //action here...
                    }
                    .tint(.black)
                }
                .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
                .background{
                    Color.yellow //or the image of your choice
                        .ignoresSafeArea()
                }
                .navigationTitle("Welcome")
                // .toolbarTitleDisplayMode(.inlineLarge)
                .navigationDestination(for: Destination.self) { destination in
                    switch destination {
                        case .orange:
                            BreedingView()
                        case .red:
                            AnimalsView()
                    }
                }
            }
            .tint(.white)
        }
    }
    
    struct OrangeButtonStyle: ButtonStyle {
        func makeBody(configuration: Configuration) -> some View {
            configuration.label
                .foregroundStyle(.black)
                .fontWeight(.semibold)
                .padding(.vertical, 8)
                .padding(.horizontal, 15)
                .foregroundStyle(.white)
                .background {
                    LinearGradient(colors: [.white.opacity(0.9), .yellow, .orange, .orange], startPoint: .top, endPoint: .bottom)
                }
                .clipShape(RoundedRectangle(cornerRadius: 12))
                .background {
                    RoundedRectangle(cornerRadius: 12)
                        .stroke(.black.opacity(0.3), lineWidth: 10)
                }
                .scaleEffect(1.2)
                .padding()
        }
    }
    
    struct AnimalsView: View {
        var body: some View {
            ZStack{
                Color.red
                    .ignoresSafeArea()
                .navigationTitle("Red View")
            }
    
        }
    }
    
    struct BreedingView: View {
        var body: some View {
            ZStack{
                Color.orange
                    .ignoresSafeArea()
                    .navigationTitle("Orange View")
            }
        }
    }
    
    #Preview {
        FarmView()
    }
    

    I didn't use a NavigationLink in order to use a Button and show how you can control navigation without a navigation link, which gives you the flexibility to use any view, as needed, or none at all (and navigate by changing the path in a function, as the part of whatever logic).

    I suggest you go through the tutorials again and make sure you can execute a basic layout like this without trouble.

    enter image description here