Home > Blockchain >  View Not Expanding to Full List Line Width- SwiftUI
View Not Expanding to Full List Line Width- SwiftUI

Time:05-10

I have Views embedded in a list, one View per List item but for some reason, the View only takes up a small leading part of the list's row, rather than filling the full line. The embedded View is fully expanded in the preview of the View so I'm unsure why this is happening.

List View

import SwiftUI

struct AnnouncementsView: View{
    @Binding var announcements: [Announcement]
    @State var displayedMessage: String = ""
    @State var isDisplayingMessage: Bool = false
    
    static let sectionDateFormat: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "dd/MM/YYYY"
        return formatter
    }()
    var body: some View{
        //NavigationView{
        VStack{
            List($announcements){$announcement in
                AnnouncementView(announcement: $announcement)
            }
            Spacer()
        }
    }
}

list view preview

List Item View

struct AnnouncementView: View{
    @Binding var announcement: Announcement
    @State private var sheetIsShowing: Bool = false
    static let sectionDateFormat: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "dd/MM/YYYY"
        return formatter
    }()
    var body: some View{
        HStack{
            Button(action: {
                sheetIsShowing = true
            }){
                if (!announcement.read){
                    Image(systemName: "exclamationmark.circle.fill")
                        .foregroundColor(.red)
                }
                Text(announcement.message)
                    .lineLimit(1)
                    .truncationMode(.tail)
                    .foregroundColor(.black)
                Spacer()
                Text("\(announcement.timestamp, formatter: Self.sectionDateFormat)")
                    .disabled(true)
            }
        }
        .padding()
        .sheet(isPresented:$sheetIsShowing){
            NavigationView{
                DetailedAnnouncementView(announcement: $announcement)
                    .navigationTitle(Text("\(announcement.timestamp, formatter: Self.sectionDateFormat)"))
                    .toolbar{
                        ToolbarItem(placement: .navigationBarLeading){
                            Button(action: {
                                announcement.read = true
                                sheetIsShowing = false
                            }){
                                Text("Mark as Read")
                            }
                        }
                        ToolbarItem(placement: .navigationBarTrailing){
                            Button(action: {
                                sheetIsShowing = false
                                announcement.read = false
                            }){
                                Text("Mark as Unread")
                            }
                        }
                    }
            }
        }
    }
}

list item view preview

I'm probably missing something really basic but any help is much appreciated.

Thanks.

CodePudding user response:

So it seems that SwiftUI renders Button's content as if it was inside an HStack by default, in case no Stack was provided.

However, when using the Button inside a List, this default behaviour changes to defaulting as if it was a VStack. (Note that it only happens when used inside a List. When used inside LazyVStack, ScrollView, ForEach... the default HStack is maintained).

So, in order to make sure the Button's content is always rendered horizontally, specify it by explicitly nesting its content inside an HStack instead of relying on Button's "default" behaviour (as it does not seem to be consistent right now)

So, change:

Button(action: ...) {
    //content
}

To:

Button(action: ...) {
    HStack {
        //content
    }
}
  • Related