我正在collectionView
中获取酒店列表,并在地图上显示用户位置。因此,当我单击酒店单元格时,我将移至酒店详细信息视图。直到这一步一切都很好,但是当我开始使用搜索功能创建的时候,我在地图上显示新位置并重新获取该位置上存在的酒店并单击酒店单元格,这次应用程序在viewWillDisappear
函数之后崩溃。
我想发送到下一个视图的内容可能有问题,尽管这与我在搜索之前第一次发送的内容相同!因此,我创建了一个空白视图仅用于测试,并且发生了同样的事情。
import UIKit
import RxSwift
import RxCocoa
import MapKit
import CoreLocation
class HomeViewController: UIViewController, MKMapViewDelegate,
CLLocationManagerDelegate{
let disposeBag = DisposeBag()
let keyChainService = KeychainService()
@IBOutlet weak var hotelCollectionView: UICollectionView!
@IBOutlet weak var backgroundImageView: UIImageView!
@IBOutlet weak var shadow: UIView!
@IBOutlet weak var searchBar: UIView!
@IBOutlet weak var citySearch: UITextField!
let hotelRepo = HotelsRepo()
@IBOutlet weak var map: MKMapView!
var locationManager: CLLocationManager!
var homeViewModel: HomeViewModel!
var user : User?
override func viewDidLoad() {
super.viewDidLoad()
homeViewModel = HomeViewModel()
map.delegate = self
getCurrentLocation()
createBindings()
createObservers()
initOverlay()
hotelCollectionView.register(UINib(nibName:
"AlbumsCollectionViewCell", bundle: nil),
forCellWithReuseIdentifier: String(describing:
AlbumsCollectionViewCell.self))
let gestureRecognizer = UITapGestureRecognizer(target:self,
action: #selector(handleTap(gestureReconizer:)))
map.addGestureRecognizer(gestureRecognizer)
}
@objc func handleTap(gestureReconizer:
UILongPressGestureRecognizer) {
let location = gestureReconizer.location(in: map)
let coordinate = map.convert(location,toCoordinateFrom:
map)
print("coord: \(coordinate)")
}
override func viewDidDisappear(_ animated: Bool) {
print("did")
}
func createBindings(){
homeViewModel.context = self
homeViewModel
.hotels
.observeOn(MainScheduler.instance)
.bind(to: hotelCollectionView.rx.items(cellIdentifier:
"AlbumsCollectionViewCell", cellType:
AlbumsCollectionViewCell.self)) { (row,hotel,cell) in
cell.cellHotel = hotel
self.homeViewModel.selectedHotel = hotel
cell.visitButton.rx.tap
.bind(onNext: self.homeViewModel.hotelAction)
.disposed(by: cell.disposeBag)
}.disposed(by: disposeBag)
hotelCollectionView.rx
.modelSelected(Hotel.self)
.subscribe(onNext: {
hotel in
self.homeViewModel.selectedHotel = hotel
})
.disposed(by: disposeBag)
hotelCollectionView.rx
.itemSelected
.subscribe(onNext:{ indexPath in
let cell = self.hotelCollectionView.cellForItem(at:
indexPath) as! AlbumsCollectionViewCell
if cell.selection == 0 {
let otherCells =
self.hotelCollectionView.indexPathsForVisibleItems
otherCells.forEach { index in
if (index == indexPath) {
cell.selection = 1
}else {
let cell =
self.hotelCollectionView.cellForItem(at: index) as!
AlbumsCollectionViewCell
cell.selection = 0
}
}
}else{
print(cell.cellHotel.name!)
cell.selection = 0
}
}).disposed(by: disposeBag)
}
func createObservers(){
homeViewModel
.hotels
.observeOn(MainScheduler.instance)
.subscribe(onNext: { (hotels) in
let annotations = hotels.map({ (hotel) ->
MKPointAnnotation in
let pointAnnotation = MKPointAnnotation()
if let address = hotel.address, let latitude =
address.latitude,
let longitude = address.longitude {
if let lat = Double(latitude), let long =
Double(longitude){
pointAnnotation.coordinate =
CLLocationCoordinate2D(latitude: lat, longitude: long)
pointAnnotation.title = hotel.name
}
}
return pointAnnotation
})
self.map.addAnnotations(annotations)
})
.disposed(by: disposeBag)
homeViewModel
.error
.observeOn(MainScheduler.instance)
.subscribe(onNext: { (error) in
self.displayMessage(userMessage: error)
})
.disposed(by: disposeBag)
homeViewModel.loading.observeOn(MainScheduler.instance)
.subscribe(onNext: { (state) in
switch state {
case true:
self.showLoading("Loading hotels")
case false:
self.hideLoading()
}
})
.disposed(by: disposeBag)
hotelCollectionView.rx.willDisplayCell
.subscribe(onNext: ({ (cell,indexPath) in
cell.alpha = 0
let transform =
CATransform3DTranslate(CATransform3DIdentity, -250, 0, 0)
cell.layer.transform = transform
UIView.animate(withDuration: 1, delay: 0,
usingSpringWithDamping: 0.7, initialSpringVelocity:
0.5, options: .curveEaseOut, animations: {
cell.alpha = 1
cell.layer.transform = CATransform3DIdentity
}, completion: nil)
})).disposed(by: disposeBag)
}
func getCurrentLocation() {
if (CLLocationManager.locationServicesEnabled()) {
if locationManager == nil {
locationManager = CLLocationManager()
}
locationManager?.requestWhenInUseAuthorization()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
}
@IBAction func primaryAction(_ sender: Any) {
let address = citySearch.text!
self.homeViewModel.getCoordinateFrom(address: address) {
coordinate, error in
guard let coordinate = coordinate, error == nil else {
self.homeViewModel.requestData(city: address); return }
let location = CLLocationCoordinate2D(latitude:
coordinate.latitude
, longitude: coordinate.longitude)
let span = MKCoordinateSpan(latitudeDelta: 1,
longitudeDelta: 1)
let region = MKCoordinateRegion(center: location,
span: span)
self.map.setRegion(region, animated: true)
self.homeViewModel.requestData(city: address)
}
}
extension HomeViewController {
func locationManager(_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]) {
self.homeViewModel.updateLocation(locations, updateMap: {
(region) -> () in
self.map.setRegion(region, animated: true)
self.locationManager.stopUpdatingLocation()
})
}
func locationManager(_ manager: CLLocationManager,
didFailWithError error: Error) {
print("location error")
}
}
// map delegate functions
extension HomeViewController {
func mapView(_ mapView: MKMapView, viewFor annotation:
MKAnnotation) -> MKAnnotationView? {
return self.homeViewModel.viewForAnnotation(annotation)
}
func mapView(_ mapView: MKMapView, annotationView view:
MKAnnotationView, calloutAccessoryControlTapped control:
UIControl) {
self.homeViewModel.annotationView(view)
}
}
错误消息:
2019-05-16 11:05:26.090098 + 0100 IDN [8514:106565] -[IDN.HomeViewController editdidEnd:]:无法识别的选择器已发送到实例0x7fd2cc408620 2019-05-16 11:05:26.101109 + 0100 IDN [8514:106565] *由于未捕获的异常而终止应用程序 'NSInvalidArgumentException',原因:'-[IDN.HomeViewController editdidEnd:]:无法识别的选择器已发送到实例0x7fd2cc408620' * 第一个调用堆栈:(0 CoreFoundation 0x000000011149012b __exceptionPreprocess + 171 1 libobjc.A.dylib
0x0000000110b24f41 objc_exception_throw + 48 2 CoreFoundation
0x0000000111511024-[NSObject(NSObject)didNotRecognizeSelector:] + 132