Используйте этот метод, чтобы установить пользовательскую ширину высоты ячейки.
Обязательно добавьте эти протоколы
UICollectionViewDelegate
UICollectionViewDataSource
UICollectionViewDelegateFlowLayout
Если вы используете быстрые 5 или Xcode 11 , а затем вам нужно установить Estimate Size
для none
использования раскадровки для того , чтобы заставить его работать правильно. Если вы не установите это значение, приведенный ниже код не будет работать должным образом.
Swift 4 или новее
extension YourViewController: UICollectionViewDelegate {
}
extension YourViewController: UICollectionViewDataSource {
}
extension YourViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: screenWidth, height: screenWidth)
}
}
Цель-C
@interface YourViewController : UIViewController<UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(CGRectGetWidth(collectionView.frame), (CGRectGetHeight(collectionView.frame)));
}
Обязательно добавьте протокол
UICollectionViewDelegateFlowLayout
вclass
декларациюclass MyCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout { //MARK: - UICollectionViewDelegateFlowLayout func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: 100.0, height: 100.0) } }
источник
Если вы используете раскадровку и переопределяете UICollectionViewDelegateFlowLayout, тогда в Swift 5 и Xcode 11 также установите для размера оценки значение None
источник
UICollectionViewFlowLayout
кажется, по умолчанию ,estimatedItemSize
чтобыUICollectionViewFlowLayout.automaticSize
при использовании IB , хотя документация говорит она должна по умолчаниюCGSizeZero
. Как заявляет Apple,automaticSize
«позволяет изменять размер ячеек для представления вашей коллекции». Вот почему другие изменения размера в IB ничего не делают.Наконец-то получил ответ. Вы должны расширить
UICollectionViewDelegateFlowLayout
Это должно работать с ответами выше.
источник
У вас есть 2 способа изменить размер CollectionView.
Первый способ -> добавить этот протокол UICollectionViewDelegateFlowLayout
для В моем случае я хочу разделить ячейку на 3 части в одной строке. Я сделал этот код ниже
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource ,UICollectionViewDelegateFlowLayout{ func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { // In this function is the code you must implement to your code project if you want to change size of Collection view let width = (view.frame.width-20)/3 return CGSize(width: width, height: width) } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return collectionData.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) if let label = cell.viewWithTag(100) as? UILabel { label.text = collectionData[indexPath.row] } return cell } }
Второй способ -> вам не нужно добавлять UICollectionViewDelegateFlowLayout, но вместо этого вам нужно написать код в функции viewDidload как код ниже
class ViewController: UIViewController { @IBOutlet weak var collectionView1: UICollectionView! var collectionData = ["1.", "2.", "3.", "4.", "5.", "6.", "7.", "8.", "9.", "10.", "11.", "12."] override func viewDidLoad() { super.viewDidLoad() let width = (view.frame.width-20)/3 let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout layout.itemSize = CGSize(width: width, height: width) } }
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return collectionData.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) if let label = cell.viewWithTag(100) as? UILabel { label.text = collectionData[indexPath.row] } return cell } }
Независимо от того, что вы пишете код первым или вторым способом, вы получите тот же результат, что и выше. Я это написал. Это сработало для меня
источник
Соотношение размеров в зависимости от размера iPhone:
Вот что вы можете сделать, чтобы иметь разную ширину и высоту для ячеек в зависимости от размера iPhone:
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { let width = (self.view.frame.size.width - 12 * 3) / 3 //some width let height = width * 1.5 //ratio return CGSize(width: width, height: height) }
И, возможно, вам также следует отключить ограничения AutoLayout для ячейки, чтобы этот ответ работал.
источник
В представлении коллекции есть объект макета . В вашем случае это, вероятно, макет потока ( UICollectionViewFlowLayout ). Задайте
itemSize
свойство макета потока .источник
в Swift3 и Swift4 вы можете изменить размер ячейки, добавив UICollectionViewDelegateFlowLayout и реализовав его следующим образом:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: 100, height: 100) }
или если программно создать UICollectionView, вы можете сделать это так:
let layout = UICollectionViewFlowLayout() layout.scrollDirection = .horizontal //this is for direction layout.minimumInteritemSpacing = 0 // this is for spacing between cells layout.itemSize = CGSize(width: view.frame.width, height: view.frame.height) //this is for cell size let collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout)
источник
swift4 swift 4 ios collection view collectionview пример последний рабочий образец кода xcode
Добавьте это в раздел "Делегат" вверху
UICollectionViewDelegateFlowLayout
и используйте эту функцию
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let width = (self.view.frame.size.width - 20) / 3 //some width let height = width * 1.5 //ratio return CGSize(width: width, height: height) }
///// пример полного кода
создать в представлении коллекции и ячейке представления коллекции в раскадровке дать ссылку на коллекцию как
@IBOutlet weak var cvContent: UICollectionView!
вставьте это в контроллер просмотра
import UIKit class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { var arrVeg = [String]() var arrFruits = [String]() var arrCurrent = [String]() @IBOutlet weak var cvContent: UICollectionView! override func viewDidLoad() { super.viewDidLoad() arrVeg = ["Carrot","Potato", "Tomato","Carrot","Potato", "Tomato","Carrot","Potato", "Tomato","Carrot","Potato", "Tomato"] arrVeg = ["Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange"] arrCurrent = arrVeg } //MARK: - CollectionView func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let width = (self.view.frame.size.width - 20) / 3 //some width let height = width * 1.5 //ratio return CGSize(width: width, height: height) } func numberOfSections(in collectionView: UICollectionView) -> Int { return 1 } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return arrCurrent.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! ContentCollectionViewCell cell.backgroundColor = UIColor.green return cell } }
источник
Попробуйте метод ниже
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { return CGSize(width: 100.0, height: 100.0) }
источник
Swift 5 программно
lazy var collectionView: UICollectionView = { let layout = UICollectionViewFlowLayout() layout.scrollDirection = .horizontal //Provide Width and Height According to your need let cellWidth = UIScreen.main.bounds.width / 10 let cellHeight = UIScreen.main.bounds.height / 10 layout.itemSize = CGSize(width: cellWidth, height: cellHeight) //You can also provide estimated Height and Width layout.estimatedItemSize = CGSize(width: cellWidth, height: cellHeight) //For Setting the Spacing between cells layout.minimumInteritemSpacing = 0 layout.minimumLineSpacing = 0 return UICollectionView(frame: self.view.frame, collectionViewLayout: layout) }()
источник
**Swift 5** To make this work you have to do the following. Add these protocols - UICollectionViewDelegate - UICollectionViewDataSource - UICollectionViewDelegateFlowLayout Your code will then look like this extension YourViewController: UICollectionViewDelegate { //Write Delegate Code Here } extension YourViewController: UICollectionViewDataSource { //Write DataSource Code Here } extension YourViewController: UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: screenWidth, height: screenWidth) } } Now the final and crucial step to see this take effect is to go to your viedDidLoad function inside your Viewcontroller. override func viewDidLoad() { super.viewDidLoad() collection.dataSource = self // Add this collection.delegate = self // Add this // Do any additional setup after loading the view. } Without telling your view which class the delegate is it won't work.
источник
# Абсолютно простой способ:
class YourCollection: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
# Вы должны добавить "UICollectionViewDelegateFlowLayout", иначе автозаполнение отсутствует:
class YourCollection: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
# Введите "sizeForItemAt ...". Готово!
class YourCollection: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: 37, height: 63) }
Вот и все.
Например, если вы хотите, чтобы «каждая ячейка заполняла всю коллекцию»:
guard let b = view.superview?.bounds else { .. } return CGSize(width: b.width, height: b.height)
источник
Другой способ - установить значение непосредственно в макете потока.
let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout layout.itemSize = CGSize(width: size, height: size)
источник
Таким образом, вам нужно установить из раскадровки для атрибута для collectionView в разделе оценки размера ячейки значение none, а в вашем ViewController вам нужен метод делегата для реализации этого метода:
optional func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
источник
Попробуйте использовать метод UICollectionViewDelegateFlowLayout. В Xcode 11 или более поздних версиях вам необходимо установить для параметра Estimate Size значение none из раскадровки.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let padding: CGFloat = 170 let collectionViewSize = advertCollectionView.frame.size.width - padding return CGSize(width: collectionViewSize/2, height: collectionViewSize/2) }
источник
Простой способ:
Если вам нужен простой фиксированный размер :
class SizedCollectionView: UIICollectionView { override func common() { super.common() let l = UICollectionViewFlowLayout() l.itemSize = CGSize(width: 42, height: 42) collectionViewLayout = l } }
Это все, что нужно сделать.
В раскадровке просто измените класс с UICollectionView на SizedCollectionView.
Но !!!
Обратите внимание на базовый класс «UI 'I' CollectionView». «I» для инициализатора.
Не так-то просто добавить инициализатор в представление коллекции. Вот общий подход:
Просмотр коллекции ... с инициализатором:
import UIKit class UIICollectionView: UICollectionView { private var commoned: Bool = false override func didMoveToWindow() { super.didMoveToWindow() if window != nil && !commoned { commoned = true common() } } internal func common() { } }
В большинстве проектов вам понадобится «представление коллекции с инициализатором». Так что вы, вероятно, все равно будете иметь
UIICollectionView
(обратите внимание на дополнительный I для Initializer!) В вашем проекте.источник
Swift 5, программная настройка UICollectionView Ширина и высота ячейки
// MARK: MyViewController final class MyViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { private lazy var collectionViewLayout: UICollectionViewFlowLayout = { let layout = UICollectionViewFlowLayout() let spacing: CGFloat = 1 let numOfColumns: CGFloat = 3 let itemSize: CGFloat = (UIScreen.main.bounds.width - (numOfColumns - spacing) - 2) / 3 layout.itemSize = CGSize(width: itemSize, height: itemSize) layout.minimumInteritemSpacing = spacing layout.minimumLineSpacing = spacing layout.sectionInset = UIEdgeInsets(top: spacing, left: spacing, bottom: spacing, right: spacing) return layout }() private lazy var collectionView: UICollectionView = { let collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: collectionViewLayout) collectionView.backgroundColor = .white collectionView.dataSource = self collectionView.delegate = self collectionView.translatesAutoresizingMaskIntoConstraints = false return collectionView }() override func viewDidLoad() { super.viewDidLoad() configureCollectionView() } private func configureCollectionView() { view.addSubview(collectionView) NSLayoutConstraint.activate([ collectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), collectionView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), collectionView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), collectionView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor) ]) collectionView.register(PhotoCell.self, forCellWithReuseIdentifier: "PhotoCell") } // MARK: UICollectionViewDataSource func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 20 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoCell", for: indexPath) as! PhotoCell cell.backgroundColor = .red return cell } } // MARK: PhotoCell final class PhotoCell: UICollectionViewCell { lazy var imageView: UIImageView = { let imageView = UIImageView() imageView.contentMode = .scaleAspectFill imageView.translatesAutoresizingMaskIntoConstraints = false imageView.layer.masksToBounds = true return imageView }() override init(frame: CGRect) { super.init(frame: frame) setupViews() } required init?(coder aDecoder: NSCoder) { fatalError("init?(coder:) not implemented") } func setupViews() { addSubview(imageView) NSLayoutConstraint.activate([ topAnchor.constraint(equalTo: topAnchor), bottomAnchor.constraint(equalTo: bottomAnchor), leadingAnchor.constraint(equalTo: leadingAnchor), trailingAnchor.constraint(equalTo: trailingAnchor) ]) } }
источник
Если, как я, вы должны держать свой пользовательский шаблон Флоу
itemSize
динамически обновляется на основе ширины вашего представления коллекции, вы должны переопределитьUICollectionViewFlowLayout
«sprepare()
метод. Вот видео WWDC, демонстрирующее эту технику .class MyLayout: UICollectionViewFlowLayout { override func prepare() { super.prepare() guard let collectionView = collectionView else { return } itemSize = CGSize(width: ..., height: ...) } }
источник
Это моя версия, найдите подходящее соотношение, чтобы получить размер ячейки в соответствии с вашими требованиями.
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { return CGSizeMake(CGRectGetWidth(collectionView.frame)/4, CGRectGetHeight(collectionView.frame)/4); }
источник