2016-08-02 4 views
2

Этот вопрос был дан ответ в Objective-C, но я не мог понять решение, потому что не знаю Objective-C.Как создать ячейки CollectionView один за другим в Swift?

Я создаю демонстрационное приложение для браузера обоев и требую, чтобы оно отображало эскизы в виде коллекции для экрана запуска приложения. Мне удалось выполнить эту работу, однако эти изображения загружаются коллективно, что займет много времени (скажем) 40 изображений.

Как настроить мой контроллер просмотра таким образом, чтобы миниатюрные изображения загружались один за другим в виде коллекции, а не коллективно?

Ниже перечислены файлы Swift.

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

вам необходимо найти учебные пособия для коллекций. –

+0

По-видимому, их нет на тему «Загрузка ячеек Collection View один за другим». Обычные учебники CollectionView имеют простой и обычный способ создания ячеек и т. Д. – 209135

+0

CollectionViewCells создаются не сразу, они создаются и настраиваются непосредственно перед их отображением, поэтому вы не загружаете сразу все изображения, если вы просто показываете несколько ячеек с изображениями. – Abizern

ответ

1

Я написал несколько шаблонов для вас код. Надеюсь, это будет полезно.

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) 
    } 

} 

Не забудьте установить многоразовый идентификатор соты в вашем .storyboard или .xib файл

UPDATE 3 авг 15:27 (предложения для ответа GoldenBanana в)

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

Не могу согласиться с вами, извините. Идея заключается в том, что вы итеративно добавляете элементы в источник данных collectionView и перезагружаете collectionVew после каждой итерации. Таким образом, ячейки появляются один за другим. – Elena

+0

Спасибо за решение Elena.Я пытаюсь понять это и заставить его работать. – 209135

+0

GoldenBanana, добро пожаловать! Моему решению может не хватать объяснений, поэтому спросите, если вам нужно. – Elena

1

Наконец-то я смог получить последовательную загрузку ячеек, используя технику таймера, как показано в коде Елены.

Если это помочь кому-либо, чтобы ответить на этот вопрос, следующие вещи необходимо сделать

  1. Сделать таймер
  2. Сделайте Мутабельном массиву
  3. Таймер имеет метод действия (addCells), который добавляет объекты из массива dataSource в изменяемый массив
  4. Изменчивый массив динамически e xpands сам по истечении времени (указанного в таймере) и используется для заполнения коллекции.

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!) 

    } 
} 
} 

Этот ответ был ранее ответил г rdelmar на языке Objective-C здесь: Loading UICollectionViewCell one at a time.

+0

1. Не следует ли объявлять 'counter' вне' addCells' функции? В противном случае каждый раз, когда 'addCells' называется' counter', снова равен нулю. – Elena

+0

Хорошо, я вижу. Код работает только потому, что вы на самом деле не пользователь 'counter'. Если вы его используете, вам не нужно 'mutableArray' вообще. – Elena

+0

Я внесла некоторые изменения в ваш код (* см. Обновление моего ответа), чтобы сделать его более понятным. – Elena

Смежные вопросы