How do use different cell styles in a UITableView - ios

I'm creating a view for accessing settings in an app which will be presented in a UITableView. Some cells will have a UITableViewCellAccessoryDisclosureIndicator, I need one with a UISwitch, and another with a UISegmentedControl sort of like this:
In other words, I think I need custom cells. Through a lot of research, I've gotten pretty close but I can't wire up everything I've learned to work together. Here's what I've done:
Created three UITableViewCell classes:
class DisclosureCell: UITableViewCell {
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
class func defaultIdentifier() -> String {
return NSStringFromClass(self)
}
}
class SegmentedControlCell: UITableViewCell {
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
class func defaultIdentifier() -> String {
return NSStringFromClass(self)
}
}
class SwitchCell: UITableViewCell {
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
class func defaultIdentifier() -> String {
return NSStringFromClass(self)
}
}
I have my Sections class and Section struct that will provide the table view sections and each choice available:
class SettingsData {
func getSectionsFromData() -> [Section] {
var settings = [Section]()
let preferences = Section(title: "OPTIONS", objects: ["Formulas", "Lifts", "Units", "Allow 15 reps"])
let patronFeatures = Section(title: "PATRON FEATURES", objects: ["Support OneRepMax"])
let feedback = Section(title: "FEEDBACK", objects: ["Send Feedback", "Please Rate OneRepMax"])
settings.append(preferences)
settings.append(patronFeatures)
settings.append(feedback)
return settings
}
}
struct Section {
var sectionHeading: String
var items: [String]
init(title: String, objects: [String]) {
sectionHeading = title
items = objects
}
}
Finally, my UITableViewController:
class SettingsViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.topItem?.title = "Settings"
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: .Plain, target: self, action: #selector(self.dismissSettings(_:)))
}
func dismissSettings(sender: AnyObject?) {
self.dismissViewControllerAnimated(true, completion: nil)
}
// MARK: - Table view data source
var sections: [Section] = SettingsData().getSectionsFromData()
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sections.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].items.count
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section].sectionHeading
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("DisclosureCell", forIndexPath: indexPath)
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row]
return cell
}
I think what I need help with is:
As I create each cell, how do I determine which of my three types each cell is so I can display them based on type as well as dequeue each type properly
I created the func defaultIdentifier() -> String in each custom class AND specified the reuse identifiers in the Storyboard for each cell type. Do I need to do both?
do I need to register these cells or is that unnecessary because I'm using a storyboard?
I've found a lot of threads about this subject but either they're in Objective-C and/or they don't speak to the particular parts I seem to be stuck on.
Thanks!
UPDATE:
I've updated my override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell as follows:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = tableView.cellForRowAtIndexPath(indexPath)?.reuseIdentifier
if cellIdentifier == "DisclosureCell" {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "DisclosureCell")
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row]
return cell
} else if cellIdentifier == "SegmentedControlCell" {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "SegmentedControlCell")
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row]
return cell
}
else {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "SwitchCell")
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row]
return cell
}
}
I hope this is a step in the right direction but I'm still missing something because I get this error:
2016-07-28 07:15:35.894 One Rep Max[982:88043] Terminating app due to uncaught exception 'NSRangeException', reason: ' -[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 0]’
And I need to figure out a way for each cell to know which of the three types it SHOULD be, then based on which type it IS, I can set it up in the code above.
UPDATE 2
I've now got it kind of working by using the indexPath.row:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CustomTableViewCell", forIndexPath: indexPath) as! CustomTableViewCell
if indexPath.row == 0 {
cell.selectionStyle = .None
cell.textLabel!.text = sections[indexPath.section].items[indexPath.row]
cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
return cell
} else if indexPath.row == 1 {
cell.selectionStyle = .None
cell.textLabel!.text = sections[indexPath.section].items[indexPath.row]
//cell.accessoryView = useAuthenticationSwitch
let switchView: UISwitch = UISwitch()
cell.accessoryView = switchView
switchView.setOn(false, animated: false)
return cell
} else {
cell.selectionStyle = .None
cell.textLabel!.text = sections[indexPath.section].items[indexPath.row]
let segmentedControl: UISegmentedControl = UISegmentedControl(items: ["lbs", "kg"])
segmentedControl.selectedSegmentIndex = 0
segmentedControl.addTarget(self, action: nil, forControlEvents: .ValueChanged)
cell.accessoryView = segmentedControl
return cell
}
}
The problem is that by using the indexPath.row, not all of the rows have the correct accessoryView. In the example above, I want the first two rows to have disclosureIndicators, the third one to have the UISegmentedControl, and the fourth to have a UISwitch. Now, I completely understand why my code produces this - it's because the accessoryView is being determined by the cell's position. Instead, I want to be able to tell each cell as it's being created, "You're the cell for this setting, so you get a [fill in the blank] accessoryView". I have custom cell classes created for each type and tried to do what I'm trying to do with those but couldn't figure it out. You may notice that in the code above I went to one custom cell class and reuse identifier.
I suppose I could do things like if indexPath.row == 0 | 1 { blah, blah } but that approach won't hold up through each section. If I try to deal with each section like this, then the code will get messier than it already is. There must be a smarter way.
Is there?

I'd suggest you to use static cells (not prototype) for such screens like settings.
You can change type of cells in storyboard.
After you can assign IBOutlets to all controls and make them interact with your model.

Related

Scrolling tableview causes checkmark to disappear | addressing reusable cells in Swift 5

I use the following to mark rows in a tableview as either marked with a checkmark or unselected with no checkmark. The issue that I have stumbled on is when scrolling the tableView seems to reload and cause the checkmark to disappear.
I understand this is caused by reusable cells,
Is there an easy fix I can implement into the code below?
class CheckableTableViewCell: UITableViewCell {
var handler: ((Bool)->())?
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.selectionStyle = .none
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
self.accessoryType = selected ? .checkmark : .none
handler?(selected)
}
}
class TableViewController: UITableViewController {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CheckableTableViewCell
cell.handler = {[weak self](selected) in
selected ? self?.selectRow(indexPath) : self?.unselectRow(indexPath)
}
let section = sections[indexPath.section]
let item = section.items[indexPath.row]
cell.textLabel?.textAlignment = .left
cell.selectionStyle = .none
let stringText = "\(item.code)"
cell.textLabel!.text = stringText
return cell
}
UPDATE:
struct Section {
let name : String
var items : [Portfolios]
}
struct Portfolios: Decodable {
let code: String
var isSelected: Bool
enum CodingKeys : String, CodingKey {
case code
}
}
You need to create your data model having a property called isSelected: Bool then use this to decide when a row should be selected or not. Note that you have to toggle this property every time didSelectRowAt(indexPath:) is triggered.
Example
// Declare your model with one of the property called isSelected
class MyModel {
var isSelected: Bool
init(isSelected: Bool) {
self.isSelected = isSelected
}
}
class TableViewController: UITableViewController {
// Dummy data note that it contains array of "MyModel" which have the "isSelected" property.
private var myModels: [MyModel] = [MyModel(isSelected: false),MyModel(isSelected: true),MyModel(isSelected: true),MyModel(isSelected: false) ]
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CheckableTableViewCell
cell.handler = {[weak self](selected) in
/// Note that I am using selected Property here
myModels[indexPath.row].isSelected ? self?.selectRow(indexPath) : self?.unselectRow(indexPath)
}
let section = sections[indexPath.section]
let item = section.items[indexPath.row]
cell.textLabel?.textAlignment = .left
cell.selectionStyle = .none
let stringText = "\(item.code)"
cell.textLabel!.text = stringText
return cell
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedIndexPath = indexPath
myModels[selectedIndexPath.row].isSelected = true
self.tableView.reloadRows(at: [selectedIndexPath], with: .none)
}
}

How to create a various type of cells in a single tableView?

I'm currently developing an app which has features like half Uber, half Tinder.
I would like to create a TableView for editing profile to make it look like a view of Tinder's profile editing view.
I successfully made a first cell for picking up profile image and second cell for textLabel.
I want to make a third cell which has an editable TextView(not textField so users can enter several lines of words) But the codes aren't working as I intended.
It seems like although I made a textView in my Custom Cell Class and set it to my third tableView cell in my tableViewController class, it doesn't appear on my simulator.
I'm still not quite sure what's the good way to make several types of cell for a single tableView so if there's other better way to do it, I would love to know.
My codes related to this issue is below.
ViewController
//EditProfileViewController For The Profile Edit view
class EditProfileViewController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
TableViewController
//MyTableViewController for the EditProfileViewController
class EditProfileTableViewController: UITableViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITextViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 5
} else if section == 1 {
return 2
} else {
return 4
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//link my custom Cell here
if let cell = tableView.dequeueReusableCell(withIdentifier: "MyCustomCell", for: indexPath) as? MyCellTableViewCell {
if indexPath.section == 0 {
if indexPath.row == 0 {
//this row is for an Image Picker
cell.textLabel?.text = "edit profile image"
} else if indexPath.row == 1 {
//this row is just like a title of third cell which is editable self description
cell.textLabel?.text = "Describe yourself"
cell.isUserInteractionEnabled = false
} else if indexPath.row == 2 {
//this row is an editable self description
cell.addSubview(cell.selfDescritionTextView)
cell.selfDescritionTextView.delegate = self
cell.selfDescritionTextView.isEditable = true
cell.selfDescritionTextView.text = "Enter some descriptions here"
}
}
else if indexPath.section == 1 {
cell.textLabel?.text = "section 1"
}
else if indexPath.section == 2 {
cell.textLabel?.text = "section 2"
}
return cell
} else {
//Just in case
return UITableViewCell()
}
}
}
TableViewCell
//MyCellTableViewCell
class MyCellTableViewCell: UITableViewCell {
//create a textView for self description
var selfDescritionTextView = UITextView()
//init
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: .default, reuseIdentifier: "MyCustomCell")
selfDescritionTextView = UITextView(frame: self.frame)
self.addSubview(selfDescritionTextView)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
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
}
}
If you need to know more codes than what I showed here, Please let me know.
I'm not obsessed with this method to create my edit profile View so if anyone knows other ways better than this, I would LOVE to know as well.
Thanks
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView.register(UINib(nibName: TableViewCell1.NibName, bundle: nil), forCellReuseIdentifier: TableViewCell1.Identifier)
tableView.register(UINib(nibName: TableViewCell2.NibName, bundle: nil), forCellReuseIdentifier: TableViewCell2.Identifier)
tableView.register(UINib(nibName: TableViewCell3.NibName, bundle: nil), forCellReuseIdentifier: TableViewCell3.Identifier)
}
You'll have 3 Custom Table View Cells, with its subviews, respectively:
class MyCellTableViewCell1: UITableViewCell {
static var NibName: String = String(describing: TableViewCell1.self)
static var Identifier: String = "TableViewCell1"
func configure() { ... }
}
Then:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell
// link my custom Cell here.
if indexPath.row == 0, let dequeuedCell = tableView.dequeueReusableCell(withIdentifier: TableViewCell1.Identifier, for: indexPath) as? TableViewCell1 {
dequeuedCell.configure()
cell = dequeuedCell
}
else if indexPath.row == 1, let dequeuedCell = tableView.dequeueReusableCell(withIdentifier: TableViewCell2.Identifier, for: indexPath) as? TableViewCell2 {
dequeuedCell.configure()
cell = dequeuedCell
}
else if indexPath.row == 2, let dequeuedCell = tableView.dequeueReusableCell(withIdentifier: TableViewCell3.Identifier, for: indexPath) as? TableViewCell3 {
dequeuedCell.configure()
cell = dequeuedCell
}
else {
cell = UITableViewCell()
}
return cell
}
Register multiple nib files like this , but it in viewDidLoad
tableView.register(UINib(nibName: "TableViewCell1", bundle: nil), forCellReuseIdentifier: CellIdentifier1)
tableView.register(UINib(nibName: "TableViewCell2", bundle: nil), forCellReuseIdentifier: CellIdentifier2)
tableView.register(UINib(nibName: "TableViewCell3", bundle: nil), forCellReuseIdentifier: CellIdentifier3)

Table Cells Are A Big

I'm going to make this as clear as possible. In my Xcode project, I am reusing a prototype cell and I want each cell to open a different view controller. How would you guys think I would be able to do that?
Here is a pic of the reusable cell in my Main.storyboard:
Here is the result of the cells being reused:
And here is the code of my controller class:
import UIKit
class NewsTableViewController: UITableViewController {
#IBOutlet var menuButton:UIBarButtonItem!
#IBOutlet var extraButton:UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
tableView.estimatedRowHeight = 242.0
tableView.rowHeight = UITableViewAutomaticDimension
if revealViewController() != nil {
menuButton.target = revealViewController()
menuButton.action = #selector(SWRevealViewController.revealToggle(_:))
revealViewController().rightViewRevealWidth = 150
extraButton.target = revealViewController()
extraButton.action = #selector(SWRevealViewController.rightRevealToggle(_:))
view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// Return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows
return 3
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! NewsTableViewCell
// Configure the cell...
if indexPath.row == 0 {
cell.postImageView.image = UIImage(named: "watchkit-intro")
cell.postTitleLabel.text = "WatchKit Introduction: Building a Simple Guess Game"
} else if indexPath.row == 1 {
cell.postImageView.image = UIImage(named: "custom-segue-featured-1024")
cell.postTitleLabel.text = "Building a Chat App in Swift Using Multipeer Connectivity Framework"
} else {
cell.postImageView.image = UIImage(named: "webkit-featured")
cell.postTitleLabel.text = "A Beginner’s Guide to Animated Custom Segues in iOS 8"
}
return cell
}
}
To be clear, I want each cell in pic 2 to open a different view controller. For example, I would want Cell 1 to open New View Controller 1, Cell 2 to open New View Controller 2, and Cell 3 to open New View Controller 3.
Thanks for reading!
I think you should implement tableview's delegate method
e.g.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
if indexPath.row == 0
{
// open VC1
}
else if indexPath.row == 1
{
// open VC2
}
else if indexPath.row == 2
{
// open VC3
}
}
i think it something like this
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0:
// segue to view 1
case 1:
// segue to view 2
case 2:
// segue to view 3
case 3:
// segue to view 4
default:
// default go here
}
}
You would have to implement tableView(_:, didSelectRowAt:):
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
let newViewController1 = ...
present(newViewController1, animated: true, completion: nil)
} else if indexPath.row == 1 {
let newViewController2 = ...
present(newViewController2, animated: true, completion: nil)
} else {
let newViewController3 = ...
present(newViewController3, animated: true, completion: nil)
}
}
Alternatively, you could add a gesture recognizer to your table view cells and implement a custom cell delegate. It doesn't seem like that would be necessary in your situation though, so I won't recommend it. It seems like it may be overkill. If you're interested, though:
class NewsTableViewCell: UITableViewCell {
var delegate: NewsTableViewCellDelegate?
override func awakeFromNib() {
let recognizer = UIGestureRecognizer(target: self, action: #selector(tapped))
contentView.addGestureRecognizer(recognizer)
}
func tapped() {
delegate?.cellTapped(self)
}
}
protocol NewsTableViewCellDelegate {
func cellTapped(_ cell: NewsTableViewCell)
}
extension MyViewController: NewsTableViewCellDelegate {
func cellTapped(_ cell: NewsTableViewCell) {
if cell == cell1 { }
else if cell == cell2 { }
else if cell == cell3 { }
//You would have to manually determine how to check if a cell is cell1, cell2, or cell3, since you wouldn't have an indexPath available.
}
}
For both the error,
Remove segue from main.storyboard because you are using segue from storyboard but in code work you presenting your ViewConroller.
In code work, replace your lines by below
**
`let storyboard = UIStoryboard(name: "main.Storyboard", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier:"myViewController") as! UIViewController
self.present(controller, animated: true, completion: nil)`
**
If you are pushing your VC, then use this below code:
let myViewController = self.storyboard?.instantiateViewController(withIdentifier: "myViewController") as! Conversation_VC
self.navigationController?.pushViewController(myViewController, animated: true)

iOS swift UIButton in TableView Cell

I have a tableView with custom cell. in my custom cell I have a like button. for like Button I wrote a function to change state from .normal to .selected like this:
FeedViewCell
class FeedViewCell: UITableViewCell {
#IBOutlet weak var likeButton: UIButton!
var likes : Bool {
get {
return UserDefaults.standard.bool(forKey: "likes")
}
set {
UserDefaults.standard.set(newValue, forKey: "likes")
}
}
override func awakeFromNib() {
super.awakeFromNib()
self.likeButton.setImage(UIImage(named: "like-btn-active"), for: .selected)
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
#IBAction func likeBtnTouch(_ sender: AnyObject) {
print("press")
// toggle the likes state
self.likes = !self.likeButton.isSelected
// set the likes button accordingly
self.likeButton.isSelected = self.likes
}
}
FeedViewController :
class FeedViewController: UIViewController {
#IBOutlet var feedTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Register Cell Identifier
let feedNib = UINib(nibName: "FeedViewCell", bundle: nil)
self.feedTableView.register(feedNib, forCellReuseIdentifier: "FeedCell")
}
func numberOfSectionsInTableView(_ tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.feeds.count
}
func tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "FeedCell", for: indexPath) as! FeedViewCell
return cell
}
}
But my problem is when I tap like button in cell with indexPath.row 0 the state of button in cell with indexPath.row 3 change state too.
where is my mistake?
thanks
You didn't post all your code, but I can tell you that for this to work the #IBAction func likeBtnTouch(_ sender: AnyObject) { } definition must be inside the FeedViewCell class definition to make it unique to a particular instance of the cell.
As a rule of thumb, I normally ensure that all the UI elements inside my cell are populated in cellForRowAtIndexPath when using dequeued cells. Also it should be set from an external source. I.o.w not from a property inside the cell. Dequeuing cells reuse them, and if not setup properly, it might have some leftovers from another cell.
For example, inside cellForRowAtIndexPath:
self.likeButton.isSelected = likeData[indexPath.row]

Each Cell need to have a Section - Parse and Swift

I'm implementing a Feed on my App using Parse.com, basically I'm populating a UITableViewController and everything works fine, BUT, I really like the way Instagram does, seems like the Instagram have a UIView inside each cell that works like a header and that view follows the scroll till the end of cell, I tried to search about that and I'm not successful, after some research I've realized that this feature is equally a Section, so I decide to implement Sections in my querys, I've implemented the code below:
import UIKit
class FeedTableViewController: PFQueryTableViewController {
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return UIStatusBarStyle.LightContent
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
loadCollectionViewData()
}
func loadCollectionViewData() {
// Build a parse query object
let query = PFQuery(className:"Feed")
// Check to see if there is a search term
// Fetch data from the parse platform
query.findObjectsInBackgroundWithBlock {
(objects: [PFObject]?, error: NSError?) -> Void in
// The find succeeded now rocess the found objects into the countries array
if error == nil {
print(objects!.count)
// reload our data into the collection view
} else {
// Log details of the failure
}
}
}
// Initialise the PFQueryTable tableview
override init(style: UITableViewStyle, className: String!) {
super.init(style: style, className: className)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
// Configure the PFQueryTableView
self.parseClassName = "Feed"
self.pullToRefreshEnabled = true
self.paginationEnabled = false
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return objects!.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "Section \(section)"
}
//override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! FeedTableViewCell!
if cell == nil {
cell = FeedTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
}
cell.anuncerPhoto.layer.cornerRadius = cell.anuncerPhoto.frame.size.width / 2
cell.anuncerPhoto.clipsToBounds = true
// Extract values from the PFObject to display in the table cell
if let nameEnglish = object?["name"] as? String {
cell?.title?.text = nameEnglish
}
let thumbnail = object?["Photo"] as! PFFile
let initialThumbnail = UIImage(named: "loadingImage")
cell.photoImage.image = initialThumbnail
cell.photoImage.file = thumbnail
cell.photoImage.loadInBackground()
return cell
}
}
Basically I will need to have a section for each cell, Now I'm successfully have sections working for each cell, but the problem is that the querys is repeating on the first post.
In the backend I have 3 different posts, so, in the App the UItableview need to have 3 posts with different content, with the code above I'm successfully counting the number of posts to know how many section I'll need to have and I declare that I want one post per section, but the app shows 3 sections with the same first post.
Any ideas if I'm capture the correct concept of the Instagram feature and why I'm facing this problem in my querys?
Thanks.
Keep the original UITableViewDataSource method and retrieve the current object using the indexPath.section
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! FeedTableViewCell!
if cell == nil {
cell = FeedTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
}
cell.anuncerPhoto.layer.cornerRadius = cell.anuncerPhoto.frame.size.width / 2
cell.anuncerPhoto.clipsToBounds = true
let object = objects[indexPath.section]
// Extract values from the PFObject to display in the table cell
if let nameEnglish = object["name"] as? String {
cell?.title?.text = nameEnglish
}
let thumbnail = object["Photo"] as! PFFile
let initialThumbnail = UIImage(named: "loadingImage")
cell.photoImage.image = initialThumbnail
cell.photoImage.file = thumbnail
cell.photoImage.loadInBackground()
return cell
}

Resources