I am getting this error in my code it says to "Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger." I am confused as to what it is actually asking here is the code in which I am thinking its asking it to be put in just not sure where?
import UIKit
// MARK: - CUSTOM SOCIAL CELL
class SocialCell:UICollectionViewCell {
/* Views */
#IBOutlet weak var socialIcon: UIImageView!
#IBOutlet weak var socialLabel: UILabel!
}
class SocialList: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
/* Views */
#IBOutlet weak var socialCollView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - COLLECTION VIEW DELEGATES
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return socials.count //socialNames.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("SocialCell", forIndexPath: indexPath) as! SocialCell
cell.socialLabel.text = "\(socials[indexPath.row]["name"]!)"
cell.socialIcon.image = UIImage(named: "\(socials[indexPath.row]["name"]!)")
return cell
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSizeMake(view.frame.size.width/3.8, view.frame.size.width/3.8)
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
selectedSocial = "\(socials[indexPath.row]["link"]!)"
selectedName = "\(socials[indexPath.row]["name"]!)"
selectedColor = socialColors[indexPath.row]
navigationController?.popViewControllerAnimated(true)
}
}
You can systematically solve this by doing this:
Also, you should share your complete error, so that I can lead you to more specific issue. My thinking is that you have some sort of autoLayout issue in your UICollectionView
On the left of your project, click the Break Point navigator
Next click on the plus button on the bottom left and click Add Symbolic BreakPoint
Then you will be shown a popup. Add UICollectionViewFlowLayoutBreakForInvalidSizes in there like so
After this, just hit enter(on keyboard) and click anywhere
Run your code and see where the project stops
You can resolve this issue by setting 'Estimate size = Custom' of collectionView in size inspector.
Related
This question already has answers here:
Outlets cannot be connected to repeating content iOS
(9 answers)
Closed 4 years ago.
I followed the attached guide to creating static UICollectionView but now I would like to add buttons to each cell and change the text on the buttons, for example. I can not do this and get the error "UIButton is invalid. Outlets cannot be connected to repeating content." How can I fix this issue and use IBOutlets with objects in cells without leaving the ViewController?
If I need to leave ViewController please describe the process with a lot of detail as I am a beginner and am not too knowledgeable on the different view classes.
Thank you!!
Instead of the outlet between the button and the view controller, you should create a subclass of UICollectionViewCell, and add your IBOutlets on that class.
class MyCollectionViewCell: UICollectionViewCell {
#IBOutlet var myButton: UIButton!
}
Then, in Interface Builder, set this subclass to be the class of your cells (in the Identity inspector pane).
You should then be able to create the outlet connection from your button to your cell.
I hope this is clear enough. If not, please let me know!
Example code
class MyCollectionViewCell: UICollectionViewCell {
#IBOutlet var myButton: UIButton!
}
class MyViewController: UIViewController, UICollectionViewDataSource {
#IBOutlet var myCollectionView: UICollectionView!
private var isMyButtonEnabled = true
// Other view controller code
func disableMyButton() {
self.isMyButtonEnabled = false
self.myCollectionView.reloadData()
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = ... as! MyCollectionViewCell // Get cell
// Other cell setup
cell.myButton.isEnabled = self.isMyButtonEnabled
return cell
}
}
Define class like following for your collection view:
class MyCollectionCell : UICollectionViewCell {
#IBOutlet weak var likeButton: UIButton?
}
Create xib for collection cell and use above custom class for collection view.
Now in your view controller define collection view and implement following delegates UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout.
class ViewController: UIViewController, UICollectionViewDataSource,
UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
#IBOutlet var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
let nib = UINib(nibName: "MyCollectionViewCell", bundle: nil)
collectionView?.registerNib(nib, forCellWithReuseIdentifier: "myCell")
}
//UICollectionViewDelegateFlowLayout methods
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat
{
return 4;
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat
{
return 1;
}
//UICollectionViewDatasource methods
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int
{
return 1
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 100
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
var cell =
collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as MyCollectionCell
cell.likeButton.setTitle("myTitle", for: .normal)
cell.likeButton.tag = indexPath.row
cell.likeButton.addTarget(self, action: #selector(mainButton:), forControlEvents: .TouchUpInside)
return cell
}
#IBAction func mainButton(sender: UIButton) {
println(sender)
// use button tag to find out which button is clicked.
}
}
In above code important method is func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell where you set tag to your button and then use that tag to find out which button is pressed and use that id to find out data source or action you want to perform.
I have UICollectionView with custom cell (xib file), I manage to display the collectionview but I don't manage to detect when I tap on a cell with the function :
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath){
Usually, I manage to do that, but this time I don't know why it doesn't work. Actually I'm using this pods "https://cocoapods.org/pods/SACollectionViewVerticalScalingFlowLayout"
My code is :
class ProjectsController: UIViewController {
#IBOutlet weak var collectionViewGridFormat: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
collectionViewGridFormat.registerNib(UINib(nibName: "ProjectsGridFormatCell", bundle: nil), forCellWithReuseIdentifier: "cellProjectGrid")
...
}
}
extension ProjectsController: UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 30
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell : ProjectsGridFormatCell = collectionView.dequeueReusableCellWithReuseIdentifier("cellProjectGrid", forIndexPath: indexPath) as! ProjectsGridFormatCell
cell.lblProjectName.text = "Test project"
return cell
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath){
print("aa")
}
}
But when I tap on a cell, "print("aa")" is not displayed.
Have I given enough information ? :)
Thanks for your help !! :D
Regards,
Is "User Interaction Enabled" checked under the Identity Inspector in Storyboard?
I have made a UICollection View. In my ViewController I have the following code:
import UIKit
import AlamofireImage
class MYViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, MYItemCellDelegate {
let viewModel : MYViewModel = StandPlaceViewModel()
#IBOutlet weak var itemCollectionView: UICollectionView!
#IBOutlet weak var ItemCountLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
self.viewModel.getItems(self.viewModel.stand) { items in
self.ItemCountLabel.text = String(self.viewModel.itemCount)
self.itemCollectionView.reloadData()
}
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.viewModel.tableDict.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
print("IN COLLECTION OF ITEMS")
let cell: MYItemCell = collectionView.dequeueReusableCellWithReuseIdentifier("itemCell", forIndexPath: indexPath) as! MYItemCell
cell.itemTitleLabel.text = self.viewModel.tableDict[indexPath.row]![0]
return cell
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
print("Cell \(indexPath.row) selected")
}
...
My Issue is that the UICollection never loads. IN COLLECTION OF ITEMS is never printed. I have a separate page with a collection and it all works just fine and I cant find the difference.
The ItemCountLabel.text is properly set in the viewDidLoad(), but the reloadData() never seems to call the collectionView code.
I would expect IN COLLECTION OF ITEMS to be printed twice.
Add these code into viewDidLoad
self.itemCollectionView.delegate = self;
self.itemCollectionView.dataSource = self;
I have a UICollectionView that I added to my UIViewController in my Storyboard.
It contains a UICollectionViewCell of class BookCell and reusable identifier BookCell.
bookArray gets passed in the prepareForSegue method from the previous ViewController
cellForItemAtIndexPath never gets called. I have attempted to declare BookCollectionVC as delegate and dataSource both in Storyboard and in viewDidLoad, as you can see commented out, but that does not change anything.
I have read multiple SO answers pertaining to cell size, to the number of items in the section, to the multiple ways of declaring delegate and dataSource and have tried/double checked all of them.
Any ideas?
class BookCollectionVC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
#IBOutlet weak var collection: UICollectionView!
var bookArray = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// collection.delegate = self
// collection.dataSource = self
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCellWithReuseIdentifier("BookCell", forIndexPath: indexPath) as? BookCell {
// This never gets called
let bookIsbn = bookArray[indexPath.row]
cell.configureCell(bookIsbn)
return cell
} else {
return UICollectionViewCell()
}
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print(bookArray.count)
return bookArray.count
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
let screenSize: CGRect = UIScreen.mainScreen().bounds
let screenWidth = screenSize.width
let cellWidth = screenWidth / 4
return CGSizeMake(cellWidth,cellWidth)
}
As a test, don't use an if-let. Just get the cell value and print it. What is its type? Have you properly assigned the cells to be the custom class (BookCell) in your StoryBoard?
I want to create a screen layout . A main UICollectionView class scrolling horizontally on the top 1/3 of the screen, followed by a table on the bottom 2/3, but in the table I would like to slide multiple images horizontally, so I thought of putting another collection view in the table cell. I've connected the datasource and delegate for the main collection view to the main view controller and that works. the table view is connected up to the main view controller as well.
Screenshot of IB shows what I want to do, only able to do what is shown on left. Can only implement main collectionview and underneath table.
want to create main collectionview and table with collection view in cells with headers on top of each row.
When I connect the second collectionview( the one in the table) either to the main viewcontroller or to the custom tablecell, i get various different runtime errors.
When connected to the tableview I get this error:
UITableView collectionView:numberOfItemsInSection:]: unrecognized
selector sent to instance 0x7fb009064800
My code is attached. Unfortunately, I cannot get the UICollectionview to appear in the Table.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension ViewController: UICollectionViewDataSource, UICollectionViewDelegate {
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("MainCell", forIndexPath: indexPath) as! CollectionViewCell
return cell
}
}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("TableCell", forIndexPath: indexPath) as! TableViewCell
return cell
}
}
TableViewCell class
import UIKit
class TableViewCell: UITableViewCell {
#IBOutlet weak var subCollectionViewObject: UICollectionView!
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
}
}
extension TableViewCell: UICollectionViewDataSource, UICollectionViewDelegate {
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 15
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let subCell = collectionView.dequeueReusableCellWithReuseIdentifier("SubCell", forIndexPath: indexPath) as! SubCollectionViewCell
return subCell
}
}
import UIKit
class CollectionViewCell: UICollectionViewCell {
#IBOutlet weak var mainImage: UIImageView!
}
import UIKit
class SubCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var subImage: UIImageView!
}
Solved the issue using a scrollview inside a tableview. Easier for me to conceptualize and implement.