`Hello!
I have a tableview and 2 arrays.
When I switch between tabs the tableview reloads. In the first tab, I click on favorites, change the color and add the data to another array. When switching to the second tab, the color does not change. how can i implement this?
MyCell
protocol CellSubclassDelegate: class {
func gestureTapped(cell: StocksCell)
}
class StocksCell: UITableViewCell {
#IBOutlet weak var logoImageView: UIImageView!
#IBOutlet weak var tickerLabel: UILabel!
#IBOutlet weak var favouriteImageView: UIImageView!{ didSet {
let panGesture = UITapGestureRecognizer(target: self, action: #selector(tapToAddFavourite))
favouriteImageView.addGestureRecognizer(panGesture)
favouriteImageView.isUserInteractionEnabled = true
}
}
#IBOutlet weak var companyNameLabel: UILabel!
#IBOutlet weak var priceLabel: UILabel!
#IBOutlet weak var deltaLabel: UILabel!
var selectedCell = false
weak var delegate: CellSubclassDelegate?
override func awakeFromNib() {
super.awakeFromNib()
}
#objc private func tapToAddFavourite(_ recognizer: UITapGestureRecognizer) {
guard recognizer.state == .ended else { return }
if selectedCell{
favouriteImageView.tintColor = UIColor.lightGray
selectedCell = false
}else{
favouriteImageView.tintColor = UIColor.yellow
selectedCell = true
}
self.delegate?.gestureTapped(cell: self)
}
}
MyController
class StocksViewController: UIViewController, CellSubclassDelegate {
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var stocksLabel: UILabel! { didSet {
let tapGestureStocks = UITapGestureRecognizer(target: self, action: #selector(tapToStocks))
stocksLabel.addGestureRecognizer(tapGestureStocks)
stocksLabel.isUserInteractionEnabled = true
}
}
#IBOutlet weak var favouriteLabel: UILabel!{ didSet {
let tapGestureFavourite = UITapGestureRecognizer(target: self, action: #selector(tapToFavourite))
favouriteLabel.addGestureRecognizer(tapGestureFavourite)
favouriteLabel.isUserInteractionEnabled = true
}
}
fileprivate var stocksData = [StocksModel(n: "VNDX", f: "Vandex, LLC", t: "4 764,6 ₽", tt: "+55 ₽ (1,15%)"), StocksModel(n: "DDD", f: "Dandex, LLC", t: "1 764,6 ₽", tt: "+155 ₽ (1,15%)")]
var favouriteData = [StocksModel]()
let privateIdentifire = "StocksCell"
var isStocksSelected = true
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
#objc private func tapToFavourite(_ recognizer: UITapGestureRecognizer) {
guard recognizer.state == .ended else { return }
favouriteLabel.alpha = 1
favouriteLabel.font = favouriteLabel.font.withSize(28)
stocksLabel.alpha = 0.65
stocksLabel.font = stocksLabel.font.withSize(18)
stocksLabel.textAlignment = .center
isStocksSelected = false
tableView.reloadData()
}
#objc private func tapToStocks(_ recognizer: UITapGestureRecognizer) {
guard recognizer.state == .ended else { return }
favouriteLabel.alpha = 0.65
favouriteLabel.font = favouriteLabel.font.withSize(18)
stocksLabel.alpha = 1
stocksLabel.font = stocksLabel.font.withSize(28)
stocksLabel.textAlignment = .left
isStocksSelected = true
tableView.reloadData()
}
}
TABLEVIEW DATASOURCE
extension StocksViewController: UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let result = isStocksSelected ? stocksData.count : favouriteData.count
return result
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: privateIdentifire, for: indexPath) as! StocksCell
cell.delegate = self
if isStocksSelected{
cell.tickerLabel.text = stocksData[indexPath.row].name
cell.companyNameLabel.text = stocksData[indexPath.row].fullname
cell.priceLabel.text = stocksData[indexPath.row].ticker
cell.deltaLabel.text = stocksData[indexPath.row].tq
}else{
cell.tickerLabel.text = favouriteData[indexPath.row].name
cell.companyNameLabel.text = favouriteData[indexPath.row].fullname
cell.priceLabel.text = favouriteData[indexPath.row].ticker
cell.deltaLabel.text = favouriteData[indexPath.row].tq
}
return cell
}
func gestureTapped(cell: StocksCell) {
guard let indexPath = self.tableView.indexPath(for: cell) else {return}
if cell.selectedCell{
let dataStock = stocksData[indexPath.row]
favouriteData.append(dataStock)
}else{
favouriteData.remove(at: indexPath.row)
}
}
}
TABLEVIEW DELEGATE
extension StocksViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 68
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.layer.cornerRadius = 16
}
}
Change the color here:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: privateIdentifire, for: indexPath) as! StocksCell
cell.delegate = self
if isStocksSelected{
favouriteImageView.tintColor = UIColor.lightGray
cell.tickerLabel.text = stocksData[indexPath.row].name
cell.companyNameLabel.text = stocksData[indexPath.row].fullname
cell.priceLabel.text = stocksData[indexPath.row].ticker
cell.deltaLabel.text = stocksData[indexPath.row].tq
}else{
favouriteImageView.tintColor = UIColor.yellow
cell.tickerLabel.text = favouriteData[indexPath.row].name
cell.companyNameLabel.text = favouriteData[indexPath.row].fullname
cell.priceLabel.text = favouriteData[indexPath.row].ticker
cell.deltaLabel.text = favouriteData[indexPath.row].tq
}
return cell
}
Related
I have the following Custom TableViewCell
The red(minus) and green(plus) button counts the left label "1"(in code snippet var myQuantity). If I scroll up and down in the tableView the variable myQuantity is always reset to 1 for selected cells.
I read that I have to set the myQuantity in the cellForRowAt method. But how can I set the cell value with its own class variable when its changed via green and red button?
Here my Custom Cell Class:
class ArticleTableViewCell: UITableViewCell {
#IBOutlet var leftLabel: UILabel!
#IBOutlet var rightLabel: UILabel!
#IBOutlet var quantityLabel: UILabel!
var myQuantity = 0
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
self.quantityLabel.text = String(self.myQuantity)
self.leftLabel.sizeToFit()
self.rightLabel.sizeToFit()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
if selected {
self.myQuantity = 1
} else {
self.myQuantity = 0
}
self.quantityLabel.text = String(self.myQuantity)
}
#IBAction func addButton(_ sender: UIButton) {
if !self.isSelected { return }
self.myQuantity += 1
self.quantityLabel.text = String(self.myQuantity)
}
#IBAction func minusButton(_ sender: UIButton) {
if !self.isSelected { return }
if self.myQuantity == 1 { return }
self.myQuantity -= 1
self.quantityLabel.text = String(self.myQuantity)
}}
Here the cellForRowAt Method in my ViewController:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "customArticleCell", for: indexPath) as? ArticleTableViewCell {
let name: String! = categoryArticles[indexPath.row].name
let price = categoryArticles[indexPath.row].price
let price2f = String(format: "%.2f", price)
cell.accessoryType = .none
cell.leftLabel.text = name!
cell.rightLabel.text = "\(price2f) €"
if cell.isSelected {
cell.accessoryType = .checkmark
}
return cell
}
}
class ArticleTableViewCell: UITableViewCell {
#IBOutlet var leftLabel: UILabel!
#IBOutlet var rightLabel: UILabel!
#IBOutlet var quantityLabel: UILabel!
var addAction: (()->())?
var minusAction: (()->())?
override func awakeFromNib() {
super.awakeFromNib()
self.selectionStyle = .none
}
func setupCellWith(data: CategoryArticle) {
self.accessoryType = (data.isSelected == true) ? .checkmark : .none
self.leftLabel.text = data.name
let price2f = String(format: "%.2f", data.price)
self.rightLabel.text = "\(price2f) €"
}
#IBAction func addButton(_ sender: UIButton) {
self.addAction?()
}
#IBAction func minusButton(_ sender: UIButton) {
self.minusAction?()
}
}
struct CategoryArticle {
let name: String
let price: Double
var isSelected: Bool?
var quantity: Int?
}
let categoryArticles: [CategoryArticle] = []
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customArticleCell", for: indexPath) as! ArticleTableViewCell
let categoryArticle = categoryArticles[indexPath.row]
cell.setupCellWith(data: categoryArticle)
cell.minusAction = { [weak self] in
// Action you want to do like decrease the count in the model at indexPath.row and set selection in th model too and reload the tableView cell
}
cell.addAction = { [weak self] in
// Action you want to do like increase the count in the model at indexPath.row and set selection in th model too and reload the tableView cell
}
return cell
}
now cell value are dynamically and its look after calling api.
I want to make total of all tickets price at last. I refer this link How do I increment/decrement a label value with two buttons pressed in tableview Swift and make changes in my code but didn't work for me.
struct Product {
var price = 0
}
class TicketBookingVC: UIViewController , UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tblView: UITableView!
#IBOutlet weak var mainTblView: UIView!
var bookingDetails = NSDictionary()
var productArray = [Product]()
var product : Product!
private var counterValue = 1
var productIndex = 0
var counterLbl = UILabel()
#IBOutlet weak var bookBtn: UIButton!
#IBOutlet weak var eventImg: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
tblView.delegate = self
tblView.dataSource = self
for _ in 0...10{
productArray.append(Product(price: 1))
}
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 1
}
else if section == 1{
return 4
}
else{
return 1
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellfirst", for: indexPath)
cell.selectionStyle = .none
return cell
}
else if indexPath.section == 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellsecond", for: indexPath)
let mainViewCell = cell.contentView.viewWithTag(2000) as! UIView
let normalView = cell.contentView.viewWithTag(2001) as! UIView
let eventName = cell.contentView.viewWithTag(2003) as! UILabel
let eventPrice = cell.contentView.viewWithTag(2004) as! UILabel
counterLbl = cell.contentView.viewWithTag(2007) as! UILabel
let decrementBtn = cell.contentView.viewWithTag(2005) as! UIButton
let incrementBtn = cell.contentView.viewWithTag(2006) as! UIButton
decrementBtn.addTarget(self, action:#selector(self.decrementbuttonClicked), for: .touchUpInside)
incrementBtn.addTarget(self, action:#selector(self.incrementbuttonClicked), for: .touchUpInside)
product = productArray[indexPath.row]
counterLbl.text = "\(product.price)"
cell.selectionStyle = .none
return cell
}
else {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellthird", for: indexPath)
cell.selectionStyle = .none
return cell
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == 0{
return UITableView.automaticDimension
}
else{
return 80
//return UITableView.automaticDimension
}
}
#objc func decrementbuttonClicked() {
print("Button decrement")
if(counterValue != 1){
counterValue -= 1;
}
self.counterLbl.text = "\(counterValue)"
product.price = counterValue
}
#objc func incrementbuttonClicked() {
counterValue += 1;
self.counterLbl.text = "\(counterValue)"
product.price = counterValue
}
func addProductToCart(product: Product, atindex: Int) {
productArray[atindex] = product
calculateTotal()
}
func calculateTotal()
{
var totalValue = 0
for objProduct in productArray {
totalValue += objProduct.price
}
self.eventPrice.text = "Total \(totalValue)"
}
}
when I increment or decrement value of first cell it reflect in 4th cell. please help. I am new at swift.
This is due to cell reuse. You should set a model for each cell
Im trying to implement BEMCheckBox and the myCheckBox.delegate = self needs to be se in viewDidLoad.
How do I do this in a tableView?
I have done this to my cells and tableView:
Cell file for the tableView:
import UIKit
import BEMCheckBox
protocol SizeSelectionDelegate: NSObjectProtocol {
func didChooseSmall(cell: SizeSelectorCell)
func didChooseLarge(cell: SizeSelectorCell)
}
class SizeSelectorCell: UITableViewCell {
#IBOutlet weak var smallSizeCheckBox: BEMCheckBox!
#IBOutlet weak var largeSizeCheckBox: BEMCheckBox!
#IBOutlet weak var smallSizePriceLabel: UILabel!
#IBOutlet weak var largeSizePriceLabel: UILabel!
weak var delegate: SizeSelectionDelegate?
func didTap(_ checkBox: BEMCheckBox) {
if checkBox.tag == 0 {
delegate?.didChooseSmall(cell: self)
}
if checkBox.tag == 1 {
delegate?.didChooseLarge(cell:self)
}
}
}
TableViewController:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "InfoCell") as! InfoTableViewCell
cell.nameLabel.text = name
cell.detailLabel.text = detail
cell.smallPriceLabel.text = String (smallPrice)
cell.largePriceLabel.text = String (largePrice)
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "SizeSelector") as! SizeSelectorCell
cell.smallSizePriceLabel.text = String (smallPrice)
cell.largeSizePriceLabel.text = String (largePrice)
return cell
}
}
extension InfoTableViewController: SizeSelectionDelegate
{
func didChooseSmall(cell: SizeSelectorCell) {
size = "Small"
print(size)
}
func didChooseLarge(cell: SizeSelectorCell) {
size = "Large"
print(size)
}
}
You need to set the delegate cell.delegate = self inside cellForRowAt
let cell = tableView.dequeueReusableCell(withIdentifier: "SizeSelector") as! SizeSelectorCell
cell.delegate = self
cell.smallSizePriceLabel.text = String (smallPrice)
cell.largeSizePriceLabel.text = String (largePrice)
return cell
I have UITableViewCell with UITextView and UIView
I'm try to hide/show UIView
Constraints — TextView:
Trailing to Superview Equals 2
Leading to Superview Equals 2
Top to Superview Equals 2
Bottom to Superview Equals 40
UIVIew:
Trailing to Superview
Leading to Superview
Bottom to Superview
Height 35
In Cell class I'm connect TextView BottomConstraint
UITableViewCell class :
#IBOutlet weak var myTextView: UITextView!
#IBOutlet weak var detailView: UIView!
#IBOutlet weak var detailLabel: UILabel!
#IBOutlet weak var TextViewConstraintToBottom: NSLayoutConstraint!
override func awakeFromNib() {
super.awakeFromNib()
detailView.isHidden = true
if detailView.isHidden == true {
TextViewConstraintToBottom.constant = 0
} else {
TextViewConstraintToBottom.constant = 40
}
}
In ViewController with UITableView :
var handle: DatabaseHandle?
var ref: DatabaseReference?
var quoteList: [String] = []
var songArray: [String] = []
override func viewWillAppear(_ animated: Bool) {
myTableView.estimatedRowHeight = 100
myTableView.rowHeight = UITableViewAutomaticDimension
}
override func viewDidLoad() {
super.viewDidLoad()
myTableView.dataSource = self
myTableView.delegate = self
dataCatch()
}
func dataCatch() {
ref = Database.database().reference()
handle = ref?.child("Цитаты").child("\(cat)").child("\(quoteNAme)").observe(.childAdded, with: { (snapshot) in
let username = snapshot.value as? NSDictionary
if let us = username?["name"] {
self.quoteList.append(us as! String)
self.quoteList = self.quoteList.filter(){$0 != "1"}
self.myTableView.reloadData()
}
if let us = username?["song"].unsafelyUnwrapped {
self.celT?.detailView.isHidden = false
self.songArray.append(us as! String)
self.myTableView.reloadData()
}
})
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! QuoteTableVC
let indexP = indexPath.row
cell.myTextView.text = quoteList[indexP]
cell.detailLabel.text = songArray[indexP]
return cell
}
In database I have structure
I decided
In ViewController :
func dataCatch() {
ref = Database.database().reference()
handle = ref?.child("Цитаты").child("\(cat)").child("\(quoteNAme)").observe(.childAdded, with: { (snapshot) in
let username = snapshot.value as? NSDictionary
if let us = username?["name"] {
self.quoteList.append(us as! String)
self.quoteList = self.quoteList.filter(){$0 != "1"}
self.myTableView.reloadData()
}
if snapshot.hasChild("song") {
let us = username?["song"]
self.songArray.append(us as! String)
} else {
let tet = "1"
// self.celT?.detailView.isHidden = true
self.songArray.append(tet as! String)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
cell.detailLabel.text = songArray[indexP]
if cell.detailLabel.text != "1" {
cell.detailView.isHidden = false
cell.butConstraint.constant = 40
} else {
cell.detailView.isHidden = true
cell.butConstraint.constant = 0
}
In cellForRow
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UI TableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! QuoteTableVC
// hide = check your model whether it has song or not
if hide {
cell.TextViewConstraintToBottom.constant = 0
}
else {
cell.TextViewConstraintToBottom.constant = 40
}
}
I m trying to create a slider cell in a UItableview with swift, it appear, but it's not working, I want to display the value of it in live but it's not working, I tried to use action on the slider itself, I tried changed Editing Changed Method not working too.
Here is my cell code :
import UIKit
class SliderCell: UITableViewCell {
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var maxLegendLabel: UILabel!
#IBOutlet weak var minLegendLabel: UILabel!
#IBOutlet weak var slider: UISlider!
#IBOutlet weak var answerLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
slider.userInteractionEnabled = true
slider.continuous = true
// slider.addTarget(self, action: #selector(sliderValueChanged), forControlEvents: UIControlEvents.ValueChanged)
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
#IBAction func sliderAction(sender: UISlider) {
print("slider ACTION value")
print(sender.value)
}
func sliderValueChanged(sender: UISlider) {
print("slider value")
print(sender.value)
answerLabel.text = "Your choice : " + String(sender.value)
}
func displayBlock(block: Block){
titleLabel.text = block.title
minLegendLabel.text = block.range?.legendMin
maxLegendLabel.text = block.range?.legendMax
slider.minimumValue = Float((block.range?.min)!)!
slider.maximumValue = Float((block.range?.max)!)!
slider.value = 1
}
}
and here is how I declare it in my tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell method :
let cell = tableView.dequeueReusableCellWithIdentifier(CurrentFormTableView.CellIdentifiers.SliderCell, forIndexPath: indexPath) as! SliderCell
cell.displayQuestion(block)
cell.selectionStyle = UITableViewCellSelectionStyle.None
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 160.0
return cell
Add this in Table view cell:
sliderDemo = UISlider(frame:CGRectMake(0, 0, 200,20))
var numberOfSteps : NSInteger = numbers.count - 1
sliderDemo.minimumValue = 6.5
sliderDemo.maximumValue = 4.1
sliderDemo.continuous = true
sliderDemo.value = 4.0
sliderDemo.addTarget(self, action: "sliderValueDidChange:", forControlEvents: .ValueChanged)
self.view.addSubview(sliderDemo)
func sliderValueDidChange(sender:UISlider!)
{
println("number:\(sender.value)")
}
I added the slider to the Storyboard itself and in the code I did this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MenuTableViewCell
if indexPath.row == 0 {
cell.slider.alpha = 1
} else {
cell.slider.alpha = 0
}
return cell
}
It means that it will show the slider only on the first cell, and every other cell won't show it.
Of