所以我在MKMapview的顶部添加了一个子视图。当我添加子视图时,MKMapview不允许我滚动更改地图的位置。但是,它仍然可以使用所有UI手势。
这是我的主要viewcontroller代码:
class mapViewController: UIViewController {
enum CardState {
case expanded
case collpased
}
var slideUpCardViews : mapSearchCardViewController!
var visualEffectview : UIVisualEffectView!
let cardHeight : CGFloat = 667
let CardHandleHeight : CGFloat = 35
var cardVisible = false
var nextState : CardState {
return cardVisible ? . collpased : .expanded
}
var runningAnimations = [UIViewPropertyAnimator]()
var animationProgressWhenIntreupted : CGFloat = 0
func setUpCard() {
visualEffectview = UIVisualEffectView()
visualEffectview.frame = self.view.frame
self.view.addSubview(visualEffectview)
slideUpCardViews = mapSearchCardViewController(nibName: "mapSearchCardView", bundle: nil)
self.addChildViewController(slideUpCardViews)
self.view.addSubview(slideUpCardViews.view)
slideUpCardViews.view.frame = CGRect(x: 0, y: self.view.frame.height - 100
, width: self.view.bounds.width, height: cardHeight)
slideUpCardViews.view.clipsToBounds = true
let tapGestureRecog = UITapGestureRecognizer(target: self, action: #selector(self.handleCardTap(recognizer:)))
let panGestureRecog = UIPanGestureRecognizer(target: self, action: #selector(self.handleCardPan(recognizer:)))
slideUpCardViews.SearchCardHandleBar.addGestureRecognizer(tapGestureRecog)
slideUpCardViews.SearchCardHandleBar.addGestureRecognizer(panGestureRecog)
}
@objc func handleCardTap(recognizer:UITapGestureRecognizer) {
}
@objc func handleCardPan(recognizer:UIPanGestureRecognizer) {
switch recognizer.state {
case .began:
startInteractiveTransition(state: nextState, duration: 0.9)
case .changed:
let translationFunction = recognizer.translation(in: self.slideUpCardViews.SearchCardHandleBar)
var fractionComplete = translationFunction.y / cardHeight
fractionComplete = cardVisible ? fractionComplete : -fractionComplete
updateInteractiveTransition(franctionCompleted: fractionComplete)
case .ended:
continueInteractiveTransition()
default:
break
}
}
func animationTransitionIfNeeded (state:CardState, duration: TimeInterval) {
if runningAnimations.isEmpty {
let frameAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) {
switch state {
case .expanded:
self.slideUpCardViews.view.frame.origin.y = self.view.frame.height - self.cardHeight + 100
case .collpased:
self.slideUpCardViews.view.frame.origin.y = self.view.frame.height - self.CardHandleHeight
}
}
frameAnimator.addCompletion {_ in
self.cardVisible = !self.cardVisible
self.runningAnimations.removeAll()
}
frameAnimator.startAnimation()
runningAnimations.append(frameAnimator)
let searchOpacityAnimator = UIViewPropertyAnimator(duration: duration, curve: .linear) {
switch state {
case . expanded:
self.slideUpCardViews.SearchCardHandleBar.layer.opacity = 0.05
case .collpased:
self.slideUpCardViews.SearchCardHandleBar.layer.opacity = 0.65
}
}
searchOpacityAnimator.startAnimation()
runningAnimations.append(searchOpacityAnimator)
let blurAnimator = UIViewPropertyAnimator(duration: duration, curve: .linear) {
switch state {
case .expanded:
self.visualEffectview.effect = UIBlurEffect(style: .light)
case .collpased:
self.visualEffectview.effect = nil
}
}
blurAnimator.startAnimation()
runningAnimations.append(blurAnimator)
}
}
func startInteractiveTransition(state: CardState, duration: TimeInterval) {
if runningAnimations.isEmpty {
animationTransitionIfNeeded(state: state, duration: duration)
}
for animator in runningAnimations {
animator.pauseAnimation()
animationProgressWhenIntreupted = animator.fractionComplete
}
}
func updateInteractiveTransition(franctionCompleted:CGFloat) {
for animator in runningAnimations {
animator.fractionComplete = franctionCompleted + animationProgressWhenIntreupted
}
}
func continueInteractiveTransition() {
for animator in runningAnimations {
animator.continueAnimation(withTimingParameters: nil, durationFactor: 0)
}
}
@IBOutlet weak var slideUpViewHeightConstraint: NSLayoutConstraint!
var eventArray : [eventClass] = []
@IBOutlet var mainEventMap : MKMapView?
@IBOutlet var eventSearchBox : UITextField? {
didSet {
eventSearchBox?.tag = 1
}
}
override func viewDidLoad() {
mainEventMap?.delegate = self
super.viewDidLoad()
setUpCard()
let SwipeDownSubView : UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(mapViewController.animateViewDown))
SwipeDownSubView.direction = .down
view.addGestureRecognizer(SwipeDownSubView)
let tap :UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(mapViewController.dismissKeyboard))
tap.numberOfTapsRequired = 2
view.addGestureRecognizer(tap)
let annosTap:UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(mapViewController.refreshAnnos))
annosTap.numberOfTapsRequired = 3
view.addGestureRecognizer(annosTap)
let tapps : UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(mapViewController.addSubView))
tapps.numberOfTapsRequired = 4
view.addGestureRecognizer(tapps)
retreiveEventData()
DispatchQueue.main.asyncAfter(wallDeadline: .now() + 5.0, execute: {
self.setUpAnnos()
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@objc func addSubView() {
print("added sub view")
animateViewUp()
}
@objc func dismissSubView() {
print("dimissed subview")
animateViewDown()
}
@objc func dismissKeyboard() {
view.endEditing(true)
}
@objc func refreshAnnos() {
print(eventArray)
setUpAnnos()
print("refresh annos called")
}
// function for collecting the event data from firebase
func retreiveEventData() {
let eventDFRef = Database.database().reference().child("events")
eventDFRef.observe(.value, with: {
datasnapShot in
for child in datasnapShot.children.allObjects as! [DataSnapshot] {
print(child.value!)
let eventObjectTitle = child.childSnapshot(forPath: "event Title").value
let eventObjectType = child.childSnapshot(forPath: "event Type").value
let eventObjectLocaiton = child.childSnapshot(forPath: "event Location").value
let eventObjectDiscriptiom = child.childSnapshot(forPath: "event Discription").value
let eventObjectLat = child.childSnapshot(forPath: "event Lat").value
let eventObjectLong = child.childSnapshot(forPath: "event Long").value
let eventObjectAnnoTitle = child.childSnapshot(forPath: "event Location Title").value
let eventObjectAnnoAddress = child.childSnapshot(forPath: "event Address").value
let eventObject = eventClass(eventTitle: eventObjectTitle as! String, eventType: eventObjectType as! String, eventLocation: eventObjectLocaiton as! String, eventDescription: eventObjectDiscriptiom as! String, eventDateTimes: "now", eventImageName: "car", eventlat: eventObjectLat as! CLLocationDegrees, eventLong: eventObjectLong as! CLLocationDegrees, eventLocationTitle: eventObjectAnnoTitle as! String, eventAddress: eventObjectAnnoAddress as! String)
self.eventArray.append(eventObject)
superEventArray.append(eventObject)
}})
print("Retrieved Data")
}
func setUpAnnos() {
eventArray.forEach { event in
let annotation = MKPointAnnotation()
annotation.title = event.eventTitleSubmit
annotation.subtitle = event.eventTypeSubmit
annotation.coordinate = CLLocationCoordinate2D(latitude: event.eventLatSubmit, longitude: event.eventLongSubmit)
mainEventMap?.addAnnotation(annotation)
}
print(eventArray)
print("annos added")
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
func animateViewUp() {
slideUpViewHeightConstraint.constant = 300
UIView.animate(withDuration: 0.3) {
self.view.layoutIfNeeded()
}
}
@objc func animateViewDown() {
slideUpViewHeightConstraint.constant = 1
UIView.animate(withDuration: 0.3) {
self.view.layoutIfNeeded()
}
}
}
extension mapViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
var annotationView = mainEventMap?.dequeueReusableAnnotationView(withIdentifier: "annotationView")
if annotationView == nil {
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "annotation view")
}
if annotation.subtitle == "Track day" {
annotationView?.image = UIImage(named: "Track day")
}
else if annotation.subtitle == "Drift event" {
annotationView?.image = UIImage(named: "Drift event")
}
else if annotation.subtitle == "Champiopnship event" {
annotationView?.image = UIImage(named: "Champiopnship event")
}
else if annotation.subtitle == "Meet" {
annotationView?.image = UIImage(named: "Meet")
}
else if annotation.subtitle == "Drag" {
annotationView?.image = UIImage(named: "Drag")
}
else if annotation.subtitle == "Rally" {
annotationView?.image = UIImage(named: "Rally")
}
annotationView?.canShowCallout = true
return annotationView
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
print("annotation Selected")
}
}
这是我添加的子视图的代码:
class mapSearchCardViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {
var eventSearchResults : [eventClass] = []
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
for events in superEventArray {
if events.eventTypeSubmit == MapCardSearchBar.text {
eventSearchResults.append(events)
}
}
mapCardTableView.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
eventSearchResults.removeAll()
mapCardTableView.reloadData()
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
print(superEventArray)
print("search bar clicked")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("returned superevent array count")
return superEventArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if eventSearchResults.count == 0 {
print("event search count = 0")
let cellIdentifier = "eventTableViewCell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! eventFeedTableViewCell
cell.eventTitleLabel.text = superEventArray[indexPath.row].eventTitleSubmit
cell.eventTypeLabel.text = superEventArray[indexPath.row].eventTypeSubmit
cell.eventLocationLabel.text = superEventArray[indexPath.row].eventLocationSubmit
cell.evenImageView.image = UIImage(named: "car")
return cell
}
else {
print("loading event search table")
let cellIdentifier = "eventTableViewCell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! eventFeedTableViewCell
cell.eventTitleLabel.text = eventSearchResults[indexPath.row].eventTitleSubmit
cell.eventTypeLabel.text = eventSearchResults[indexPath.row].eventTypeSubmit
cell.eventLocationLabel.text = eventSearchResults[indexPath.row].eventLocationSubmit
cell.evenImageView.image = UIImage(named: "car")
return cell
}
}
@IBOutlet weak var SearchCardHandleBar:RoundedSearchView!
@IBOutlet weak var MapCardSearchBar: UISearchBar!
@IBOutlet weak var mapCardTableView: UITableView!
}
我只是在使用地图视图时遇到麻烦,并且不想在添加子视图后滚动。
提前谢谢。
Rory