Как установить динамическую высоту UIImage в UICollectionView Like Pinterest в Swift - PullRequest
0 голосов
/ 20 ноября 2018

Я пытаюсь сделать макет, как Pinterest использует для своей галереи изображений, но проблема в том, что я возвращаю высоту изображения для размера ячеек, и когда изображения имеют разную высоту, они оставляют пробелы в ячейках.Я просмотрел много статей, но я не нашел простого решения.Есть ли простой способ сделать это?Спасибо за ваше время и помощь!

Пожалуйста, смотрите это изображение

class ViewController: UIViewController {

    @IBOutlet var collectionVIew: UICollectionView!
    var imgData = [#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8"),#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8"),#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8"),#imageLiteral(resourceName: "p1"),#imageLiteral(resourceName: "p2"),#imageLiteral(resourceName: "p3"),#imageLiteral(resourceName: "p4"),#imageLiteral(resourceName: "p5"),#imageLiteral(resourceName: "p6"),#imageLiteral(resourceName: "p7"),#imageLiteral(resourceName: "p8")]

    override func viewDidLoad() {
        super.viewDidLoad()

    }


}

extension ViewController: UICollectionViewDelegateFlowLayout{
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
                let width = collectionView.frame.size.width
    let img = imgData[indexPath.item]
   // 335 is the width of my cell image
    return CGSize(width: width/2-15, height: (img.size.height / 335) * width)
    }

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

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

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource{

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
        cell.imgView.image = imgData[indexPath.row];
        cell.imgView.contentMode = .scaleAspectFit
        return cell
    }
}

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

То, что вы упомянули, может быть достигнуто с помощью макета потока - класса макетов, предоставляемого UIKit.

Это то, что вы ищете:

https://www.raywenderlich.com/392-uicollectionview-custom-layout-tutorial-pinterest

Надеюсь, вы сможете приложить некоторые усилия для прочтения этого очень простого поста и внимательно следить за каждым шагом.

0 голосов
/ 20 ноября 2018

Вы пытаетесь вписать неквадратные изображения в квадратное отверстие.Когда мы делаем это, что-то должно дать.В этом случае я бы порекомендовал вам сделать каждую из ваших ячеек фиксированной высотой и установить для них режим содержания заливки, чтобы они полностью заполняли рамку ячейки.Недостатком является то, что некоторые из больших изображений будут обрезаны.Другой вариант заключается в использовании режима содержимого подгонки аспекта, который масштабирует изображение, чтобы подогнать его без потери части изображения.Это снова оставило бы интервал между ячейками.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let width = collectionView.frame.size.width
    return CGSize(width: width/2-15, height: 100) // fixed height
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
    cell.imgView.image = imgData[indexPath.row];
    cell.imgView.contentMode = .scaleAspectFill // Set the scale mode to aspect fill
    return cell
}

Кроме того, вы можете воспользоваться некоторыми библиотеками с открытым исходным кодом, которые могут реализовать это для вас.Это выглядит многообещающе https://github.com/abdullahselek/ASCollectionView

Вы можете просмотреть большой список библиотек с открытым исходным кодом представления коллекции здесь https://github.com/vsouza/awesome-ios#collection-view

Если вы хотите, чтобы ячейки имели разную высоту, вам нужно вычислить правильнуювысота основана на соотношении сторон изображения и ширине, которая зафиксирована.Вы вычисляете соотношение сторон в этом случае по высоте / ширине, когда наша ширина фиксирована, а наша высота является динамической.Затем умножьте это на ширину ячейки изображения, чтобы получить динамическую высоту ячейки.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let width = collectionView.frame.size.width / 2 - 15;
    let img = imgData[indexPath.item]
    return CGSize(width: width, height: (img.size.height / img.size.width) * width)
}

В этом случае вы должны установить режим контента для подгонки аспекта.

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
    cell.imgView.image = imgData[indexPath.row];
    cell.imgView.contentMode = .scaleAspectFit // Set the scale mode to aspect fit
    return cell
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...