ios - 有缺陷的 UI 表格 View

标签 ios swift api uitableview

我希望 View 像Apple map UI Tableview一样,当您单击 map 注释时,UI Tableview会随着加载的信息向上移动,并且很平滑。我创建了一个 UITableView 来从 Yelp API 和 Firebase 数据库加载数据。虽然我确实在 UI Tableview 中加载了数据,但 tableview 的移动似乎不稳定。例如,当我第一次单击 map 注释时,UI Tableview 将弹出,但在随机位置,然后在 Yelp API 加载后,它将再次移动到默认位置。另一件事是,如果我在 Yelp API 加载之前使用滑动手势,UI Tableview 将相应移动,但在加载 Yelp API 数据时重置到其原始位置,然后我必须重做滑动手势。

这个表格 View 有很多部分,所以我将提供我使用的代码片段列表:

注意: 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 的信息将加载到位置信息 View 中,并且动画应向上移动

    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
                }
            }
        }
    }

最佳答案

尝试添加一个完成 block 来获取,首先将其提取到一个单独的函数中。加载数据时,点击注释会显示一些加载状态。收到完成 block 后,根据结果决定要做什么。当用户看到加载状态时就会完成抓取,并且不会发生闪烁。

关于ios - 有缺陷的 UI 表格 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59347872/

相关文章:

ios - “禁止。需要用户。”保存QBCOCustomObject时出现错误

ios - 添加 RealmSwift 作为子项目 : Missing required modules: 'Realm.Private' , 'Realm'

swift - 关闭 NSWindow 但不要将其置零

Javascript:Soundmanager2 和 Soundcloud 事件回调

php - API系统的安全性| PHP 语言

ios - 调整 viewDidLoad 中 UITableViewCell 的高度到内容

ios - 上次单击时如何使按钮 UIButton 保存

ios - 如何将 CNContact 转换为 CNMutableContact?

ios - 如何在 Swift 中硬编码 UIView 的大小属性

api - 如何限制对 Google App Engine 的外部访问并仅允许 Apigee Edge?