UICellView cell layout in swift

前端 未结 4 423
野趣味
野趣味 2020-12-04 03:21

I am trying to use a UICollectionView to create a grid which a user can set to be x cells by y cells (entered in text boxes), while still occupying the same width on the scr

相关标签:
4条回答
  • 2020-12-04 03:28

    Simple, add an extension of your view controller that implements the UICollectionViewDelegateFlowLayout protocol:

    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 represents here the spacing you want to place between your cells.

    0 讨论(0)
  • 2020-12-04 03:29

    Here is code to add to your collectionView. The properties cellsAcross, cellsDown, horizGap, and vertGap are the values you can set in your app. The horizGap and vertGap are set in the methods minimumInteritemSpacingForSectionAtIndex and minimumLineSpacingForSectionAtIndex. sizeForItemAtIndexPath will compute the necessary dimensions of your cell to make it work.

    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)
    }
    

    For this demo, I added the following code:

    @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()
    }
    
    0 讨论(0)
  • 2020-12-04 03:41

    Try this code:

    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="stackoverflow_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" width="600" height="600"/>
                        <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" width="600" height="580"/>
                                <collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="ILL-QA-nex">
                                    <size key="itemSize" width="50" height="50"/>
                                    <size key="headerReferenceSize" width="0.0" height="0.0"/>
                                    <size key="footerReferenceSize" width="0.0" height="0.0"/>
                                    <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" width="50" height="50"/>
                                        <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" width="50" height="50"/>
                                            <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>
    

    results on different iPhones

    0 讨论(0)
  • 2020-12-04 03:50

    Swift 4.2 version for the answer provided by @vacawama:

    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)
    }
    
    0 讨论(0)
提交回复
热议问题