Search code examples
iosswiftnavigation

SwiftUI Custom Navigation Bar VStack doesn't work


I'm trying to make a custom navigation bar with back button, image, VStack (2 labels) but it didn't work. The whole view will stick to the center and not following the alignment I set. Thank you!

struct WeatherNavigation: View {
    var body: some View {
        HStack {
            WeatherNavigation()
        }
        .
        .
        .
    }
}

//

struct WeatherNavigation: View {
    var body: some View {
                Button(action: {
                    //action
                }, label: {
                    HStack {
                        Image("Back")
                            .foregroundColor(.black)
                        Image("Weather")
                            .resizable()
                            .frame(width: 40, height: 40)
                   }
                })
                .frame(width: 100, height: 50, alignment: .leading)
            VStack {
                Text(weather.description)
                    .font(.appFont(size: 18))
                    .foregroundColor(Color(uiColor: .black))
                Text(weather.location)
                    .font(.appFont(size: 12))
                    .foregroundColor(Color(uiColor: .blue))
            }
            .frame(width: .infinity, height: 50, alignment: .leading)            
        }
}

Solution

  • First of all, you shouldn't set frame of the whole view like that. For you problem, it can divide into: make a HStack to store all the container view and make a space between those two of them. Because using HStack you don't need to add leading.

    Code will be like this

    struct WeatherNavigation: View {
        var body: some View {
            // make a HStack to store all the attribute
            HStack(alignment: .top) {
                Button(action: {
                    //action
                }, label: {
                    HStack {
                        Image("Back")
                            .foregroundColor(.black)
                        Image("Weather")
                            .resizable()
                            .frame(width: 40, height: 40)
                   }
                })
                .frame(width: 100, height: 50)
                VStack {
                    Text("Tokyo")
                        .foregroundColor(Color(uiColor: .black))
                    Text("Japan")
                        .foregroundColor(Color(uiColor: .blue))
                }
                // make a space at the end
                Spacer()
            }
        }
    }
    

    And the usage like this

    struct ContentView: View {
        var body: some View {
            VStack {
                HStack {
                    WeatherNavigation()
                }
                Spacer()
            }
    
        }
    }
    

    More over: adding Spacer() means that make space between view. That will solved your problem if you want to keep like your way.