Remove the subView inside Cell - swift

In my ViewController, I have a variable:
var shareButtonTapped = false
I want when I click the shareButton on the navigationBar, it will show the shareButton all of the cell, except the cell which indexPath.row == 0.
Here is the action of shareButton:
#IBAction func shareButtonTapped(sender: AnyObject) {
shareButtonTapped = !shareButtonTapped
collectionView.reloadData()
}
And here is the CollectionViewDataSource method:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! GiftCollectionViewCell
if shareButtonTapped {
cell.gift = gifts[indexPath.row]
let shareButton = FBSDKShareButton(frame: CGRect(x: 0, y: 0, width: 80, height: 30))
shareButton.tag = 1
let photo = FBSDKSharePhoto()
photo.image = gifts[indexPath.row].image
photo.userGenerated = true
let content = FBSDKSharePhotoContent()
content.photos = [photo]
content.contentURL = NSURL(string: "http://www.fantageek.com")
shareButton.shareContent = content
cell.contentView.addSubview(shareButton)
return cell
} else {
cell.gift = gifts[indexPath.row]
return cell
}
}
It worked:
But I want to click this shareButton on NavigationBar again, all of shareButton inside each cell will disappear. How to do this?
Any helps would be appreciated. Thanks.

Use removeFromSuperview() method inside your else block:
else {
cell.gift = gifts[indexPath.row]
for subview in cell.contentView.subviews {
if subview is FBSDKShareButton {
subview.removeFromSuperview()
}
}
return cell
}

Better approach will be to keep the share button always be part of cell. And show and hide the button based on status of shareButtonTapped of bar button.
Let's say your button name is shareImage then in cellForRow
cell.shareButton.hidden = false
if(shareButtonTapped){
cell.shareButton.hidden = true
}

Related

Programmatically Setting UIButton Font Removes "background Configuration" Section

I am attempting to change my font for my UIButton programmatically because it is in a UICollectionView. When I do this however, it removes the "background configuration" in the Attributes Inspector, an example is shown here. The reason why is because the text has to be set to "default" in order for the font to shown from the code. I need that area in order to add a corner style. I have shown my code below In which I have tried to programmatically add a corner style to no luck.
The attempted code specifically is in the "if" statement towards the bottom.
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.buttonLive.setTitle("Handling a Breakup", for: .normal) //set button title
cell.buttonLive.titleLabel!.font = UIFont(name: "Marker Felt", size: 20)
_ = UIButton.Configuration.CornerStyle.large
if indexPath.item == 0 { //first button
cell.buttonLive.backgroundColor = UIColor.darkGray //set button background
}
else if indexPath.item == 1 { //second button
cell.buttonLive.backgroundColor = UIColor.systemGray
cell.buttonLive.setTitle("Good Work", for: .normal)
}
else if indexPath.item == 2 { //3rd button
cell.buttonLive.backgroundColor = UIColor.darkGray
}
else { // for remaining buttons
cell.buttonLive.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 num
Use switch statement, this is how your collection view cellForItemAt look like:
cell.myButton.setTitle("Handling a Breakup", for: .normal) //set button title
cell.myButton.titleLabel?.font = UIFont(name: "Marker Felt", size: 20)
cell.myButton.layer.cornerRadius = 10
cell.myButton.clipsToBounds = true
switch indexPath.item {
case 1:
cell.myButton.backgroundColor = .link // add your color
cell.myButton.setTitle("Good Work", for: .normal)
default:
cell.myButton.backgroundColor = .white // add your color
}
return cell

CollectionView Custom cell Label Disappears on Scroll

I have a custom cell for my collectionview and one of the labels in the cell disappears when I scroll down and back up to the cell again.
Here is my cellForItemAt:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == productCollectionView {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Identifiers.ProductCell, for: indexPath) as? ProductCell {
if cartProducts.contains(products[indexPath.item]) {
//this is the product
var product = products[indexPath.item]
//get the index from cartProducts
let index = cartProducts.firstIndex(of: product)
//Get the cartcount and update the product
let cartCount: Int = cartProducts[index!].cartCount
product.cartCount = cartCount
products[indexPath.item] = product
//now set the updated product for cell.product
cell.product = products[indexPath.item]
cell.delegate = self
return cell
} else {
cell.product = products[indexPath.item]
cell.delegate = self
return cell
}
} else
if collectionView == categoryCollectionView{
//...this is another collection and not the collectionView that I have problem with
return cell
}
return UICollectionViewCell()
}
}
And here is what I have in y custom cell for the label that is disappearing when I scroll down and back up to the cell:
class ProductCell: UICollectionViewCell {
var product: Product!
{
didSet {
commonUIUpdate()
}
}
func commonUIUpdate() {
//set the price per amount and its unit
if product.pricePerAmountExist == true {
pricePerAmountLbl.isHidden = false
if let PricePerAmount = formatter.string(from: Double(product.pricePerAmount)/100 as NSNumber) {
let PricePerAmountVoume = Float(String(Double(product.pricePerAmountVolume)/100))?.clean ?? ""
pricePerAmountLbl.text = "\(PricePerAmount)/\(String(describing: PricePerAmountVoume))\(product.pricePerAmountUnit)"
}
} else
if product.pricePerAmountExist == false {
pricePerAmountLbl.isHidden = true
}
}
}
I have the label pricePerAmountLbl.isHidden set to true and false when needed but still I dont understand why its disappearing. When I dont set the hidden status for the label in the custom cell the content of the label gets repeated in all cell which is not right either.
Edit:
I added the following to the cell but still no success the problem is still there
else if product.pricePerAmountExist == false {
pricePerAmountLbl.isHidden = true
} else {
pricePerAmountLbl.isHidden = false
}
You are not handling all cases. Your label stays hidden because it was set hidden in the previous cell. You might want to alter you code to cover for the missing case. Hope it helps:
else if product.pricePerAmountExist == false {
pricePerAmountLbl.isHidden = true
} else {
pricePerAmountLbl.isHidden = false
pricePerAmountLbl.text = "This case was not handled before"
}
There was nothing wrong with my code! The error was happening in storyboard. My label was stored in a stackview and that stackview was stored in another stackview; when I was scrolling and the label would go hidden the stackview height would have gone to zero and it stayed at zero even though I unhide the label.

Why my checkbox in custom cell shows different behaviour while selecting and scrolling in swift?

I have a xib view in which I took a tableView with a customcell xib. In this custom cell I have a checkbox button which behaves like check and uncheck using custom cell. But when ever I click the first cell checkbox as tick the multiple of 9th cell like 9th row cell, 18th row cell, .....also became ticked. and while scrolling the checkbox tick option is changing between cells. I am not able to know why this is happening..??
I have registered cell xib view as:
override func viewDidLoad() {
super.viewDidLoad()
//Register custom cell
let nib = UINib(nibName: "CustomOneCell", bundle: nil)
AddOnTableView.registerNib(nib, forCellReuseIdentifier: "addoncell")
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return ADDONITEMS.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:CustomOneCell = AddOnTableView.dequeueReusableCellWithIdentifier("addoncell") as! CustomOneCell
let item: AddOnItems = ADDONITEMS[indexPath.row]
cell.addOnName.text = item.name
cell.addOnPrice.text = "£\(item.price!)"
return cell
}
For checkbox I have added a custom class as below:
var isCheckedAddOnGlobal = Bool()
class AddOnCheckBox: UIButton {
let checkedImage = UIImage(named: "checkboxredtick.png")! as UIImage
let unCheckedImage = UIImage(named:"checkbox untick.png")!as UIImage
//bool property
var ischecked:Bool = false{
didSet{
//print(ischecked)
if ischecked == true{
self.setImage(checkedImage, forState: .Normal)
}else{
self.setImage(unCheckedImage, forState: .Normal)
}
}
}
override func awakeFromNib() {
self.addTarget(self, action:#selector(CheckBox.buttonClicked(_:)), forControlEvents: UIControlEvents.TouchUpInside)
self.ischecked = false
}
func buttonClicked(sender: UIButton) {
if (sender == self) {
if ischecked == true{
ischecked = false
isCheckedAddOnGlobal = false
}else{
ischecked = true
isCheckedAddOnGlobal = true
}
}
}
}
This is happening because you are reusing the TableViewCell, To solve your problem you can try something like this, first create an array of Int that give you selected row and use that array inside cellForRowAtIndexPath method.
var selectedItems = [Int]()
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:CustomOneCell = AddO nTableView.dequeueReusableCellWithIdentifier("addoncell") as! CustomOneCell
let item: AddOnItems = ADDONITEMS[indexPath.row]
cell.addOnName.text = item.name
cell.addOnPrice.text = "£\(item.price!)"
cell.checkBoxBtn.tag = indexPath.row
if (selectedItems.contains(indexPath.row)) {
cell.checkBoxBtn.setImage(UIImage(named:"checkbox untick.png"), forState: .Normal)
}
else {
cell.checkBoxBtn.setImage(UIImage(named: "checkboxredtick.png"), forState: .Normal)
}
cell.checkBoxBtn.addTarget(self, action:#selector(self.buttonClicked(_:)), forControlEvents: UIControlEvents.TouchUpInside)
return cell
}
func buttonClicked(sender: UIButton) {
if (self.selectedItems.contains(sender.tag)) {
let index = self.selectedItems.indexOf(sender.tag)
self.selectedItems.removeAtIndex(index)
}
else {
self.selectedItems.append(sender.tag)
}
self.tableView.reloadData()
}
Best way is on selecting cell call
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath) as! CustomOneCell
cell.buttonClicked()
}
and change buttonClicked method to
func buttonClicked() {
...
}
I would make an object, which contains the product information and a boolean, to check if the product has been selected or not.
If you make it this way, the checkmarks will appear correct. When you are scrolling on a tableview, then it loads the data everytime it shows new cells.
Right now, it only knows that the index etc. 9 is selected, and when you scroll down and load new cells, then the index 9 will be selected automatic again.
Try something like this:
Example
class Product {
var productName = "Test"
var isSelected: Bool = false
}
Under your cellForRowAtIndexPath
if product.isSelected == true {
cell.checkBoxBtn.setImage(UIImage(named:"checkbox untick.png"), forState: .Normal)
} else {
cell.checkBoxBtn.setImage(UIImage(named: "checkboxredtick.png"), forState: .Normal)
}

UITableview with custom cells

Hi I am having a problem in my app
I am using UITableView with the custom cell. In each cell, I have a
checkbox, when I check it, it is getting the cell’s element into a
set. Everything is working correctly except a small problem.
The Problem:
2
As in the image when I click on the first row, the 10th row is seeming
like checked. The image changed to checked but in practice, it did
not occur in my set.
Here is the related part of the code
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: TblCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as! TblCell
cell.labelInCell.text = tableData[indexPath.row]//data.myFunc().myset[indexPath.row]
cell.checkBoxInCell.tag = indexPath.row
cell.checkBoxInCell.addTarget(self, action: Selector("yourCheckBoxClicked:"), forControlEvents: .TouchUpInside)
// cell.images.image = UIImage(named: tableData[indexPath.row])
// if images name is same as in tableData put it in front of label
return cell
}
func yourCheckBoxClicked(cbx:UIButton){
let picked = self.tableData[cbx.tag]
if choosenSet.contains(picked) {
choosenSet.remove(picked) // uncheck
} else {
choosenSet.insert(picked) // check
}
print(choosenSet)
}
Number of rows in section ->
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableData.count
}
Checkboxes class ->
class checkBox: UIButton {
//images
let checkedImage = UIImage(named: "button_checkboxFilled")
let uncheckedImage = UIImage(named: "button_checkboxEmpty")
// Bool Property
var isChecked : Bool = false {
didSet{
if isChecked == true{
self.setImage(checkedImage, forState: .Normal)
}else {
self.setImage(uncheckedImage, forState: .Normal)
}
}
}
override func awakeFromNib() {
self.addTarget(self, action: "buttonClicked:" , forControlEvents: UIControlEvents.TouchUpInside)
self.isChecked = false
}
func buttonClicked (sender:UIButton) {
if (sender == self) {
if isChecked == true {
isChecked = false
}else {
isChecked = true
}
}
}
}
This is because of cells reusage. You should just add this line to your func tableView(tableView:cellForRowAtIndexPath:) method:
cell.checkBoxInCell.isChecked = choosenSet.contains(tableData[indexPath.row])
Your cells are reused, quick solution which will work fine as your table view doesn't have a lot of cells:
let cell: TblCell = self.tableView.dequeueReusableCellWithIdentifier("cell" + String(indexPath.row)) as! TblCell
If your tableView has many rows than you should have "cell" identifier and update the selection style on each cellForRowAtIndexPath call

swift tableview how to select all rows

I have Button in tableview I want when I press that button will select all cell rows, how to do that? I tried alot but I got nothing
I'm so confused how to make the button contact the cell
I've tried to make var like this
var x = false
then I do like
if( x == true ) { //Code }
and when you press the button it will be true
but I don't know in which func I should put this ? and I don't know how to select all rows
Could someone help me how to Select \ Deselect all rows in cell when pressing button in tableview.
Thank you so much!
var selectedUsernameArray : NSMutableArray = []
var username1Array : NSMutableArray = ["hel","dsf","fsdg"]//just a sample
Initially button name should be "Select all"
Button action :
#IBAction func buttonAction(sender: UIButton) {
if(sender.titleLabel?.text == "Select all")
{
selectedUsernameArray .addObjectsFromArray(username1Array as [AnyObject])
sender.titleLabel?.text = "Deselect all"
}
else
{
selectedUsernameArray .removeAllObjects();
sender.titleLabel?.text = "Select all"
}
self.tableView .reloadData()
}
tableview delegate
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
var ob: AnyObject = username1Array .objectAtIndex(indexPath.row);
cell.textLabel?.text = ob as? String;
if(selectedUsernameArray .containsObject(ob))
{
cell.backgroundColor = UIColor.blueColor();
}
else
{
cell.backgroundColor = UIColor.whiteColor();
}
return cell
}
var isSelectAll = false; //global variable
isSelectAll = true;//on button action
self.tableView.reloadData()//on button action
in cellForRowAtIndexPath method
if(isSelectAll==true)
{
cell.backgroundColor = UIColor.blueColor();
}
else
{
cell.backgroundColor = UIColor.white();
}
In cellForRowAtIndexPath:
UITableViewCell *cell...
cell.accesoryType = isSelectAll ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;