高级地点详情组件
高级版“地点详情”组件提供的功能与地点详情基本版相同。您还可以选择是否显示地点名称、配置组件的操作按钮,以及对显示的评价和媒体应用搜索和过滤选项。
高级地点详情配置
使用 AdvancedPlaceDetailsView 或 AdvancedPlaceDetailsCompactView 即可使用高级功能。
内容显示选项
您可以使用 AdvancedPlaceDetailsContent 中的枚举指定要显示的内容。您可以配置与地点详情精简版相同的所有内容,还可以选择是否显示地点名称。
配置操作按钮
使用 AdvancedPlaceDetailsView 或 AdvancedPlaceDetailsCompactView 的 .cornerActions 和 .mainActions 方法可移除或自定义操作按钮。
视觉提供方说明要求
重要提示:当自定义操作按钮会将用户信息分享给 Google 以外的第三方时,您必须向最终用户明确说明这一点。请参阅视觉提供方信息要求。
右侧的示例展示了一张自定义图片,其中明确指出用户的信息将发送给“Altostrat”。
应用搜索和过滤选项
使用 AdvancedPlaceDetailsView 或 AdvancedPlaceDetailsCompactView 的 .searchMediaOptions 和 .searchReviewOptions 方法可为媒体或评价启用搜索和过滤功能。
创建自定义内容槽
借助自定义内容槽,您可以将自己的内容(例如 AI 生成的摘要、行程时间戳或自定义徽章)直接添加到预定义的布局区域中。
如需添加自定义内容,请使用 AdvancedPlaceDetailsCompactView 的 .placeDetailsCompactContentSlot 方法。可用的位置为 .basicSectionTop 和 .basicSectionBottom。
内容槽位的提供方信息要求和内容建议
当自定义内容槽被挂载时,披露声明会自动更新,以明确指出哪些内容由 Google 提供,哪些内容由第三方提供。
正确做法
在 Google 地点详情和自定义内容之间保持清晰的视觉层次结构,以避免对信息来源产生任何歧义。
正确做法
考虑提供本地化的高价值数据洞见,以满足用户的即时目标。量身定制的内容(例如实时预订窗口或当前空房情况)有助于用户更快做出更明智的决策。
错误做法
即使您已隐藏 Google 提供的内容,也不要复制现有的 Google 地点详细信息,例如评分、评价或营业时间。这样做可能会让用户对内容的来源感到困惑,不清楚内容是来自 Google 还是第三方。
错误做法
请勿展示未注明出处的声明或徽章(例如“强烈推荐!”),以免被误认为 Google 的官方认可。自定义内容必须明确注明其来源。
错误做法
请勿在自定义位置容器中添加广告、营销文案、促销折扣或订阅提示。
高级地点详情示例
省略地点名称
如需省略地点名称,请勿在AdvancedPlaceDetailsConfiguration 的 content 参数中添加 .name。
Swift
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))") } } ) } }
移除操作按钮
Swift
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 [] } } }
添加自定义操作和预定义操作
此示例添加了一个选项,供用户将某个地点标记为收藏或取消收藏,同时还添加了预定义的在 Google 地图中打开操作。
Swift
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) } } }
过滤评价和媒体内容
此代码示例仅显示提及“咖啡”的媒体和评价。
Swift
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 slot 添加了内容。
Swift
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) } } }