如何使用按钮创建自定义集合视图?
Posted
技术标签:
【中文标题】如何使用按钮创建自定义集合视图?【英文标题】:How to create custom collection views with buttons? 【发布时间】:2017-06-19 23:42:31 【问题描述】:我想创建一个集合视图,其中每个集合单元格都是可自定义的,并且每个单元格都有一个描述和一个按钮,每个单元格都应该指向另一个视图控制器,就像这样。
【问题讨论】:
那么是什么阻止您创建自定义单元格?到目前为止,您尝试过什么? 我只能用图像创建一个集合视图,但我真的不知道如何将它们转换为自定义按钮单元格 您是否尝试过将按钮拖入情节提要中的自定义单元格? 是的,但是当我在模拟器上运行应用程序时,单元格会随着文本、按钮和其中的图像一起消失,我也无法做到,所以情节提要中有多个单元格那些不容易看到的,可以水平滚动,就像上面的图片一样 UICollectionViewCells 可以通过实现 UICollectionViewDelegate 方法 didSelectItemAt: 表现得像按钮一样 【参考方案1】:详情
xCode 8.3.2,斯威夫特 3.1
完整样本
CollectionViewCell
import UIKit
protocol CollectionViewCellDelegate: class
func touchUpInside(delegatedFrom cell: CollectionViewCell)
class CollectionViewCell: UICollectionViewCell
@IBOutlet weak var button: UIButton!
weak var delegate: CollectionViewCellDelegate?
@IBAction func touchUpInside(_ sender: UIButton)
delegate?.touchUpInside(delegatedFrom: self)
视图控制器
import UIKit
class ViewController: UIViewController
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet weak var collectionViewFlowLayout: UICollectionViewFlowLayout!
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 viewWillLayoutSubviews()
super.viewWillLayoutSubviews()
let inset:CGFloat = 20.0
collectionViewFlowLayout.itemSize = collectionView.frame.size
collectionViewFlowLayout.itemSize.width -= inset*2
collectionViewFlowLayout.itemSize.height -= inset*2
collectionViewFlowLayout.sectionInset.left = inset
collectionViewFlowLayout.sectionInset.right = inset
extension ViewController: UICollectionViewDataSource
func numberOfSections(in collectionView: UICollectionView) -> Int
return 1
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return 10
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell
cell.delegate = self
return cell
extension ViewController: UICollectionViewDelegate
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
print("Selected cell: \(indexPath)")
extension ViewController: CollectionViewCellDelegate
func touchUpInside(delegatedFrom cell: CollectionViewCell)
if let indexPath = collectionView.indexPath(for: cell)
print("Button pressed in cell: \(indexPath)")
Main.storyboard
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12120" systemVersion="16F73" targetRuntime="ios.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="***_44641545" 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" showsVerticalScrollIndicator="NO" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="H99-jD-EE5">
<rect key="frame" x="0.0" y="20" />
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="10" minimumInteritemSpacing="10" id="47T-Wc-WqB">
<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="CollectionViewCell" id="X5i-B5-0He" customClass="CollectionViewCell" customModule="***_44641545" customModuleProvider="target">
<rect key="frame" x="0.0" y="18.5" />
<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"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ng9-IJ-srl">
<rect key="frame" x="152.5" y="560" />
<state key="normal" title="Button">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="touchUpInside:" destination="X5i-B5-0He" eventType="touchUpInside" id="mNT-vz-F9c"/>
</connections>
</button>
</subviews>
</view>
<color key="backgroundColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<constraints>
<constraint firstAttribute="bottomMargin" secondItem="ng9-IJ-srl" secondAttribute="bottom" constant="12" id="AGX-Ye-rNr"/>
<constraint firstItem="ng9-IJ-srl" firstAttribute="centerX" secondItem="X5i-B5-0He" secondAttribute="centerX" id="sFI-KT-pyQ"/>
</constraints>
<connections>
<outlet property="button" destination="ng9-IJ-srl" id="mnC-Ln-j2F"/>
</connections>
</collectionViewCell>
</cells>
</collectionView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="H99-jD-EE5" firstAttribute="bottom" secondItem="wfy-db-euE" secondAttribute="top" id="0hj-ig-J9f"/>
<constraint firstItem="H99-jD-EE5" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="NWe-0c-k9w"/>
<constraint firstItem="H99-jD-EE5" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" id="axO-mx-zBv"/>
<constraint firstAttribute="trailing" secondItem="H99-jD-EE5" secondAttribute="trailing" id="eP4-pi-EX2"/>
</constraints>
</view>
<connections>
<outlet property="collectionView" destination="H99-jD-EE5" id="Cje-QN-sIz"/>
<outlet property="collectionViewFlowLayout" destination="47T-Wc-WqB" id="qBp-S0-pyU"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="132" y="137.18140929535232"/>
</scene>
</scenes>
</document>
结果
【讨论】:
【参考方案2】:对于可能在我之后阅读此内容的任何人,我找到了一种方法来使用 Vasily Bodnarchuk 提供的其他答案来创建按钮。
按照他所做的一切,除了 Main.storyboard 代码(我太困惑了,无法弄清楚如何实现它)我只是进入了我的 ViewController 并向 UIViewControllerCell 添加了一个按钮。
之后,我创建了一个从我的 UICollectionView 到下一个 ViewController 的 Segway 并给它一个标识符。
我调整了上面提供的代码,并在他的函数中添加了一个“if”语句来打印选定的单元格:
extension ViewController: UICollectionViewDelegate
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
print("Selected cell: \(indexPath)")
if indexPath == [0,0]
self.performSegue(withIdentifier: "toGridView", sender: self)
如果您在控制台中注意到,它会打印每个单元格的值,并且我使用 indexPath 设置为一个值来引用该单元格。在这段代码中,[0,0] 处的按钮(单元格)将在单击时转到下一个 ViewController。
您可以为所有按钮执行此操作!
我会附上屏幕截图,以防我的描述让你感到困惑。
【讨论】:
以上是关于如何使用按钮创建自定义集合视图?的主要内容,如果未能解决你的问题,请参考以下文章