UICollectionView show strange behaviour while scrolling - ios

I am trying to create seatMap and I want to hide the image for certain cell, but when i am doing so the image is hiding for other cells randomly not getting the issue. Suppose i hide the image for the 2nd cell the image for 4th cell is also hiding while i scroll horizontally or vertically.
Here is my ViewController Code
import UIKit
class BookViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var dropButton: UIButton!
#IBOutlet weak var dropDownOutlet: UITableView!
#IBOutlet weak var seatMapCollection: UICollectionView!
#IBOutlet weak var dateSelecterCollection: UICollectionView!
#IBOutlet weak var timeSelecterCollection: UICollectionView!
var selectedIndexPath: IndexPath!
var dateValue = ["1","2","3","4","10","6","7","8","9","5"]
var dayValue = ["Mon","Tue","Wed","Thu","Thu","Thu","Thu","Thu","Thu","Thu"]
var month = ["jan","feb","mar","apr","Thu","Thu","Thu","Thu","Thu","Thu"]
var venue = ["Smart Cinemaz, Rupnagar","Smart Cinemaz, Fatehgarh Sahib "]
var numberSection:Int = 10
var numberOfItems:Int = 15
var seatNumber = [Int]()
var columns = [[Int]]()
var rows = [[Int]]()
var col = [2,3]
var rowno = [6,7,14]
var col1 = [5,6,7,8,9,11,12]
var rowno1 = [7]
var sectionHeader = [0,4,10]
override func viewDidLoad() {
super.viewDidLoad()
self.seatMapCollection.dataSource = self
self.seatMapCollection.delegate = self
self.seatMapCollection.reloadData()
self.seatMapCollection.maximumZoomScale = 2
self.seatMapCollection.minimumZoomScale = 0.50
self.view.sendSubview(toBack: seatMapCollection)
seatMapCollection.register(UINib(nibName: "HeaderMulticolumn", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "Header")
for seat in 0...numberOfItems-1{
seatNumber.append(seat + 1)
}
self.dateSelecterCollection.dataSource = self
self.dateSelecterCollection.delegate = self
self.timeSelecterCollection.dataSource = self
self.timeSelecterCollection.delegate = self
self.dropDownOutlet.delegate = self
self.dropDownOutlet.dataSource = self
dropButton.contentHorizontalAlignment = .left
/* let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(pinchAction(sender:)))
seatMapCollection.addGestureRecognizer(pinchGesture)*/
columns.append(col)
columns.append(col1)
rows.append(rowno)
rows.append(rowno1)
}
#IBAction func dropDown(_ sender: Any) {
self.view.bringSubview(toFront: dropDownOutlet)
if dropDownOutlet.isHidden == true{
dropDownOutlet.isHidden = false
}else {
dropDownOutlet.isHidden = true
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView.tag == 1{
return 1
}else if collectionView.tag == 2{
return 1
}else{
return 15
}
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
if collectionView.tag == 1{
return 7
}else if collectionView.tag == 2{
return 5
}
else{
return 10 + 3
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView.tag == 1 {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DateSelecterCollectionViewCell", for: indexPath) as! DateSelecterCollectionViewCell
if (self.selectedIndexPath != nil && indexPath == self.selectedIndexPath){
cell.backgroundColor = UIColor.yellow
cell.dateOutlet.textColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
cell.monthOutlet.textColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
cell.dayOutlet.textColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
}
else{
cell.backgroundColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
cell.dateOutlet.textColor = UIColor.white
cell.monthOutlet.textColor = UIColor.white
cell.dayOutlet.textColor = UIColor.white
}
return cell
}else if collectionView.tag == 2{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TimeSelecterCollectionViewCell", for: indexPath) as! TimeSelecterCollectionViewCell
if (self.selectedIndexPath != nil && indexPath == self.selectedIndexPath){
cell.backgroundColor = UIColor.yellow
cell.timeOutlet.textColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
}
else{
cell.backgroundColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
cell.timeOutlet.textColor = UIColor.white
}
return cell
}
else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SeatMapCollectionViewCell", for: indexPath) as! SeatMapCollectionViewCell
for r1 in 0...rows.count-1{
for c1 in 0...columns.count-1{
if (r1 == c1){
for colum in 0...columns[c1].count-1 {
for ro in 0...rows[r1].count-1{
if indexPath.row == rows[r1][ro] && indexPath.section == columns[c1][colum]{
cell.alpha = 0
}
}
}
}
}
}
for i in 0...sectionHeader.count-1{
if indexPath.section==sectionHeader[i] && indexPath.row==0{
cell.seatDetail.alpha=1
cell.seatDetail.text = "Gold - 180"
cell.seatImage.isHidden = true
}
}
//cell.seatDetail.alpha=0
return cell
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if collectionView.tag == 1{
let cell = collectionView.cellForItem(at: indexPath) as! DateSelecterCollectionViewCell
if cell.isSelected == true{
cell.backgroundColor = UIColor.yellow
cell.dateOutlet.textColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
cell.monthOutlet.textColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
cell.dayOutlet.textColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
}
self.selectedIndexPath = indexPath
}else if collectionView.tag == 2 {
let cell = collectionView.cellForItem(at: indexPath) as! TimeSelecterCollectionViewCell
self.selectedIndexPath = nil
cell.backgroundColor = UIColor.yellow
cell.timeOutlet.textColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
}
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
if collectionView.tag == 1{
let cell = collectionView.cellForItem(at: indexPath) as! DateSelecterCollectionViewCell
self.selectedIndexPath = nil
cell.backgroundColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
cell.dateOutlet.textColor = UIColor.white
cell.monthOutlet.textColor = UIColor.white
cell.dayOutlet.textColor = UIColor.white
}
else if collectionView.tag == 2{
let cell = collectionView.cellForItem(at: indexPath) as! TimeSelecterCollectionViewCell
self.selectedIndexPath = nil
cell.backgroundColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
cell.timeOutlet.textColor = UIColor.white
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return venue.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DropDownTableViewCell") as! DropDownTableViewCell
cell.venueDetails.text = "\(venue[indexPath.row])"
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! DropDownTableViewCell
dropButton.setTitle(cell.venueDetails.text, for: .normal)
tableView.isHidden = true
}
}
Here is my Custom CollectionViewlayout
import UIKit
protocol SeatMapDelegate:class {
func collectionView(Width: Double)-> Double
func collectionView(Height: Double)-> Double }
class CustomCollectionViewLayout: UICollectionViewLayout {
var delegate: SeatMapDelegate?
var CELL_HEIGHT = 35.0
var CELL_WIDTH = 35.0
let STATUS_BAR = UIApplication.shared.statusBarFrame.height
var cache = [UICollectionViewLayoutAttributes]()
var contentSize = CGSize.zero
var cellAttrsDictionary = [UICollectionViewLayoutAttributes]()
var cellPadding = 5.0
var sectionHeader = [0,4,10]
override var collectionViewContentSize: CGSize{
return self.contentSize
}
var interItemsSpacing: CGFloat = 8
// 5
var contentInsets: UIEdgeInsets {
return collectionView!.contentInset
}
override func prepare() {
var counts: Int = 0
// Cycle through each section of the data source.
if collectionView!.numberOfSections > 0 {
for section in 0...collectionView!.numberOfSections-1 {
// Cycle through each item in the section.
if collectionView!.numberOfItems(inSection: section) > 0 {
for item in 0...collectionView!.numberOfItems(inSection: section)-1 {
// Build the UICollectionVieLayoutAttributes for the cell.
let cellIndex = NSIndexPath(item: item, section: section)
/* let width: Double = 35.0
let height: Double = 35.0
CELL_WIDTH = (delegate?.collectionView(Width: width))!
CELL_HEIGHT = (delegate?.collectionView(Height: height))!*/
if counts<sectionHeader.count {
if item == 0 && section == sectionHeader[counts]{
let xPos = 0.0
let yPos = Double(section) * CELL_HEIGHT
let frame = CGRect(x: xPos, y: yPos, width: 15 * CELL_WIDTH, height: CELL_HEIGHT)
let cellFinalAttribute = frame.insetBy(dx:CGFloat(cellPadding) ,dy:CGFloat(cellPadding))
let cellAttributes = UICollectionViewLayoutAttributes(forCellWith: cellIndex as IndexPath)
cellAttributes.frame = cellFinalAttribute
//cellAttributes.frame = CGRect(x: xPos, y: yPos, width: CELL_WIDTH, height: CELL_HEIGHT)
cellAttrsDictionary.append(cellAttributes)
counts=counts+1
break
}
}
let xPos = Double(item) * CELL_WIDTH
let yPos = Double(section) * CELL_HEIGHT
let frame = CGRect(x: xPos, y: yPos, width: CELL_WIDTH, height: CELL_HEIGHT)
let cellFinalAttribute = frame.insetBy(dx:CGFloat(cellPadding) ,dy:CGFloat(cellPadding))
let cellAttributes = UICollectionViewLayoutAttributes(forCellWith: cellIndex as IndexPath)
cellAttributes.frame = cellFinalAttribute
//cellAttributes.frame = CGRect(x: xPos, y: yPos, width: CELL_WIDTH, height: CELL_HEIGHT)
cellAttrsDictionary.append(cellAttributes)
}
}
}
}
// Update content size.
let contentWidth = Double(collectionView!.numberOfItems(inSection: 0)) * CELL_WIDTH
let contentHeight = Double(collectionView!.numberOfSections) * CELL_HEIGHT
self.contentSize = CGSize(width: contentWidth, height: contentHeight)
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
// Create an array to hold all elements found in our current view.
var attributesInRect = [UICollectionViewLayoutAttributes]()
// Check each element to see if it should be returned.
for cellAttributes in cellAttrsDictionary {
if rect.intersects(cellAttributes.frame) {
attributesInRect.append(cellAttributes)
}
}
// Return list of elements.
return attributesInRect
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
return cellAttrsDictionary[indexPath.row]
}
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return false
}
}
Custom CollectionView cell class
import UIKit
class SeatMapCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var seatDetail: UILabel!
#IBOutlet weak var seatImage: UIImageView!
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
setup()
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
func setup() {
//self.layer.borderWidth = 1.0
// self.layer.borderColor = UIColor.gray.cgColor
// self.layer.cornerRadius = 5.0
}}

Related

Cardlayout swipe left programmatically not working

I am using pod 'CardsLayout' to my project.
cardlayout library
The image is
this library doesn't have functionality of swipe left and swipe right programmatically. so, i checked that, it is using UICollectionView. So, i thought that i can use selectItem by following code.
func onNextButtonClicked(collectionViewCell:QuestionrieViewCell) {
let currentIndex = collectionViewCell.getIndexPath().row
if currentIndex < getIndexPaths().count-1{
collectionView.deselectItem(at: collectionViewCell.getIndexPath(), animated: true)
collectionView.selectItem(at: getIndexPaths()[collectionViewCell.getIndexPath().row + 1], animated: true, scrollPosition: .left)
self.collectionView(collectionView, didSelectItemAt:getIndexPaths()[collectionViewCell.getIndexPath().row + 1] )
}
}
func onPrevButtonClicked(collectionViewCell:QuestionrieViewCell) {
let currentIndex = collectionViewCell.getIndexPath().row
if currentIndex > 0{
collectionView.deselectItem(at: collectionViewCell.getIndexPath(), animated: true)
collectionView.selectItem(at: getIndexPaths()[collectionViewCell.getIndexPath().row - 1], animated: true, scrollPosition: .right)
self.collectionView(collectionView, didSelectItemAt:getIndexPaths()[collectionViewCell.getIndexPath().row - 1] )
}
}
I want that, swipe left and swipe right should be happen when the user click the buttons. here,
onPreviousButtonClicked working fine. whereas, swipe right button click not responding like i expected.
onNextBUttonClick gives weird response. response as below
it's stopped going to left and if i click the same right arrow button, on that stopped card, then it still slide little bit of the screen then stopped going to left.i don't know what should i do. Anyone can help me?
Edit
Additional images below.
ViewController Class is here
class ControllerQuestionarie: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate,QuestionrieViewCellDelegate{
var currentIndexPath:IndexPath?
var indexPaths:[IndexPath] = [IndexPath]()
var swipeToLeft:UISwipeGestureRecognizer?,swipeToRight:UISwipeGestureRecognizer?
var previousPage : Int = 0
#IBOutlet weak var linearProgressBar: LinearProgressBar!
#IBOutlet weak var lblQuestionNumber: UILabel!
func setIndexPaths(indexPath:IndexPath){
self.indexPaths.append(indexPath)
}
func getIndexPaths()->[IndexPath]{
return self.indexPaths
}
func onNextButtonClicked(collectionViewCell:QuestionrieViewCell) {
let currentIndex = collectionViewCell.getIndexPath().row
if currentIndex < getIndexPaths().count-1{
self.collectionView.selectItem(at: IndexPath(item: collectionViewCell.getIndexPath().row + 1, section: 0), animated: true, scrollPosition: .left)
self.collectionView(self.collectionView, didSelectItemAt: IndexPath(item: collectionViewCell.getIndexPath().row + 1, section: 0))
self.collectionView.layoutIfNeeded()
self.currentIndexPath = collectionViewCell.getIndexPath()
if self.currentIndexPath!.row == 4{
let controllerQuestionarieCompletionViewController = ControllerQuestionarieCompletionViewController.init(nibName: "ControllerQuestionarieCompletionViewController", bundle: nil)
self.navigationController!.pushViewController(controllerQuestionarieCompletionViewController, animated: true)
}
}
}
func onPrevButtonClicked(collectionViewCell:QuestionrieViewCell) {
let currentIndex = collectionViewCell.getIndexPath().row
if currentIndex > 0{
self.collectionView.selectItem(at: IndexPath(item: collectionViewCell.getIndexPath().row - 1, section: 0), animated: true, scrollPosition: .right)
self.collectionView(self.collectionView, didSelectItemAt: IndexPath(item: collectionViewCell.getIndexPath().row - 1, section: 0))
self.collectionView.layoutIfNeeded()
self.currentIndexPath = collectionViewCell.getIndexPath()
}
}
override func viewDidLoad() {
super.viewDidLoad()
collectionView.register(UINib.init(nibName: "QuestionrieViewCell", bundle: nil), forCellWithReuseIdentifier: "QuestionrieViewCell")
collectionView.collectionViewLayout = CardsCollectionViewLayout()
collectionView.dataSource = self
collectionView.delegate = self
collectionView.isPagingEnabled = true
collectionView.showsHorizontalScrollIndicator = false
let progressValue = 100/CGFloat(colors.count)
let progress = CGFloat(progressValue) * CGFloat(previousPage + 1)
lblQuestionNumber.text = "\(previousPage + 1) / \(colors.count)"
linearProgressBar.progressValue = progress
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.currentIndexPath = indexPath
// ... Other settings
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let pageWidth = scrollView.frame.size.width
let page = Int(floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1)
print (page)
if previousPage != page{
let progressValue = 100/CGFloat(colors.count)
let progress = CGFloat(progressValue) * CGFloat(page + 1)
lblQuestionNumber.text = "\(page + 1) / \(colors.count)"
linearProgressBar.progressValue = progress
}
previousPage = page
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "QuestionrieViewCell", for: indexPath) as! QuestionrieViewCell
cell.questionrieViewCellDelegate = self
cell.layer.cornerRadius = 50.0
cell.setIndexPath(indexPath: indexPath)
setIndexPaths(indexPath: indexPath)
cell.bindData()
cell.view.backgroundColor = colors[indexPath.row]
return cell
}
#IBOutlet var collectionView: UICollectionView!
var colors: [UIColor] = [
UIColor(red: 255, green: 255, blue: 255),
UIColor(red: 249, green: 220, blue: 92),
UIColor(red: 194, green: 234, blue: 189),
UIColor(red: 1, green: 25, blue: 54),
UIColor(red: 255, green: 184, blue: 209)
]
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return colors.count
}
}
extension UIColor {
convenience init(red: Int, green: Int, blue: Int) {
self.init(red: CGFloat(red)/255 ,
green: CGFloat(green)/255,
blue: CGFloat(blue)/255,
alpha: 1.0)
}
}
Yes. I did it. Finally i have tasted the answer for this question.
public func moveToPage(position:Int){
let totalPage = collectionView.contentOffset.x/collectionView.frame.width// getting totalNumberOfPage
if position < Int(totalPage){
scrollToPage(page: position, animated: true)
}
}
public func moveToNextPage()->Int{
let pageIndex = round(collectionView.contentOffset.x/collectionView.frame.width)
let pageNo = Int(pageIndex+1)
scrollToPage(page: pageNo, animated: true)
return pageNo
}
public func moveToPreviousPage()->Int{
let pageIndex = round(collectionView.contentOffset.x/collectionView.frame.width)
let pageNo = Int(pageIndex-1)
scrollToPage(page: pageNo, animated: true)
return pageNo
}
func scrollToPage(page: Int, animated: Bool) {
var frame: CGRect = self.collectionView.frame
frame.origin.x = frame.size.width * CGFloat(page)
frame.origin.y = 0
self.collectionView.scrollRectToVisible(frame, animated: animated)
}
It works like charm. Thank you

Data has been replaced or missing while scrolling collectionview

i am implementing collection view as my ChatMessagViewController and i am populating message in collectionview all things works perfect for me but issue is that when i scrolled collection view message was . issing or replaced on scroll let me show you my code for populating collectionview
here i am adding screen shot for what output i get before scrolling and after scrolling please have a look
func loadMessageData(){
self.message.removeAll()
guard let uid = Auth.auth().currentUser?.uid else{
return
}
let userref = Database.database().reference().child("Message").child(uid)
userref.child(self.senderID!).observe(.childAdded, with: { (snapshot) in
print(snapshot)
if let dictonary = snapshot.value as? [String:AnyObject]{
let key = snapshot.key
let mainDict = NSMutableDictionary()
mainDict.setObject(key, forKey: "userid" as NSCopying)
self.namesArray.add(mainDict)
let message = Message(dictionary: dictonary)
self.message.append(message)
self.timer?.invalidate()
self.timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(self.handleReload), userInfo: nil, repeats: false)
}
}, withCancel: nil)
}
extension ChatViewController: UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return message.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! ChatMessageCell
let message1 = message[indexPath.item]
cell.tetxtView.text = message1.msg
cell.bubbleWidthAnchor?.constant = estimatedFrameForText(text: message1.msg!).width + 32
let ketID = message1.key_id
if ketID == Auth.auth().currentUser?.uid{
cell.bubbleView.backgroundColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1)
cell.bubbleViewRightAnchor?.isActive = false
cell.bubbleViewLeftAnchor?.isActive = true
}else{
cell.bubbleView.backgroundColor = UIColor(red: 0/255, green: 158/255, blue: 214/255, alpha: 1)
cell.tetxtView.textColor = UIColor.white
cell.bubbleViewRightAnchor?.isActive = true
cell.bubbleViewLeftAnchor?.isActive = false
}
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
var height: CGFloat = 80
if let mesg = message[indexPath.item].msg{
height = estimatedFrameForText(text: mesg).height + 20
}
return CGSize(width: view.frame.width, height: height)
}
}
and here is the collectionview methods for populating
issue is that when i scroll the message was replaced or missing
please check screen shot first i am getting messages and after scrolling i came back to top message is missing
cell.tetxtView.textColor is dequeued make sure to add it inside the if also
if ketID == Auth.auth().currentUser?.uid{
cell.bubbleView.backgroundColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1)
cell.tetxtView.textColor = UIColor.black /////// here
cell.bubbleViewRightAnchor?.isActive = false
cell.bubbleViewLeftAnchor?.isActive = true
}else{
cell.bubbleView.backgroundColor = UIColor(red: 0/255, green: 158/255, blue: 214/255, alpha: 1)
cell.tetxtView.textColor = UIColor.white
cell.bubbleViewRightAnchor?.isActive = true
cell.bubbleViewLeftAnchor?.isActive = false
}
The text color is white so it same as the background of it's superview , hence doesn't appear

Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) getting nil in the delegate variable

I am creating a seat layout and want to get the coordinates from the view controller class in the form of array using delegate but I am getting nil from the view controller while passing the coordinates and getting this error.
Here is my view controller
import UIKit
class BookViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UITableViewDelegate, UITableViewDataSource, SeatMapDelegate {
#IBOutlet weak var dropButton: UIButton!
#IBOutlet weak var dropDownOutlet: UITableView!
#IBOutlet weak var seatMapCollection: UICollectionView!
#IBOutlet weak var dateSelecterCollection: UICollectionView!
#IBOutlet weak var timeSelecterCollection: UICollectionView!
var selectedIndexPath: IndexPath!
var dateValue = ["1","2","3","4","10","6","7","8","9","5"]
var dayValue = ["Mon","Tue","Wed","Thu","Thu","Thu","Thu","Thu","Thu","Thu"]
var month = ["jan","feb","mar","apr","Thu","Thu","Thu","Thu","Thu","Thu"]
var venue = ["Smart Cinemaz, Rupnagar","Smart Cinemaz, Fatehgarh Sahib "]
var numberSection:Int = 10
var numberOfItems:Int = 15
var seatNumber = [Int]()
var columns = [[Int]]()
var rows = [[Int]]()
var col = [2,3]
var rowno = [8,9,16]
var col1 = [5,6,7,8,9,11,12]
var rowno1 = [9]
var sectionHeader: Array<Int> = [0,4,10]
var sectionHeading = ["Gold (₹180.00)","Silver (₹150.00)","Bronze (₹100.00)"]
var rowValue = ["A","B","C","D","E","F","G","H","I","J"]
var kCounter: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
self.seatMapCollection.dataSource = self
self.seatMapCollection.delegate = self
self.seatMapCollection.reloadData()
self.seatMapCollection.maximumZoomScale = 2
self.seatMapCollection.minimumZoomScale = 0.50
self.view.sendSubview(toBack: seatMapCollection)
seatMapCollection.register(UINib(nibName: "HeaderMulticolumn", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "Header")
for seat in 0...numberOfItems-1{
seatNumber.append(seat + 1)
}
self.dateSelecterCollection.dataSource = self
self.dateSelecterCollection.delegate = self
self.timeSelecterCollection.dataSource = self
self.timeSelecterCollection.delegate = self
self.dropDownOutlet.delegate = self
self.dropDownOutlet.dataSource = self
dropButton.contentHorizontalAlignment = .left
/* let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(pinchAction(sender:)))
seatMapCollection.addGestureRecognizer(pinchGesture)*/
columns.append(col)
columns.append(col1)
rows.append(rowno)
rows.append(rowno1)
}
#IBAction func dropDown(_ sender: Any) {
self.view.bringSubview(toFront: dropDownOutlet)
if dropDownOutlet.isHidden == true{
dropDownOutlet.isHidden = false
}else {
dropDownOutlet.isHidden = true
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView.tag == 1{
return 1
}else if collectionView.tag == 2{
return 1
}else{
return 15 + 2
}
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
if collectionView.tag == 1{
return 7
}else if collectionView.tag == 2{
return 5
}
else{
return 10 + 3
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView.tag == 1 {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DateSelecterCollectionViewCell", for: indexPath) as! DateSelecterCollectionViewCell
if (self.selectedIndexPath != nil && indexPath == self.selectedIndexPath){
cell.backgroundColor = UIColor.yellow
cell.dateOutlet.textColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
cell.monthOutlet.textColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
cell.dayOutlet.textColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
}
else{
cell.backgroundColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
cell.dateOutlet.textColor = UIColor.white
cell.monthOutlet.textColor = UIColor.white
cell.dayOutlet.textColor = UIColor.white
}
return cell
}else if collectionView.tag == 2{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TimeSelecterCollectionViewCell", for: indexPath) as! TimeSelecterCollectionViewCell
if (self.selectedIndexPath != nil && indexPath == self.selectedIndexPath){
cell.backgroundColor = UIColor.yellow
cell.timeOutlet.textColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
}
else{
cell.backgroundColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
cell.timeOutlet.textColor = UIColor.white
}
return cell
}
else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SeatMapCollectionViewCell", for: indexPath) as! SeatMapCollectionViewCell
cell.seatImage.isHidden = false
cell.seatImage.image = UIImage(named: "available")
for r1 in 0...rows.count-1{
for c1 in 0...columns.count-1{
if (r1 == c1){
for colum in 0...columns[c1].count-1 {
for ro in 0...rows[r1].count-1{
if indexPath.row == rows[r1][ro] && indexPath.section == columns[c1][colum]{
cell.isHidden = true
}
}
}
}
}
}
for i in 0...collectionView.numberOfSections-1{
for j in 0...sectionHeader.count-1{
// for k in 0...rowValue.count-1{
if indexPath.section != sectionHeader[j] && indexPath.row == 1{
cell.seatImage.isHidden=true
}
if indexPath.section != sectionHeader[j] && indexPath.row == 0 {
cell.seatDetail.isHidden = false
cell.seatDetail.text = rowValue[kCounter]
cell.seatDetail.textColor = UIColor.white
cell.seatImage.isHidden = true
}
if kCounter<rowValue.count-1{
kCounter=kCounter+1
}
// }
}
}
for i in 0...sectionHeader.count-1{
if indexPath.section==sectionHeader[i] && indexPath.row==0{
cell.seatDetail.isHidden=false
cell.seatDetail.text = sectionHeading[i]
cell.seatDetail.textColor = UIColor.white
cell.seatImage.isHidden = true
}
}
return cell
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if collectionView.tag == 1{
let cell = collectionView.cellForItem(at: indexPath) as! DateSelecterCollectionViewCell
if cell.isSelected == true{
cell.backgroundColor = UIColor.yellow
cell.dateOutlet.textColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
cell.monthOutlet.textColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
cell.dayOutlet.textColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
}
self.selectedIndexPath = indexPath
}else if collectionView.tag == 2 {
let cell = collectionView.cellForItem(at: indexPath) as! TimeSelecterCollectionViewCell
self.selectedIndexPath = nil
cell.backgroundColor = UIColor.yellow
cell.timeOutlet.textColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
}
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
if collectionView.tag == 1{
let cell = collectionView.cellForItem(at: indexPath) as! DateSelecterCollectionViewCell
self.selectedIndexPath = nil
cell.backgroundColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
cell.dateOutlet.textColor = UIColor.white
cell.monthOutlet.textColor = UIColor.white
cell.dayOutlet.textColor = UIColor.white
}
else if collectionView.tag == 2{
let cell = collectionView.cellForItem(at: indexPath) as! TimeSelecterCollectionViewCell
self.selectedIndexPath = nil
cell.backgroundColor = UIColor(red: 44/255, green: 150/255, blue: 208/255, alpha: 1)
cell.timeOutlet.textColor = UIColor.white
}
}
/* #objc func pinchAction(sender:UIPinchGestureRecognizer){
var scaleValue: CGFloat!
if sender.state == .changed || sender.state == .began {
if scaleValue == nil{
seatMapCollection.transform = CGAffineTransform.init(scaleX: sender.scale, y: sender.scale)
scaleValue = sender.scale
}else{
seatMapCollection.transform = CGAffineTransform.init(scaleX: scaleValue, y: scaleValue)
}
}
}*/
//
//
//
// Drop Down Section
//
//
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return venue.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DropDownTableViewCell") as! DropDownTableViewCell
cell.venueDetails.text = "\(venue[indexPath.row])"
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! DropDownTableViewCell
dropButton.setTitle(cell.venueDetails.text, for: .normal)
tableView.isHidden = true
}
func getSectionCoordinates() -> Array<Int> {
return sectionHeader
}
}
And here is my custom collection view class:
import UIKit
protocol SeatMapDelegate: class {
func getSectionCoordinates() -> Array<Int>
}
class CustomCollectionViewLayout: UICollectionViewLayout {
var delegate: SeatMapDelegate?
var CELL_HEIGHT = 20.0
var CELL_WIDTH = 20.0
let STATUS_BAR = UIApplication.shared.statusBarFrame.height
var cache = [UICollectionViewLayoutAttributes]()
var contentSize = CGSize.zero
var cellAttrsDictionary = [UICollectionViewLayoutAttributes]()
var cellPadding = 2.0
var sectionHeader1: Array<Int>!
var sectionHeader = [0,4,9]
override var collectionViewContentSize: CGSize{
return self.contentSize
}
var interItemsSpacing: CGFloat = 8
// 5
var contentInsets: UIEdgeInsets {
return collectionView!.contentInset
}
override func prepare() {
var counts: Int = 0
sectionHeader1=(delegate?.getSectionCoordinates())!
// Cycle through each section of the data source.
if collectionView!.numberOfSections > 0 {
for section in 0...collectionView!.numberOfSections-1 {
// Cycle through each item in the section.
if collectionView!.numberOfItems(inSection: section) > 0 {
for item in 0...collectionView!.numberOfItems(inSection: section)-1 {
// Build the UICollectionVieLayoutAttributes for the cell.
let cellIndex = NSIndexPath(item: item, section: section)
/* let width: Double = 35.0
let height: Double = 35.0
CELL_WIDTH = (delegate?.collectionView(Width: width))!
CELL_HEIGHT = (delegate?.collectionView(Height: height))!*/
if counts<sectionHeader1.count {
if item == 0 && section == sectionHeader1[counts]{
let xPos = 0.0
let yPos = Double(section) * CELL_HEIGHT
let frame = CGRect(x: xPos, y: yPos, width: 15 * CELL_WIDTH, height: CELL_HEIGHT)
let cellFinalAttribute = frame.insetBy(dx:CGFloat(cellPadding) ,dy:CGFloat(cellPadding))
let cellAttributes = UICollectionViewLayoutAttributes(forCellWith: cellIndex as IndexPath)
cellAttributes.frame = cellFinalAttribute
//cellAttributes.frame = CGRect(x: xPos, y: yPos, width: CELL_WIDTH, height: CELL_HEIGHT)
cellAttrsDictionary.append(cellAttributes)
counts=counts+1
break
}
}
let xPos = Double(item) * CELL_WIDTH
let yPos = Double(section) * CELL_HEIGHT
let frame = CGRect(x: xPos, y: yPos, width: CELL_WIDTH, height: CELL_HEIGHT)
let cellFinalAttribute = frame.insetBy(dx:CGFloat(cellPadding) ,dy:CGFloat(cellPadding))
let cellAttributes = UICollectionViewLayoutAttributes(forCellWith: cellIndex as IndexPath)
cellAttributes.frame = cellFinalAttribute
//cellAttributes.frame = CGRect(x: xPos, y: yPos, width: CELL_WIDTH, height: CELL_HEIGHT)
cellAttrsDictionary.append(cellAttributes)
}
}
}
}
// Update content size.
let contentWidth = Double(collectionView!.numberOfItems(inSection: 0)) * CELL_WIDTH
let contentHeight = Double(collectionView!.numberOfSections) * CELL_HEIGHT
self.contentSize = CGSize(width: contentWidth, height: contentHeight)
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
// Create an array to hold all elements found in our current view.
var attributesInRect = [UICollectionViewLayoutAttributes]()
// Check each element to see if it should be returned.
for cellAttributes in cellAttrsDictionary {
if rect.intersects(cellAttributes.frame) {
attributesInRect.append(cellAttributes)
}
}
// Return list of elements.
return attributesInRect
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
return cellAttrsDictionary[indexPath.row]
}
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return false
}
}
I am not sure what are you trying to do with that sectionHeader1=(delegate?.getSectionCoordinates())!, but you can't use the delegate like that. In your function onPrepare there is no guarantee that your delegate was already instanced and you are unwrapping it with !, that is when you are getting the exception.

Changed TableViewCell with XMSegmentedControl

I want to changed tableviewcell's data with XMSegmentedControl(https://github.com/xaviermerino/XMSegmentedControl),
and I using switch in the
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
,but it's always print
fatal error: unexpectedly found nil while unwrapping an Optional value**,and say *segmentedControl1 is nil.
let tin = ["1","2","3","4"]
let how = ["one","two","three","four"]
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var segmentedControl1: XMSegmentedControl!
override func viewDidLoad() {
super.viewDidLoad()
let segmentedControl3 = XMSegmentedControl(frame: CGRect(x: 0, y: 70, width: self.view.frame.width, height: 44), segmentTitle: ["Hello", "World", "Three"], selectedItemHighlightStyle: XMSelectedItemHighlightStyle.topEdge)
segmentedControl3.backgroundColor = UIColor(red: 22/255, green: 150/255, blue: 122/255, alpha: 1)
segmentedControl3.highlightColor = UIColor(red: 25/255, green: 180/255, blue: 145/255, alpha: 1)
segmentedControl3.tint = UIColor.white
segmentedControl3.highlightTint = UIColor.black
self.view.addSubview(segmentedControl3)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var returnValue = 0
switch(segmentedControl1.selectedSegment)
{
case 0 :
returnValue = tin.count
case 1 :
returnValue = how.count
default :
break
}
return returnValue
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
switch(segmentedControl1.selectedSegment)
{
case 0 :
cell.textLabel?.text = tin[indexPath.row]
case 1 :
cell.textLabel?.text = how[indexPath.row]
default :
break
}
return cell
}
Can anyone help me solve this problem?
Thanks!
replace your viewDidLoad() by my code.
override func viewDidLoad() {
super.viewDidLoad()
segmentedControl1 = XMSegmentedControl(frame: CGRect(x: 0, y: 70, width: self.view.frame.width, height: 44), segmentTitle: ["Hello", "World", "Three"], selectedItemHighlightStyle: XMSelectedItemHighlightStyle.topEdge)
segmentedControl1.backgroundColor = UIColor(red: 22/255, green: 150/255, blue: 122/255, alpha: 1)
segmentedControl1.highlightColor = UIColor(red: 25/255, green: 180/255, blue: 145/255, alpha: 1)
segmentedControl1.tint = UIColor.white
segmentedControl1.highlightTint = UIColor.black
self.view.addSubview(segmentedControl1)
}
put into valuechenged method of segmentControl
DispatchQueue.main.async{
self.ttblView.reloadData()
}
You have applied wrong segmentControl . You put value in segmentedControl3 so segmentedControl1 gives nil .

How to show an image in a UICollection View cell while clicking that cell in swift ios?

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! PlaceCollectionViewCell
//let imageView = UIImageView()
//cell.backgroundColor = UIColor(colorLiteralRed: 0.278, green: 0.694, blue: 0.537, alpha: 1.00)
cell.layer.borderWidth = 0.5
cell.layer.borderColor = UIColor(colorLiteralRed: 0.278, green: 0.694, blue: 0.537, alpha: 1.00).cgColor
//cell.placeLabel.tintColor = UIColor(colorLiteralRed: 0.278, green: 0.694, blue: 0.537, alpha: 1.00).cgColor
cell.layer.cornerRadius = 40
cell.layer.masksToBounds = true
print("places\(indexPath.row)")
//cell.placeLabel.text = places[indexPath.row] as! String
cell.placeLabel.text = places[indexPath.row]
cell.placeLabel.textColor = UIColor(colorLiteralRed: 0.278, green: 0.694, blue: 0.537, alpha: 1.00)
// code for VIew
let view = UIView(frame: cell.bounds)
//Set background color that you want
view.backgroundColor = UIColor(colorLiteralRed: 0.278, green: 0.694, blue: 0.537, alpha: 1.00)
cell.selectedBackgroundView = view
return cell
I have an image in collection view cell. I need to display that image only when I click the cell.Do we have to do it in cellforRowat index path?
//Custom class code:
#IBOutlet weak var tickImageView: UIImageView!
#IBOutlet weak var placeViewBtn: UIButton!
#IBOutlet weak var placeLabel: UILabel!
#IBOutlet weak var imageView: UIImageView!
override func layoutSubviews() {
}
override func awakeFromNib() {
self.imageView.layer.cornerRadius = self.imageView.frame.size.width/2
self.imageView.layer.masksToBounds = true
super.awakeFromNib()
// Initialization code
}
Custom class code added. I want to display the ticMark image which I have declared above.
Declare one instance of type IndexPath and maintain the cell status is it selected or not with it. Now use this array within cellForItemAt indexPath and didSelectItemAt indexPath like this.
var selectedIndexPaths = IndexPath()
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! PlaceCollectionViewCell
//Your code
//decide weather to show tick image or not
self.tickImageView.isHidden = self.selectedIndexPaths != indexPath
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if self.selectedIndexPaths == indexPath {
self.selectedIndexPaths = IndexPath()
}
else {
self.selectedIndexPaths = indexPath
}
self.tableview.reloadData()
}
You need to read wether the tick is selected or not in cellForRow
if tick is selected {
showImage
} else {
hideImage
}
Then in didSelectRow
set the tick to selected or deselected
then call reloadRowForIndexPath

Resources