2016-08-02 10 views
2

Diese Frage wurde bereits in Objective-C beantwortet, aber ich konnte die Lösung nicht verstehen, weil ich Objective-C nicht kenne.Wie erstellt man CollectionView Zellen nacheinander in Swift?

Ich bin im Begriff, einen Demo-Wallpaper Browser app machen und erfordern es die Miniaturansicht für die App-Start-Bildschirm in einer Sammlung Ansicht anzuzeigen. Ich schaffte es, die Arbeit zu erledigen, aber diese Bilder werden zusammen geladen, was eine lange Zeit für (sagen wir) 40 Bilder benötigen würde.

Wie richte ich sind meine View-Controller, so dass die Miniaturbilder nicht kollektiv eins nach dem anderen in die Sammlung Ansicht geladen?

Im Folgenden sind die Swift-Dateien.

ViewController.Swift

class ViewController: UIViewController , UICollectionViewDataSource { 

@IBOutlet weak var collectionView: UICollectionView! 


let imageFetcher = ImageFetcher() 
var initialItem = 5 

override func viewDidLoad() { 
    super.viewDidLoad() 
    //imageFetcher.setImageURL() 
    // Do any additional setup after loading the view, typically from a nib. 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 

    return initialItem 
} 

     func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("ImageCell", forIndexPath: indexPath) as! CollectionViewCell 
    cell.backgroundColor = UIColor.redColor() 
    // cell.imageView.image = imageFetcher.ImageArray[indexPath.row] 
    return cell 
} 


} 
+0

Sie benötigen für eine Sammlung Ansicht Tutorials zu suchen. –

+0

Anscheinend gibt es keine zum Thema "Laden von Zellen nacheinander anzeigen". Die üblichen CollectionView-Tutorials haben die einfache und übliche Art, wie Zellen geladen usw. werden. – 209135

+0

CollectionViewCells werden nicht alle gleichzeitig erstellt. Sie werden erst erstellt und konfiguriert, bevor sie angezeigt werden. Sie laden also nicht alle Bilder auf einmal, wenn Sie nur einige der Zellen mit Bildern zeigen. – Abizern

Antwort

1

schrieb ich für Sie einige Template-Code. Hoffe, das wird hilfreich sein.

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate { 

    @IBOutlet weak var collectionView: UICollectionView! 

    var colors = [UIColor]() 

    var timer = NSTimer() 

    var counter = 0 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     self.colors.append(UIColor.randomColor()) 

     self.timer = NSTimer.scheduledTimerWithTimeInterval(3, target: self, selector: #selector(addCellToCollectionView), userInfo: nil, repeats: true) 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 

    } 


    override func viewDidDisappear(animated: Bool) { 
     super.viewDidDisappear(animated) 

     self.timer.invalidate() 

    } 


    //MARK: - CollectionView Delegate - 
    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { 
     return 1 
    } 

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 

     return self.colors.count 
    } 

    func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) { 
     UIView.animateWithDuration(0.6, animations: { 

      cell.alpha = 1 

     }) 
    } 

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 

     let cell = collectionView.dequeueReusableCellWithReuseIdentifier("MyCell", forIndexPath: indexPath) 
     cell.alpha = 0 
     cell.layer.cornerRadius = 12 
     cell.backgroundColor = self.colors[indexPath.row] 

     return cell 
    } 


    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { 

     let width = (collectionView.frame.size.width-20)/3 
     let height = width 
     let cellSize = CGSize(width: width, height: height) 

     return cellSize 
    } 



    //MARK: - Timer Selector - 
    func addCellToCollectionView(){ 

     self.counter += 1 

     if counter < 30{ 

      self.colors.append(UIColor.randomColor()) 
      self.collectionView.reloadSections(NSIndexSet(index: 0)) 

     }else{ 

      self.timer.invalidate() 
     } 

    } 

} 



//MARK: - Extensions - 

extension CGFloat{ 

    static func random() -> CGFloat { 
     return CGFloat(arc4random())/CGFloat(UInt32.max) 
    } 

} 

extension UIColor{ 

    static func randomColor() -> UIColor { 
     // If you wanted a random alpha, just create another 
     // random number for that too. 
     return UIColor(red: .random(), 
         green: .random(), 
         blue: .random(), 
         alpha: 1.0) 
    } 

} 

Vergessen Sie nicht, wiederverwendbare Zellenkennung in Ihrem .storyboard oder .xib Datei

UPDATE 3. August 15.27 (Vorschläge für GoldenBanana Antwort)

var counter = 0 

func addCells(timer : NSTimer){ 

    if(counter == imageFetcher.ImageArray.count){ 
     timer.invalidate() 
     return 
    } 

    counter = counter + 1 

    let indexPath = NSIndexPath(forItem: counter-1 , inSection: 0) 
    collectionView.insertItemsAtIndexPaths([indexPath]) 
} 



func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
    print("numberOfItemsInSection method just ran")             //timeline indicator 
    return counter 

} 
+0

Ich kann Ihnen nicht zustimmen, tut mir leid. Die Idee ist, dass Sie Elemente iterativ zur Datenquelle collectionView hinzufügen und collectionVew nach jeder Iteration neu laden. Auf diese Weise erscheinen die Zellen nacheinander. – Elena

+0

Danke für die Lösung Elena. Ich versuche es zu verstehen und es zur Arbeit zu bringen. – 209135

+0

GoldenBanana, willkommen! Meine Lösung mag Erklärungen fehlen, also fragen Sie, wenn Sie brauchen. – Elena

1
einstellen

Endlich konnte ich das sequentielle Laden der Zellen mit der Timer-Technik erreichen, wie in Elenas Code dargestellt.

Wenn dies der Hilfe für jeden ist, die Frage zu beantworten, folgende Dinge müssen

  1. Sie einen Timer
  2. ein änderbaren Array
  3. Der Timer hat Make getan werden eine Aktionsmethode (addCells), die dynamisch e fügt Objekte aus der Datenquelle auf das Array änderbare Array
  4. die änderbare Array Xpands selbst als Zeit verstreicht (im Timer angegeben) und wird zum Auffüllen der CollectionView verwendet.

ViewController.swift

class ViewController: UIViewController , UICollectionViewDataSource { 


@IBOutlet weak var collectionView: UICollectionView! 

let imageFetcher = ImageFetcher() 

var mutableArray : NSMutableArray = [] 

override func viewDidLoad() { 
    super.viewDidLoad() 

    imageFetcher.setImageURL() 
    NSTimer.scheduledTimerWithTimeInterval(01, target: self, selector: #selector(addCells), userInfo: nil, repeats: true) 
    // Do any additional setup after loading the view, typically from a nib. 
} 

func addCells(timer : NSTimer){ 

    var counter = 0 
    mutableArray.addObject(imageFetcher.ImageArray[counter]) 
    counter = counter + 1 
    let indexPath = NSIndexPath(forItem: mutableArray.count-1 , inSection: 0) 
    collectionView.insertItemsAtIndexPaths([indexPath]) 
    if(mutableArray.count == imageFetcher.ImageArray.count){ 
     timer.invalidate() 
    } 

} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
    print("numberOfItemsInSection method just ran")             //timeline indicator 
    return mutableArray.count 

} 

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("ImageCell", forIndexPath: indexPath) as! CollectionViewCell 
     cell.imageView.image = imageFetcher.ImageArray[indexPath.row] 
     return cell 
} 
} 

ImageFetcher.swift

class ImageFetcher { 



var newImage : UIImage? 
var ImageArray = [UIImage]() 
var imageURL : NSURL?{ 
    didSet{ newImage = nil 
      Adder() 
     } 
    } 

func setImageURL(){ 
imageURL = DemoURLs.randomImageUrl 
} 


func fetchImage() { 
    if let url = imageURL{ 
     let imageData = NSData(contentsOfURL: url) 
     if imageData != nil{ 
      self.newImage = UIImage(data: imageData!) 
     } else { 
      self.newImage = nil 

     } 
     } 
    } 

func Adder(){ 
    for _ in 1...20 { 

     fetchImage() 
     ImageArray.append(newImage!) 

    } 
} 
} 

Diese Antwort wurde bisher von Herrn rdelmar in der Objective-C-Sprache hier beantwortet: Loading UICollectionViewCell one at a time.

+0

1. Sollten Sie 'counter' außerhalb der Funktion' addCells' deklarieren? Andernfalls ist jedes Mal, wenn "addCells" als "counter" bezeichnet wird, gleich null. – Elena

+0

Ok ich sehe. Ihr Code funktioniert nur, weil Sie 'counter' nicht wirklich benutzen. Wenn Sie es verwenden, brauchen Sie nicht "mutableArray" überhaupt. – Elena

+0

Ich habe einige Änderungen an Ihrem Code vorgenommen (* siehe Update zu meiner Antwort), um es etwas übersichtlicher zu gestalten. – Elena