so i have collectionview where i want the first cell of the collectionview cell is selected when the view is load, i try to use viewDidAppear method and.....well not work very good.
cause for the very first time i try to load the view the first collectionview cell is not selected, but when i back to previous controller and then tap back to the collectionview controller, the first cell of the collectionview is selected.
i mean i dont know what i have to go back and forth so the first cell can automatically be selected.
heres my code :
#IBOutlet weak var katalogColView: UICollectionView!
let indexPos = NSIndexPath(row: 0, section: 0) as IndexPath
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.katalogColView.selectItem(at: indexPos, animated: false, scrollPosition: [])
self.collectionView(katalogColView, didSelectItemAt: indexPos)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if collectionView == katalogColView {
guard let cell = collectionView.cellForItem(at: indexPath) as? KatalogCell else {return}
cell.indicator.backgroundColor = #colorLiteral(red: 0.9916914105, green: 0.2737390399, blue: 0.284696877, alpha: 1)
cell.katalogText.textColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
if collectionView == katalogColView {
guard let cell = collectionView.cellForItem(at: indexPath) as? KatalogCell else {return}
cell.indicator.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
cell.katalogText.textColor = #colorLiteral(red: 0.3950070143, green: 0.4162634611, blue: 0.4362195134, alpha: 1)
}
}
so the code is when the cell is selected, there's a uiview indicator that colored red if selected, and white if not selected
is there something wrong with my code? i mean of course there's something wrong but can anyone tell me why its not working?
i mean like i said it only work if i go back to previous controller, and then i go back to that collectionView controller where it automatically selected first cell, but not selected automatically at the first time i load the controller.
Thanks
Add these lines in cell class and try:
override var isSelected: Bool {
didSet {
if isSelected {
indicator.backgroundColor = #colorLiteral(red: 0.9916914105, green: 0.2737390399, blue: 0.284696877, alpha: 1)
katalogText.textColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
}else {
indicator.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
katalogText.textColor = #colorLiteral(red: 0.3950070143, green: 0.4162634611, blue: 0.4362195134, alpha: 1)
}
}
}
You have to select it from visibleCells.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
let selectedIndex = collectionView.indexPathsForVisibleItems![0]
collectionView.selectItem(at: selectedIndex, animated: true, scrollPosition: .none)
}
Related
I'm showing the data on tableview with multiple section,
when I open tableView height of section 1 should be 0. If I click a button in section 0 the height of the section 1 will be 150. For example if I click Agent button height of (want to) section cell show 150,I click builder button section hight will 0
I want to make the Section 1 visible on the button click from section 0
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) as! postaddTableViewCell1
cell.ownerButton.addTarget(self, action: #selector(FisrtButtonClick), for: .touchUpInside)
cell.agentButton.addTarget(self, action: #selector(FisrtButtonClick), for: .touchUpInside)
cell.builderButton.addTarget(self, action: #selector(FisrtButtonClick), for: .touchUpInside)
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell2", for: indexPath) as! postaddTableViewCell2
cell.checkbutton.tag = indexPath.row
cell.checkbutton.addTarget(self, action: #selector(checkbuttonClick) , for: .touchUpInside)
return cell
}
}
#objc func FisrtButtonClick(_ sender :UIButton)
{
let indexPath = IndexPath(row: 0, section: 0)
let cell = TableView.cellForRow(at: indexPath) as? postaddTableViewCell1
print(cell?.agentButton.titleLabel as Any)
if sender.tag == 10
{
cell?.ownerButton.backgroundColor = #colorLiteral(red: 0, green: 0.7254901961, blue: 0.4588235294, alpha: 1)
cell?.agentButton.backgroundColor = #colorLiteral(red: 0.768627451, green: 0.768627451, blue: 0.768627451, alpha: 1)
cell?.builderButton.backgroundColor = #colorLiteral(red: 0.768627451, green: 0.768627451, blue: 0.768627451, alpha: 1)
}else if sender.tag == 11
{
cell?.ownerButton.backgroundColor = #colorLiteral(red: 0.768627451, green: 0.768627451, blue: 0.768627451, alpha: 1)
cell?.agentButton.backgroundColor = #colorLiteral(red: 0, green: 0.7254901961, blue: 0.4588235294, alpha: 1)
cell?.builderButton.backgroundColor = #colorLiteral(red: 0.768627451, green: 0.768627451, blue: 0.768627451, alpha: 1)
} else if sender.tag == 12
{
cell?.ownerButton.backgroundColor = #colorLiteral(red: 0.768627451, green: 0.768627451, blue: 0.768627451, alpha: 1)
cell?.agentButton.backgroundColor = #colorLiteral(red: 0.768627451, green: 0.768627451, blue: 0.768627451, alpha: 1)
cell?.builderButton.backgroundColor = #colorLiteral(red: 0, green: 0.7254901961, blue: 0.4588235294, alpha: 1)
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == 0
{
return 80
}
if indexPath.section == 1
{
return 0
}
return 80
}
Check if the required button is clicked in the FisrtButtonClick method and set a boolean that is accessible to heightForRowAt. After toggling the boolean you can just reload the section you require (also cleaned up your code lil bit).
var selectedAgent = false
#objc func firstButtonClick(_ sender: UIButton) {
if sender.currentTitle == "Agent" {
selectedAgent = true
tableView.reloadSections([1], with: .automatic)
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == 1 && !selectedAgent {
return 0
}
return 80
}
According to the codes below, the first time I run the application.
The first 3 lines are working correctly.
But when I scroll up and down.
Some lines also change.
When I make a little more up and down
It changes to other lines
How can i solve this problem
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = KategoriEkleCell()
var KategoriId :String = ""
if tableView == tableView {
cell.selectionStyle = .none
cell = self.tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath as IndexPath) as! KategoriEkleCell
cell.itemLabel.text = (AltKategoriKayit[indexPath.section][indexPath.row] as? [String:String])?["kategoriadi"]
cell.itemLabel.font = UIFont(name:"OpenSans-Light", size: 14.0)
KategoriId = ((AltKategoriKayit[indexPath.section][indexPath.row] as? [String:String])?["kategoriid"])!
if (KategoriId) == (MenuKategoriKayit[indexPath.row]["kategoriid"]!) {
cell.EkleButton.layer.cornerRadius = 2
cell.EkleButton.layer.borderWidth = 1
cell.EkleButton.layer.borderColor = UIColor(red: 255/255, green: 56/255, blue: 107/255, alpha: 1.0).cgColor
cell.EkleButton.backgroundColor = UIColor(red: 255/255, green: 56/255, blue: 107/255, alpha: 1.0)
cell.EkleButton.setTitleColor(UIColor.white, for: .normal)
cell.EkleButton.clipsToBounds = true
}else {
cell.EkleButton.layer.cornerRadius = 2
cell.EkleButton.layer.borderWidth = 1
cell.EkleButton.layer.borderColor = UIColor(red: 255/255, green: 56/255, blue: 107/255, alpha: 1.0).cgColor
cell.EkleButton.clipsToBounds = true
}
}
return cell
}
Right employee
Faulty employee. when I scroll up and down.
As mentioned in the comments cells are reused.
You have to ensure that any UI element is set to a defined state in cellForRow. I moved the duplicate lines which both are executed in the if and else branch out of the if - else scope for better readability.
By the way the parentheses in the if line are not needed either
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let specialRed = UIColor(red: 1.0, green: 56/255, blue: 107/255, alpha: 1.0)
let cell = self.tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath) as! KategoriEkleCell
cell.selectionStyle = .none
cell.itemLabel.text = (AltKategoriKayit[indexPath.section][indexPath.row] as? [String:String])?["kategoriadi"]
cell.itemLabel.font = UIFont(name:"OpenSans-Light", size: 14.0)
let KategoriId = ((AltKategoriKayit[indexPath.section][indexPath.row] as? [String:String])?["kategoriid"])!
cell.EkleButton.layer.cornerRadius = 2
cell.EkleButton.layer.borderWidth = 1
cell.EkleButton.clipsToBounds = true
cell.EkleButton.layer.borderColor = specialRed.cgColor
if KategoriId == MenuKategoriKayit[indexPath.row]["kategoriid"]! {
cell.EkleButton.backgroundColor = specialRed
cell.EkleButton.setTitleColor(UIColor.white, for: .normal)
} else {
cell.EkleButton.backgroundColor = UIColor.white
cell.EkleButton.setTitleColor(specialRed, for: .normal)
}
return cell
}
Please consider that according to the naming convention variable names are supposed to start with a lowercase letter.
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
I have a tableview inside a viewcontroller. I have a little function to select all rows in the tableview. When I first display the viewcontroller and hit the select all button the function does not work. However, if I firstly select a row and then press the select all button, the function works as it should and all rows are selected. I'm not sure why this is happening. The tableview's delegate and data source have been set up in the storyboard.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:myTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell") as! myTableViewCell
cell.accessoryType = .None
if allJobsSelected {
let bgColorView = UIView()
bgColorView.backgroundColor = UIColor(red: 250/255, green: 182/255, blue: 17/255, alpha: 1)
cell.contentView.backgroundColor = UIColor(red: 250/255, green: 182/255, blue: 17/255, alpha: 1)
cell.selectedBackgroundView = bgColorView
cell.accessoryType = .Checkmark
cell.highlighted = false
cell.selected = true
// cell.accessoryType = .Checkmark
self.tableView.selectRowAtIndexPath(indexPath, animated: true, scrollPosition: UITableViewScrollPosition.None)
self.tableView(self.tableView, didSelectRowAtIndexPath: indexPath)
}
var job: Jobs!
job = jobs[UInt(indexPath.row)] as! Jobs
cell.reports2JobTitle.text = job.jobTitle
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.tableView.allowsMultipleSelection = true
if let cell:myTableViewCell = tableView.cellForRowAtIndexPath(indexPath) as? myTableViewCell {
let bgColorView = UIView()
bgColorView.backgroundColor = UIColor(red: 250/255, green: 182/255, blue: 17/255, alpha: 1)
cell.contentView.backgroundColor = UIColor(red: 250/255, green: 182/255, blue: 17/255, alpha: 1)
cell.selectedBackgroundView = bgColorView
cell.accessoryType = .Checkmark
cell.highlighted = false
self.tableView.selectRowAtIndexPath(indexPath, animated: true, scrollPosition: UITableViewScrollPosition.Bottom)
}
}
#IBAction func doSelectAll(sender: UIBarButtonItem) {
let totalRows = tableView.numberOfRowsInSection(0)
for row in 0..<totalRows {
tableView.selectRowAtIndexPath(NSIndexPath(forRow: row, inSection: 0), animated: false, scrollPosition: UITableViewScrollPosition.None)
}
}
It would probably be a good idea to move this line:
self.tableView.allowsMultipleSelection = true
to your viewDidLoad
You are not guaranteed that the didSelect is called immediately -- it might be that each select is turning off the previous one and then a single didSelect is being called on the last row.
Anytime I tap segmented control in UICell, immediately some other cell gets this segmented control in the same position. It looks like segmented control recognizes that not only this particular one was tapped but also some other one in other cell.
Have you ever encountered issue like this?
this is my custom cell implementation:
class QuestionYesNoCustomCellTableViewCell: UITableViewCell {
#IBOutlet weak var questionLabel: UILabel!
#IBOutlet weak var segmentControl: ADVSegmentedControl!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
segmentControl.items = ["TAK", "NIE"]
segmentControl.font = UIFont(name: "Avenir-Black", size: 12)
segmentControl.borderColor = UIColor.grayColor()
segmentControl.selectedIndex = 1
segmentControl.selectedLabelColor = UIColor.whiteColor()
segmentControl.unselectedLabelColor = UIColor.grayColor()
segmentControl.thumbColor = UIColor(red: 46.0/255.0, green: 204.0/255.0, blue: 113.0/255.0, alpha: 1.0)
segmentControl.addTarget(self, action: "segmentValueChanged:", forControlEvents: .ValueChanged)
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func segmentValueChanged(sender: AnyObject?){
if segmentControl.selectedIndex == 0 {
segmentControl.thumbColor = UIColor(red: 231.0/255.0, green: 76.0/255.0, blue: 60.0/255.0, alpha: 1.0)
segmentControl.selectedLabelColor = UIColor.whiteColor()
segmentControl.unselectedLabelColor = UIColor.grayColor()
}else if segmentControl.selectedIndex == 1{
segmentControl.thumbColor = UIColor(red: 46.0/255.0, green: 204.0/255.0, blue: 113.0/255.0, alpha: 1.0)
segmentControl.selectedLabelColor = UIColor.grayColor()
segmentControl.unselectedLabelColor = UIColor.whiteColor()
}
}
Also, I think it is worth to provide my tableView delegate methods implemented
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (dict2 as NSDictionary).objectForKey(dictKeysSorted[section])!.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: QuestionYesNoCustomCellTableViewCell = self.tableView.dequeueReusableCellWithIdentifier("Cell") as! QuestionYesNoCustomCellTableViewCell
cell.questionLabel.text = (dict2 as NSDictionary).objectForKey(dictKeysSorted[indexPath.section])![indexPath.row] as? String
if indexPath.row % 2 == 0 {
cell.backgroundColor = UIColor(red: 245.0/255.0, green: 245.0/255.0, blue: 245.0/255.0, alpha: 1.0)
}
else {
cell.backgroundColor = UIColor(red: 225.0/255.0, green: 225.0/255.0, blue: 225.0/255.0, alpha: 0.7)
}
return cell
}
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return dictKeysSorted[section]
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerCell = tableView.dequeueReusableCellWithIdentifier("CellHeader") as! CustomHeaderCell
headerCell.backgroundColor = UIColor(red: 20.0/255.0, green: 159.0/255.0, blue: 198.0/255.0, alpha: 1.0)
headerCell.headerLabel.text = dictKeysSorted[section]
return headerCell
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 70.0
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return dictKeysSorted.count
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 110.0
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
To recap what the problem actually is: In every tableView cell there is a segment control. When I change the position of the one located in first row, I scroll down and see that segment control in row 5 also has been moved despite the fact it should be in the default position.
Thanks in advance
EDIT:
I recognized one of the biggest problem in solutions below - they are good as long as you don't use section in tableView. The thing is, from what I have discovered right now, in each sections the rows are counted over from 0.
This might be the cause when you are using reusing the cells, when you scroll the cell you changed will be shown again for another row.
To avoid this when you reuse cell make sure you reset the data in it also
In your case you have to check if the segmented value is changed then change the segmented control value also in cellForRowAtIndexPath
Please let me know if you need more explanation.
Here is a sample project for you sampleTableReuse
It's because of reusable nature of UITableViewCells. You must keep track in your datasource selected segment index for each row. Then in cellForRowAtIndexPath you must set it properly for each cell.
example
define somewhere an enum with possible Answers:
enum Answer {
case Yes
case No
case None
}
then define and init your answers' array:
var answer = [Answer](count: numberOfQuestions, repeatedValue: .None)
in your cell's implementation add a method to configure a cell with Answer
func setupWithAnswer(answer: Answer)
{
var selectedIdex = UISegmentedControlNoSegment
switch answer {
case .Yes: selectedIdex = 0
case .No: selectedIdex = 1
default: break
}
self.segmentedControl.selectedSegmentIndex = selectedIdex
}
and finally, in your cellForRowAtIndex do after dequeuing
cell.setupWithAnswer(answer: self.answers[indexPath.row])