2017-02-16 48 views
0

我正在尝试制作“标签”体验。每个选项卡都具有屏幕宽度,用户可以在每个选项卡之间滑动。一切都工作得很好,除了在索引为“3”的选项卡上实现MKMapView。在集合视图中预加载MKMapView

enter image description here

当用户打开应用程序,收集视图被初始化为索引“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,则收集视图触发器cellForIndexAtIndexPath被调用为IndexPath(row: 2, section: 0)。我试图在该索引处“强制”称重传感器,但不幸的是,地图似乎在屏幕上呈现之前被初始化。有没有解决方法?

编辑:

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 
} 

} 
+0

如果你的用户界面被阻塞,那么你在这里做的错误:cell.SetupMapView(),没有与预加载做什么。 – 2017-02-17 03:23:50

+0

我对此不确定。我正在创建新的MapView实例并处理这个约束,这里没有额外的工作。没有数据加载,没有注释绘图,没有CPU密集或阻塞任务。 – Marcin

+0

首先,您可以更轻松地添加调用问题的代码。其次你每次都调用cell.SetupMapView()方法调用cellForRowAtItem,你会做任何检查以避免在你的单元被调用时重做所有事情吗? – 2017-02-17 09:39:30

回答

0

既然你不重用的MapView细胞。

尝试加载你的MapView作为变量外的UICollectionViewCell(在你UIViewController),并将其作为一个子视图中collectionView:willDisplayCell:forItemAtIndexPath:

添加到细胞和collectionView:didEndDisplayingCell:forItemAtIndexPath:你可以从细胞中移除。

只需将所有的mapView代码加载到您的单元格之外,并使用Cell将地图显示为子视图即可。

+1

你说得对!初始化map的对象真的是CPU密集型的,我在父ViewController的初始化器中做了这个,并且只是作为子视图添加到单元格中,现在像一个魅力一样工作。谢谢! – Marcin

+0

@Marcin很高兴帮助:) – 2017-02-18 13:13:11