2017-01-02 17 views
0

私のコレクションビューでデータを再読み込みする際に問題が発生しました。私は配列をcollectionviewに入れています。しかし、配列にアイテムを追加するたびに、reloaddata()を使わなければ表示されません。新しい要素を削除したり追加したりしていても、配列ビューに変更があるたびにコレクションビューの再読み込みを行う最良の方法は何ですか?前もって感謝します!編集:追加されたコード。配列とcollectionview.reloaddata()の変更を追跡する方法

クラスCheckoutController:UICollectionViewCell、UICollectionViewDataSource、UICollectionViewDelegate、UICollectionViewDelegateFlowLayout {

var inventoryTabController: InventoryTabController? 

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

} 

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


func loadItems() -> [Item]? { 
    return NSKeyedUnarchiver.unarchiveObject(withFile: Item.ArchiveURL.path) as? [Item] 
} 

func saveItems() { 
    let isSuccessfulSave = NSKeyedArchiver.archiveRootObject(checkout, toFile: Item.ArchiveURL.path) 
    if !isSuccessfulSave { 
     print("Failed to save items...") 
    } 
} 

func addItem(item: Item) { 
    items.append(item) 
    collectionView.reloadData() 
} 

func editItem(item: Item, index: Int) { 
    items[index] = item 
    collectionView.reloadData() 
} 

func prepare(for segue: UIStoryboardSegue, sender: Any?) { 

    // Identify which segue is occuring. 
    if segue.identifier == "ShowDetail" { 
     let itemDetailViewController = segue.destination as! AddItemController 

     // Get the cell that generated this segue. 
     if let selectedItemCell = sender as? InventoryCell { 
      let indexPath = collectionView.indexPath(for: selectedItemCell)! 
      let selectedItem = items[indexPath.row] 
      itemDetailViewController.item = selectedItem 
     } 
    } 
    else if segue.identifier == "AddItem" { 
     print("Adding new meal.") 
    } 
} 

lazy var collectionView: UICollectionView = { 
    let layout = UICollectionViewFlowLayout() 
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout) 

    cv.dataSource = self 
    cv.delegate = self 

    cv.backgroundColor = UIColor.rgb(r: 247, g: 247, b: 247) 
    return cv 
}() 

let cellId = "cellId" 
let paynow = "paynow" 
func setupViews() { 
    backgroundColor = .brown 

    addSubview(collectionView) 

    addConstraintsWithFormat("H:|[v0]|", views: collectionView) 
    addConstraintsWithFormat("V:|[v0]|", views: collectionView) 
    collectionView.indicatorStyle = UIScrollViewIndicatorStyle.white 

    collectionView.register(PayNowCell.self, forCellWithReuseIdentifier: paynow) 

    collectionView.register(CheckoutCell.self, forCellWithReuseIdentifier: cellId) 
} 

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
    return checkout.count //init number of cells 
} 

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 

    if indexPath.item == 0 { 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "paynow", for: indexPath) as! PayNowCell //init cells 
    return cell 
    }else{ 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! CheckoutCell //init cells 
    print("Printing this \(checkout.count)") 
    cell.item = checkout[indexPath.item] 
    return cell 
    } 

} 

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 
    //let item = items[indexPath.item] 
    //inventoryController?.showItemDetailForItem(item: item, index: indexPath.item) 
    print("selected") 
    print(indexPath.item) 
    collectionView.reloadData() 
} 

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
    if indexPath.item == 0 { 
     return CGSize(width:frame.width, height: 100) //each cell dimensions 
    }else{ 
     return CGSize(width:frame.width, height: 150) //each cell dimensions 
    } 
} 

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

}

答えて

2

あり、これを行うには多くの方法があるが、任意のコードを見ることなく、私は特に、特定の方法をお勧めすることはできません。最も一般的なのは、配列にdidSetリスナーを設定し、変更時にcollectionView.reloadData()を呼び出します。グローバル変数についてのコメントをもとに、以下の

var dataArr = [1, 2, 3, 4] { 
     didSet { 
     //collectionView.reloadData() 
     print("Changed from \(oldValue) to \(dataArr)") 
     } 
} 

dataArr.append(5) 
//prints - Changed from [1, 2, 3, 4] to [1, 2, 3, 4, 5] 
dataArr.removeFirst() 
//prints - Changed from [1, 2, 3, 4, 5] to [2, 3, 4, 5] 

編集

あなたが本当に離れて、グローバル変数から滞在してみてください。リストを永続させるので、必要なときに検索することができます。私は細部に入るつもりはありませんが、その理由についてはSOにはたくさんのものがあります。今、私は先に進み、このような状況に対処する方法を教えてくれると述べました。

アレイの値が変更されると、NotificationCenterを使用してアプリワイド通知を送信できます。そしてあなたが望むどんなviewControllerの通知にも購読してください。

extension Notification.Name { 
    static let arrayValueChanged = Notification.Name("arrayValueChanged") 
} 

var dataArr = [1, 2, 3, 4] { 
    didSet { 
     NotificationCenter.default.post(name: .arrayValueChanged, object: nil) 
    } 
} 

class ViewController: UIViewController { 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     NotificationCenter.default.addObserver(forName: .arrayValueChanged, object: nil, queue: OperationQueue.main) { [weak self] (notif) in 
      self?.collectionView.reloadData() 
     } 
    } 

    deinit { 
     NotificationCenter.default.removeObserver(self) 
    } 
} 
+0

コードを追加しました。申し訳ありません。 –

+0

グローバル変数が宣言されている場合はどうすればいいですか?私は使用できませんvar dataArr –

+0

私は、アイテム配列がコレクションビューと同じクラスにあるという前提を外していました。私は私の答えを編集します。 – JustinM

関連する問題