Компонент «Расширенная информация о месте»
Расширенная версия компонента «Подробная информация о месте» предлагает те же функции, что и базовая версия компонента «Подробная информация о месте» . Она также позволяет выбирать, будет ли отображаться название места, настраивать кнопки действий компонента, а также применять параметры поиска и фильтрации к отображаемым отзывам и медиафайлам.
Расширенные настройки сведений о месте
Для доступа к расширенным функциям используйте AdvancedPlaceDetailsView или AdvancedPlaceDetailsCompactView .
Параметры отображения содержимого
Вы можете указать, какой контент отображать, используя перечисления в AdvancedPlaceDetailsContent . Вы можете настроить весь тот же контент, что и в Places Details Essentials , а также выбрать, будет ли отображаться название места.
Настройка кнопок действий
Используйте методы .cornerActions и .mainActions объектов AdvancedPlaceDetailsView или AdvancedPlaceDetailsCompactView , чтобы удалить или настроить кнопки действий.
Требования к визуальному указанию авторства
Важно: необходимо четко указывать конечным пользователям, когда пользовательская кнопка действия будет передавать информацию о пользователе третьей стороне, помимо Google. См. требования к визуальной атрибуции .
В примере справа показано пользовательское изображение, которое наглядно демонстрирует, что информация о пользователе будет отправлена в компанию «Altostrat».
Примените параметры поиска и фильтрации.
Используйте методы .searchMediaOptions и .searchReviewOptions объектов AdvancedPlaceDetailsView или AdvancedPlaceDetailsCompactView , чтобы включить поиск и фильтрацию медиафайлов или отзывов.
Создание пользовательских слотов для контента

Слоты для пользовательского контента позволяют добавлять собственный контент (например, сгенерированные ИИ сводки, временные метки маршрута или пользовательские значки) непосредственно в предопределенные зоны макета.
Для добавления пользовательского контента используйте метод ` .placeDetailsCompactContentSlot класса ` AdvancedPlaceDetailsCompactView . Доступные позиции: .basicSectionTop и .basicSectionBottom .
Требования к указанию авторства и рекомендации по контенту для тематических разделов.
При добавлении пользовательского контентного слота информация автоматически обновляется, чтобы уточнить, какой контент предоставлен Google, а какой — сторонними организациями.
Делать
Поддерживайте четкую визуальную иерархию между подробной информацией о местах в Google Places и пользовательским контентом, чтобы избежать любой двусмысленности в отношении источника информации.

Делать
Рассмотрите возможность предоставления персонализированной, ценной информации, адаптированной к непосредственным целям ваших пользователей. Контент, такой как информация о времени бронирования в режиме реального времени или о текущей доступности, помогает пользователям принимать более быстрые и обоснованные решения.

Не
Не дублируйте существующую информацию о Google Places, такую как рейтинги, отзывы или часы работы, даже если вы скрыли контент, предоставленный Google. Это может ввести пользователей в заблуждение относительно источника контента и того, исходит ли он от Google или от третьей стороны.

Не
Не следует отображать утверждения или значки без указания источника (например, «Лучшая рекомендация!»), которые могут быть ошибочно приняты за официальные рекомендации Google. Пользовательский контент должен явно указывать свой источник.

Не
Не размещайте рекламу, маркетинговые тексты, рекламные скидки или запросы на подписку внутри пользовательских контейнеров.

Примеры подробной информации о месте проживания
Опустите название места.
Чтобы опустить название места, не включайте.name в параметр content параметра AdvancedPlaceDetailsConfiguration . Быстрый
struct DemoView: View { static let peetsCoffeePlaceID = "ChIJT7FdmYiAhYAROFOvrIxRJDU" // Query for loading the place details component. @State var query: PlaceDetailsQuery = PlaceDetailsQuery( identifier: .placeID(peetsCoffeePlaceID) ) @State private var favoritePlaces: Set<String> = [] var body: some View { AdvancedPlaceDetailsView( query: $query, configuration: AdvancedPlaceDetailsConfiguration( content:[.address()], theme: PlacesMaterialTheme() ), placeDetailsCallback: { result in if let place = result.place { print("Place: \(place.description)") } else { print("Error: \(String(describing: result.error))") } } ) } }
Удалить кнопки действий
Быстрый
struct DemoView: View { static let peetsCoffeePlaceID = "ChIJT7FdmYiAhYAROFOvrIxRJDU" @State var query: PlaceDetailsQuery = PlaceDetailsQuery( identifier: .placeID(peetsCoffeePlaceID) ) var body: some View { AdvancedPlaceDetailsView( query: $query, configuration: AdvancedPlaceDetailsConfiguration( content: AdvancedPlaceDetailsView.allContent, theme: PlacesMaterialTheme() ), placeDetailsCallback: { result in if let place = result.place { print("Place: \(place.description)") } else { print("Error: \(String(describing: result.error))") } } ) .mainActions{ _ in return [] } } }
Добавляйте пользовательские и предопределенные действия
В этом примере добавлена возможность для пользователя добавлять или удалять места из избранного, а также предопределенное действие «Открыть в Картах» .
Быстрый
struct DemoView: View { static let peetsCoffeePlaceID = "ChIJT7FdmYiAhYAROFOvrIxRJDU" @State var query: PlaceDetailsQuery = PlaceDetailsQuery( identifier: .placeID(peetsCoffeePlaceID) ) @State var favoritePlaces: Set<String> = [] var body: some View { AdvancedPlaceDetailsView( query: $query, configuration: AdvancedPlaceDetailsConfiguration( content: AdvancedPlaceDetailsView.allContent, theme: PlacesMaterialTheme() ), placeDetailsCallback: { result in if let place = result.place { print("Place: \(place.description)") } else { print("Error: \(String(describing: result.error))") } } ) .mainActions{ place in var actions: [MainPlaceActionElement] = [] let placeID = place.placeID! if self.favoritePlaces.contains(placeID) { actions.append( .action( MainPlaceAction( image: Image(systemName: "heart.fill"), label: "Unfavorite" ) { _ in self.toggleFavorite(placeID) } ) ) } else { actions.append( .action( MainPlaceAction( image: Image(systemName: "heart"), label: "Favorite" ) { _ in self.toggleFavorite(placeID) } ) ) } actions.append(.actionId(.openMap(style: .primary))) return actions } .cornerActions { place in var actions: [CornerPlaceActionElement] = [] let placeID = place.placeID! if self.favoritePlaces.contains(placeID) { actions.append( .action( CornerPlaceAction( image: Image(systemName: "heart.fill"), accessibilityLabel: "Unfavorite", ) { _ in self.toggleFavorite(placeID) } ) ) } else { actions.append( .action( CornerPlaceAction( image: Image(systemName: "heart"), accessibilityLabel: "Favorite", ) { _ in self.toggleFavorite(placeID) } ) ) } actions.append(.actionId(.openMap(style: .primary))) return actions } } func toggleFavorite(_ placeID: String) { if favoritePlaces.contains(placeID) { favoritePlaces.remove(placeID) } else { favoritePlaces.insert(placeID) } } }
Фильтр отзывов и медиафайлов
В этом примере кода отображаются только медиафайлы и обзоры, в которых упоминается «кофе».
Быстрый
struct DemoView: View { static let peetsCoffeePlaceID = "ChIJT7FdmYiAhYAROFOvrIxRJDU" @State var query: PlaceDetailsQuery = PlaceDetailsQuery( identifier: .placeID(peetsCoffeePlaceID) ) let searchMediaOptions = SearchMediaOptions(query: "coffee") let searchReviewsOptions = SearchReviewsOptions(query: "coffee") var body: some View { AdvancedPlaceDetailsView( query: $query, configuration: AdvancedPlaceDetailsConfiguration( content: [.media(), .reviews()], theme: PlacesMaterialTheme() ), placeDetailsCallback: { _ in } ) .searchMediaOptions(searchMediaOptions) { results in guard let result = results.first else { return } switch result { case .success(let summary): print("Summary: \(summary)") case .failure(let error): print("Error: \(error)") } } .searchReviewsOptions(searchReviewsOptions) { results in guard let result = results.first else { return } switch result { case .success(let summary): print("Summary: \(summary)") case .failure(let error): print("Error: \(error)") } } } }
Создание контентных слотов
Этот пример добавляет контент в слоты basicSectionTop и basicSectionBottom .
Быстрый
import SwiftUI import PlacesSwift struct ItineraryCard: View { static let peetsCoffeePlaceID = "ChIJT7FdmYiAhYAROFOvrIxRJDU" @State var query: PlaceDetailsQuery = PlaceDetailsQuery( identifier: .placeID(peetsCoffeePlaceID) ) var body: some View { AdvancedPlaceDetailsCompactView( orientation: .vertical, query: $query, configuration: AdvancedPlaceDetailsCompactConfiguration( content: AdvancedPlaceDetailsCompactView.allContent, theme: PlacesMaterialTheme() ), placeDetailsCallback: { _ in } ) .placeDetailsCompactContentSlot(position: .basicSectionTop) { place in Text("Day 2 • 2:30 PM") .font(.caption) .fontWeight(.bold) .foregroundColor(.accentColor) } .placeDetailsCompactContentSlot(position: .basicSectionBottom) { place in VStack(alignment: .leading, spacing: 4) { Text("AI Notes") .font(.caption) .bold() Text("Great quiet atmosphere for morning meetings. Famous for house-roasted pour-overs.") .font(.footnote) .foregroundColor(.secondary) } .padding(8) .background(Color(.systemGray6)) .cornerRadius(8) } } }