進階 Place Details 元件
Place Details 元件的 Advanced 版本提供與 Places Details Essentials 相同的功能。您也可以選擇是否顯示地點名稱、設定元件的動作按鈕,以及對顯示的評論和媒體套用搜尋和篩選選項。
進階 Place Details 設定
使用 AdvancedPlaceDetailsView 或 AdvancedPlaceDetailsCompactView 存取進階功能。
內容顯示選項
您可以使用 AdvancedPlaceDetailsContent 中的列舉,指定要顯示的內容。您可以設定與Place Details Essentials相同的所有內容,以及選擇是否顯示地點名稱。
設定動作按鈕
使用 AdvancedPlaceDetailsView 或 AdvancedPlaceDetailsCompactView 的 .cornerActions 和 .mainActions 方法,移除或自訂動作按鈕。
視覺出處規定
重要事項:如果自訂動作按鈕會將使用者資訊分享給 Google 以外的第三方,請務必向使用者清楚說明。請參閱視覺出處註明規定。
右側範例顯示的自訂圖片,清楚說明使用者資訊將傳送至「Altostrat」。
套用搜尋和篩選選項
使用 AdvancedPlaceDetailsView 或 AdvancedPlaceDetailsCompactView 的 .searchMediaOptions 和 .searchReviewOptions 方法,啟用媒體或評論的搜尋和篩選功能。
建立自訂內容版位
自訂內容版位可讓您直接在預先定義的版面配置區域中,加入自己的內容 (例如 AI 生成的摘要、行程時間戳記或自訂徽章)。
如要新增自訂內容,請使用 AdvancedPlaceDetailsCompactView 的 .placeDetailsCompactContentSlot 方法。可用的位置為 .basicSectionTop 和 .basicSectionBottom。
內容版位的出處規定和內容建議
掛接自訂內容版位時,揭露聲明會自動更新,說明哪些內容由 Google 提供,以及部分內容由第三方提供。
正確做法
Google 地點詳細資料和自訂內容之間,應維持清楚的視覺階層結構,避免資訊來源混淆。
正確做法
建議提供本地化的高價值深入分析,滿足使用者當下的目標。即時預訂時段或目前空房情況等量身打造的內容,可協助使用者更快做出更明智的決策。
錯誤做法
請勿複製現有的 Google Place Details,例如評分、評論或營業時間,即使您已隱藏 Google 提供的內容也一樣。否則使用者可能會混淆內容來源,不確定是來自 Google 還是第三方。
錯誤做法
請勿顯示未註明出處的聲明或徽章 (例如「首選推薦!」),以免使用者誤以為是 Google 官方背書。自訂內容必須明確註明來源。
錯誤做法
請勿在自訂地點容器中加入廣告、行銷文案、促銷折扣或訂閱提示。
Place Details (Advanced) 範例
省略地點名稱
如要省略地點名稱,請勿在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 版位。
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) } } }