import UIKit
class My_CustomTableViewCell: UITableViewCell {
#IBOutlet weak var collectionView: UICollectionView!
#IBOutlet weak var collectionViewHeight: NSLayoutConstraint!
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var numberLabel: UILabel!
#IBOutlet weak var imageV: UIImageView!
let collectionArray = generateRandomData()
var index = 0
override func awakeFromNib()
{
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool)
{
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func getCellSize(_ targetSize: CGSize) -> CGSize
{
return CGSize(width: 44, height: 44)
}
override func prepareForReuse()
{
self.collectionView.contentOffset = .zero
}
override func systemLayoutSizeFitting(_ targetSize: CGSize) -> CGSize
{
// let frame = self.collectionView.frame
// self.collectionView.layoutIfNeeded()
//
// let height: CGFloat = self.collectionView.collectionViewLayout.collectionViewContentSize.height
// self.collectionViewHeight.constant = height
// self.collectionView.frame = CGRect(x: frame.minX, y: frame.minY, width: frame.width, height: height)
// return self.collectionView.collectionViewLayout.collectionViewContentSize
self.collectionViewHeight.constant = collectionView.collectionViewLayout.collectionViewContentSize.height
return self.contentView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
}
override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize
{
self.collectionView.layoutIfNeeded()
self.collectionViewHeight.constant = collectionView.collectionViewLayout.collectionViewContentSize.height
return self.contentView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
}
}
extension My_CustomTableViewCell: UICollectionViewDelegate, UICollectionViewDataSource
{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
let number = Int(self.numberLabel.text!)! + 10
return number
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollVCell", for: indexPath) as! My_CustomCollectionViewCell
// let number = Int(self.numberLabel.text!)!
cell.numberlabel.text = "\(indexPath.row)"
return cell
}
}
extension My_CustomTableViewCell: UICollectionViewDelegateFlowLayout
{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
return CGSize(width: 44, height: 44)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat
{
return 8.0
}
}
import UIKit
class My_CustomViewController: UIViewController
{
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Enable automatic row auto layout calculations
self.tableView.rowHeight = UITableView.automaticDimension
// Set the estimatedRowHeight to a non-0 value to enable auto layout.
self.tableView.estimatedRowHeight = 44
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
extension My_CustomViewController: UITableViewDelegate, UITableViewDataSource
{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return 66
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "TbVCell", for: indexPath) as! My_CustomTableViewCell
cell.collectionView.tag = indexPath.row
cell.nameLabel.text = "\(indexPath.row)"
cell.numberLabel.text = "\(indexPath.row)"
cell.index = indexPath.row
print("cellForRowAt-----------\(indexPath.row)")
return cell
}
}
storyboard settings
here I am not able to get the required number of collection cells as expected by the numberOfItemsInSection function which is increasing with the tableviewcell number like 64 collectionview items for 64rth tableviewcell.
What I need to do to get exact matching of number of items with tableviewcell.
with none of the above variables I am able to keep track of the count to match.
Regards
Related
How to make UICollectionView dynamic height? The height of the UICollectionView should depend on the number of cells in it.
class ProduitViewController: UIViewController {
var productCollectionViewManager: ProductCollectionViewManager?
var sizeCollectionViewManager: SizeCollectionViewManager?
var product: ProductModel?
var selectedSize: String?
#IBOutlet weak var productCollectionView: UICollectionView!
#IBOutlet weak var sizeCollectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
}
private extension ProduitViewController {
func setup() {
guard let product = product else { return }
colorNameLabel.text = product.color[0].name
sizeCollectionViewManager = SizeCollectionViewManager.init()
sizeCollectionView.delegate = sizeCollectionViewManager
sizeCollectionView.dataSource = sizeCollectionViewManager
sizeCollectionViewManager?.set(product: product)
sizeCollectionViewManager?.didSelect = { selectedSize in
self.selectedSize = selectedSize
}
sizeCollectionView.reloadData()
}
}
Collection View Manager
import UIKit
final class SizeCollectionViewManager: NSObject, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
var sizeProduct: [SizeModel] = []
var didSelect: ((String) -> Void)?
func set(product: ProductModel) {
sizeProduct = product.size
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return sizeProduct.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SizeCell", for: indexPath) as? SizeCollectionViewCell {
cell.configureCell(cellModel: sizeProduct[indexPath.row])
return cell
}
return UICollectionViewCell.init()
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.frame.width / 3 + 20
let height: CGFloat = 35
return CGSize(width: width, height: height)
}
}
The height is now 35. If it is not set static, then the collection view will disappear altogether from the screen.
Screenshot Storyboard
You should set a height constraint on the UICollectionView reference. Once the constraint is set, you can calculate and set the constraint value based on number of objects, since you know how many rows it should display.
I want to have this progression view (pod) inside each collectionviewcell. When I run the app, the progression is 0%, it should animate to 100% for testing, but it stays at 0%. Only when I swipe up and down (refresh the cells???) it starts animating to 100%. This is my code:
import UIKit
import MKRingProgressView
class myCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var ringView: UIView!
let ringsize = 150
var ringProgressView = RingProgressView()
override func layoutSubviews() {
ringProgressView = RingProgressView(frame: CGRect(x: 0, y: 0, width: ringsize, height: ringsize))
ringProgressView.startColor = .red
ringProgressView.endColor = .magenta
ringProgressView.ringWidth = CGFloat(ringsize) * 0.15
ringProgressView.progress = 0.0
ringProgressView.shadowOpacity = 0.5
ringView.addSubview(ringProgressView)
}
}
extension myCollectionViewCell{
func setProgress(progress: Double){
UIView.animate(withDuration: 0.5){
self.ringProgressView.progress = progress
}
}
}
import UIKit
private let reuseIdentifier = "Cell"
class myCollectionViewController: UICollectionViewController {
#IBOutlet var myCollectionView: UICollectionView!
var cellColor = true
override func viewDidLoad() {
super.viewDidLoad()
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of items
return 7
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! myCollectionViewCell
cell.setProgress(progress: 1.0)
return cell
}
}
Can someone help me? Thanks!!
Call myCollectionView.reloadData() inside viewDidAppear method.
In myscenario, I am using UICollectionView in Storyboard. The didSelectItemAtIndexPath not working. I have added Imageview on UICollectionView and using customcell.
CollectionView CustomCell
class CustomCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var imageView: UIImageView!
override func draw(_ rect: CGRect) {
super.draw(rect)
self.layer.cornerRadius = self.frame.size.width / 2
}
}
My CollectionView Delegates
class ModernViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
#IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
collectionView.allowsSelection = true
}
// MARK: CollectionView Delegate
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.listData
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath as IndexPath) as! CustomCollectionViewCell
let item = self.listData[indexPath.item]
let url = item.profileimage
cell.imageView?.sd_setImage(with: URL(string: url ?? "sample.png"), placeholderImage: UIImage(named: "sample.png"))
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 35.0, height: 35.0)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("You selected cell #\(indexPath.item)!")
//let item = self.listData[indexPath.item]
//print("SELECTED COLLECTION CELL: \(item.firstname ?? "")")
}
}
remove this line from collectionViewCell class
self.layer.cornerRadius = self.frame.size.width
updated code
class CustomCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var imageView: UIImageView!
override func draw(_ rect: CGRect) {
super.draw(rect)
// self.layer.cornerRadius = self.frame.size.width / 2 // remove this line
}
}
I think you need to set cornerRadius of imageView instead of cell.
self.imageView.layer.cornerRadius = self.frame.size.width/ 2
i want to create an exact screen in my ios application with xcode & swift im not able to create it, what shall i used? an collectionView or ScroolView?
import UIKit
class ViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout{
#IBOutlet weak var newCollectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
newCollectionView.delegate = self
newCollectionView.dataSource = self
// Do any additional setup after loading the view, typically from a nib.
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 4
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: view.frame.height)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
}
It is my class. It works completely. Also i added an image of storyboard. Link to my github project : https://github.com/Agisight/scroller.git
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var scroll: UIScrollView!
#IBOutlet var btns: [UIView]!
override func viewDidLoad() {
super.viewDidLoad()
scroll.delegate = self
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
methodAnimation()
}
func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
methodAnimation()
}
func methodAnimation() {
if btns.count == 0 {return}
var i = 0
// i – calculate it, it is your visible/desirable view.
// here is variant of code
let dragOffset = view.frame.width * 0.5 // callibrate it for you
let offX = scroll.contentOffset.x
i = Int(offX + dragOffset) / Int(view.frame.width)
i = max(0, min(i, btns.count - 1))
let yourX = btns[i].frame.width * CGFloat(i) // ()
let p = CGPoint(x: yourX, y: 0);
scroll.setContentOffset(p, animated: true)
}
}
enter image description here import UIKit
import FirebaseAuth
class SideMenuController: UIViewController, UICollectionViewDelegate,UICollectionViewDataSource, UITableViewDataSource, UITableViewDelegate,UICollectionViewDelegateFlowLayout
{
var users = [User]()
var newmessage: NewMessageController?
struct userobject {
var username:String
var profilepicture:UIImage
}
var userArray: [userobject] = []
#IBOutlet weak var sidecollectionview: UICollectionView!
#IBOutlet weak var tableView: UITableView!
struct PreviewDetail {
let title: String
let preferredHeight: Double
}
let sampleData:[String] = [
"Trending Events","International Islamic University,Islamabad","Shaheed Zulfikar Ali Bhutto Institute of Science and Technology,Islamabad","Institute of Space Technology, Islamabad","Bahria University,Islamabad","Chat","CreateEvent","Signout"
]
let sampleData1:[String] = [
"Trending Events","International Islamic University,Islamabad","Shaheed Zulfikar Ali Bhutto Institute of Science and Technology,Islamabad","Institute of Space Technology, Islamabad","Bahria University Islamabad"
]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
sidecollectionview.delegate = self
sidecollectionview.dataSource = self
userArray.append(userobject(username: "Farasat Niazi",profilepicture: #imageLiteral(resourceName: "images-8") ))
tableView.dataSource = self
tableView.delegate = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
// Do any additional setup after loading the view.
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return userArray.count
}
override func viewWillAppear(_ animated: Bool) {
animateTable()
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
return CGSize(width: UIScreen.main.bounds.size.width, height: 10.0)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
print("executing cell")
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "usercell" , for: indexPath)as! SideMenuCollectionViewCell
cell.username.text = userArray[indexPath.item].username
cell.imageview.image = userArray[indexPath.item].profilepicture
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of items in the sample data structure.
var count:Int?
if tableView == self.tableView {
if Auth.auth().currentUser != nil {
count = sampleData.count
}
else {
count = sampleData1.count
}
}
return count!
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell:UITableViewCell?
if tableView == self.tableView {
cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath as IndexPath)
cell!.textLabel!.text = sampleData[indexPath.row]
}
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("did select: \(indexPath.row) ")
}
func animateTable() {
tableView.reloadData()
let cells = tableView.visibleCells; let tableHeight: CGFloat = tableView.bounds.size.height
for i in cells {
let cell: UITableViewCell = i as UITableViewCell
cell.transform = CGAffineTransform(translationX: 0, y: tableHeight)
}
var index = 0
for a in cells {
let cell: UITableViewCell = a as UITableViewCell
UIView.animate(withDuration: 1.5, delay: 0.05 * Double(index), usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: UIViewAnimationOptions(rawValue: UInt(0)) , animations: {
cell.transform = CGAffineTransform(translationX: 0, y: 0);
}, completion: nil)
index += 1
}
}
import UIKit
class SideMenuCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var signbutton: UIButton!
#IBOutlet weak var username: UILabel!
#IBOutlet weak var imageview: UIImageView!
}
import UIKit
class SideMenuLayoutCollectionView: UICollectionViewLayout {
}
hey guys my collection view only showing its background and not displaying cell contents.
Things i have checked:
Data source and delegate is assigned to Collection view.
Collection view cell identifier is "usercell"
collection view cell class is attached in identity inspector.
Implement size for item method
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
// your code here
}
in viewDidLoad
collectionView.registerClass(SideMenuCollectionViewCell.self, forCellWithReuseIdentifier: "usercell")
If you have configured the cell in a storyboard or an xib, then remove the following line,
collectionView.registerClass(SideMenuCollectionViewCell.self, forCellWithReuseIdentifier: "usercell")
It worked for me.