Reputation: 556
I created UICollection View without use Storyboard. I 'll share the my codes and the screenshots in the below. I want to help about the how can I properly arrange my UICollection View Cell with constraint and anchor. Thank you for the helping me for the solving my problem.
Here is my code in 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()
}
}
}
and here is the collection view cell file;
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")
}
}
and lastly I got result on simulator in the below
As you can see my collection view cell not properly set I want them in perfect square and the space for the middle of the cell should be reduced too. Thanks for help again.
Upvotes: 0
Views: 834
Reputation: 4632
Since you have used storyboard, first thing you would want to do is to use a 1:1 ratio constraint on the cell. This will ensure that the cell is always perfectly square.
Secondly, to reduce the padding between cells, you can do something like this in view did load:
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
Upvotes: 1