如何在Swift中正确设计UICollection View Cell

时间:2017-02-13 16:20:39

标签: ios swift uicollectionview uicollectionviewcell uicollectionviewlayout

我在不使用Storyboard的情况下创建了UICollection View。我将在下面分享我的代码和屏幕截图。我想帮助我如何使用约束和锚点正确安排我的UICollection View Cell。感谢您帮助我解决问题。

这是我在collectionview.swift中的代码;

class ProductViewController : UICollectionViewController, UICollectionViewDelegateFlowLayout {


var product : Product?
var productdetail : [ProductDetail]?
var categories : [NSDictionary] = [NSDictionary]()
var mainurl  = "http://www.example.com"
var idforurl = ""


override func viewDidLoad() {
    idforurl = (product?.id)!
    mainurl = ("\(mainurl)\(idforurl)")
    print(mainurl)
    //self.mainurl += (product?.id)!

    fetchproductDetail()

    collectionView?.backgroundColor = .white
    navigationItem.title = self.product?.name
    self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Close", style: .plain, target: self, action: #selector (handleCloseBook))

    collectionView?.register(ProductDetailCell.self, forCellWithReuseIdentifier: "cellId")
    let layout =  collectionView?.collectionViewLayout as? UICollectionViewFlowLayout
    //layout?.scrollDirection = .vertical
    layout?.minimumLineSpacing = 40
    collectionView?.isPagingEnabled = false





}

func handleCloseBook() {

    dismiss(animated: true, completion: nil)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    return CGSize(width: view.frame.width / 4, height: view.frame.height / 5)

}

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {


    let selectedproduct = self.productdetail?[indexPath.row]
    let productVC = DetailViewController()
    productVC.detailproduct = selectedproduct
    let navController = UINavigationController(rootViewController: productVC)
    present(navController, animated: true, completion: nil)



}


override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let pagecell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! ProductDetailCell

    let products1 = productdetail?[indexPath.item]
    pagecell.product = products1
    return pagecell

}

override func numberOfSections(in collectionView: UICollectionView) -> Int {

    return 1

}

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

    return productdetail?.count ?? 0
}

func fetchproductDetail () {

    if let url = URL(string: mainurl) {
        URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in

            if let err = error {

                print("fetch error",err)

            }

            guard let data = data else{return}

            do {
                self.productdetail = []

                let json = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:AnyObject]

                if let tempData = json["data"] as? [NSDictionary] {
                    for category in tempData {
                        if let tempResult = category["Menu"] as? NSDictionary {
                            self.categories.append(tempResult)
                        }
                    }
                }

                for category in self.categories {

                    let product =  ProductDetail(dictionary: category as! [String : Any])
                    self.productdetail?.append(product)
                    print(product.productname)
                    print(product.productdesc)

                }

                DispatchQueue.main.async {
                    self.collectionView?.reloadData()
                }

            }

            catch let JsonErr {

                print("Failed to Parse json properly", JsonErr)
            }


        }).resume()
    }

}





}

,这是集合视图单元文件;

class ProductDetailCell : UICollectionViewCell {
        var product : ProductDetail? {
            didSet{
                textLbl.text =  product?.productname
                priceLbl.text = product?.productprice

                guard let productImages = product?.productimage else {return}
                let baseUrl = "http://www.example.com"
                guard let url = URL(string: baseUrl) else {return}
                productImage.image = nil

                URLSession.shared.dataTask(with: url) { (data, response, error) in

                    if let err = error {

                        print("Error has been occurred", err)

                    }

                    guard let imagedata = data else{return}
                    let image = UIImage(data: imagedata)

                    DispatchQueue.main.async {

                        self.productImage.image = image
                    }

                    }.resume()

            }
            }

    let textLbl: UILabel = {

        let label = UILabel()
        label.text = "Veri Yok!"
        label.numberOfLines = 0
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = UIFont(name: "Avenir-Light", size: 12)
        label.textAlignment = .center
        label.lineBreakMode = .byWordWrapping
        label.numberOfLines = 1
        label.minimumScaleFactor = 0.1
        label.adjustsFontSizeToFitWidth = true

        return label
    }()

    let priceLbl: UILabel = {

        let label = UILabel()
        label.text = "Veri Yok!"
        label.numberOfLines = 0
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = UIFont(name: "Avenir-Light", size: 12)
        label.textAlignment = .center
        label.lineBreakMode = .byWordWrapping
        label.numberOfLines = 1
        label.adjustsFontSizeToFitWidth = true

        return label
    }()

    let productImage : UIImageView = {

        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.contentMode = .scaleAspectFit
        imageView.clipsToBounds = false
        imageView.image = #imageLiteral(resourceName: "amazon_icon")
        return imageView

    }()


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

        addSubview(productImage)
        productImage.topAnchor.constraint(equalTo: topAnchor, constant: 5).isActive = true
        productImage.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 5).isActive = true
        productImage.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -10).isActive = true
        productImage.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -5).isActive = true
        productImage.widthAnchor.constraint(equalToConstant: frame.size.width / 5).isActive = true



        addSubview(textLbl)
        textLbl.topAnchor.constraint(equalTo: productImage.bottomAnchor, constant: 2).isActive = true
       // textLbl.leftAnchor.constraint(equalTo: self.leftAnchor, constant: -5).isActive = true
        //textLbl.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 5).isActive = true
       // textLbl.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        textLbl.heightAnchor.constraint(equalToConstant: 30).isActive = true
        textLbl.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true


        addSubview(priceLbl)
        priceLbl.topAnchor.constraint(equalTo: textLbl.bottomAnchor, constant: 2).isActive = true
        // textLbl.leftAnchor.constraint(equalTo: self.leftAnchor, constant: -5).isActive = true
        //textLbl.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 5).isActive = true
        //textLbl.heightAnchor.constraint(equalToConstant: 40).isActive = true
        priceLbl.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true

    }

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


     }

}

最后我在下面的模拟器上得到了结果

Simulator Screenshot

正如你可以看到我的集合视图单元格没有正确设置我希望它们在完美的正方形中,并且单元格中间的空间也应该减少。再次感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

由于您使用过故事板,因此您首先要做的是在单元格上使用1:1比率约束。这将确保细胞总是完全正方形。

其次,要减少单元格之间的填充,您可以在视图中执行类似的操作:

let columns:CGFloat = 3
let sW = self.view.frame.width
let padding = sW / 32      // 32 points being the padding space between cells
cellWidth = (sW - (padding*(columns+1))) / columns