You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
5.2 KiB

2 years ago
// Copyright 2020 Google LLC. All rights reserved.
//
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under
// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
// ANY KIND, either express or implied. See the License for the specific language governing
// permissions and limitations under the License.
import GooglePlaces
import UIKit
/// All other autocomplete demo classes inherit from this class. This class optionally adds a button
/// to present the autocomplete widget, and displays the results when these are selected.
class AutocompleteBaseViewController: UIViewController {
private lazy var textView: UITextView = {
let textView = UITextView()
textView.isEditable = false
textView.textContainerInset = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)
return textView
}()
private lazy var photoButton: UIBarButtonItem = {
return UIBarButtonItem(
title: "Photos", style: .plain, target: self, action: #selector(showPhotos))
}()
private lazy var pagingPhotoView: PagingPhotoView = {
let photoView = PagingPhotoView()
photoView.isHidden = true
return photoView
}()
var autocompleteConfiguration: AutocompleteConfiguration?
override func viewDidLoad() {
super.viewDidLoad()
if #available(iOS 13.0, *) {
view.backgroundColor = .systemBackground
} else {
view.backgroundColor = .white
}
view.addSubview(textView)
textView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(pagingPhotoView)
pagingPhotoView.translatesAutoresizingMaskIntoConstraints = false
let guide = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
textView.topAnchor.constraint(equalTo: guide.topAnchor),
textView.bottomAnchor.constraint(equalTo: guide.bottomAnchor),
textView.leadingAnchor.constraint(equalTo: guide.leadingAnchor),
textView.trailingAnchor.constraint(equalTo: guide.trailingAnchor),
])
NSLayoutConstraint.activate([
pagingPhotoView.topAnchor.constraint(equalTo: guide.topAnchor),
pagingPhotoView.bottomAnchor.constraint(equalTo: guide.bottomAnchor),
pagingPhotoView.leadingAnchor.constraint(equalTo: guide.leadingAnchor),
pagingPhotoView.trailingAnchor.constraint(equalTo: guide.trailingAnchor),
])
}
@objc func showPhotos() {
pagingPhotoView.isHidden = false
navigationItem.rightBarButtonItem = nil
textView.isHidden = true
}
func autocompleteDidSelectPlace(_ place: GMSPlace) {
let text = NSMutableAttributedString(string: place.description)
text.append(NSAttributedString(string: "\nPlace status: "))
text.append(NSAttributedString(string: place.isOpen().description))
if let attributions = place.attributions {
text.append(NSAttributedString(string: "\n\n"))
text.append(attributions)
}
if #available(iOS 13.0, *) {
text.addAttribute(.foregroundColor, value: UIColor.label, range: NSMakeRange(0, text.length))
}
textView.attributedText = text
textView.isHidden = false
pagingPhotoView.isHidden = true
if let photos = place.photos, photos.count > 0 {
preloadPhotoList(photos: photos)
}
}
func autocompleteDidFail(_ error: Error) {
textView.text = String(
format: NSLocalizedString(
"Demo.Content.Autocomplete.FailedErrorMessage",
comment: "Format string for 'autocomplete failed with error' message"), error as NSError)
}
func autocompleteDidCancel() {
textView.text = NSLocalizedString(
"Demo.Content.Autocomplete.WasCanceledMessage",
comment: "String for 'autocomplete canceled message'")
}
override func viewWillTransition(
to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator
) {
super.viewWillTransition(to: size, with: coordinator)
pagingPhotoView.shouldRedraw = true
}
}
extension AutocompleteBaseViewController {
// Preload the photos to be displayed.
func preloadPhotoList(photos: [GMSPlacePhotoMetadata]) {
var attributedPhotos: [AttributedPhoto] = []
let placeClient = GMSPlacesClient.shared()
DispatchQueue.global().async {
let downloadGroup = DispatchGroup()
photos.forEach { photo in
downloadGroup.enter()
placeClient.loadPlacePhoto(photo) { imageData, error in
if let image = imageData, let attributions = photo.attributions {
attributedPhotos.append(AttributedPhoto(image: image, attributions: attributions))
}
downloadGroup.leave()
}
}
downloadGroup.notify(queue: DispatchQueue.main) {
self.navigationItem.rightBarButtonItem = self.photoButton
self.pagingPhotoView.updatePhotos(attributedPhotos)
}
}
}
}
extension GMSPlaceOpenStatus: CustomStringConvertible {
public var description: String {
switch self {
case .open:
return "Open"
case .closed:
return "Closed"
case .unknown:
return "Unknown"
default:
return ""
}
}
}