基本地点自动补全组件
Places UI Kit 的基本地点自动补全组件可让您添加一个单独的界面组件,该组件会在用户选择地点时返回地点 ID。该组件是一个全屏覆盖层,可为用户提供一个用于输入查询内容的搜索栏。当用户输入内容时,搜索栏下方会显示自动补全结果列表。当用户点按某个地点时,系统会向开发者返回一个仅包含地点 ID 的地点对象。此组件可自定义。
该组件通过 AutocompleteFilter
结构体获取地理边界和其他搜索参数。
响应提供了一个 Place
结构体,其中仅填充了 placeID
字段。
基本地点自动补全组件具有以下自定义选项:列表密度,以及是否包含位置图标。使用 AutocompleteUICustomization
结构体自定义组件。
您可以单独使用基本地点自动填充组件,也可以将其与其他 Google Maps Platform API 和服务搭配使用。
结算
每次打开该组件并进行查询时,系统都会向您收取费用。除非会话过期或从列表中选择某个地点,否则系统不会再针对该会话向您收费。
向应用添加基本自动补全组件
设置自动补全过滤条件参数(例如要返回的类型、要将结果限制到的国家/地区、结果的区域坐标,以及用户出发地的距离信息,如果已设置),就像在不使用 Places UI Kit 的情况下使用地点自动补全(新)一样。如需查看完整说明和用于创建自动补全过滤器的代码示例,请参阅地点自动补全(新)文档。
创建自动补全过滤条件后,您可以创建一个包含界面自定义设置的结构。查看自定义选项和说明。
然后,创建一个用于启动自定义的基本自动补全组件的按钮。
Swift
Button("Search for a place") { showWidget.toggle() } .basicPlaceAutocomplete( show: $showWidget // ... )
自定义基本自动补全组件
自定义内容
列表密度
您可以选择显示双行列表或多行列表。使用 AutocompleteUICustomization
类中的 AutocompleteListDensity
选项(.twoLine
或 .multiLine
)。如果您未指定列表密度,该组件将显示双行列表。
“位置”图标
您可以选择是否在结果列表中显示默认地点图标。使用 AutocompleteUICustomization
类中的 AutocompleteUIIcon
(.defaultIcon
或 .noIcon
)中的选项。
自定义主题
您可以指定一个主题来替换任何默认样式属性。您可以自定义地点详情组件的颜色、排版、间距、边框和边角。默认值为 PlacesMaterialTheme
。
未被覆盖的任何主题背景属性都使用默认样式。
Places 界面套件默认提供深色主题,因此您可能需要同时自定义深色主题和浅色主题。如需自定义深色主题,请向您的自定义主题添加 .dark
和 attribution.darkModeColor
的值。
如需详细了解主题,请参阅自定义样式部分。
向基本自动补全组件添加内容和主题自定义设置
使用 AutocompleteUICustomization
类自定义基本自动补全组件。
Swift
let uiCustomization = AutocompleteUICustomization( listDensity: .multiLine, listItemIcon: .noIcon, theme: PlacesMaterialTheme() )
示例
添加基本自动补全组件
此示例创建了一个带有按钮的自定义基本自动补全组件。已设置默认图标、双行列表密度和自定义主题。自动补全过滤器设置为查找拉斯维加斯及其附近与会计相关的地点。
Swift
// Note: You must provide an API key in your app entry point first. // A demo view of the basic place autocomplete widget. public struct BasicPlaceAutocompleteView: View { @State private var fetchedPlace: Place? @State private var placesError: PlacesError? @State private var showWidget = false public var body: some View { let types: Set<PlaceType> = [.accounting] let countries: Set<String> = ["US"] let origin = CLLocation(latitude: 36.19030535579595, longitude: -115.25397680618019) let coordinateRegion = RectangularCoordinateRegion( northEast: CLLocationCoordinate2D( latitude: 36.25290087640495, longitude: -115.08025549571225), southWest: CLLocationCoordinate2D(latitude: 36.06607422287787, longitude: -115.33431432920293) ) let regionCode = "US" let inputOffset = 10 let filter = AutocompleteFilter( types: types, countries: countries, origin: origin, coordinateRegionBias: coordinateRegion, regionCode: regionCode) let uiCustomization = AutocompleteUICustomization( listDensity: .multiLine, listItemIcon: .noIcon, theme: PlacesMaterialTheme() ) VStack { Button("Search for a place") { showWidget.toggle() } .basicPlaceAutocomplete( filter: filter, uiCustomization: uiCustomization ?? AutocompleteUICustomization(), show: $showWidget, onSelection: { place in guard let placeID = place.placeID else { self.placesError = .internal( "Could not fetch place details because place ID from selected suggestion not found." ) return } Task { let placesClient = await PlacesClient.shared let fetchPlaceRequest = FetchPlaceRequest( placeID: placeID, placeProperties: [.displayName, .formattedAddress] ) switch await placesClient.fetchPlace(with: fetchPlaceRequest) { case .success(let place): print("Fetched place: \(place)") self.fetchedPlace = place case .failure(let placesError): print("Failed to fetch place: \(placesError)") self.placesError = placesError } } }, onError: { placesError in self.placesError = placesError } ) if let placesError = $placesError.wrappedValue { Text(placesError.localizedDescription) .frame(maxWidth: .infinity, alignment: .leading) } else if let fetchedPlace = $fetchedPlace.wrappedValue { Text("\(fetchedPlace)") .frame(maxWidth: .infinity, alignment: .leading) } } } }
自定义主题
Swift
@Environment(\.colorScheme) var colorScheme var theme: PlacesMaterialTheme { if customTheme { var theme = PlacesMaterialTheme() var color = PlacesMaterialColor() color.surface = (colorScheme == .dark ? .blue : .gray) color.outlineDecorative = (colorScheme == .dark ? .white : .black) color.onSurface = (colorScheme == .dark ? .yellow : .red) color.onSurfaceVariant = (colorScheme == .dark ? .white : .blue) color.onSecondaryContainer = (colorScheme == .dark ? .white : .red) color.secondaryContainer = (colorScheme == .dark ? .green : .purple) color.positive = (colorScheme == .dark ? .yellow : .red) color.primary = (colorScheme == .dark ? .yellow : .purple) color.info = (colorScheme == .dark ? .yellow : .purple) var shape = PlacesMaterialShape() shape.cornerRadius = 10 var font = PlacesMaterialFont() font.labelLarge = .system(size: UIFontMetrics.default.scaledValue(for: 18)) font.headlineMedium = .system(size: UIFontMetrics.default.scaledValue(for: 15)) font.bodyLarge = .system(size: UIFontMetrics.default.scaledValue(for: 15)) font.bodyMedium = .system(size: UIFontMetrics.default.scaledValue(for: 12)) font.bodySmall = .system(size: UIFontMetrics.default.scaledValue(for: 11)) var attribution = PlacesMaterialAttribution() attribution.lightModeColor = .black attribution.darkModeColor = .white theme.color = color theme.shape = shape theme.font = font theme.attribution = attribution } else { return PlacesMaterialTheme() } }