Search code examples
swiftuiuilabelsf-symbols

Swift UI center text below label and icon


How can I center text below my labels and icons? Every time I add text below each label the labels and icons are shifted. What am I missing?

For example:

                    Text("sub title text")
                       .foregroundColor(Color(.systemGray))
                       .multilineTextAlignment(.center)
                       .padding()

The code above I am trying to insert shifts the labels and icons in the wrong direction. I would like to center the inputed text below each label and icon.

enter image description here

 struct ContentView: View {
        var body: some View {
            
            
            VStack {
                Text("My Title")
                    .font(.system(.title))
                    .fontWeight(.bold)
                    .padding()
                
                
                
               // MARK: LABELS
                
                VStack (alignment: .leading) {
                    
                   
                        
                        Label {
                            Text("Design")
                                .font(.title)
                                .foregroundColor(Color(.systemGray))
                                .labelStyle(.titleAndIcon)
                                .padding()
                            
                        } icon: {
                            Image(systemName: true ? "pencil.circle" : "pencil.circle")
                                .foregroundColor(Color(.systemBlue))
                                .font(.title)
                                .multilineTextAlignment(.center)
                            
                            
                        }
                    
                
                    
                    
                        
                        
//                      Text("sub title text")
//                        .foregroundColor(Color(.systemGray))
//                        .multilineTextAlignment(.center)
//                        .padding()
                    
                        
                    
                    Label {
                        Text("Develop")
                            .font(.title)
                            .foregroundColor(Color(.systemGray))
                            .labelStyle(.titleAndIcon)
                            .padding()
                        
                    } icon: {
                        Image(systemName: true ? "qrcode" : "qrcode")
                            .foregroundColor(Color(.systemBlue))
                            .font(.title)
                        
                    }
                   
                    
                    Label {
                        Text("Launch")
                            .font(.title)
                            .foregroundColor(Color(.systemGray))
                            .labelStyle(.titleAndIcon)
                            .padding()
                        
                    } icon: {
                        Image(systemName: true ? "cart.circle" : "cart")
                            .foregroundColor(Color(.systemBlue))
                            .font(.title)
                            //.imageScale(.large)
                        
                    }
                    
                    
                }//END Label VSTACK
                
            }
            .padding()
        }//END VSTACK
    }

Solution

  • The best you can do is not using Label at all, instead, use HStack.

    Try this code instead:

    struct ContentView: View {
        var body: some View {
            VStack {
                Text("My Title")
                    .font(.system(.title))
                    .fontWeight(.bold)
                    .padding()
    
                // MARK: LABELS
                VStack (alignment: .leading) {
                    HStack(alignment: .top) {
                        Image(systemName: true ? "pencil.circle" : "pencil.circle")
                            .foregroundColor(Color(.systemBlue))
                            .font(.title)
                        
                        VStack(alignment: .leading) {
                            Text("Design")
                                .font(.title)
                                .foregroundColor(Color(.systemGray))
                            
                            Text("Subtitle text")
                        }
                        .padding(.horizontal)
                    }
                    .padding()
                    
                    HStack(alignment: .top) {
                        Image(systemName: true ? "qrcode" : "qrcode")
                            .foregroundColor(Color(.systemBlue))
                            .font(.title)
                        
                        VStack(alignment: .leading) {
                            Text("Develop")
                                .font(.title)
                                .foregroundColor(Color(.systemGray))
                            
                            Text("Subtitle text")
                        }
                        .padding(.horizontal)
                    }
                    .padding()
                    
                    HStack(alignment: .top) {
                        Image(systemName: true ? "cart.circle" : "cart")
                            .foregroundColor(Color(.systemBlue))
                            .font(.title)
                        
                        VStack(alignment: .leading) {
                            Text("Launch")
                                .font(.title)
                                .foregroundColor(Color(.systemGray))
                            
                            Text("Subtitle text")
                        }
                        .padding(.horizontal)
                    }
                    .padding()
    
                }//END Label VSTACK
            }
            .padding()
        }//END VSTACK
    }
    

    Edit: I improved the code above to not repeat any iteration, hope it helps!

    struct ContentView: View {
        var body: some View {
            VStack {
                Text("My Title")
                    .font(.system(.title))
                    .fontWeight(.bold)
                    .padding()
    
                // MARK: LABELS
                VStack (alignment: .leading) {
                    row(icon: "pencil.circle", iconSelected: "pencil.circle", isSelected: true, title: "Design", subtitle: "Subtitle text")
                    
                    row(icon: "qrcode", iconSelected: "qrcode", isSelected: true, title: "Develop", subtitle: "Subtitle text")
                    
                    row(icon: "cart", iconSelected: "cart.circle", isSelected: true, title: "Launch", subtitle: "Subtitle text")
    
                }//END Label VSTACK
            }
            .padding()
        }//END VSTACK
        
        private func row(icon: String, iconSelected: String, isSelected: Bool, title: String, subtitle: String) -> some View {
            HStack(alignment: .top) {
                Image(systemName: isSelected ? iconSelected : icon)
                    .foregroundColor(Color(.systemBlue))
                    .font(.title)
                
                VStack(alignment: .leading) {
                    Text(title)
                        .font(.title)
                        .foregroundColor(Color(.systemGray))
                    
                    Text(subtitle)
                }
                .padding(.horizontal)
            }
            .padding()
        }
    }