why my first cell on collection view always show the wrong data? - ios

I have collection view of products like the image below
if the product is in stock, the the button will be black, otherwise the button background color will be yellow.
but as you can see from the file gif in here: http://g.recordit.co/HTEVw88Tt4.gif
the first product (index = 0) from the image slider initially has black button (stock is still available), in the array it only has 1 product that out of stock, but after I scroll to right and then back to the first index (index = 0) then suddenly the button become yellow (as if now it has 2 product that out of stock) even though the product that out of stock (yellow button) is only one product.
how to solve this issue?
here is the simplified class of the product:
class Product {
var productID : Int = 0
var name : String = ""
var quantityFromServer: Int = 0
var lowLimit : Int = 0
var isInStock : Bool {
return quantityFromServer > lowLimit ? true : false
}
convenience init(dictionary: [String:Any]) {
self.init()
name = dictionary["products_name"] as? String ?? ""
quantityFromServer = dictionary["products_quantity"] as? Int ?? 0
lowLimit = dictionary["low_limit"] as? Int ?? 0
}
}
in the view controller I set the cellForRow at using the code below
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == firstListProductCollectionView {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: HomeStoryBoardData.CollectionViewIdentifiers.productSliderCell.rawValue, for: indexPath) as! ListProductCell
let selectedProduct = firstProducts[indexPath.item]
cell.minimumOrderQuantity = selectedProduct.minimumOrderQuantity
cell.stepperValue = selectedProduct.quantityInCart
cell.productData = selectedProduct
cell.delegate = self
cell.collectionView = firstListProductCollectionView
cell.indexPath = indexPath
return cell
}
}
and here is the code on my collection view cell
class ListProductCell: UICollectionViewCell {
#IBOutlet weak var addToCartButton: UIButton!
#IBOutlet weak var counterStackView: UIStackView!
#IBOutlet weak var textFieldStepper: UITextField!
#IBOutlet weak var decrementButton: UIButton!
#IBOutlet weak var incrementButton: UIButton!
#IBOutlet weak var loveButtonHeightConstraint: NSLayoutConstraint!
#IBOutlet weak var loveButtonWidthConstraint: NSLayoutConstraint!
var minimumOrderQuantity = 0
var stepperValue = 0
var indexPath: IndexPath?
var collectionView : UICollectionView?
var delegate: ListProductCellDelegate?
var productData : Product? {
didSet {
updateUI()
checkIfProductIsInStock()
}
}
override func awakeFromNib() {
super.awakeFromNib()
setSpecialConstraint()
}
func checkIfProductIsInStock() {
guard let product = productData else {return}
if !product.isInStock {
showAddToCartButton(status: true)
addToCartButton.isEnabled = false
addToCartButton.setTitle("HABIS", for: .normal)
addToCartButton.setTitleColor(.black, for: .normal)
addToCartButton.backgroundColor = AppColor.mainYellow.getUIColor()
}
}
}
I use checkIfProductIsInStock() method in the property observer of productData to check whether to show yellow button or black button.

Cells are dequeued , you need else here
if product.isInStock {
// supply in stock logic here
}
else {
showAddToCartButton(status: true)
addToCartButton.isEnabled = false
addToCartButton.setTitle("HABIS", for: .normal)
addToCartButton.setTitleColor(.black, for: .normal)
addToCartButton.backgroundColor = AppColor.mainYellow.getUIColor()
}

This happens because of the behavior of dequeueing the cells. At this point, I would recommend to override prepareForReuse():
Performs any clean up necessary to prepare the view for use again.
In your custom UICollectionViewCell class, add:
override func prepareForReuse() {
super.prepareForReuse()
// do the reset/cleanup here...
}

Related

Table View Cell has no Initialiser

I am trying to display table view cell property into different table view cell when button I clicked . I am using story board . I added the Horizontal and vertical stack to contains the image and label properties . I want to display this property into another table view cell when user clicked the show button . In cellFor row function i defined the button action property . I am getting following error .Class 'DetailsViewCell' has no initializers. Cannot use instance member 'mc' within property initializer; property initializers run before 'self' is available
Here is the screenshot of the both view controller .
Here is the code .
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// guard let cell = tableView.dequeueReusableCell(withIdentifier: MovieCell.identifier, for: indexPath) as? MovieCell
// else { return UITableViewCell() }
let cell = tableView.dequeueReusableCell(withIdentifier: MovieViewCell.identifier, for: indexPath) as! MovieViewCell
cell.showButton.tag = indexPath.row
cell.showButton.addTarget(self, action: Selector("movieDetails"), for: .touchUpInside)
let row = indexPath.row
let title = presenter.getTitle(by: row)
let overview = presenter.getOverview(by: row)
let data = presenter.getImageData(by: row)
cell.configureCell(title: title, overview: overview, data: data)
return cell
}
}
Here is the code in identifier class with table view cell.
class MovieViewCell: UITableViewCell {
static let identifier = "MovieViewCell"
#IBOutlet weak var mainStackView: UIStackView!
#IBOutlet weak var movieImage: UIImageView!
#IBOutlet weak var movieTtile: UILabel!
#IBOutlet weak var movieOverview: UILabel!
#IBOutlet weak var showButton: UIButton!
#IBAction func movieDetails(_ sender: UIButton) {
var dc : DetailsViewCell
movieTtile = dc.movieTitle
movieOverview = dc.movieOverview
movieImage = dc.movieImage
}
func configureCell(title: String?, overview: String?, data: Data?) {
movieTtile.text = title
movieOverview.text = overview
if let imageData = data{
movieImage.image = UIImage(data: imageData)
}
}
}
Here is the code for Details view cell.
class DetailsViewCell: UITableViewCell {
#IBOutlet weak var movieTitle: UILabel!
#IBOutlet weak var movieOverview: UILabel!
#IBOutlet weak var movieImage: UIImageView!
var mc : MovieViewCell
movieTitle = mc.movieTtile
movieOverview = mc.movieOverview
movieImage = mc.movieImage
}
import UIKit
var loginData = ["", "", ""]
class LoginDataCell: UITableViewCell, UITextFieldDelegate {
#IBOutlet weak var txtLoginData: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func textFieldDidEndEditing(_ textField: UITextField) {
if textField.tag == 0 {
loginData[0] = textField.text
} else if textField.tag == 1 {
loginData[1] = textField.text
} else if textField.tag == 2 {
loginData[2] = textField.text
}
}
}

how to pass data from one Tableview to another Tableview when button is pressed in cell?

Im trying to pass data from the ViewController to my CartViewController. The cells in the ViewController have 3 buttons(optionBtns) that have a price and weight label above each of them.
What Im trying to do is have the optionBtn selected pass the label data above it once the ATC button is pressed
the ATC button in the cell passes the data of image, name, category, and optionBtn data to the CartViewController cells(CartCell)
how would I be able to pass selected data to the CartVC when the ATC is pressed to present selected item Name, Image, and Category in cell with selected optionBtn data(Price & Weight)
I am also using Cloud Firestore to post data to populate my VC cells
class Cell: UITableViewCell {
weak var items: Items!
#IBOutlet weak var name: UILabel!
#IBOutlet weak var category: UILabel!
#IBOutlet weak var productImage: UIImageView!
#IBOutlet weak var weightOne: UILabel!
#IBOutlet weak var weightTwo: UILabel!
#IBOutlet weak var weightThree: UILabel!
#IBOutlet weak var priceOne: UILabel!
#IBOutlet weak var priceTwo: UILabel!
#IBOutlet weak var priceThree: UILabel!
#IBOutlet weak var addToCart: RoundButton!
#IBOutlet weak var optionBtn1: RoundButton!
#IBOutlet weak var optionBtn2: RoundButton!
#IBOutlet weak var optionBtn3: RoundButton!
var addActionHandler: (() -> Void)?
func configure(withItems items: Items) {
name.text = items.name
category.text = items.category
image.sd_setImage(with: URL(string: items.image))
priceOne.text = items.price1
priceTwo.text = items.price2
priceThree.text = items.price3
weightOne.text = items.weight1
weightTwo.text = items.weight2
weightThree.text = items.weight3
self.items = items
}
var lastSelectedButton = UIButton()
#IBAction func cartTypeSelected(_ sender: RoundButton) {
lastSelectedButton.isSelected = false; do {
self.lastSelectedButton.backgroundColor = UIColor.blue
lastSelectedButton = sender
sender.isSelected = true; do {
self.lastSelectedButton.backgroundColor = UIColor.lightGreen
}
}
#IBAction func atcBtn(_ sender: UIButton) {
self.addActionHandler?()
}
}
class CartViewController: UIViewController {
var items: Items!
#IBOutlet weak var cartTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
cartTableView.dataSource = self
cartTableView.delegate = self
}
}
extension CartViewController: UITableViewDataSource, UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Cart.currentCart.cartItems.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CartCell", for: indexPath) as! CartCell
let cart = Tray.currentCart.cartItems[indexPath.row]
cell.configure(withItems: cart)
return cell
}
}
class CartCell: UITableViewCell {
var selctedBtn: Cell?
#IBOutlet weak var lblMealName: UILabel!
#IBOutlet weak var imageUrl: UIImageView!
#IBOutlet weak var lblSubTotal: UILabel!
#IBOutlet weak var lblWeight: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
func configure(withItems items: Items) {
// lblWeight.text = "\(items.weight1)"
lblMealName.text = "\(items.category): \(items.name)"
let formatter = NumberFormatter()
formatter.maximumFractionDigits = 2
formatter.numberStyle = .decimal
// lblSubTotal.text = "$\(formatter.string(for: items.price1)!)"
imageUrl.sd_setImage(with: URL(string: items.imageUrl))
if selctedBtn?.optionBtn1.isSelected == true {
lblSubTotal.text = "$\(formatter.string(for: items.price1)!)"
lblWeight.text = "\(items.weight1)"
} else if selctedBtn?.optionBtn2.isSelected == true {
lblSubTotal.text = "$\(formatter.string(for: items.price2)!)"
lblWeight.text = "\(items.weight2)"
} else if selctedBtn?.optionBtn3.isSelected == true {
lblSubTotal.text = "$\(formatter.string(for: items.price3)!)"
lblWeight.text = "\(items.weight3)"
}
}
}
class Cart {
static let currentCart = Cart()
var cartItems = [Items]()
}
If the idea is for firebase to handle all of your data then the data should go through firebase and not through the viewController. ie your Firebase db should have an items collection (or perhaps one per store) and your user should have a cart collection. When the use taps the add to cart button you add the item in question to that users cart collection in firebase then show the cartViewController. The cartViewController should subscribe to the cart collection on the current user and then populate its tableview from that firebase collection.
TLDR the typical design of a firebase app is that the firebase DB is the source of truth for the app, so you should write all changes to firebase and then simply observe these collections elsewhere in the app. This also insures that if the user edits the cart on another device that it will update itself on the iOS device with the new cart items.
You can pass the values in closures.
So, in your Cell class you could change your closure var to:
var addActionHandler: ((Int) -> Void)?
Then, in your addToCart button action, something along these lines:
#IBAction func atcBtn(_ sender: UIButton) {
// pass back the user selected values
var i = 0
switch lastSelectedButton {
case optionBtn1:
i = 1
case optionBtn2:
i = 2
default:
i = 3
}
self.addActionHandler?(i)
}
Create a .selectedOption property of your Items class, you should add one (of type Int). You can use that to track the user's selection.
Modify cellForAt in Cell:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? Cell else { return UITableViewCell() }
// use var to make item mutable
var item = itemSetup[indexPath.row]
cell.configure(withItem: item)
cell.addActionHandler = { (option: Int) in
print("Option selected = \(option)")
item.selectedOption = option
Cart.currentCart.items.append(item)
}
return cell
}
In your CartCell you can make the labels like this:
if items.selectedOption == 1 {
lblSubTotal.text = "$\(formatter.string(for: items.price1)!)"
lblWeight.text = "\(items.weight1)"
} else if items.selectedOption == 2 {
lblSubTotal.text = "$\(formatter.string(for: items.price2)!)"
lblWeight.text = "\(items.weight2)"
} else if items.selectedOption == 3 {
lblSubTotal.text = "$\(formatter.string(for: items.price3)!)"
lblWeight.text = "\(items.weight3)"
}

How to set specific row cell's image of tableView to dynamic image

As below gif showed, in the specific row of tableView, the playing song's image(Just Dance.mp3) is changed to dynamic image.
My main question is how to achieve this effect in my App, to use a GIF image or other approach? Need advice here.
What effect I want to achieve:
when a song is playing, the specific row cell's image is changed to dynamic image. (the main question)
if the song is paused, then that dynamic image stop to play.
when another song is selected to play, the previous song's(cell) image is resume to its album artwork.
Here is my snip code, I'm not test it yet since I'm not sure if I should use GIF or other approach.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
if resultSearchController.isActive {
cell.addButton.tag = indexPath.row
cell.songTitle.text = filteredTableData[indexPath.row].songName
cell.songArtist.text = filteredTableData[indexPath.row].artistName
cell.songArtwork.image = filteredTableData[indexPath.row].albumArtwork
return cell
} else {
cell.addButton.tag = indexPath.row
cell.songTitle.text = tableData[indexPath.row].songName
cell.songArtist.text = tableData[indexPath.row].artistName
cell.songArtwork.image = tableData[indexPath.row].albumArtwork
return cell
}
// set image of specific tableView row cell to GIF image
if indexPath.row == SongData.currentTrack {
let image = UIImage(named: "playing-gif-image")
cell.songArtwork.image = image
} else {
// do nothing
}
}
===================================================================
Update my code according to ATV's answer, currently I use static image to set different state of playing cell. Well I get interested to this fancy CAShapeLayer:), and I need time to learn about it then to set the dynamic image for the specific cell.
/ / / Model, SongData.swift
import UIKit
class SongData: NSObject, NSCoding {
var songName: String
var artistName: String
var albumName: String
var albumArtwork: UIImage
var url: URL
static var songList = [SongData]()
static var shuffleSongList = [SongData]()
static var currentTrack = 0
static var showCurrentPlayingSong = false
static var repeatSequence = "repeatList"
static var isPlaying = false
enum PlayingCellState {
case nonState
case playing
case paused
}
init(songName: String, artistName: String, albumName: String, albumArtwork: UIImage, url: URL) {
self.songName = songName
self.artistName = artistName
self.albumName = albumName
self.albumArtwork = albumArtwork
self.url = url
}
...
}
/ / / CustomCell.swift
import UIKit
class CustomCell: UITableViewCell {
#IBOutlet weak var songTitle: UILabel!
#IBOutlet weak var songArtist: UILabel!
#IBOutlet weak var songArtwork: UIImageView!
#IBOutlet weak var addButton: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
songArtwork.layer.cornerRadius = 8.0
}
func config(forState state: SongData.PlayingCellState) {
// setup your cell depends on state
switch state {
case .nonState:
print("nonState") //update cell to default state
case .playing:
songArtwork.image = UIImage(named: "Play")
case .paused:
songArtwork.image = UIImage(named: "Pause")
}
}
}
/ / / TableViewController
// use for track cell state, for playing dynamic image usage
func stateForCell(at indexPath: IndexPath) -> SongData.PlayingCellState {
// when firstly open the tab song list/app(with no song played), do not attach playing state image
if SongData.songList.count == 0 {
return .nonState
} else {
if indexPath.row == SongData.currentTrack {
return SongData.isPlaying ? .playing : .paused
} else {
return .nonState
}
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
if resultSearchController.isActive {
cell.addButton.tag = indexPath.row
cell.songTitle.text = filteredTableData[indexPath.row].songName
cell.songArtist.text = filteredTableData[indexPath.row].artistName
cell.songArtwork.image = filteredTableData[indexPath.row].albumArtwork
// return cell
} else {
cell.addButton.tag = indexPath.row
cell.songTitle.text = tableData[indexPath.row].songName
cell.songArtist.text = tableData[indexPath.row].artistName
cell.songArtwork.image = tableData[indexPath.row].albumArtwork
// return cell
}
cell.config(forState: stateForCell(at: indexPath))
return cell
}
/// Update, finally I make it worked, to involve lottie-ios library, and import it in CustomCell.swift, implement it in playAnimation(), but the pity thing is that animation repeat mode is not working, the animation just repeat once even I set the loopMode. I will search what is wrong later.
import UIKit
import Lottie
class CustomCell: UITableViewCell {
#IBOutlet weak var songTitle: UILabel!
#IBOutlet weak var songArtist: UILabel!
#IBOutlet weak var songArtwork: UIImageView!
#IBOutlet weak var view: UIView!
#IBOutlet weak var addButton: UIButton!
let animationView = AnimationView()
override func awakeFromNib() {
super.awakeFromNib()
songArtwork.layer.cornerRadius = 8.0
}
func playAnimation(){
let animation = Animation.named("366-equalizer-bounce")
animationView.animation = animation
// weird thing is that animation repeat is not working here...
animationView.loopMode = LottieLoopMode.repeat(3600.0)
animationView.play()
animationView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(animationView)
NSLayoutConstraint.activate([
animationView.heightAnchor.constraint(equalTo: view.heightAnchor),
animationView.widthAnchor.constraint(equalTo: view.widthAnchor)
])
}
func config(forState state: SongData.PlayingCellState) {
// setup your cell depends on state
switch state {
case .nonState:
print("nonState")
view.isHidden = true
case .playing:
view.isHidden = false
playAnimation()
case .paused:
view.isHidden = false
// to set this latter
// songArtwork.image = UIImage(named: "Pause")
}
}
}
For the implementing of:
"Is that a GIF image used or other dynamic image?" - You can choose any of the options below that is more preferable for you:
You can use GIF image (the similar question)
You can even
draw it by using UIBezierPath and CAShapeLayer (some
examples)
Or use lottie-ios library which can work with Adobe After Effects animations (eg you can use this)
Changing of the cell's state:
//e.g. add it to your presenter or wherever you are storing info about `currentTrack`
...
enum PlayingCellState {
case default
case playing
case paused
...
}
...
func stateForCell(at indexPath: IndexPath) -> PlayingCellState {
if indexPath.row == SongData.currentTrack {
return isPlaying? .playing : .paused
} else {
return .default
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
if resultSearchController.isActive {
cell.addButton.tag = indexPath.row
cell.songTitle.text = filteredTableData[indexPath.row].songName
cell.songArtist.text = filteredTableData[indexPath.row].artistName
cell.songArtwork.image = filteredTableData[indexPath.row].albumArtwork
return cell
} else {
cell.addButton.tag = indexPath.row
cell.songTitle.text = tableData[indexPath.row].songName
cell.songArtist.text = tableData[indexPath.row].artistName
cell.songArtwork.image = tableData[indexPath.row].albumArtwork
return cell
}
cell.config(forState: stateForCell(at: indexPath)
}
//add to your CustomCell
func config(forState state: PlayingCellState) {
// setup your cell depends on state
}

How to make DetailView change data by indexPath

I'm currently working on a Master-DetailView application and I'm stuck on how to make the data change....
I saw a great tutorial on how to do this :
Tutorial
But the guy is using a blank ViewController & I'm using a TableViewController With static Cells,So it doesn't work.
I want to put the data manually like
var Label1Data = ["You Tapped Cell 1,You Tapped Cell 2,You Tapped Cell 3"]
and it will show in the DetailView by the index path if i pressed the first cell the first data will show up in that Label...i know its not ideal to use static cells here but i do wanna use them design wise.
It will be great if any one could show me finally how can i put the data successfully like i said above and how the Tutorial does it.
MasterViewController Code:
import UIKit
import AVFoundation
class BarsViewController: UITableViewController,UISearchResultsUpdating,UISearchBarDelegate,UISearchDisplayDelegate,UITabBarControllerDelegate{
#IBOutlet var tableViewController: UITableView!
var audioPlayer = AVAudioPlayer()
var sel_val : String?
// TableView Data :
struct User {
var name: String
var streetName: String
var image: UIImage?
}
var allUsers: [User]!
var filteredUsers: [User]!
func createUsers(names: [String], streets: [String], images: [UIImage?]) -> [User] {
var users = [User]()
guard names.count == streets.count && names.count == images.count else { return users }
for (index, name) in names.enumerated() {
let user = User(name: name, streetName: streets[index], image: images[index])
users.append(user)
}
return users
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == self.tableView {
return self.names.count
} else {
return self.filteredUsers.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = self.tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
let user:User!
if tableView == self.tableView {
user = allUsers[indexPath.row]
} else {
user = filteredUsers[indexPath.row]
}
cell.photo.image = user.image
cell.name.text = user.name
cell.streetName.text = user.streetName
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
let object = self.storyboard?.instantiateViewController(withIdentifier: "BarProfileTableViewController") as! BarsProfile
let user:User!
if tableView == self.tableView {
user = allUsers[indexPath.row]
} else {
user = filteredUsers[indexPath.row]
}
print("username : \(user.name)")
print("streetName : \(user.streetName)")
MyIndex = indexPath.row
object.barImage = user.image!
object.barName = user.name
object.streetName = user.streetName
self.navigationController?.pushViewController(object, animated: true)
}
DetailView's Code:
import UIKit
import AVFoundation
import MapKit
class BarsProfile: UITableViewController,MKMapViewDelegate {
#IBOutlet var Distance: UILabel!
#IBOutlet var headerImage: UIImageView!
#IBOutlet var OnlineMenu: UIButton!
#IBOutlet var Address: UILabel!
#IBOutlet var ProfileMapView: MKMapView!
#IBOutlet var BarNameLBL: UILabel!
#IBOutlet var streetNameLBL: UILabel!
#IBOutlet var MusicLabel: UILabel!
#IBOutlet var KindOfBarCell: UITableViewCell!
var barName = String()
var barImage = UIImage()
var streetName = String()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
BarNameLBL.text = barName
streetNameLBL.text = streetName
navigationItem.title = barName
}
How it looks like : ( Red line is a label i would like to put data manually in)
you cant use a TableViewController for your purpose. Instead you can use a normal ViewController with labels and textfields.
In the above picture of yours, you can use a simple label of width = 1 and color = lightGrey so that you can get the same separator line as in the tableview.

How to alter a button in cell on click in swift ios?

I have a table layout inside a view which as a custom cell,The problem I'm facing is that the cells inside has a button i want to hide the button in cell on clicking it(only the one that is clicked should be hidden) how can i do thing in correct method?
ScrollCell.swift
class ScrollCell: UITableViewCell {
#IBOutlet weak var ProfilePic: SpringImageView!
#IBOutlet weak var UserName: SpringButton!
#IBOutlet weak var Closet: UILabel!
#IBOutlet weak var Style: UILabel!
//------//
#IBOutlet weak var MianImg: UIImageView!
//-------//
#IBOutlet weak var ProductName: UILabel!
#IBOutlet weak var LoveCount: UIButton!
#IBOutlet weak var Discount: UILabel!
#IBOutlet weak var OrginalPrice: UILabel!
#IBOutlet weak var Unliked: UIButton!
#IBOutlet weak var Liked: UIButton!
#IBOutlet weak var Comment: UIButton!
#IBOutlet weak var Share: SpringButton!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
override func layoutSubviews() {
ProfilePic.layer.cornerRadius = ProfilePic.bounds.height / 2
ProfilePic.clipsToBounds = true
}
}
ScrollController.swift
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1 // however many sections you need
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(try! Realm().objects(Feed))
var FeedModel = Feed()
let realm = try! Realm()
let tan = try! Realm().objects(Feed).sorted("ID", ascending: false)
return tan.count // however many rows you need
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// get an instance of your cell
cell = tableView.dequeueReusableCellWithIdentifier("ScrollCellDqueue", forIndexPath: indexPath) as! ScrollCell
IndexPath = indexPath.row
var FeedModel = Feed()
let realm = try! Realm()
let tan = try! Realm().objects(Feed).sorted("ID", ascending: false)
cell.ProfilePic.kf_setImageWithURL(NSURL(string:tan[indexPath.row].ProfilePic)!)
cell.UserName.setTitle(tan[indexPath.row].FullName, forState: .Normal)
cell.Style.text = tan[indexPath.row].StyleType
if tan[indexPath.row].UserType == "store_front"{
cell.Closet.text = "Store Front"
}else if tan[indexPath.row].UserType == "normal"{
cell.Closet.text = "Pri Loved"
}
//-----//
var SingleImage:String = ""
var ImageArray = tan[indexPath.row].ImageArraySet.componentsSeparatedByString(",")
SingleImage = ImageArray[0]
cell.MianImg.kf_setImageWithURL(NSURL(string:SingleImage)!)
//-----//
cell.ProductName.text = tan[indexPath.row].ItemName
cell.OrginalPrice?.text = "\(tan[indexPath.row].OrginalPrice)"
cell.LoveCount.setTitle("\(tan[indexPath.row].LikeCount)"+" Loves", forState: .Normal)
cell.Discount.text = "\(tan[indexPath.row].Discount)"+" % off"
if(tan[indexPath.row].LikeStatus){
cell.Unliked.hidden = true
cell.Liked.hidden = false
}
else if (!tan[indexPath.row].LikeStatus){
cell.Unliked.hidden = false
cell.Liked.hidden = true
}
cell.Unliked.tag = tan[indexPath.row].ID
cell.Liked.tag = tan[indexPath.row].ID
return cell
}
#IBAction func LikeBtn(sender: AnyObject) {
print(sender.tag)
print(IndexPath)
//here i want to know who i can hide the button i have clicked ?
}
Here i want to access the cell in which button is clicked and make changes to UI item inside that cell how can i do that ?
There are many ways to do it. One possible solution is use block.
Add this to ScrollCell
var didLikedTapped: (() -> Void)?
and receive the event of the LikedButton in the cell
#IBAction func LikeBtn(sender: AnyObject) {
didLikedTapped?()
}
Then in cellForRowAtIndexPath of viewController add this
cell.didLikedTapped = {[weak self] in
print(IndexPath)
}
Liked is uibutton in ScrollCell, i don't known, why can you add IBAction for it in ScrollController? . You must implement it in ScrollCell And code:
#IBAction func LikeBtn(sender: UIButton) {
print(sender.tag)
sender.hiden = true
}
And i think, if you have only one UIbutton, it will better. In there, like and unlike is 2 state of uibutton(seleted and none). When you click the button, change it's state
Update:
class sampleCell: UITableViewCell{
#IBOutlet var btnLike : UIButton!
#IBOutlet var btnUnLike : UIButton! // frame of 2 button is equal
override func awakeFromNib() {
super.awakeFromNib()
self.btnUnLike.hidden = true
// ...
}
func updateData(data:AnyObject){ // data's type is Feed
// set data for cell
// i think you should implement in here. and in ScollController call : cell.updateData() , it's better
/* e.x
self.ProductName.text = tan[indexPath.row].ItemName
self.OrginalPrice?.text = "\(tan[indexPath.row].OrginalPrice)"
self.LoveCount.setTitle("\(tan[indexPath.row].LikeCount)"+" Loves", forState: .Normal)
self.Discount.text = "\(tan[indexPath.row].Discount)"+" % off"
*/
}
#IBAction func likeTap(sender:UIButton){ // rememeber set outlet event for btnLike and btnUnLike is this function
if sender == self.btnLike{
self.btnLike.hidden = true
self.btnUnLike.hidden = false
// do s.t
}else if sender == self.btnUnLike{
self.btnLike.hidden = false
self.btnUnLike.hidden = true
// do s.t
}
}
}
Check if the following code help
#IBAction func LikeBtn(sender: AnyObject) {
var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
let indexPath = self.tableView.indexPathForRowAtPoint(position)
let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath!)! as
UITableViewCell
print(indexPath?.row)
}
give the LikeBtn the property indexpath, in cellForRowAtIndexPath method, pass the indexPath to the LikeBtn, then you will know which cell's LikeBtn clicked.
class LikeBtn: UIButton {
var indexPath: NSIndexPath?
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)
// here pass the indexpath to your button
cell.likeBtn.indexPath = indexPath
return cell
}
#IBAction func likeTap(sender: LikeBtn){
if let indexPath = sender.indexPath {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
//here you will know the exact cell, now you can hide or show your buttons
}
}
}

Resources