我正在尝试实施CollectionView
。
当我使用Autolayout时,我的细胞不会改变大小,而是它们的对齐。
现在我宁愿将他们的尺寸改为例如。
//var size = CGSize(width: self.view.frame.width/10, height: self.view.frame.width/10)
我尝试在我的CellForItemAtIndexPath
collectionCell.size = size
但它没有工作。
有没有办法实现这个目标?
修改:
似乎答案只会改变我的CollectionView宽度和高度本身。约束中是否存在冲突?有什么想法?
答案 0 :(得分:94)
使用此方法设置自定义单元格高度宽度。
确保添加此协议
UICollectionViewDelegate
UICollectionViewDataSource
UICollectionViewDelegateFlowLayout
<强>目标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)));
}
Swift 4或更高版本
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)
}
}
答案 1 :(得分:57)
确保在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)
}
}
答案 2 :(得分:19)
答案 3 :(得分:18)
终于得到了答案。
你应该延长UICollectionViewDelegateFlowLayout
这应该与上面的答案一起使用。
答案 4 :(得分:10)
swift 4.1
您有两种方法可以更改CollectionView的大小
第一种方式 - &gt;添加此协议 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
}
}
第二种方式 - &gt;您不必须添加 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
}
}
无论您编写代码作为第一种方式还是第二种方式,您都将得到与上述相同的结果。我写的。 对我有用
答案 5 :(得分:8)
尺寸比例根据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约束,以使此答案起作用。
答案 6 :(得分:6)
集合视图有一个布局对象。在您的情况下,它可能是流程布局(UICollectionViewFlowLayout)。设置流布局的itemSize
属性。
答案 7 :(得分:4)
在 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)
答案 8 :(得分:3)
swift4 swift 4 ios集合视图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)
}
////// 示例完整代码
在情节提要中的集合视图上创建集合和collectionview单元对集合进行引用为
@IBOutlet弱var cvContent:UICollectionView!
将此内容粘贴到View控制器
import UIKit
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
}
}
答案 9 :(得分:2)
尝试以下方法
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSize(width: 100.0, height: 100.0)
}
答案 10 :(得分:1)
**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.
答案 11 :(得分:1)
#绝对简单的方法:
class YourCollection: UIViewController,
UICollectionViewDelegate,
UICollectionViewDataSource {
#您必须添加“ UICollectionViewDelegateFlowLayout”,否则就不会自动完成:
class YourCollection: UIViewController,
UICollectionViewDelegate,
UICollectionViewDataSource,
UICollectionViewDelegateFlowLayout {
#Type“ 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)
答案 12 :(得分:0)
另一种方法是直接在流程布局中设置值
let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: size, height: size)
答案 13 :(得分:0)
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)
}()
答案 14 :(得分:0)
如果您只需要简单的固定大小:
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
(请注意要为Initializer附加的I!)。
答案 15 :(得分:0)
因此,您需要从情节提要中将单元格区域估计大小中collectionView的属性设置为无,并且在ViewController中,您需要具有用于实现此方法的委托方法:optional func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
答案 16 :(得分:0)
尝试使用UICollectionViewDelegateFlowLayout方法。在Xcode 11或更高版本中,您需要将情节提要中的“估计大小”设置为“无”。
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)
}
答案 17 :(得分:0)
快速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)
])
}
}
答案 18 :(得分:0)
如果像我一样,需要根据集合视图的宽度动态更新自定义流程布局的itemSize
,则应覆盖UICollectionViewFlowLayout
的{{1}}方法。这是WWDC video demoing this technique。
prepare()
答案 19 :(得分:0)
如果您没有使用 UICollectionViewController,则需要通过设置委托 UICollectionViewDelegate、UICollectionViewDataSource、UICollectionViewDelegateFlowLayout 来添加一致性。
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
之后,您必须为添加到 ViewController 的集合视图设置一个委托。
collectionView.delegate = self
collectionView.dataSource = self
最后,您必须向集合视图添加布局:
let collectionLayout = UICollectionViewFlowLayout()
collectionView.collectionViewLayout = collectionLayout
完成这些步骤后,您可以在 func 中更改大小:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
答案 20 :(得分:-3)
这是我的版本,根据您的要求找到合适的比例以获得单元尺寸。
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(CGRectGetWidth(collectionView.frame)/4, CGRectGetHeight(collectionView.frame)/4);
}