Buggy UI Tableview

时间:2019-12-15 20:38:52

标签: ios swift api uitableview

当您单击地图批注时,我希望视图类似于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
                }
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

尝试添加用于获取的完成块,首先将其提取到单独的函数中。在加载数据时,在注解上点击显示一些加载状态。收到完成模块后,请根据结果决定要执行的操作。在用户看到加载状态时将完成提取,并且不会发生闪烁。