I am using google map in my project. I want to give user 2 options when tapping the infoWindowOfMarker which call the delegate method: mapView(_ mapView: GMSMapView, didTapInfoWindowOfMarker marker: GMSMarker)
if I wanted to perform just one action, I could just retrieve the info in the marker and just perform my action. Actually I want to give the user 2 options: See Detail (which will send user to a new view controller), and Visit (which would get the directions from google apis base on position property of the marker and current location of the user) those 2 options will be two buttons.
I don’t see how I can pass the marker parameter to the method called when tapping the button.
See the code, and please let me know any other way I can do this.
class ItemMarker: GMSMarker {
let item: Item
init(item: Item){
self.item = item
super.init(position: item.coordinate)
//and necessary initialization
}}
class MapViewController: GMSMapViewDelegate{
@IBOutlet weak var actionStackView: UIStackView!
@IBoutlet weak var mapView: GMSMapView!
var currentUser: User!
var users = [User]()
var items = [Item]()
override viewDidLoad(){
super.viewDidLoad()
//implement code for mapView
self.currentUser = UserManager.shared.currentUser
self.users = UserManager.shared.users
users.forEach {self.items.append(contentOf: $0.items}
self.items.forEach {let marker = ItemMarker(item: $0)
marker.map = mapView}
}
@objc func seeDetailButtonTapped(_ sender: UIButton){
//here I want to verify if the user is the owner of the item he wants to see the detail,
//then allow him to modify it and present the new view controller modally.
//if the user is not the owner, then not allowing editing, and show the new view controller.
//i guess for that I need to be able to have the marker for that.
}
@objc func visitButtonTapped(_ sender: UIButton) {
//here I want to use the user current location,
//the item location, get the directions for the user,
//I need the ItemMarker to do that.
}
func mapView(_ mapView: GMSMapView, didtapInfoWindowOfMarker marker: GMSMarker)
{
let visitButton = UIButton(type: .roundedRect)
visitButton.setTitle(Utilities.visit, for: .normal)
visitButton.backgroundColor = UIColor.systemBlue
visitButton.addTarget(self, action: #selector(visitButtonTapped(_:)), for: .touchUpInside)
let seeDetail = UIButton(type: .roundedRect)
seeDetail.setTitle(Utilities.detail, for: .normal)
seeDetail.backgroundColor = UIColor.systemGray
seeDetail.addTarget(self, action: #selector(showDetailHouse(_:)), for: .touchUpInside)
actionStackView.addArrangedSubview(visitButton)
actionStackView.addArrangedSubview(seeDetail)
let stackViewHeight = actionStackView.intrinsicContentSize.height
let topInset = self.mapView.safeAreaInsets.top
mapView.padding = UIEdgeInsets(top: topInset, left: 0.0, bottom: stackViewHeight, right: 0.0)
UIView.animate(withDuration: 0.25) {
actionStackView.bottomAnchor.constraint(equalTo: self.mapView.safeAreaLayoutGuide.bottomAnchor, constant: 2.0).isActive = true
actionStackView.alpha = 0.9 }
}
}
How can I pass the marker to the seeDetail method and visitButtonTapped method? 🤷
Create a subclass from UIButton with desired properties, then you can use it in tap
handler.
class UIButtonWithMarker: UIButton {
var itemMarker: ItemMarker?
}
func mapView(_ mapView: GMSMapView, didtapInfoWindowOfMarker marker: GMSMarker)
{
let visitButton = UIButtonWithMarker(type: .roundedRect)
visitButton.itemMarker = marker as? ItemMarker
visitButton.setTitle(Utilities.visit, for: .normal)
visitButton.backgroundColor = UIColor.systemBlue
visitButton.addTarget(self, action: #selector(visitButtonTapped(_:)), for: .touchUpInside)
let seeDetail = UIButtonWithMarker(type: .roundedRect)
seeDetail.itemMarker = marker as? ItemMarker
seeDetail.setTitle(Utilities.detail, for: .normal)
seeDetail.backgroundColor = UIColor.systemGray
seeDetail.addTarget(self, action: #selector(showDetailHouse(_:)), for: .touchUpInside)
}
@objc func seeDetailButtonTapped(_ sender: UIButtonWithMarker){
if itemMarker = sender.itemMarker {
//use itemMarker here
}
}
@objc func visitButtonTapped(_ sender: UIButtonWithMarker) {
if itemMarker = sender.itemMarker {
//use itemMarker here
}
}