在集合视图中预加载 MKMapView
Preloading MKMapView in collection view
我正在尝试 "tab" 体验。每个选项卡都有屏幕宽度,用户可以在每个选项卡之间滑动。一切正常,除了在索引为“3”的选项卡上实现了 MKMapView。
当用户打开应用程序时,集合视图被初始化为索引“1”,同时 cellForIndexAtIndexPath
被调用 IndexPath(row: 1, section: 0)
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PageIndentifier, for: indexPath) as! TabCell
if (indexPath.item == 0)
{
cell.SetupNearestView()
NearestView = cell.nearestView
NearestView?.Delegate = self
}
if (indexPath.item == 1)
{
cell.SetupStationsView()
StationsView = cell.stationsView
StationsView?.Delegate = self
}
if (indexPath.item == 2)
{
cell.SetupMapView()
MapView = cell.stationsMapView
}
return cell
}
问题是,当用户从 1 -> 2 滑动时,UI 被阻止大约一秒钟,然后为 IndexPath(row: 2, section: 0)
调用集合视图触发器 cellForIndexAtIndexPath
。我在该索引处尝试 "force" 称重传感器,但不幸的是,地图似乎在渲染到屏幕之前就被初始化了。有什么解决方法吗?
编辑:
TabCell.swift
class TabCell : UICollectionViewCell
{
var nearestView : NearestView?
var stationsView : StationsView?
var stationsMapView : MapView?
override init(frame: CGRect)
{
super.init(frame: frame)
let gradient = CAGradientLayer()
gradient.frame = bounds
gradient.colors = [UIColor.clear, RuntimeResources.Get(color: .VeryDarkBlue).cgColor]
layer.insertSublayer(gradient, at: 0)
}
required init?(coder aDecoder: NSCoder)
{
fatalError("init(coder:) has not been implemented")
}
func SetupNearestView()
{
if (nearestView != nil)
{
return
}
nearestView = NearestView(frame: CGRect(x: 0, y: 0, width: frame.width, height: frame.height))
addSubview(nearestView!)
addConstraintsWithFormat(format: "H:|[v0]|", views: nearestView!)
addConstraintsWithFormat(format: "V:|[v0]|", views: nearestView!)
}
func SetupMapView()
{
if (stationsMapView != nil)
{
return
}
stationsMapView = MapView(frame: CGRect(x: 0, y: 0, width: frame.width, height: frame.height))
addSubview(stationsMapView!)
addConstraintsWithFormat(format: "H:|[v0]|", views: stationsMapView!)
addConstraintsWithFormat(format: "V:|[v0]|", views: stationsMapView!)
}
func SetupStationsView()
{
if (stationsView != nil)
{
return
}
stationsView = StationsView(frame: CGRect(x: 0, y: 0, width: frame.width, height: frame.height))
addSubview(stationsView!)
addConstraintsWithFormat(format: "H:|[v0]|", views: stationsView!)
addConstraintsWithFormat(format: "V:|[v0]|", views: stationsView!)
}
}
MapView.swift
import UIKit
import MapKit
class MapView: MKMapView, MKMapViewDelegate
{
private let infoViewHeight = CGFloat(500)
private let FocusZoomLevel = 0.01
private let ZoomLevel = 0.04
private let centerOfSzczecin = CLLocationCoordinate2D(latitude: 53.433345, longitude: 14.544139)
private var infoViewTopConstraint : NSLayoutConstraint?
lazy var mainStationView : UIView = {
let msv = UIView(frame: CGRect(x: 0, y: 0, width: self.frame.width, height: self.infoViewHeight))
msv.translatesAutoresizingMaskIntoConstraints = false
msv.backgroundColor = RuntimeResources.Get(color: .DarkBlue)
return msv
}()
override init(frame: CGRect)
{
super.init(frame: frame)
delegate = self
// Adding info view
SetupInfoView()
// Setting center of map
let span = MKCoordinateSpanMake(ZoomLevel, ZoomLevel)
let region = MKCoordinateRegion(center: centerOfSzczecin, span: span)
setRegion(region, animated: false)
}
required init?(coder aDecoder: NSCoder)
{
fatalError("init(coder:) has not been implemented")
}
private func SetupInfoView()
{
addSubview(mainStationView)
infoViewTopConstraint = mainStationView.topAnchor.constraint(equalTo: self.bottomAnchor)
infoViewTopConstraint?.isActive = true
mainStationView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
mainStationView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
mainStationView.heightAnchor.constraint(equalToConstant: infoViewHeight).isActive = true
}
}
因为您没有重复使用 MapView 单元格。
尝试将您的 mapView 作为变量 outside 加载到 UICollectionViewCell
(在您的 UIViewController
中)并将其作为子视图添加到 collectionView:willDisplayCell:forItemAtIndexPath:
在 collectionView:didEndDisplayingCell:forItemAtIndexPath: 中,您可以将其从单元格中删除。
只需在单元格外加载所有 mapView 代码,然后使用 Cell 将地图显示为子视图即可。
我正在尝试 "tab" 体验。每个选项卡都有屏幕宽度,用户可以在每个选项卡之间滑动。一切正常,除了在索引为“3”的选项卡上实现了 MKMapView。
当用户打开应用程序时,集合视图被初始化为索引“1”,同时 cellForIndexAtIndexPath
被调用 IndexPath(row: 1, section: 0)
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PageIndentifier, for: indexPath) as! TabCell
if (indexPath.item == 0)
{
cell.SetupNearestView()
NearestView = cell.nearestView
NearestView?.Delegate = self
}
if (indexPath.item == 1)
{
cell.SetupStationsView()
StationsView = cell.stationsView
StationsView?.Delegate = self
}
if (indexPath.item == 2)
{
cell.SetupMapView()
MapView = cell.stationsMapView
}
return cell
}
问题是,当用户从 1 -> 2 滑动时,UI 被阻止大约一秒钟,然后为 IndexPath(row: 2, section: 0)
调用集合视图触发器 cellForIndexAtIndexPath
。我在该索引处尝试 "force" 称重传感器,但不幸的是,地图似乎在渲染到屏幕之前就被初始化了。有什么解决方法吗?
编辑:
TabCell.swift
class TabCell : UICollectionViewCell
{
var nearestView : NearestView?
var stationsView : StationsView?
var stationsMapView : MapView?
override init(frame: CGRect)
{
super.init(frame: frame)
let gradient = CAGradientLayer()
gradient.frame = bounds
gradient.colors = [UIColor.clear, RuntimeResources.Get(color: .VeryDarkBlue).cgColor]
layer.insertSublayer(gradient, at: 0)
}
required init?(coder aDecoder: NSCoder)
{
fatalError("init(coder:) has not been implemented")
}
func SetupNearestView()
{
if (nearestView != nil)
{
return
}
nearestView = NearestView(frame: CGRect(x: 0, y: 0, width: frame.width, height: frame.height))
addSubview(nearestView!)
addConstraintsWithFormat(format: "H:|[v0]|", views: nearestView!)
addConstraintsWithFormat(format: "V:|[v0]|", views: nearestView!)
}
func SetupMapView()
{
if (stationsMapView != nil)
{
return
}
stationsMapView = MapView(frame: CGRect(x: 0, y: 0, width: frame.width, height: frame.height))
addSubview(stationsMapView!)
addConstraintsWithFormat(format: "H:|[v0]|", views: stationsMapView!)
addConstraintsWithFormat(format: "V:|[v0]|", views: stationsMapView!)
}
func SetupStationsView()
{
if (stationsView != nil)
{
return
}
stationsView = StationsView(frame: CGRect(x: 0, y: 0, width: frame.width, height: frame.height))
addSubview(stationsView!)
addConstraintsWithFormat(format: "H:|[v0]|", views: stationsView!)
addConstraintsWithFormat(format: "V:|[v0]|", views: stationsView!)
}
}
MapView.swift
import UIKit
import MapKit
class MapView: MKMapView, MKMapViewDelegate
{
private let infoViewHeight = CGFloat(500)
private let FocusZoomLevel = 0.01
private let ZoomLevel = 0.04
private let centerOfSzczecin = CLLocationCoordinate2D(latitude: 53.433345, longitude: 14.544139)
private var infoViewTopConstraint : NSLayoutConstraint?
lazy var mainStationView : UIView = {
let msv = UIView(frame: CGRect(x: 0, y: 0, width: self.frame.width, height: self.infoViewHeight))
msv.translatesAutoresizingMaskIntoConstraints = false
msv.backgroundColor = RuntimeResources.Get(color: .DarkBlue)
return msv
}()
override init(frame: CGRect)
{
super.init(frame: frame)
delegate = self
// Adding info view
SetupInfoView()
// Setting center of map
let span = MKCoordinateSpanMake(ZoomLevel, ZoomLevel)
let region = MKCoordinateRegion(center: centerOfSzczecin, span: span)
setRegion(region, animated: false)
}
required init?(coder aDecoder: NSCoder)
{
fatalError("init(coder:) has not been implemented")
}
private func SetupInfoView()
{
addSubview(mainStationView)
infoViewTopConstraint = mainStationView.topAnchor.constraint(equalTo: self.bottomAnchor)
infoViewTopConstraint?.isActive = true
mainStationView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
mainStationView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
mainStationView.heightAnchor.constraint(equalToConstant: infoViewHeight).isActive = true
}
}
因为您没有重复使用 MapView 单元格。
尝试将您的 mapView 作为变量 outside 加载到 UICollectionViewCell
(在您的 UIViewController
中)并将其作为子视图添加到 collectionView:willDisplayCell:forItemAtIndexPath:
在 collectionView:didEndDisplayingCell:forItemAtIndexPath: 中,您可以将其从单元格中删除。
只需在单元格外加载所有 mapView 代码,然后使用 Cell 将地图显示为子视图即可。