Reputation: 11
I am trying to use a collection view inside a popup window. The cell's data will be taken from an array and from pre-added data (image and text) inside the application. I tried to create a custom collection view swift class and try to add it inside popup window swift class but didn't work and gives me a fatal error when I tried to put it inside the view.addsubview(). Any ideas on how to do it to be able to insert the collection view inside a popup window?
Update: Code below
import UIKit
protocol PopUpDelegate {
func handleDismissal()
}
class PopUpWindow: UIView, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 2
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellid, for: indexPath) as! TeamCell
cell.backgroundColor = .cyan
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: (self.frame.width / 3) - 16, height: 100)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
// MARK: - Properties
let cellid = "cellid"
let label: UILabel = {
let label1 = UILabel()
label1.translatesAutoresizingMaskIntoConstraints = false
label1.text = "Tawasol Message"
label1.textColor = .black
label1.textAlignment = .center
label1.backgroundColor = UIColor.red
return label1
}()
let collectionview: UICollectionView = {
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
cv.register(TeamCell.self, forCellWithReuseIdentifier: "cellid")
//If you set it false, you have to add constraints.
cv.translatesAutoresizingMaskIntoConstraints = false
// cv.delegate = self
// cv.dataSource = self
// cv.register(HeaderCell.self, forCellWithReuseIdentifier: "HeaderCell")
cv.backgroundColor = .yellow
return cv
}()
let col: MyViewController = {
let coll = MyViewController()
return coll
}()
let button: UIButton = {
let button = UIButton(type: .system)
button.backgroundColor = UIColor.blue
button.setTitle("Done", for: .normal)
button.setTitleColor(.white, for: .normal)
button.addTarget(self, action: #selector(handleDismissal), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
button.layer.cornerRadius = 5
return button
}()
// var delegate: PopUpDelegate?
// MARK: - Init
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .white
addSubview(label)
label.heightAnchor.constraint(equalToConstant: 50).isActive = true
label.leftAnchor.constraint(equalTo: leftAnchor, constant: 12).isActive = true
label.topAnchor.constraint(equalTo: topAnchor, constant: 12).isActive = true
label.rightAnchor.constraint(equalTo: rightAnchor, constant: -12).isActive = true
addSubview(col as! UICollectionView)
addSubview(button)
button.heightAnchor.constraint(equalToConstant: 50).isActive = true
button.leftAnchor.constraint(equalTo: leftAnchor, constant: 12).isActive = true
button.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -12).isActive = true
button.rightAnchor.constraint(equalTo: rightAnchor, constant: -12).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Selectors
@objc func handleDismissal() {
print("DONE...")
// delegate?.handleDismissal()
}
}
class TeamCell: UICollectionViewCell{
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
func setup(){
self.backgroundColor = .red
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
I created in another swift file the collectionView as a Subclass of UICollectionView and the code is below:
import UIKit
class MyViewController : UIViewController {
var myCollectionView:UICollectionView?
override func viewDidLoad() {
super.viewDidLoad()
let view = UIView()
view.backgroundColor = .white
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 20, left: 10, bottom: 10, right: 10)
layout.itemSize = CGSize(width: 60, height: 60)
myCollectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
myCollectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MyCell")
myCollectionView?.backgroundColor = UIColor.white
myCollectionView?.dataSource = self
myCollectionView?.delegate = self
view.addSubview(myCollectionView ?? UICollectionView())
self.view = view
}
}
extension MyViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 9 // How many cells to display
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath)
myCell.backgroundColor = UIColor.blue
return myCell
}
}
extension MyViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("User tapped on item \(indexPath.row)")
}
}
The error is given when I want to show the popup window. The error is shown in init of the popUp swift file, in addSubview(col as! UICollectionView)
, the error is:
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
Upvotes: 0
Views: 772
Reputation: 2859
The crash occurs because you're trying to force cast your col
variable to UICollectionView
, however it is declared as MyViewController
here:
let col: MyViewController = {
let coll = MyViewController()
return coll
}()
Assuming that you are not using a storyboard and doing everything in code, then in order to display some screen as a popup, I recommend doing the following:
modalPresentationStyle
property.present(_:animated:completion:)
method, passing an instance of your modal view controller as an argument.Upvotes: 0