swift中的UICellView单元格布局
Posted
技术标签:
【中文标题】swift中的UICellView单元格布局【英文标题】:UICellView cell layout in swift 【发布时间】:2016-08-17 09:55:17 【问题描述】:我正在尝试使用 UICollectionView 创建一个网格,用户可以将其设置为 x 个单元格乘 y 个单元格(在文本框中输入),同时在屏幕上仍然占据相同的宽度。
我已经能够创建一个包含正确数量的单元格的网格视图,但这些单元格的布局还不是正确的,即输入 5 x 7 将给出 35 个单元格,但不是 5 x 7 单元格布局.这是我目前的代码。
MyCollectionViewCell.swift 导入 UIKit
class MyCollectionViewCell: UICollectionViewCell
@IBOutlet var cellLabel: UILabel!
CreateNewProject.swift
class CreateNewProject : UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UITextFieldDelegate
@IBOutlet var widthTextBox: UITextField!
@IBOutlet var lengthTextBox: UITextField!
@IBOutlet var myCollection: UICollectionView!
let reuseIdentifier = "cell" // also enter this string as the cell identifier in the storyboard
@IBAction func updateView(sender: AnyObject)
let widthValue = Int(widthTextBox.text!)
let lengthValue = Int(lengthTextBox.text!)
multiplyValue = Int(widthValue! * lengthValue!)
createArray()
func createArray()
var i = 0
while i < multiplyValue
items.append("")
i += 1
myCollection.reloadData()
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
print(self.items.count)
// make a cell for each cell index path
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
// get a reference to storyboard cell
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! MyCollectionViewCell
// Use the outlet in custom class to get a reference to the UILabel in the cell
cell.cellLabel.text = self.items[indexPath.item]
cell.backgroundColor = UIColor.lightGrayColor()
return cell
我已将 UICollectionView 限制在左侧、右侧和顶部,并希望以编程方式将集合视图中的单元格调整为 UICollectionView.width / x(用户选择的单元格宽度)。
不确定执行此操作的最佳方法,并且还需要在各个单元格之间保留一些空白。任何帮助将不胜感激!
【问题讨论】:
【参考方案1】:这是要添加到您的 collectionView 的代码。 cellsAcross
、cellsDown
、horizGap
和 vertGap
属性是您可以在应用程序中设置的值。 horizGap
和 vertGap
在方法 minimumInteritemSpacingForSectionAtIndex
和 minimumLineSpacingForSectionAtIndex
中设置。 sizeForItemAtIndexPath
将计算单元格的必要尺寸以使其正常工作。
var cellsAcross = 5
var cellsDown = 7
var horizGap = 4
var vertGap = 4
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return cellsAcross * cellsDown
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat
return CGFloat(vertGap)
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat
return CGFloat(horizGap)
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
// Compute the dimensions of a cell for a cellsAcross x cellsDown layout.
let dimH = (collectionView.bounds.width - (CGFloat(cellsAcross) - 1) * CGFloat(horizGap)) / CGFloat(cellsAcross)
let dimV = (collectionView.bounds.height - (CGFloat(cellsDown) - 1) * CGFloat(vertGap)) / CGFloat(cellsDown)
return CGSize(width: dimH, height: dimV)
对于这个演示,我添加了以下代码:
@IBAction func threeBy5(sender: UIButton)
cellsAcross = 3
cellsDown = 5
collectionView.reloadData()
@IBAction func fourBy6(sender: UIButton)
cellsAcross = 4
cellsDown = 6
collectionView.reloadData()
@IBAction func fiveBy7(sender: UIButton)
cellsAcross = 5
cellsDown = 7
collectionView.reloadData()
// Handle screen rotation
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)
collectionView.reloadData()
【讨论】:
【参考方案2】:简单,添加实现UICollectionViewDelegateFlowLayout
协议的视图控制器的扩展:
extension ViewController: UICollectionViewDelegateFlowLayout
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
let size = collectionView.frame.size.width / CGFloat(cols) - CGFloat((cols - 1)) * spacingBetweenCells
return CGSize(width: size, height: size)
spacingBetweenCells
在这里表示您希望在单元格之间放置的间距。
【讨论】:
【参考方案3】:试试这个代码:
import UIKit
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate
@IBOutlet var collectionView: UICollectionView!
let rows = 7
let columns = 3
let spaceBetweenRows = 2
let spaceBetweenColumns = 4
var cellHeight: CGFloat
get
return collectionView.frame.height/CGFloat(rows)-CGFloat(spaceBetweenRows)
var cellWidth: CGFloat
get
return collectionView.frame.width/CGFloat(columns)-CGFloat(spaceBetweenColumns)
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
collectionView.dataSource = self
collectionView.delegate = self
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int
return 1
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return rows*columns
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
return collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath)
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat
return CGFloat(spaceBetweenRows)
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat
return CGFloat(spaceBetweenRows)
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
return CGSize(width: cellWidth, height: cellHeight)
Main.storyboard
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="ios.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="***_38993378" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" />
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="StH-xe-9BK">
<rect key="frame" x="0.0" y="20" />
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="ILL-QA-nex">
<size key="itemSize" />
<size key="headerReferenceSize" />
<size key="footerReferenceSize" />
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</collectionViewFlowLayout>
<cells>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="cell" id="NTl-75-34J">
<rect key="frame" x="0.0" y="0.0" />
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" />
<autoresizingMask key="autoresizingMask"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
</collectionViewCell>
</cells>
</collectionView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="StH-xe-9BK" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="RD1-j0-nbz"/>
<constraint firstItem="StH-xe-9BK" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" id="SMe-NI-E7C"/>
<constraint firstItem="StH-xe-9BK" firstAttribute="bottom" secondItem="wfy-db-euE" secondAttribute="top" id="hxb-pd-z2C"/>
<constraint firstAttribute="trailing" secondItem="StH-xe-9BK" secondAttribute="trailing" id="zgF-i5-4fX"/>
</constraints>
</view>
<connections>
<outlet property="collectionView" destination="StH-xe-9BK" id="eU8-eE-LXc"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="706" y="586"/>
</scene>
</scenes>
</document>
不同 iPhone 上的结果
【讨论】:
【参考方案4】:@vacawama 提供的答案的 Swift 4.2 版本:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat
return CGFloat(vertGap)
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat
return CGFloat(horizGap)
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
// Compute the dimensions of a cell for a cellsAcross x cellsDown layout.
let dimH = (collectionView.bounds.width - (CGFloat(cellsAcross) - 1) * CGFloat(horizGap)) / CGFloat(cellsAcross)
let dimV = (collectionView.bounds.height - (CGFloat(cellsDown) - 1) * CGFloat(vertGap)) / CGFloat(cellsDown)
return CGSize(width: dimH, height: dimV)
【讨论】:
以上是关于swift中的UICellView单元格布局的主要内容,如果未能解决你的问题,请参考以下文章
使用图像和文本单元拖放单元格,如 Swift 中的 MyAlbum 应用程序
使用 nib 自定义单元格和自动布局滚动跳转(ios 8 swift - UITableview)
Swift 无法让 UICollectionView 正确布局
在 UITableView 中使用自动布局进行动态单元格布局和可变行高