I have created a customTableCell class that serves as a formatter for the construction of the UITableView in my FirstViewController. The code for all relevant classes will be provided below.
What I am attempting to do:
I am attempting to change the value of the regularBubbleCostLabel which is a property of the customTableCell class. The problem that I am having is that I cannot reference a specific cell that has been displayed in the UITableView.
How can I create references to each of the customTableCells that are being displayed in the UITableView?
customTableCell.h
#import <UIKit/UIKit.h>
#interface customTableCell : UITableViewCell
#property (strong, nonatomic) IBOutlet UIImageView *primaryImageView;
#property (strong, nonatomic) IBOutlet UILabel *upgradeNameLabel;
#property (strong, nonatomic) IBOutlet UILabel *descriptionLabel;
#property (strong, nonatomic) IBOutlet UIImageView *regularCurrencyIcon;
#property (strong, nonatomic) IBOutlet UILabel *regularBubbleCostLabel;
#end
customTableCell.m
#import "customTableCell.h"
#implementation customTableCell
#synthesize primaryImageView = _primaryImageView;
#synthesize upgradeNameLabel = _upgradeNameLabel;
#synthesize descriptionLabel = _descriptionLabel;
#synthesize regularBubbleCostLabel = _regularBubbleCostLabel;
#end
FirstViewController.h
#import <UIKit/UIKit.h>
#import "RWGameData.h"
#import "customTableCell.h"
#interface FirstViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
#property (strong, nonatomic) IBOutlet UILabel *regularBubbleLabel;
#property (strong, nonatomic) IBOutlet UILabel *premiumBubbleLabel;
#property (strong, nonatomic) IBOutlet UIImageView *regularBubbleIcon;
#property (strong, nonatomic) IBOutlet UIImageView *premiumBubbleIcon;
#property (strong, nonatomic) IBOutlet UINavigationBar *navBar;
#property (strong, nonatomic) IBOutlet UITableView *tableView;
#end
FirstViewController.m
#import "FirstViewController.h"
#interface FirstViewController ()
#end
#implementation FirstViewController
{
NSArray *upgrades;
NSArray *thumbnails;
NSArray *descriptions;
NSArray *megaBubbleUpgradeFees;
NSInteger rowID;
NSInteger cellCount;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *path = [[NSBundle mainBundle] pathForResource:#"Upgrades" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
upgrades = [dict objectForKey:#"UpgradeStrings"];
thumbnails = [dict objectForKey:#"UpgradeImages"];
descriptions = [dict objectForKey:#"UpgradeDescriptions"];
megaBubbleUpgradeFees = [dict objectForKey:#"MegaBubbleUpgradeFee"];
_regularBubbleLabel.text = [NSString stringWithFormat:#"%li", [RWGameData sharedGameData].regularBubbleCount];
_premiumBubbleLabel.text = [NSString stringWithFormat:#"%li", [RWGameData sharedGameData].premiumBubbleCount];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [upgrades count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Handles appearance of cells in table.
static NSString *TableIdentifier = #"TableCell";
//customTableCell *cell = (customTableCell *)[tableView dequeueReusableCellWithIdentifier:TableIdentifier];
customTableCell *cell = (customTableCell *)[tableView dequeueReusableCellWithIdentifier:TableIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"customTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.primaryImageView.image = [UIImage imageNamed:[thumbnails objectAtIndex:indexPath.row]];
cell.upgradeNameLabel.text = [upgrades objectAtIndex:indexPath.row];
cell.descriptionLabel.text = [descriptions objectAtIndex:indexPath.row];
cell.regularCurrencyIcon.image = [UIImage imageNamed:#"megaBubbleLarge30.png"];
cell.regularBubbleCostLabel.text = [NSString stringWithFormat:#"%#", megaBubbleUpgradeFees[[RWGameData sharedGameData].megaBubbleUpgradeTier]];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 78;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
rowID = indexPath.row;
[self makePayment:self];
}
- (IBAction)makePayment:(id)sender {
UIAlertView *messageAlert;
if (rowID == 0) {
if ([RWGameData sharedGameData].regularBubbleCount >= [megaBubbleUpgradeFees[[RWGameData sharedGameData].megaBubbleUpgradeTier] intValue]) {
//NSLog(#"Balance: %li | Cost: %# |-> Sufficient amount!", [RWGameData sharedGameData].regularBubbleCount, megaBubbleUpgradeFees[[RWGameData sharedGameData].megaBubbleUpgradeTier]);
if ([RWGameData sharedGameData].megaBubblePopValue <= 1) {
[RWGameData sharedGameData].megaBubblePopValue++;
} else {
[RWGameData sharedGameData].megaBubblePopValue *= 2;
}
[[RWGameData sharedGameData] save];
NSLog(#"New Pop Value: %i", [RWGameData sharedGameData].megaBubblePopValue);
} else {
messageAlert = [[UIAlertView alloc] initWithTitle:#"Not enough bubbles!!" message:#"You need to collect more bubbles or purchase them from our store!" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:#"Buy", nil]; [messageAlert show];
} NSLog(#"Cell ID: %li | Balance: %li | Cost: %#", rowID, [RWGameData sharedGameData].regularBubbleCount, megaBubbleUpgradeFees[[RWGameData sharedGameData].megaBubbleUpgradeTier]);
} else if (rowID == 1) {
if ([RWGameData sharedGameData].regularBubbleCount >= [megaBubbleUpgradeFees[[RWGameData sharedGameData].megaBubbleUpgradeTier] intValue]) {
NSLog(#"Balance: %li | Cost: %# |-> Sufficient amount!", [RWGameData sharedGameData].regularBubbleCount, megaBubbleUpgradeFees[[RWGameData sharedGameData].megaBubbleUpgradeTier]);
} else {
messageAlert = [[UIAlertView alloc] initWithTitle:#"Not enough bubbles!!" message:#"You need to collect more bubbles or purchase them from our store!" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:#"Buy", nil]; [messageAlert show];
} NSLog(#"Cell ID: %li | Balance: %li | Cost: %#", rowID, [RWGameData sharedGameData].regularBubbleCount, megaBubbleUpgradeFees[[RWGameData sharedGameData].megaBubbleUpgradeTier]);
} else if (rowID == 2) {
if ([RWGameData sharedGameData].regularBubbleCount >= [megaBubbleUpgradeFees[[RWGameData sharedGameData].megaBubbleUpgradeTier] intValue]) {
NSLog(#"Balance: %li | Cost: %# |-> Sufficient amount!", [RWGameData sharedGameData].regularBubbleCount, megaBubbleUpgradeFees[[RWGameData sharedGameData].megaBubbleUpgradeTier]);
} else {
messageAlert = [[UIAlertView alloc] initWithTitle:#"Not enough bubbles!!" message:#"You need to collect more bubbles or purchase them from our store!" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:#"Buy", nil]; [messageAlert show];
} NSLog(#"Cell ID: %li | Balance: %li | Cost: %#", rowID, [RWGameData sharedGameData].regularBubbleCount, megaBubbleUpgradeFees[[RWGameData sharedGameData].megaBubbleUpgradeTier]);
} else if (rowID == 3) {
if ([RWGameData sharedGameData].regularBubbleCount >= [megaBubbleUpgradeFees[[RWGameData sharedGameData].megaBubbleUpgradeTier] intValue]) {
NSLog(#"Balance: %li | Cost: %# |-> Sufficient amount!", [RWGameData sharedGameData].regularBubbleCount, megaBubbleUpgradeFees[[RWGameData sharedGameData].megaBubbleUpgradeTier]);
} else {
messageAlert = [[UIAlertView alloc] initWithTitle:#"Not enough bubbles!!" message:#"You need to collect more bubbles or purchase them from our store!" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:#"Buy", nil]; [messageAlert show];
} NSLog(#"Cell ID: %li | Balance: %li | Cost: %#", rowID, [RWGameData sharedGameData].regularBubbleCount, megaBubbleUpgradeFees[[RWGameData sharedGameData].megaBubbleUpgradeTier]);
} else if (rowID == 4) {
if ([RWGameData sharedGameData].regularBubbleCount >= [megaBubbleUpgradeFees[[RWGameData sharedGameData].megaBubbleUpgradeTier] intValue]) {
NSLog(#"Balance: %li | Cost: %# |-> Sufficient amount!", [RWGameData sharedGameData].regularBubbleCount, megaBubbleUpgradeFees[[RWGameData sharedGameData].megaBubbleUpgradeTier]);
} else {
messageAlert = [[UIAlertView alloc] initWithTitle:#"Not enough bubbles!!" message:#"You need to collect more bubbles or purchase them from our store!" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:#"Buy", nil]; [messageAlert show];
} NSLog(#"Cell ID: %li | Balance: %li | Cost: %#", rowID, [RWGameData sharedGameData].regularBubbleCount, megaBubbleUpgradeFees[[RWGameData sharedGameData].megaBubbleUpgradeTier]);
}
}
#end
You don't actively drive individual cells in a UITableView this way. You drive the dataSource that the table uses.
The dataSource should alert the table that data has changed. (Check the fetchedResultsController code in a sample project that Xcode creates for a project using Core Data.)
You can do several things to get the table and cell to update:
Call [myTable reloadData] (crudest, but easy for very few cells)
Call beginUpdate, signal the changes, call endUpdate (the fetchedResultsController way)
For custom cells, they can use KVO or NSNotificationCenter with the data source objects and update themselves when signaled. When cells are recycled, they need to unsubscribe. When reused they subscribe again. (No updates will be needed if they are not on-screen.)
For the first two, the table will start calling 'cellForRowAtIndexpath' for the cells it needs.
You can use -(UITableViewCell *)tableView:cellForRowAtIndexPath: for retrieving a specific cell from the tableView. Just provide the relevant index for the cell you want to reference with indexPathForRow:inSection:.
Problem solved.
I went ahead and did something very primitive, but it works. I'm sure there are many downfalls to this, but I can update it to be more reliable in the future.
In - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath, I added the following:
if (indexPath.row == 0) {
cell.regularBubbleCostLabel.text = [NSString stringWithFormat:#"%#", megaBubbleUpgradeFees[[RWGameData sharedGameData].megaBubbleUpgradeTier]];
} ...
Related
I'm developing an app in Xcode in Objective-C.
The app has a TableView with an array of restaurants. My problem is that when I try to use the SearchBar I use the Title (name of the restaurant as a filter) but when I show the rows after the filter search, only the Title is right. The other label and the image in the cell is wrong (it shows me the correct title but the image and the other label (description label) is the same as the first row in the original tableview).
I have to change my cellForRowAtIndexPath method but I don't now how to change it.
This is TableViewController called MainTableViewController.h
#import <UIKit/UIKit.h>
#interface MainTableViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate>
#property (weak, nonatomic) IBOutlet UIBarButtonItem *barButton;
//#property (nonatomic, strong) NSArray *Images;
//#property (nonatomic, strong) NSArray *Description;
//#property (nonatomic, strong) NSArray *Title;
#property (nonatomic, strong) NSMutableArray *Title;
#property (nonatomic, strong) NSMutableArray *Images;
#property (nonatomic, strong) NSMutableArray *Description;
#property (nonatomic, strong) NSMutableArray *filteredRest;
#property BOOL isFiltered;
#property (strong, nonatomic) IBOutlet UITableView *RestTableView;
#property (strong, nonatomic) IBOutlet UITableView *mySearchBar;
#end
This is my MainTableViewController.c
#import "MainTableViewController.h"
#import "SWRevealViewController.h"
#import "RestTableViewCell.h"
#import "RestViewController.h"
#interface MainTableViewController ()
#end
#implementation MainTableViewController
#synthesize mySearchBar, filteredRest, isFiltered;
- (void)viewDidLoad {
[super viewDidLoad];
_barButton.target = self.revealViewController;
_barButton.action = #selector(revealToggle:);
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
[self.navigationItem setTitle:#"MadEat"]; /*Cambia el titulo del navigation controller*/
[self.navigationController.navigationBar setTitleTextAttributes:#{NSForegroundColorAttributeName : [UIColor whiteColor]}]; /*Cambia el color de las letras del navigation controller bar del menu principal*/
[self.navigationController.navigationBar setBarTintColor:[UIColor colorWithRed:27/255.0f green:101/255.0f blue:163/255.0f alpha:1.0f]];
self.navigationController.navigationBar.tintColor = [UIColor whiteColor]; /*Cambia el color del boton de la izquierda*/
self.RestTableView.tableFooterView = [[UIView alloc] init]; /*Esta linea hace que en la tabla solo aparezcan el numero de filas que tienes establecidas, es decir, que las vacias no aparezcan*/
/*Alerta que se muestra solo la primera vez. Está desactivada*/
if (![#"1" isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:#"alert"]]) {
[[NSUserDefaults standardUserDefaults] setValue:#"1" forKey:#"alert"];
[[NSUserDefaults standardUserDefaults] synchronize];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"Terms of use" message:#"The brands mentioned have no relationship with MadEat and the app has no any liability on that content." preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:#"Accept" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:ok];
[self presentViewController:alertController animated:YES completion:nil];
}
_Title = #[#"80 Grados",
#"90 Grados",
#"B&B Babel",
#"Babelia",
#"Bacira",
#"Bar Galleta",
#"Bar Tomate",
#"Barra Atlantica",
#"BaRRa de Pintxos",
#"BaRRa de Pintxos",];
_Description = #[#"Barrio Malasaña",
#"Barrio Retiro",
#"Barrio Chueca",
#"Barrio de Salamanca",
#"Barrio Chamberí",
#"Barrio Malasaña",
#"Barrio Chamberí",
#"Barrio Malasaña",
#"Barrio del Pilar",
#"Barrio Retiro",];
_Images = #[#"80_grados.png",
#"90_grados",
#"babel.png",
#"babelia.png",
#"bacira.png",
#"bar_galleta.png",
#"bar_tomate.png",
#"barra_atlantica.png",
#"barra_de_pintxos.png",
#"barra_de_pintxos.png",];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
//return _Title.count;
if (isFiltered == YES) {
return filteredRest.count;
} else {
return _Title.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TableCell";
RestTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
if (isFiltered == YES) {
cell.TitleLabel.text = [filteredRest objectAtIndex:indexPath.row];
} else {
int row = [indexPath row];
cell.TitleLabel.text = _Title[row];
cell.DescriptionLabel.text = _Description[row];
cell.RestImage.image = [UIImage imageNamed:_Images[row]];
}
cell.RestImage.layer.cornerRadius = 6;
cell.RestImage.clipsToBounds = YES;
cell.RestImage.layer.borderWidth = 1;
return cell;
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
/*Cambia el nombre del boton de la izquierda sin afectar al titulo del navigation controller*/
self.navigationItem.backBarButtonItem=[[UIBarButtonItem alloc] initWithTitle: NSLocalizedString (#"Back", nil) style:UIBarButtonItemStylePlain target:nil action:nil];
if ([[segue identifier] isEqualToString:#"ShowDetails"]){
RestViewController *restviewcontroller = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
int row = [myIndexPath row];
restviewcontroller.DetailModal = #[_Title[row],_Description[row],_Images[row]];
}
}
-(void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
if (searchText.length == 0) {
//Set our boolean flag
isFiltered = NO;
} else {
//Set our boolean flag
isFiltered = YES;
}
//Alloc and init our filteredData
filteredRest = [[NSMutableArray alloc] init];
for (NSString * restTitle in _Title) {
NSRange restTitleRange = [restTitle rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (restTitleRange.location != NSNotFound) {
[filteredRest addObject:restTitle];
}
}
for (NSString * restDescription in _Description) {
NSRange restDescriptionRange = [restDescription rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (restDescriptionRange.location != NSNotFound) {
//[filteredRest addObject:restDescription];
}
}
for (NSString * restImages in _Images) {
NSRange restImagesRange = [restImages rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (restImagesRange.location != NSNotFound) {
//[filteredRest addObject:restImages];
}
}
//Reload our table view
[_RestTableView reloadData];
}
-(void) searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[mySearchBar resignFirstResponder];
}
#end
Finally, this is my TableViewCell.h called RestTableViewCell.h
#import <UIKit/UIKit.h>
#interface RestTableViewCell : UITableViewCell
#property (strong, nonatomic) IBOutlet UILabel *TitleLabel;
#property (strong, nonatomic) IBOutlet UILabel *DescriptionLabel;
#property (strong, nonatomic) IBOutlet UIImageView *RestImage;
#end
This is my problem graphically:
Obviously, you just apply the filter condition to the Title array, and not filtering the Images and Description array.
So you need to two more NSMutableArray to hold the filtering results for Images and Description.
But I recommend you to build a new Model for your results. Sample code for your reference:
Model layer: Restaurant.h
#interface Restaurant : NSObject
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *desc;
#property (nonatomic, copy) NSString *image;
- (instancetype)init:(NSString *)title descripiton:(NSString *)description image:(NSString *)image;
#end
Restaurant.m
#implementation Restaurant
- (instancetype)init:(NSString *)title descripiton:(NSString *)description image:(NSString *)image {
self = [super init];
if (self != nil) {
self.title = title;
self.desc = description;
self.image = image;
}
return self;
}
#end
RestViewController.h
#interface RestViewController : UIViewController
#property (nonatomic, strong) Restaurant *DetailModal;
#end
MainTableViewController.m
#interface MainTableViewController ()
#property (nonatomic, strong) NSArray<Restaurant *> *originData;
#property (nonatomic, strong) NSMutableArray<Restaurant *> *filteredRest;
#property (nonatomic, assign) Boolean isFiltered;
#end
#implementation MainTableViewController
#synthesize mySearchBar, filteredRest, isFiltered, originData;
- (void)viewDidLoad {
[super viewDidLoad];
originData = #[
[[Restaurant alloc] init:#"80 Grados" descripiton:#"Barrio Malasaña" image:#"80_grados.png"],
[[Restaurant alloc] init:#"90 Grados" descripiton:#"Barrio Retiro" image:#"90_grados"]
];
filteredRest = [NSMutableArray new];
isFiltered = NO;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
//return _Title.count;
if (isFiltered == YES) {
return filteredRest.count;
} else {
return originData.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TableCell";
RestTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
if (isFiltered == YES) {
cell.TitleLabel.text = [filteredRest objectAtIndex:indexPath.row].title;
cell.DescriptionLabel.text = [filteredRest objectAtIndex:indexPath.row].desc;
cell.RestImage.image = [UIImage imageNamed:[filteredRest objectAtIndex:indexPath.row].image];
} else {
cell.TitleLabel.text = [originData objectAtIndex:indexPath.row].title;
cell.DescriptionLabel.text = [originData objectAtIndex:indexPath.row].desc;
cell.RestImage.image = [UIImage imageNamed:[originData objectAtIndex:indexPath.row].image];
}
cell.RestImage.layer.cornerRadius = 6;
cell.RestImage.clipsToBounds = YES;
cell.RestImage.layer.borderWidth = 1;
return cell;
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
/*Cambia el nombre del boton de la izquierda sin afectar al titulo del navigation controller*/
self.navigationItem.backBarButtonItem=[[UIBarButtonItem alloc] initWithTitle: NSLocalizedString (#"Back", nil) style:UIBarButtonItemStylePlain target:nil action:nil];
if ([[segue identifier] isEqualToString:#"ShowDetails"]){
RestViewController *restviewcontroller = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
if (isFiltered) {
restviewcontroller.DetailModal = filteredRest[myIndexPath.row];
} else {
restviewcontroller.DetailModal = originData[myIndexPath.row];
}
}
}
-(void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
if (searchText.length == 0) {
//Set our boolean flag
isFiltered = NO;
} else {
//Set our boolean flag
isFiltered = YES;
}
//Alloc and init our filteredData
filteredRest = [[NSMutableArray alloc] init];
for (Restaurant *item in originData) {
if ([item.title containsString:searchText]) {
[filteredRest addObject:item];
}
}
//Reload our table view
[self.tableView reloadData];
}
-(void) searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[mySearchBar resignFirstResponder];
}
#end
With building a new model object for your information is very efficient, so you don't need to apply there filter to three array, you just need to search once, and results will be kept kept in one array.
PS: One more tips for your coding style, naming the variable, object instance with starting lowercase, and naming the class with starting uppercase is best practise when writing OC codes. e.g., TitleLabel should rename to titleLabel, etc...
Here you are filtering cell and reusing them.
You are just replacing text. You need to replace the image and data as well.
if (isFiltered == YES) {
cell.TitleLabel.text = [filteredRest objectAtIndex:indexPath.row];
} else {
int row = [indexPath row];
cell.TitleLabel.text = _Title[row];
cell.DescriptionLabel.text = _Description[row];
cell.RestImage.image = [UIImage imageNamed:_Images[row]];
}
I am not sure but I think you have not clearly understood concept of reusable cell. You will be reusing cell which are not in the view what that means is iOS framework will give you one of the already used cell so that it doesnt have to recreate cell everytime in your case thats first cell 80Grados.
So, after you receive that cell, you replace the title but leave all other content alone. That is why you see old content with new Title Label.
What you need to do here is create a wrapper class, which will have three properties text, description and imagefile name.
#class Restaurant
#property NSString *title;
#property NString *description;
#property NSString *image;
#end
Combine your logic with this rather than treating all data as separate array. That will be extremely easy to maintain. In future you can easily fill that class with data coming from server, user entered or any otherway. Handling data in 3 different array is not very sustainable model.
So create wrapper class, fill data by creating NSMutableArray/NSMutableDictionary. Rather than putting title, fill entire wrapper object.
[filteredRest addObject: restaurantObj];
And change your code this way
Restaurant *r;
if (isFiltered == YES) {
r = [self.filteredRest objectAtIndex:indexPath.row];
} else {
r = [self.restaurantList objectAtIndex:indexPath.row]];
}
cell.TitleLabel.text = r.title;
cell.DescriptionLabel.text = r.description;
cell.RestImage.image = [UIImage imageNamed:r.image];
Let me know if any of the ideas are not clear. This is just a prototype, you will have to change your code in multiple places but would highly recommend making these changes sooner than later.
I have 3 textfields, a submit button and a table view in a view controller. Now I want to show the datas of the 3 text fields to 3 labels of a custom cell in my table view and when I again update the datas the updated datas should be shown in the next cell. But in my code the updated datas are showing in the cells. The previous datas are overwriting. SO can any one tell me where am I wrong?
This is my ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *nameTextField;
#property (weak, nonatomic) IBOutlet UITextField *addressTextField;
#property (weak, nonatomic) IBOutlet UITextField *phoneTextField;
- (IBAction)submitButton:(id)sender;
#property (weak, nonatomic) IBOutlet UITableView *detailTable;
#property(nonatomic, strong)NSMutableArray *arrPeopleDetail;
#end
This is my ViewController.m
#import "ViewController.h"
#import "detailObject.h"
#interface ViewController ()
#end
#implementation ViewController
{
detailObject *peopleDetail;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.arrPeopleDetail = [[NSMutableArray alloc]init];
peopleDetail = [[detailObject alloc]init];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)submitButton:(id)sender {
[self.detailTable reloadData];
if ([self.nameTextField.text isEqualToString:#""] || [self.addressTextField.text isEqualToString:#""] || [self.phoneTextField.text isEqualToString:#""] ) {
UIAlertView *alrt = [[UIAlertView alloc]initWithTitle:#"Warning" message:#"Plaeas Enter Text In The Empty Field" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:nil ];
[alrt show];
}
else{
peopleDetail.strPeopleName = self.nameTextField.text;
peopleDetail.strPeopleAddress = self.addressTextField.text;
peopleDetail.strPeoplePhoneNumber = self.phoneTextField.text;
[self.arrPeopleDetail addObject:peopleDetail];
}
//[self.detailTable reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell1"];
UILabel *lbl1 = (UILabel*)[cell.contentView viewWithTag:1];
lbl1.text = [[self.arrPeopleDetail objectAtIndex:indexPath.row]valueForKey:#"strPeopleName"];
UILabel *lbl2 = (UILabel*)[cell.contentView viewWithTag:2];
lbl2.text = [[self.arrPeopleDetail objectAtIndex:indexPath.row]valueForKey:#"strPeopleAddress"];
UILabel *lbl3 = (UILabel*)[cell.contentView viewWithTag:3];
lbl3.text = [[self.arrPeopleDetail objectAtIndex:indexPath.row]valueForKey:#"strPeoplePhoneNumber"];
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.arrPeopleDetail count];
}
#end
This is the .h NSObject class that I have Taken.
#import <Foundation/Foundation.h>
#interface detailObject : NSObject
#property(nonatomic,strong) NSString *strPeopleName;
#property(nonatomic,strong) NSString *strPeopleAddress;
#property(nonatomic,strong) NSString *strPeoplePhoneNumber;
#end
Add line peopleDetail = [[detailObject alloc]init]; in else case of submitButton action and after adding the new object into array reload table view data
i.e.
else{
peopleDetail = [[detailObject alloc]init];
peopleDetail.strPeopleName = self.nameTextField.text;
peopleDetail.strPeopleAddress = self.addressTextField.text;
peopleDetail.strPeoplePhoneNumber = self.phoneTextField.text;
[self.arrPeopleDetail addObject:peopleDetail];
[self.detailTable reloadData];
}
You can remove the peopleDetail = [[detailObject alloc]init]; from viewDidLoad
I realised where I was wrong. I was creating the object globally instead of creating it locally. If anyone does this mistake what happens is, every time when user enters data the datas are being overwritten because the created object is one. So the main mistake was creating the object globally instead of creating it locally.
So the updated ViewController.m is..
#import "ViewController.h"
#import "detailObject.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.arrPeopleDetail = [[NSMutableArray alloc]init];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)submitButton:(id)sender {
if ([self.phoneTextField.text isEqualToString:#""] && [self.addressTextField.text isEqualToString:#""] && [self.phoneTextField.text isEqualToString:#""] ) {
UIAlertView *alrt = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Please Fillup The Above Fields" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:nil];
[alrt show];
}
else if ([self.nameTextField.text isEqualToString:#""]) {
UIAlertView *alrt_name = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Plaeas Enter Name" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:nil ];
[alrt_name show];
}
else if ([self.addressTextField.text isEqualToString:#""]) {
UIAlertView *alrt_address = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Please Enter Address" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:nil];
[alrt_address show];
}
else if ([self.phoneTextField.text isEqualToString:#""]) {
UIAlertView *alrt_phoneNumber = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Please Enter Phone Number" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:nil];
[alrt_phoneNumber show];
}
else
{
detailObject *peopleDetail = [[detailObject alloc] init];
peopleDetail.strPeopleName = self.nameTextField.text;
peopleDetail.strPeopleAddress = self.addressTextField.text;
peopleDetail.strPeoplePhoneNumber = self.phoneTextField.text;
[self.arrPeopleDetail addObject:peopleDetail];
self.nameTextField.text = #"";
self.addressTextField.text = #"";
self.phoneTextField.text = #"";
}
[self.detailTable reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell1"];
UILabel *lbl1 = (UILabel*)[cell.contentView viewWithTag:1];
lbl1.text = [[self.arrPeopleDetail objectAtIndex:indexPath.row]valueForKey:#"strPeopleName"];
UILabel *lbl2 = (UILabel*)[cell.contentView viewWithTag:2];
lbl2.text = [[self.arrPeopleDetail objectAtIndex:indexPath.row]valueForKey:#"strPeopleAddress"];
UILabel *lbl3 = (UILabel*)[cell.contentView viewWithTag:3];
lbl3.text = [[self.arrPeopleDetail objectAtIndex:indexPath.row]valueForKey:#"strPeoplePhoneNumber"];
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.arrPeopleDetail count];
}
#end
I have in my .h file:
#import <UIKit/UIKit.h>
#import "SQLClient.h"
#interface mgrViewController : UIViewController <UITableViewDelegate, UITableViewDataSource,
SQLClientDelegate>{
NSMutableArray *pajaros;
}
#property (weak, nonatomic) IBOutlet UITableView *miTabla;
#property (nonatomic, retain)NSMutableArray *pajaros;
#end
And in my .m file:
#import "mgrViewController.h"
#import "Vista2.h"
#import "SQLClient.h"
#interface mgrViewController ()
#end
#implementation mgrViewController
#synthesize miTabla;
#synthesize pajaros;
- (void)viewDidLoad
{
[super viewDidLoad];
SQLClient* client = [SQLClient sharedInstance];
client.delegate = self;
[client connect:#"xxx.xxx.xxx.xxx:xxxx" username:#"xxxxxxxxxxx" password:#"xxxxxxxxxxxx" database:#"xxxxxxxxxxx" completion:^(BOOL success) {
if (success)
{
pajaros =[[NSMutableArray alloc]init];
[client execute:#"SELECT field FROM table WHERE field='xxxxxxxxx'" completion:^(NSArray* results) {
NSMutableString* resulta = [[NSMutableString alloc] init];
for (NSArray* table in results)
for (NSDictionary* row in table)
for (NSString* column in row){
//[results appendFormat:#"\n%# = %#", column, row[column]];
[resulta appendFormat:#"\n%#", row[column]];
[pajaros addObject:resulta];
}
[client disconnect];
}];
}
}];
self.miTabla.delegate = self;
self.miTabla.dataSource = self;
}
#pragma mark - SQLClientDelegate
- (void)error:(NSString*)error code:(int)code severity:(int)severity
{
NSLog(#"Error #%d: %# (Severity %d)", code, error, severity);
[[[UIAlertView alloc] initWithTitle:#"Error" message:error delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil] show];
}
- (void)message:(NSString*)message
{
NSLog(#"Message: %#", message);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return pajaros.count;
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"celdaPajaros";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// elementos que contienen cada celda con sus tags
UILabel *labelTitulo = (UILabel *) [cell viewWithTag:10];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
labelTitulo.text = [pajaros objectAtIndex:indexPath.row];
return cell;
}
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 70.f;
}
#end
I added elements to NSMutableArray pajaros in -(void)viewDidLoad{}, and my question is, how I can use my NSMutableArray pajaros in -(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath?.
Thanks :)
If I use count on my NSMutable Array and print that number, the result is 1 (because I selected only A data), but only if I use:
...
[pajaros addObject:resulta];
}
NSInteger num = pajaros.count;
NSString *inStr = [NSString stringWithFormat: #"%ld", (long)num];
self.textView.text = inStr;
[client disconnect];
}];
...
But if I perform that count in another part of my .m file show me 0, my next questions becomes why my NSMutableArray contains only the data in:
...
[pajaros addObject:resulta];
}
[client disconnect];
}];
...
?
Thanks for the help!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//code here to dequecell
NSString *cellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell.textLabel.text = [pajaraos objectAtIndex:indexPath.row];
}
return cell;
}
I am trying to make an ios app on xcode by following this - http://www.appcoda.com/search-bar-tutorial-ios7/. When I type in search bar everything works in console but output is not getting displayed on the screen
#interface AllUseraStatusViewController ()
#property (weak, nonatomic) IBOutlet UITableView *statusText;
#property (weak, nonatomic) IBOutlet UITableView *statusTime;
#property (weak, nonatomic) IBOutlet UITableView *statusUserName;
#property (strong,nonatomic) NSArray *statusList;
#property (strong,nonatomic) NSMutableArray *allStatusLists;
#property(strong,nonatomic) NSArray *searchResults;
#property(strong,nonatomic) PFObject *object;
#end
#implementation AllUseraStatusViewController
- (void)viewDidLoad {
[super viewDidLoad];
PFQuery *query = [PFQuery queryWithClassName:#"Status"];
[query includeKey:#"user"];
[query orderByDescending:#"createdAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
// 3
if (!error){
self.statusList = objects;
[self.tableView reloadData];
} else {
// 4
[[[UIAlertView alloc] initWithTitle:#"Error" message:[error userInfo][#"error"] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil] show];
}
}];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 70;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(tableView==self.searchDisplayController.searchResultsTableView)
{
return [self.searchResults count];
}else{
return [self.statusList count];
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier= #"AllUsersStatusCell";
UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell==nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView){
self.object =[self.searchResults objectAtIndex:indexPath.item];
NSLog(#"THIS IS object %#",self.object);
}else{
self.object =[self.statusList objectAtIndex:indexPath.item];
}
NSLog(#"THIS IS objectttt %#",self.object); <--this prints correct status in console
UILabel *statusText = (UILabel *)[cell viewWithTag:100];
[statusText setText:[self.object objectForKey:#"status"]];
NSLog(#"THIS IS objectttt %#",statusText);<--but this prints null in console
UILabel *statusTime = (UILabel *)[cell viewWithTag:101];
[statusTime setText:[[self.object createdAt] description]];
UILabel *statusUserName = (UILabel *)[cell viewWithTag:102];
PFUser *userName = [self.object objectForKey:#"user"];
[statusUserName setText:userName.username];
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"detail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UserProfileViewController *vc = segue.destinationViewController;
PFObject *object = [self.statusList objectAtIndex:indexPath.row];
vc.statusObject=object;
}
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForTextSearch:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
return YES;
}
-(void)filterContentForTextSearch:(NSString *)searchText scope:(NSString *)scope
{
NSPredicate *resultPredicate=[NSPredicate predicateWithFormat:#"status contains[c] %#",searchText];
NSLog(#"THIS IS %#",resultPredicate);
self.searchResults = [self.statusList filteredArrayUsingPredicate:resultPredicate];
NSLog(#"THIS IS THE %#", self.searchResults);
}
#end
MAKING THE ERROR MORE CLEAR
This is the error in the above code
NSLog(#"THIS IS object %#",self.object);// this prints correct object
UILabel *statusText = (UILabel *)[cell viewWithTag:100];
[statusText setText:[self.object objectForKey:#"status"]];
NSLog(#".....THIS IS objectt %#",statusText.text);// it prints null on console
NSLog(#".....THIS IS objectttt %#",[self.object objectForKey:#"status"]);// this prints correct o/p
I'm seeing a gradual build up of memory that I think might be a retain cycle.
When does this happen: Click on a custom cell that expands and injects a nib with 3 buttons into the expanded area. Clicking the cell again closes the cell, shrinks the cell's tablerow height, rotates an open indicator and removes the previously injected nib.
If I open and close the cell multiple times I see the memory gradually building up.
Any ideas what might be causing this would be greatly appreciated.
Sorry I don't have enough reputation to post photos.
Build up:
Example of retained objects(mostly Animation related):
EDIT: Using ARC and on iOS 6
MasterViewController - TableView Functions
#pragma mark - UITABLEVIEW
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.topicsArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier2 = #"SRCollapsibleCellClosed";
SRCollapsibleCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if (cell == nil) {
cell = [[SRCollapsibleCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2];
}
SRTopic *topic = [self.topicsArray objectAtIndex:indexPath.row];
[cell updateWithTopic:topic];
if([self isCellOpen:indexPath]){
CGAffineTransform transformation = CGAffineTransformMakeRotation(M_PI/2);
cell.arrow.transform = transformation;
if(![self hasChoiceBox:cell]){
[self insertChoiceBox:cell atIndex:indexPath];
}
} else{
CGAffineTransform transformation = CGAffineTransformMakeRotation(0);
cell.arrow.transform = transformation;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if([self isCellOpen:indexPath]){
[self closeCellAtIndexPath:indexPath];
}
else{
NSIndexPath * openCell= self.openCellIndex;
NSIndexPath * newOpenCell= indexPath;
[self closeCellAtIndexPath:openCell];
[self openCellAtIndexPath:newOpenCell];
}
[tableView beginUpdates];
[tableView endUpdates];
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
-(CGFloat)tableView: (UITableView*)tableView heightForRowAtIndexPath: (NSIndexPath*) indexPath {
if([indexPath isEqual:self.openCellIndex]){
return 217.0;
} else {
return 63.0;
}
}
-(void)rotateCellArrowAtIndexPath:(NSIndexPath*)indexPath willOpen:(bool)willOpen Animated:(bool)animated{
// Change Arrow orientation
SRCollapsibleCell *cell = (SRCollapsibleCell*) [self.topicsTableView cellForRowAtIndexPath:indexPath];
CGAffineTransform transformation;
if(willOpen){
transformation = CGAffineTransformMakeRotation(M_PI/2);
} else {
transformation = CGAffineTransformMakeRotation(0);
}
if(animated){
[UIView animateWithDuration:.2 delay:0 options:nil animations:^{
cell.arrow.transform = transformation;
} completion:nil];
}
else{
cell.arrow.transform = transformation;
}
}
-(BOOL)isCellOpen:(NSIndexPath *)indexPath{
return [indexPath isEqual:self.openCellIndex];
}
-(void)closeCellAtIndexPath:(NSIndexPath*)indexPath{
//NSLog(#"Cell closing");
[self rotateCellArrowAtIndexPath:indexPath willOpen:NO Animated:YES];
[self removeSRChoiceBoxFromCellAtIndexPath:indexPath];
self.openCellIndex = nil;
}
-(void)openCellAtIndexPath:(NSIndexPath*)indexPath{
[self rotateCellArrowAtIndexPath:indexPath willOpen:YES Animated:YES];
SRCollapsibleCell *cell = (SRCollapsibleCell*)[self.topicsTableView cellForRowAtIndexPath:indexPath];
[self insertChoiceBox:cell atIndex:indexPath];
self.openCellIndex = indexPath;
}
-(void)removeSRChoiceBoxFromCellAtIndexPath:(NSIndexPath *)indexPath{
SRCollapsibleCell *cell = (SRCollapsibleCell*) [self.topicsTableView cellForRowAtIndexPath:indexPath];
for(id subview in cell.SRCollapsibleCellContent.subviews){
if([subview isKindOfClass:[SRChoiceBox class]]){
SRChoiceBox *tempBox = subview;
[tempBox removeFromSuperview];
tempBox.delegate = nil;
tempBox = nil;
}
}
}
-(void)insertChoiceBox: (SRCollapsibleCell *)cell atIndex:(NSIndexPath *) indexPath
{
//SRChoiceBox *newBox = [[SRChoiceBox alloc] initWithFrame:CGRectMake(0, 0, 310, 141)];
SRChoiceBox *newBox = [[SRChoiceBox alloc] init];
SRTopic *topic = [self.topicsArray objectAtIndex:indexPath.row];
[newBox updateWithSRTopic:topic];
newBox.delegate = self;
[cell.SRCollapsibleCellContent addSubview:newBox];
cell = nil;
topic = nil;
newBox = nil;
}
-(bool)hasChoiceBox:(SRCollapsibleCell *)cell{
for(UIView *subview in cell.SRCollapsibleCellContent.subviews){
if([subview isKindOfClass:[SRChoiceBox class]]){
return true;
}
}
return false;
}
SRChoiceBox - UIView object that gets inserted into cell
//.h
#protocol SRChoiceBoxDelegate <NSObject>
-(void)positionWasChoosen: (NSString *)choice topicId: (NSNumber *)topicId;
#end
#interface SRChoiceBox : UIView
-(id) initWithLabel: (NSDictionary *)labels andTopicID: (NSNumber *)topicId andFrame:(CGRect)frame;
#property (nonatomic, weak) IBOutlet UIView *SRChoiceBox;
#property (nonatomic, strong) NSNumber *SRTopicId;
#property (nonatomic, weak) id<SRChoiceBoxDelegate> delegate;
#property (weak, nonatomic) IBOutlet UILabel *agreeCount;
#property (weak, nonatomic) IBOutlet UILabel *disagreeCount;
#property (weak, nonatomic) IBOutlet UILabel *observeCount;
-(IBAction)buttonPress:(id)sender;
-(void)updateWithSRTopic:(SRTopic *)topic;
....
//.m
-(id)init{
self = [super init];
if (self) {
UINib *nib = [UINib nibWithNibName:#"SRChoiceBox" bundle:nil];
NSArray *q = [nib instantiateWithOwner:self options:nil];
[self addSubview:q[0]];
}
return self;
}
-(void)updateWithSRTopic:(SRTopic *)topic
{
self.SRTopicId = topic.topicId;
self.agreeCount.text = [NSString stringWithFormat: #"%#",topic.agreeDebaters];
self.disagreeCount.text = [NSString stringWithFormat: #"%#",topic.disagreeDebaters];
self.observeCount.text = [NSString stringWithFormat: #"%#",topic.observers];
}
- (IBAction)buttonPress:(id) sender {
int tag = [sender tag];
switch (tag) {
case 0:
[self.delegate positionWasChoosen:#"agree" topicId:self.SRTopicId];
break;
case 1:
[self.delegate positionWasChoosen: #"disagree" topicId:self.SRTopicId];
break;
case 2:
[self.delegate positionWasChoosen: #"observe" topicId:self.SRTopicId];
break;
default:
break;
}
}
- (void)dealloc
{
self.SRChoiceBox =nil;
self.SRTopicId=nil;
self.delegate=nil;
self.agreeCount=nil;
self.disagreeCount=nil;
self.observeCount=nil;
//NSLog(#"choicebox deallocated: %#", self);
}
SRCollapsibleCell -- Reusable cell
//.h
#interface SRCollapsibleCell : UITableViewCell
#property (strong) NSNumber *topicId;
#property (strong) NSDictionary *topicStats;
#property (weak, nonatomic) IBOutlet UILabel *title;
#property (weak, nonatomic) IBOutlet UILabel *subtitle;
#property (weak, nonatomic) IBOutlet UILabel *agreeDebaters;
#property (weak, nonatomic) IBOutlet UILabel *disagreeDebaters;
#property (weak, nonatomic) IBOutlet UILabel *observers;
#property (weak, nonatomic) IBOutlet UIImageView *arrow;
#property (weak, nonatomic) IBOutlet UIView *SRCollapsibleCellContent;
//-(void)updateWithTopic:(NSDictionary *) stats;
-(void)formatTitle:(NSString *)title;
-(void)updateWithTopic: (SRTopic *)topic;
#end
//.m
#implementation SRCollapsibleCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
}
return self;
}
-(void)formatTitle:(NSString *)title{
if(title.length<30){
self.title.text= title;
self.subtitle.text =#"";
} else {
NSArray *splitString = [self splitString:title maxCharacters:30];
self.title.text = splitString[0];
self.subtitle.text = splitString[1];
splitString = nil;
title = nil;
}
}
////http://www.musicalgeometry.com/?p=1197
- (NSArray *)splitString:(NSString*)str maxCharacters:(NSInteger)maxLength {
NSMutableArray *tempArray = [NSMutableArray arrayWithCapacity:1];
NSArray *wordArray = [str componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSInteger numberOfWords = [wordArray count];
NSInteger index = 0;
NSInteger lengthOfNextWord = 0;
while (index < numberOfWords && tempArray.count<2) {
NSMutableString *line = [NSMutableString stringWithCapacity:1];
while ((([line length] + lengthOfNextWord + 1) <= maxLength) && (index < numberOfWords)) {
lengthOfNextWord = [[wordArray objectAtIndex:index] length];
[line appendString:[wordArray objectAtIndex:index]];
index++;
if (index < numberOfWords) {
[line appendString:#" "];
}
}
[tempArray addObject:line];
NSMutableString *subtitle = [NSMutableString stringWithCapacity:1];
while(index<numberOfWords){
[subtitle appendString:[wordArray objectAtIndex:index]];
[subtitle appendString:#" "];
index++;
}
[tempArray addObject:subtitle];
break;
}
return tempArray;
}
//Breaks MVC but it makes the MasterVC cleaner
-(void)updateWithTopic: (SRTopic *)topic
{
[self formatTitle:topic.title];
self.topicId = topic.topicId;
self.agreeDebaters.text = [NSString stringWithFormat:#"%#",topic.agreeDebaters];
self.disagreeDebaters.text = [NSString stringWithFormat:#"%#", topic.disagreeDebaters];
self.observers.text = [NSString stringWithFormat:#"%#", topic.observers];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
}
#end