0

horizo​​ntal scrollToItemコレクションビューの実装に問題があります。私はcollectionView(menuBar)を持っています。これは、セルのタップで、collectionViewが適切なセルに水平にスクロールします。メニューバーのタップを押すと、アプリケーションのクラッシュが表示されます。エラーの原因は不明です。前もって感謝します!scrollToItem水平スクロールコレクションビュークラッシュ

//コントローラクラス

class CurrentUserPlaceDetailsVC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { 

    var titleText: String? 

    let cellId = "cellId" 

    // UI elements 
    lazy var contentCollectionView: UICollectionView = { 
     let cv = UICollectionView() 
     cv.backgroundColor = UIColor.red 
     cv.layer.zPosition = 0 
     cv.translatesAutoresizingMaskIntoConstraints = false 
     cv.layer.masksToBounds = true 
     return cv 
    }() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     setupMenuBar() 
     setupCollectionView() 

    } 

    func scrollToMenuIndex(_ menuIndex: Int) { 
     let indexPath = IndexPath(item: menuIndex, section: 0) 
     contentCollectionView.scrollToItem(at: indexPath, at: UICollectionViewScrollPosition(), animated: true) 
    } 

    lazy var menuBar: MenuBar = { 
     let mb = MenuBar() 
     mb.currentUserPlaceDetailsVC = self 
     return mb 
    }() 

    private func setupMenuBar() { 
     view.addSubview(menuBar) 
     view.addConstraintsWithFormat("H:|[v0]|", views: menuBar) 
     view.addConstraintsWithFormat("V:|[v0(114)]", views: menuBar) 
    } 

    func setupCollectionView() { 

     let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() 

     layout.scrollDirection = .horizontal 
     layout.minimumLineSpacing = 0 
//  layout.sectionInset = UIEdgeInsets(top: 0, left: 10, bottom: 10, right: 10) 
     layout.itemSize = CGSize(width: self.view.frame.width, height: self.view.frame.height) 

     let contentCollectionView:UICollectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout) 
     contentCollectionView.dataSource = self 
     contentCollectionView.delegate = self 

     // register cells 
     contentCollectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cellId") 
     contentCollectionView.backgroundColor = .white 
//  contentCollectionView.scrollIndicatorInsets = UIEdgeInsets(top:114, left: 10, bottom: 10, right: 10) 
     self.view.addSubview(contentCollectionView) 

     _ = contentCollectionView.anchor(view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, topConstant: 114, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 0) 
     view.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true 
     contentCollectionView.isPagingEnabled = true 
    } 

    func scrollViewDidScroll(_ scrollView: UIScrollView) { 
     print(scrollView.contentOffset.x) 
     menuBar.horizontalBarLeftAnchorConstraint?.constant = scrollView.contentOffset.x/4 
    } 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return 4 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) 
     let colors: [UIColor] = [.blue, .red, .yellow, .green] 
     myCell.backgroundColor = colors[indexPath.item] 
     return myCell 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
     return CGSize(width: view.frame.width, height: view.frame.height) 
    } 

} 

//メニューバークラスコメントで

class MenuBar: UIView, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { 

    lazy var collectionView: UICollectionView = { 
     let layout = UICollectionViewFlowLayout() 
     layout.minimumLineSpacing = 0 
     layout.headerReferenceSize = .zero 
     layout.sectionInset = .zero 
     let cv = UICollectionView(frame: .zero, collectionViewLayout: layout) 
     cv.backgroundColor = .green 
     cv.dataSource = self 
     cv.delegate = self 
     return cv 
    }() 

    let cellId = "cellId" 

    var currentUserPlaceDetailsVC: CurrentUserPlaceDetailsVC? 

    override init(frame: CGRect) { 
     super.init(frame: frame) 

     collectionView.register(MenuCell.self, forCellWithReuseIdentifier: cellId) 

     addSubview(collectionView) 
     addConstraintsWithFormat("H:|[v0]|", views: collectionView) 
     addConstraintsWithFormat("V:|[v0]|", views: collectionView) 

     let selectedIndexPath = IndexPath(item: 0, section: 0) 
     collectionView.selectItem(at: selectedIndexPath, animated: false, scrollPosition: UICollectionViewScrollPosition()) 

     setupHorizontalBar() 
    } 

    var horizontalBarLeftAnchorConstraint: NSLayoutConstraint? 

    func setupHorizontalBar() { 
     let horizontalBarView = UIView() 
     horizontalBarView.backgroundColor = .white 
     horizontalBarView.translatesAutoresizingMaskIntoConstraints = false 
     addSubview(horizontalBarView) 

     horizontalBarLeftAnchorConstraint = horizontalBarView.leftAnchor.constraint(equalTo: self.leftAnchor) 
     horizontalBarLeftAnchorConstraint?.isActive = true 

     horizontalBarView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true 
     horizontalBarView.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 1/4).isActive = true 
     horizontalBarView.heightAnchor.constraint(equalToConstant: 4).isActive = true 

    } 

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 
     print(indexPath.item) 
     let x = CGFloat(indexPath.item) * frame.width/4 
     horizontalBarLeftAnchorConstraint?.constant = x 

     UIView.animate(withDuration: 0.75, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: { 
      self.layoutIfNeeded() 
     }, completion: nil) 

     currentUserPlaceDetailsVC?.scrollToMenuIndex(indexPath.item) 

    } 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return 4 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MenuCell 
     cell.imageView.image = UIImage(named: imageNames[indexPath.item])?.withRenderingMode(.alwaysTemplate) 
     cell.tintColor = UIColor.rgb(91, green: 14, blue: 13) 

     return cell 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
     return CGSize(width: frame.width/4, height: frame.height) 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { 
     return 0 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

} 
+0

どのようなエラーがありますか?また、私はあなたがあまりにも2つの異なるコレクションのビューをスクロールしようと見ることができるように、多分それはポイントですか?ところで、あなたのMenuBarの 'var currentUserPlaceDetailsVC:CurrentUserPlaceDetailsVC?'は 'weak'でなければなりません。 –

+0

こんにちは - "NSException型の未知の例外で終了"エラーが表示されています。 – user3708224

+0

すべてのエラーメッセージを提供できますか?スタックトレースなどがあります。 –

答えて

0

あなたが言った:あなたので、あなたのビュー内で、たまたま

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'UICollectionView must be initialized with a non-nil layout parameter'. I believe there is something wrong in my func scrollToMenuIndex()... when I remove that func the app does not crash.

コントローラは、あなたのcollectionViewが遅延として宣言されています。オンデマンドで計算することができます。

lazy var contentCollectionView: UICollectionView = { 
    let layout = UICollectionViewFlowLayout() 
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout) 
    cv.backgroundColor = UIColor.red 
    cv.layer.zPosition = 0 
    cv.translatesAutoresizingMaskIntoConstraints = false 
    cv.layer.masksToBounds = true 
    return cv 
}() 

P.S.: 問題は、このコードでUICollectionViewの初期化を交換あなたのビューコントローラでは、あなたのcollectionView(reason: 'UICollectionView must be initialized with a non-nil layout parameter'

を初期化していますあなたの質問に私のコメントで書いたように、あなたはreference cycleです。 MenuBarは、これを防ぐためにビューコントローラに弱い参照を保持する必要があります。

+0

ありがとう...助けてくれましたが、私のUICollectionViewFlowLayout制約がいくつかの問題を引き起こしていることもわかりました。 setupCollectionView()メソッドに次のコードを追加する必要がありました。場合は、flowLayout = contentCollectionView.collectionViewLayoutとして? UICollectionViewFlowLayout { flowLayout.scrollDirection = .horizo​​ntal flowLayout.minimumLineSpacing = 0 } – user3708224

+0

'let Layout = UICollectionViewFlowLayout()'の直後に 'MenuBar'クラスのようにこの行を設定することができます:)。 –