当您单击地图批注时,我希望视图类似于Apple Maps UI Tableview,UI Tableview随加载的信息向上移动,并且平滑。我创建了一个UITableView来从Yelp API和Firebase数据库加载数据。虽然我确实在UI Tableview中加载了数据,但是tableview的移动似乎有些混乱。例如,当我第一次单击地图注释时,将弹出UI Tableview,但是它处于随机位置,然后在加载Yelp API之后,它将再次移至其默认位置。另一件事是,如果我在加载Yelp API之前使用了滑动手势,则UI Tableview将相应地移动,但是当Yelp API数据加载时,UI Tableview将重置为原始位置,然后我必须重做滑动手势。
此表视图有很多部分,因此我将提供我使用的代码清单:
注意:UI Tableview(locationInfoViews)在ViewDidLoad中配置
向上/向下滑动
func configureGestureRecognizer() {
let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipeGesture))
swipeUp.direction = .up
addGestureRecognizer(swipeUp)
let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipeGesture))
swipeDown.direction = .down
addGestureRecognizer(swipeDown)
}
func animateInputView(targetPosition: CGFloat, completion: @escaping(Bool) -> ()) {
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .curveEaseInOut, animations: {self.frame.origin.y = targetPosition}, completion: completion)
}
// MARK: - Handlers
@objc func handleSwipeGesture(sender: UISwipeGestureRecognizer) {
if sender.direction == .up {
if expansionState == .Disappeared {
animateInputView(targetPosition: self.frame.origin.y - 100) { (_) in
self.expansionState = .NotExpanded
}
}
if expansionState == .NotExpanded {
animateInputView(targetPosition: self.frame.origin.y - 200) { (_) in
self.expansionState = .PartiallyExpanded
}
}
if expansionState == .PartiallyExpanded {
animateInputView(targetPosition: self.frame.origin.y - 250) { (_) in
self.expansionState = .FullyExpanded
}
}
} else {
if expansionState == .FullyExpanded {
animateInputView(targetPosition: self.frame.origin.y + 250) { (_) in
self.expansionState = .PartiallyExpanded
}
}
if expansionState == .PartiallyExpanded {
animateInputView(targetPosition: self.frame.origin.y + 200) { (_) in
self.expansionState = .NotExpanded
}
}
if expansionState == .NotExpanded {
animateInputView(targetPosition: self.frame.origin.y + 100) { (_) in
self.expansionState = .Disappeared
}
}
}
}
选择注释时,来自Yelp和Firebase的信息将被加载到位置信息视图中,并且动画应向上移动
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
self.locationPosts.removeAll()
self.inLocationInfoMode = true
if view.annotation is MKUserLocation {
print("selected self")
} else {
self.selectedAnnotation = view.annotation as? Annotation
let coordinates = selectedAnnotation.coordinate
let coordinateRegion = MKCoordinateRegion(center: coordinates, latitudinalMeters: 1000, longitudinalMeters: 100)
mapView.setRegion(coordinateRegion, animated: true)
self.locationInfoViews.locationTitle = self.selectedAnnotation.title
// Fetch Location Post
guard let currentUid = Auth.auth().currentUser?.uid else {return}
LOCATION_REF.child(self.selectedAnnotation.title).child(currentUid).observe(.childAdded) { (snapshot) in
let postId = snapshot.key
Database.fetchLocationPost(with: postId) { (locationPost) in
self.locationPosts.append(locationPost)
self.locationPosts.sort { (post1, post2) -> Bool in
return post1.creationDate > post2.creationDate
}
self.locationInfoViews.locationResults = self.locationPosts
// self.locationInfoViews.tableView.reloadData()
// Fetch Location Information
guard let locationName = locationPost.locationName else {return}
guard let locationAddress = locationPost.address else {return}
let locationRef = COORDINATES_REF.child(locationName).child(locationAddress)
locationRef.child("mainTypeOfPlace").observe(.value) { (snapshot) in
guard let mainTypeOfPlace = snapshot.value as? String else {return}
// self.locationInfoViews.typeOfPlace = mainTypeOfPlace
locationRef.child("shortAddress").observe(.value) { (snapshot) in
guard let address1 = snapshot.value as? String else {return}
locationRef.child("city").observe(.value) { (snapshot) in
guard let city = snapshot.value as? String else {return}
locationRef.child("state").observe(.value) { (snapshot) in
guard let state = snapshot.value as? String else {return}
locationRef.child("countryCode").observe(.value) { (snapshot) in
guard let country = snapshot.value as? String else {return}
// fetch Yelp API Data
self.service.request(.match(name: locationName, address1: address1, city: city, state: state, country: country)) {
(result) in
switch result {
case .success(let response):
let businessesResponse = try? JSONDecoder().decode(BusinessesResponse.self, from: response.data)
let firstID = businessesResponse?.businesses.first?.id
self.information.request(.BusinessID(id: firstID ?? "")) {
(result) in
switch result {
case .success(let response):
if let jsonResponse = try? JSONSerialization.jsonObject(with: response.data, options: []) as? [String: Any] {
// print(jsonResponse)
if let categories = jsonResponse["categories"] as? Array<Dictionary<String, AnyObject>> {
var mainCategory = ""
for category in categories {
mainCategory = category["title"] as? String ?? ""
break
}
self.locationInfoViews.typeOfPlace = mainCategory
}
let price = jsonResponse["price"] as? String ?? ""
if let hours = jsonResponse["hours"] as? Array<Dictionary<String, AnyObject>> {
for hour in hours {
let isOpen = hour["is_open_now"] as? Int ?? 0
if isOpen == 1 {
let attributedText = NSMutableAttributedString(string: "open ", attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 16), NSAttributedString.Key.foregroundColor: UIColor(rgb: 0x066C19)])
attributedText.append(NSAttributedString(string: " \(price)", attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16), NSAttributedString.Key.foregroundColor: UIColor.black]))
self.locationInfoViews.hoursLabel.attributedText = attributedText
} else {
let attributedText = NSMutableAttributedString(string: "closed ", attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 16), NSAttributedString.Key.foregroundColor: UIColor.red])
attributedText.append(NSAttributedString(string: " \(price)", attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16), NSAttributedString.Key.foregroundColor: UIColor.darkGray]))
self.locationInfoViews.hoursLabel.attributedText = attributedText
}
}
}
}
case .failure(let error):
print("Error: \(error)")
}
}
case .failure(let error):
print("Error: \(error)")
}
}
}
}
}
}
}
self.locationInfoViews.tableView.reloadData()
}
}
// enable the goButton
if inLocationInfoMode {
locationInfoViews.goButton.isEnabled = true
locationInfoViews.coordinates = selectedAnnotation.coordinate
}
// the movement of the location info view
if self.locationInfoViews.expansionState == .Disappeared {
self.locationInfoViews.animateInputView(targetPosition: self.locationInfoViews.frame.origin.y - 335) { (_) in
self.locationInfoViews.expansionState = .PartiallyExpanded
}
}
}
}
答案 0 :(得分:0)
尝试添加用于获取的完成块,首先将其提取到单独的函数中。在加载数据时,在注解上点击显示一些加载状态。收到完成模块后,请根据结果决定要执行的操作。在用户看到加载状态时将完成提取,并且不会发生闪烁。