使用滑块

时间:2017-06-16 12:31:23

标签: ios nsfetchedresultscontroller

我是初学iOS开发人员(这实际上是我第一次尝试使用iOS应用)。我正在制作的应用程序应该在地图上显示污染程度。我想要的是设置一个滑块并根据滑块设置显示特定时间的污染程度。

我最初的,显然是错误的方法是,每当滑块更改并更改func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>)内显示的结果时,更改fetchResultsController获取请求谓词。这种方法的问题在于,更改获取请求似乎并没有调用controllerDidChangeContent函数。似乎只有在向db添加新元素时才会触发此操作。制作这种动态更改获取请求的规范解决方案是什么?

我在下面介绍了完成上述工作的课程。

CoreDataViewController

import UIKit
import CoreData

class CoreDataViewController: UIViewController, NSFetchedResultsControllerDelegate {
    // MARK: Properties

    var fetchedResultsController : NSFetchedResultsController<NSFetchRequestResult>? {
        didSet {
            // Whenever the frc changes, execute the search and
            // reload the data
            print("fetchedResultsController did set")
            fetchedResultsController?.delegate = self
            executeSearch()
        }
    }

    // MARK: Initializers

    init?(_ coder: NSCoder, fetchedResultsController fc : NSFetchedResultsController<NSFetchRequestResult>) {
        fetchedResultsController = fc
        super.init(coder: coder)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

extension CoreDataViewController {

    func executeSearch() {
        if let fc = fetchedResultsController {
            do {
                try fc.performFetch()
            } catch let e as NSError {
                print("Error while trying to perform a search: \n\(e)\n\(fetchedResultsController)")
            }
        }
    }
}

MapViewController(扩展CoreDataViewController)

import UIKit
import GoogleMaps
import CoreData

class MapViewController: CoreDataViewController {

//    var mapView: GMSMapView!
    @IBOutlet weak var testButton: UIBarButtonItem!
    @IBOutlet weak var timestampSlider: UISlider!

    override func loadView() {

        // Get the stack
        let delegate = UIApplication.shared.delegate as! AppDelegate
        let stack = delegate.stack

        // Create a fetchrequest
        let fr = NSFetchRequest<NSFetchRequestResult>(entityName: "Measurement")
        fr.sortDescriptors = [NSSortDescriptor(key: "fromDatetime", ascending: true)]
        fr.predicate = NSPredicate(format: "fromDatetime = %@", argumentArray: [2])

        // Create the FetchedResultController
        fetchedResultsController = NSFetchedResultsController(fetchRequest: fr, managedObjectContext: stack.context,
                                                              sectionNameKeyPath: nil, cacheName: nil)

        let measurements = fetchedResultsController?.fetchedObjects as! [Measurement]

        // Create a GMSCameraPosition that tells the map to display the
        // coordinate latitude: 50.0646501, longitude: 19.9449799 at zoom level 6.
        let camera = GMSCameraPosition.camera(withLatitude: 50.0646501, longitude: 19.9449799, zoom: 14.0)
        let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
        view = mapView

        _ = measurements.flatMap({(m: Measurement) -> Void in
            print(m.fromDatetime)
            let marker = GMSMarker()
            marker.position = CLLocationCoordinate2D(latitude: m.latitude, longitude: m.longitude)
            marker.title = "Measurement"
            marker.snippet = String(format: "pm10: %f, pm25: %f", m.pm10, m.pm25)
            marker.map = mapView
        })

    }

    override func viewWillAppear(_ animated: Bool) {
        self.navigationController?.isToolbarHidden = true

    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    @IBAction func testButtonAction(_ sender: Any) {
        // Get the stack
        let delegate = UIApplication.shared.delegate as! AppDelegate
        let stack = delegate.stack
        _ = Measurement(sensorId: 0, fromDatetime: 2, pm10: 0.6, pm25: 0.3, airQualityIndex: 0.8, latitude: 50.0626402, longitude: 19.9385001, source: "Airly", windDeg: 0.9, windSpeed: 23.0, insertInto: stack.context)
    }

    @IBAction func timestampSliderAction(_ sender: Any) {
        if self.timestampSlider == nil {
            return
        }
        let sliderValue = floor(self.timestampSlider.value)
        print(sliderValue)

        let delegate = UIApplication.shared.delegate as! AppDelegate
        let stack = delegate.stack
        let fr = NSFetchRequest<NSFetchRequestResult>(entityName: "Measurement")
        fr.sortDescriptors = [NSSortDescriptor(key: "fromDatetime", ascending: true)]
        fr.predicate = NSPredicate(format: "fromDatetime = %@", argumentArray: [sliderValue])
//         Create the FetchedResultController
        fetchedResultsController = NSFetchedResultsController(fetchRequest: fr, managedObjectContext: stack.context,
                                                              sectionNameKeyPath: nil, cacheName: nil)

        // alternative solution without creating new NSFetchedResultsController
//        fetchedResultsController?.fetchRequest.predicate = NSPredicate(format: "fromDatetime = %@", argumentArray: [sliderValue])
//        executeSearch()
    }

    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        print("controllerDidChangeContent called")
        let measurements = fetchedResultsController?.fetchedObjects as! [Measurement]
        let mapView = view as! GMSMapView
        _ = measurements.flatMap({(m: Measurement) -> Void in
            let marker = GMSMarker()
            marker.position = CLLocationCoordinate2D(latitude: m.latitude, longitude: m.longitude)
            marker.title = "Measurement"
            marker.snippet = String(format: "pm10: %f, pm25: %f", m.pm10, m.pm25)
            marker.map = mapView
        })
    }
}

1 个答案:

答案 0 :(得分:0)

解决方案结果非常简单。要触发Galera,我只需在谓词更改后调用public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String server = "http://server.tld"; String subURI = request.getRequestURI().split("/ProxyServlet")[1]; System.out.println("ProxyServlet: " + server + subURI); URL remoteServer = new URL(server + subURI); HttpURLConnection connection = (HttpURLConnection) remoteServer.openConnection(); //somehow apply request to remoteServer and receive response } 。我不确定这是否是正式的方式,但它对我有用。