Skip to main content
ObjectItem is the primary list-row component for Fiori object displays. It arranges a rich set of fields — title, subtitle, footnote, description, status indicators, a detail image, icon stacks, avatar stacks, footnote icons, tags, and an action button — into the standard Fiori two-column object layout.

Parameters

title
any View / AttributedString
required
The primary label of the object. Required.
subtitle
any View / AttributedString?
Secondary label displayed below the title.
footnote
any View / AttributedString?
Tertiary label displayed at the bottom of the left column.
description
any View / AttributedString?
Extended description text. Hidden in compact mode unless showsDescriptionInCompact is true.
status
any View / TextOrIcon?
Status label or icon shown in the top-right area.
substatus
any View / TextOrIcon?
Secondary status label or icon shown below the status.
detailImage
any View / Image?
Image displayed in the leading position (left column).
icons
any View / [TextOrIcon]
Stack of icons shown in the trailing area. Rendered by @IconBuilder.
avatars
any View / [TextOrIcon]
Stack of avatar images. Rendered by @AvatarsBuilder.
footnoteIcons
any View / [TextOrIcon]
Icon stack shown in the footnote row. Rendered by @FootnoteIconsBuilder.
footnoteIconsText
any View / AttributedString?
Text accompanying the footnoteIcons stack.
tags
any View / [AttributedString]
Array of tag strings. Rendered by @TagBuilder.
action
any View / FioriButton?
Primary action button.
objectItemButton
any View / FioriButton?
Accessory button displayed at the trailing edge of the row.
showsDescriptionInCompact
Bool
default:"false"
When true, shows the description field even in compact size class.

ViewBuilder initializer

Use the @ViewBuilder initializer when you need to render a field as a non-text view, or when you want precise control over layout and styling of individual fields.
ObjectItem(
    title: {
        Text("Rouja Pakiman")
    },
    description: {
        Text("Rouja has worked for the company for ten years and has all of the skills " +
             "that would be necessary for developing quality applications. " +
             "She is proficient in Java as well as CSS, Bootstrap, and Swift.")
    },
    status: {
        Text("Available")
    },
    detailImage: {
        Image("person_square4")
            .resizable()
            .frame(width: 45, height: 45)
            .clipShape(Circle())
    }
)

Type-based initializer

Use the type-based initializer for direct data-model binding with Fiori default styling.
ObjectItem(
    title: "Transformer Overheating When After Being on for 1 Hour or Longer",
    subtitle: "Three Phase Pad Mounted Transformer (533423)",
    footnote: "1000 - Hamburg, MECHANIK",
    description: "Customer noticed that the transformer started to over heat within 45 minutes " +
                 "each time he turned it on at 7:30am. The first technician who looked at this " +
                 "did not have the correct additional tools to complete the job.",
    status: TextOrIcon.text("High"),
    detailImage: Image(systemName: "person"),
    icons: [
        TextOrIcon.text("1"),
        TextOrIcon.icon(Image(systemName: "circle.fill")),
        TextOrIcon.icon(Image(systemName: "mail"))
    ]
)

Complete example: work order row

The following example shows a realistic work order ObjectItem inside a List.
struct WorkOrderListView: View {
    let workOrders: [WorkOrder]

    var body: some View {
        List(workOrders) { order in
            ObjectItem(
                title: AttributedString(order.title),
                subtitle: AttributedString(order.assetDescription),
                footnote: AttributedString(order.locationCode),
                status: .text(AttributedString(order.priorityLabel)),
                substatus: .icon(order.priorityIcon),
                detailImage: Image(systemName: "wrench.adjustable"),
                icons: [
                    .icon(Image(systemName: "paperclip")),
                    .text(AttributedString("\(order.attachmentCount)"))
                ],
                tags: order.tags.map { AttributedString($0) }
            )
            .statusStyle { config in
                config.status
                    .foregroundStyle(
                        order.priority == .high
                            ? Color.preferredColor(.negativeLabel)
                            : Color.preferredColor(.primaryLabel)
                    )
            }
        }
    }
}

Using in a List

SwiftUI list rows include a separator by default. If you embed ObjectItem inside a plain List, the separator appears beneath each row. To remove it, apply .listRowSeparator(.hidden) to the ObjectItem.
List(items) { item in
    ObjectItem(title: AttributedString(item.name))
        .listRowSeparator(.hidden)
}

Build docs developers (and LLMs) love