0
votes

You can download my project files here

Look at my cells.
At First it is very normal. Normal pic But it get into a mess after I scroll down and up like below. Abnormal pic

I don't know why.. and I have wasted my time a few days.
I implemented the method: collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize

Source code: SettingsViewController.swift

import UIKit

class SupplementaryView: UICollectionReusableView {
    var imageView = UIImageView()
    override init(frame: CGRect) {
        super.init(frame: frame)

        self.addSubview(imageView)
        imageView.translatesAutoresizingMaskIntoConstraints = false
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class SettingsCell: UICollectionViewCell {
    var imageView = UIImageView()
    var cellLabel = UILabel()
    var textField = UITextField()

    override init(frame: CGRect) {
        super.init(frame: frame)

        self.contentView.addSubview(cellLabel)
        cellLabel.translatesAutoresizingMaskIntoConstraints = false
        self.contentView.addSubview(textField)
        textField.translatesAutoresizingMaskIntoConstraints = false
        self.contentView.addSubview(imageView)
        imageView.translatesAutoresizingMaskIntoConstraints = false
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class SettingsViewController: UIViewController {

    let uidesign = UIDesign()
    let layout = UICollectionViewFlowLayout()
    var collectionView: UICollectionView!

    let reuseIdentifier = "reuseIdentifier"
    let headerIdentifier = "headerIdentifier"
    let sections = ["image", "image"]
    let cells = ["label", "textField", "image", "label", "textField", "image", "label", "textField", "image", "label", "textField", "image"]

    var collectionViewWidth: CGFloat = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        setupUI()

        collectionView.dataSource = self
        collectionView.delegate = self

    }


    func setupUI() {

        //  Navi Bar
        self.title = "Math Avengers - Settings"
        self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "이전 단계로", style: .Plain, target: self, action: #selector(self.leftBarButtonPressed))
        self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "다음 단계로", style: .Plain, target: self, action: #selector(self.nextButtonPressed))

        layout.scrollDirection = .Vertical
        layout.headerReferenceSize = (UIImage(named: "name")?.size)!
        layout.sectionHeadersPinToVisibleBounds = true
        layout.minimumLineSpacing = 10
        layout.minimumInteritemSpacing = 0
        layout.sectionInset = UIEdgeInsetsZero

        collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
        collectionView.backgroundColor = UIColor.yellowColor()
        collectionView.collectionViewLayout = layout
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(collectionView)
        collectionView.registerClass(SettingsCell.self, forCellWithReuseIdentifier: reuseIdentifier)
        collectionView.registerClass(SupplementaryView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: headerIdentifier)

        collectionViewWidth = collectionView.frame.size.width

        let viewsDictionary = ["collectionView": collectionView]
        self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[collectionView]|",
            options: .AlignAllCenterX, metrics: nil, views: viewsDictionary))
        self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[collectionView]|",
            options: .AlignAllCenterY, metrics: nil, views: viewsDictionary))

    }

    func leftBarButtonPressed() {

    }

    func nextButtonPressed() {

    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

extension SettingsViewController: UITextFieldDelegate {

    func textFieldShouldReturn(textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        self.nextButtonPressed()
        return true
    }
}


extension SettingsViewController: UICollectionViewDataSource {
    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return sections.count
    }

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return cells.count
    }

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! SettingsCell

        switch cells[indexPath.row] {
        case "label":

            //cell.cellLabel.hidden = false
            cell.cellLabel.frame = cell.contentView.frame
            cell.cellLabel.text = "이름을 적어주세요.\(indexPath.row)"
            uidesign.setLabelLayout(cell.cellLabel, fontsize: 40)

            break

        case "textField":

            cell.textField.frame = cell.contentView.frame
            cell.textField.text = "007_\(indexPath.row)"
            uidesign.setTextFieldLayout(cell.textField, fontsize: 40)

            break

        case "image":

            cell.imageView.frame = cell.contentView.frame
            cell.imageView.image = UIImage(named: "next")
            cell.imageView.contentMode = .ScaleAspectFit

            break

        default:
            debugPrint("default")
            break
        }
        return cell
    }

    // 섹션 헤더 설정
    func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
        var headerView: SupplementaryView?
        if (kind == UICollectionElementKindSectionHeader) {
            headerView = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: headerIdentifier, forIndexPath: indexPath) as? SupplementaryView
            let image = indexPath.row % 2 == 0 ? UIImage(named: "name") : UIImage(named: "age")
            headerView?.imageView.image = image
            headerView?.imageView.contentMode = .ScaleAspectFit
            headerView?.imageView.frame = CGRectMake(0, 0, collectionViewWidth, image!.size.height)
            headerView?.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.5)
        }
        return headerView!
    }

    func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
        let cell = cell as! SettingsCell

        switch cells[indexPath.row] {
        case "label":
            cell.backgroundColor = UIColor(red: 0, green: 1, blue: 0, alpha: 0.5)
            cell.cellLabel.hidden = false
            cell.imageView.hidden = true
            cell.textField.hidden = true
            break

        case "textField":
            cell.backgroundColor = UIColor(red: 1, green: 0.5, blue: 0, alpha: 0.5)
            cell.textField.hidden = false
            cell.cellLabel.hidden = true
            cell.imageView.hidden = true
            break

        case "image":
            cell.backgroundColor = UIColor(red: 0, green: 0.5, blue: 1, alpha: 0.5)
            cell.imageView.hidden = false
            cell.cellLabel.hidden = true
            cell.textField.hidden = true
            break

        default:
            break

        }
    }
}

extension SettingsViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

        switch cells[indexPath.row] {
        case "label":
            return CGSizeMake(collectionViewWidth, 200)

        case "image":
            let img = UIImage(named: "next")
            return CGSizeMake(collectionViewWidth, 200) //(img?.size.height)!)

        case "textField":
            return CGSizeMake(collectionViewWidth-200, 100)

        default:
            return CGSizeMake(collectionViewWidth, 200)

        }
    }
}
1
You should debug sizeForItemAtIndexPath. — Also, your idea of configuring these cells subviews without using autolayout might not be a very good idea.matt
you need to use auto layout for your cellsDaniel Galasko
@matt and Daniel Galasko - Both of you are all right. It works good. Thank you!Donghee Seo
@DongheeSeo You should either answer your own question (to help others) or delete the question (if it was trivially solved).matt

1 Answers

0
votes

I solved this problem with AutoLayout like below.
1. I blocked some statements that "//cell.cellLabel.frame = cell.contentView.frame"
2. I added constraints.

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! SettingsCell

    switch cells[indexPath.row] {
    case "label":

        //cell.cellLabel.hidden = false
        //cell.cellLabel.frame = cell.contentView.frame
        cell.cellLabel.text = "이름을 적어주세요.\(indexPath.row)"
        uidesign.setLabelLayout(cell.cellLabel, fontsize: 40)

        let viewsDictionary = ["cellLabel": cell.cellLabel]
        cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[cellLabel]-|", options: .AlignAllCenterX, metrics: nil, views: viewsDictionary))
        cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[cellLabel]-|", options: .AlignAllCenterY, metrics: nil, views: viewsDictionary))

        break

    case "textField":

        //cell.textField.frame = cell.contentView.frame
        cell.textField.text = "007_\(indexPath.row)"
        uidesign.setTextFieldLayout(cell.textField, fontsize: 40)
        cell.textField.delegate = self

        let viewsDictionary = ["textField": cell.textField]
        cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[textField]-|", options: .AlignAllCenterX, metrics: nil, views: viewsDictionary))
        cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[textField]-|", options: .AlignAllCenterY, metrics: nil, views: viewsDictionary))

        break

    case "image":

        //cell.imageView.frame = cell.contentView.frame
        cell.imageView.image = UIImage(named: "next")
        cell.imageView.contentMode = .ScaleAspectFit

        let viewsDictionary = ["imageView": cell.imageView]
        cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[imageView]-|", options: .AlignAllCenterX, metrics: nil, views: viewsDictionary))
        cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[imageView]-|", options: .AlignAllCenterY, metrics: nil, views: viewsDictionary))

        break

    default:
        debugPrint("default")
        break
    }
    return cell
}