IBOutlet pageControl is invalid - swift

I trying to add pageControl in viewController for display current page and total pages.
I have collectionView inside viewController. But if i add #IBOutlet in viewController i get the error:
"The pageControl outlet from the DetailViewController to the UIPageControl is invalid. Outlet cannot be connected to repeating content."
That means repeating content?
I understand that this question has been asked many times, but I tried what was suggested but nothing helped.
PageControl in main.storyboard have only one #IBOutlet and it throws an error...
If need my code, he is here:
class DetailViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UITableViewDelegate, UITableViewDataSource {
// MARK: - IBOutlet's
#IBOutlet weak var collectionView: UICollectionView!
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var pageControl: UIPageControl!
var hallImages: Hall?
var currentPage = 0
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
tableView.estimatedRowHeight = 626
tableView.rowHeight = UITableViewAutomaticDimension
}
// MARK: - CollectionView
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
guard let imagesHall = hallImages?.ImagesHalls.count else {
return 0
}
return imagesHall
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! DetailCollectionViewCell
if let imagesHalls = hallImages?.ImagesHalls[indexPath.item] {
cell.imageView.sd_setImage(with: URL(string: imagesHalls))
}
return cell
}
}
How i can add pageControll in collectionView or collectionCell (i don't know how is better)?

I had the same problem. It is because your page control is a subview of the cell. You cannot do this.
take it out of your cell
put it in your main view/ safe area

Related

Cells for CollectionView Are Not All Showing

The code below is my test files for my final project that will look like this. As you can see I will be scrolling by rows of one or two.
I have figured out how to get the horizontal scroll to work, however, it only displays two out of the six buttons as shown here in the simulator. As You can tell, it just repeats itself. I am needing the app to show app six buttons respectively.
The code for this:
var multiButton = [String]()
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
var multiButton = ["faceButton", "faceButtonTwo", "faceButtonThree", "faceButtonFour", "faceButtonFive", "faceButtonSix"]
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return multiButton.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell=collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MyCollectionViewCell
// cell.multiButton.layer.cornerRadius=50.0
return cell
// cell.myWebSeriesImage.image=UIImage(named: webSeriesImages[indexPath.row])
// return cell
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
I have a separate file with all my IBOutlets as shown in this code:
import UIKit
class MyCollectionViewCell: UICollectionViewCell {
// var multiButton = ["faceButton", "faceButtonTwo", "faceButtonThree", "faceButtonFour", "faceButtonFive", "faceButtonSix"]
#IBOutlet weak var faceButtonFour: UIButton!
#IBOutlet weak var faceButtonFive: UIButton!
#IBOutlet weak var faceButtonThree: UIButton!
#IBOutlet weak var faceButtonTwo: UIButton!
#IBOutlet weak var faceButton: UIButton!
#IBOutlet weak var faceButtonSix: UIButton!
I have double checked the Identifiers, classes (class for cells are set for "myCollectionViewCell", which is the same file all IBOutlets are in), made sure all UIButtons were Installed, and have tried to find any abnormalities in the Attributes and Identity Inspector.
I also would like to address the issue of not being able to scroll horizontal without clicking outside the button.
UPDATE for Post:
This is what we are seeing currently after a previous comment to resize the collectionview. It continues to repeat over and over and I am struggling to find the reasons in my code.
This is a screenshot of main.storyboard.
This is very basic. You need to create something like this:
First create a collectionView with required height (50 for example) and add a button inside its cell. Give any width or height to the button (maybe 80 x 30) and add leading, trailing, top and bottom constraints. Make sure to change scroll direction to horizontal as required by you.
After that create a collectionView class and connect your button outlet to it:
import UIKit
class ButtonCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var button: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
}
}
In your main ViewController, connect collectionView and add delegate & datasource function:
import UIKit
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
#IBOutlet weak var collectionViewButtons: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
collectionViewButtons.delegate = self
collectionViewButtons.dataSource = self
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 6 //number of buttons
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! ButtonCollectionViewCell
cell.button.setTitle("Button\(indexPath.item)", for: .normal) //set button title
if indexPath.item == 0 { //first button
cell.button.backgroundColor = UIColor.purple //set button background
}
else if indexPath.item == 1 { //second button
cell.button.backgroundColor = UIColor.red
}
else if indexPath.item == 2 { //3rd button
cell.button.backgroundColor = UIColor.systemGreen
}
else { // for remaining buttons
cell.button.backgroundColor = UIColor.darkGray
}
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if indexPath.item == 0 { // opens any page by clicking button 1
let vc = storyboard?.instantiateViewController(withIdentifier: "anyVC1") as! ViewController1
navigationController?.pushViewController(vc, animated: true)
}
else if indexPath.item == 1 {
let vc = storyboard?.instantiateViewController(withIdentifier: "anyVC2") as! ViewController2
navigationController?.pushViewController(vc, animated: true)
}
else if indexPath.item == 2 {
let vc = storyboard?.instantiateViewController(withIdentifier: "anyVC3") as! ViewController3
navigationController?.pushViewController(vc, animated: true)
}
else {
let vc = storyboard?.instantiateViewController(withIdentifier: "anyVC4") as! ViewController4
navigationController?.pushViewController(vc, animated: true)
}
}
}
You can return any number of buttons by changing return 6 to any required number or use any array which can further be used to set properties of buttons created.
The didSelectAnItem can be used to add functionality when a cell is tapped.
In the end you should get output like this where you can scroll horizontally to see remaining buttons:

Cannot get CollectionViewCells to work in SWIFT

I have tried this numerous ways but I am unable to get it to work. I am trying to add a simple image and two text labels to a collection view cell and when the build completes the tableview is just blank. I am brand new too SWIFT but I am pretty sure I am missing something simple. What am I doing wrong?
ViewController
import UIKit
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate{
let locationName = ["Hawaii Resort", "Mountain Expedition", "Scuba Diving"]
let locationImage = [UIImage(named: "img0"), UIImage(named: "img1"), UIImage(named: "img2")]
let locationDescription = ["Lorem Ipsum 0", "Lorem Ipsum 1", "Lorem Ipsum 2"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return locationName.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.locationName.text = locationName[indexPath.row]
cell.locationImage.image = locationImage[indexPath.row]
cell.locationDescription.text = locationDescription[indexPath.row]
return cell
}
}
CollectionViewCell
import UIKit
class CollectionViewCell: UICollectionViewCell {
#IBOutlet weak var locationImage: UIImageView!
#IBOutlet weak var locationName: UILabel!
#IBOutlet weak var locationDescription: UILabel!
}
You need to connect the collectionView to the ViewController.
Beneath locationDescription add:
#IBOutlet weak var collectionView: UICollectionView!
Then connect it on the storyboard.
Then within the viewDidLoad,set the delegate and data source to self
self.collectionView.delegate = self
self.collectionView.datasource = self

UICollectionView Cells overlapping with each other when i use a button to increase cell height

I have a CollectionView setup and i have a button inside that increases the cell height by a fixed amount. However when it does this is overlapps with the cell below meaning the cell below doesnt move down to make space.
Ive been trying to figure this out for days and i cant seem to get it working.
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
var colors = [UIColor.red,UIColor.blue]
#IBOutlet weak var col: UICollectionView!
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 2
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! cellCollectionViewCell
cell.frame.size.height = CGFloat(317 + cell.button.tag*45)
cell.backgroundColor = colors[indexPath.row]
return cell
}
#IBAction func increaseHeight(_ sender: Any) {
col.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
class cellCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var butt: UIButton!
#IBAction func incHeight(_ sender: UIButton) {
sender.tag = sender.tag + 1
}
}
Editing the frame of the cell directly is probably not the best approach. Instead override collectionView sizeForItemAtIndexPath, and specify the height change there. This should allow the collection view to re-layout correctly with the new cell height.
You can see other questions like this one for more details

How can I create a public function to show the indexPath of a selected cell in a UICollectionView

In my application I need a public function / public var in which I need to know the indexPath of a selected cell. Since Im a new coder I have some ideas how to make it but none of them has worked yet.
I just want, that I can access the selected indexPath from everywhere in the class. So I need some advice/help.
func selectedColor(){
let cell = gamePad.dequeueReusableCell(withReuseIdentifier: "coloredCell", for: IndexPath) as! UICollectionViewCell
let selectedCell = gamePad.indexPathForItem(at: CGPoint)
}
I agree with Dávid Pásztor, but help you for first time. You need implement delegate of UITableView. I think it's will be look like this:
class TableViewController: UIViewController {
#IBOutlet var tableView: UITableView!
var selectedIndexPath: IndexPath?
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
}
}
extension TableViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedIndexPath = indexPath
}
}
P.S. For UICollectionView it is same, but you need implement UICollectionViewDelegate and look like this:
class ViewController: UIViewController {
#IBOutlet var collectionView: UICollectionView!
var selectedIndexPath: IndexPath?
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
}
}
extension ViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
selectedIndexPath = indexPath
}
}
P.S. If you don't need to know a moment when cell was tapped, then you can use indexPathForSelectedRow (#rmaddy)
indexPathsForSelectedItems on UICollectionView
https://developer.apple.com/documentation/uikit/uicollectionview/1618099-indexpathsforselecteditems

Trouble added cell to UICollectionView

Trying to add a cell to my ViewController, and I'm having trouble. I'm wondering if I have all my delegates. Currently, I can change the color of the collection view's background, but can't add any cells.
I'm using an array of text from my Listing() object to drive the collection view cells. On viewDidLoad the length is 4. I envisioned using this count for the numberofItemsInSection, however, if I put the print statement there it is never printed. Which makes me think the wrong delegate is called and the method is never hit. Correct?
import UIKit
class ListingDetailViewController: UIViewController,
UICollectionViewDelegateFlowLayout {
var listing = Listing()
// #IBOutlet var image: UIImageView!
#IBOutlet var post: UITextView!
#IBOutlet var price: UILabel!
#IBOutlet var amenitiesCollection: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
navigationItem.title = listing.title
self.amenitiesCollection!.backgroundColor = UIColor.gray
print(listing.amenities.count)//printed 4
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
print(listing.amenities.count)
return listing.amenities.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let identifier = "UICollectionViewCell"
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath)
return cell
}
}
Make sure you have linked the CollectionView delegate and datasource to your view controller.
In viewDidLoad() add:
self.amenitiesCollection.delegate = self
self.amenitiesCollection.dataSource = self
==================================
EDIT:
If you have already linked the delegate and dataSource, try reloading the collection view in viewDidAppear(_:)
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.amenitiesCollection.reloadData()
}