I have custom TableView dynamically populated with custom cells, each cell contains 2 buttons with images and 2 labels.
When scrolling my Table view and than scrolling back the buttons picures are changed. This is my code for custom cell
.h file
class #interface CatalogCategoriesDetailsCell : UITableViewCell
#property (nonatomic, weak) IBOutlet UIButton * firstStickerImageButton;
#property (nonatomic, weak) IBOutlet UIButton *secondStickerImageButton;
#property (strong, nonatomic) IBOutlet UILabel * firstStickerName;
#property (strong, nonatomic) IBOutlet UILabel * secondStickerName;
#end
.m file
#implementation CatalogCategoriesDetailsCell
#synthesize firstStickerImageButton = _firstStickerImageButton;
#synthesize secondStickerImageButton = _secondStickerImageButton;
#synthesize firstStickerName = _firstStickerName;
#synthesize secondStickerName = _secondStickerName;
#end
My TableViewControllerClass
.h file
#import "CatalogCategoriesStickerDetails.h"
#interface CatalogCategoriesDetails : UITableViewController
{
TagSingleton *sobj;
}
#property (strong,nonatomic) NSArray *categoryDetails;
#property (strong,nonatomic) NSString *selectedCategoryId;
#property (strong,nonatomic) NSMutableArray *categoryFileNames;
#property (strong, nonatomic) NSString *documentsDirectory;
#end
.m file
- (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 [self.categoryFileNames count] / 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"categoryDetailsTableCell";
CatalogCategoriesDetailsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CatalogCategoriesDetailsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
NSString *stickerFilePath = [self.documentsDirectory stringByAppendingString:#"/"];
//first column
if(self.stickerIndex < [self.categoryFileNames count])
{
NSString *stickerFileName = [self.categoryFileNames objectAtIndex:self.stickerIndex];
//NSLog(#"file name is %#", stickerFileName);
if(stickerFileName != #"end")
{
NSString *stickerFullFilePath = [stickerFilePath stringByAppendingString:stickerFileName];
UIImage *Image = [UIImage imageWithContentsOfFile:stickerFullFilePath];
[cell.firstStickerImageButton setImage:Image forState:UIControlStateNormal];
[cell.firstStickerImageButton setTag:self.stickerIndex];
[cell.firstStickerImageButton addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
NSLog(#"Tag is: %i",cell.firstStickerImageButton.tag);
//NSLog(#"filename is: %#",stickerFileName);
NSArray *stickerFileNameCoponents = [stickerFileName componentsSeparatedByString:#"_"];
NSString *stickerName = [stickerFileNameCoponents objectAtIndex: 1];
cell.firstStickerName.text = [cell.firstStickerName.text stringByAppendingString:stickerName];
}
}
//second column
if(self.stickerIndex < [self.categoryFileNames count] - 1)
{
NSString *stickerFileName = [self.categoryFileNames objectAtIndex:self.stickerIndex + 1];
//NSLog(#"file name is %#", stickerFileName);
if(stickerFileName != #"end")
{
NSString *stickerFullFilePath = [stickerFilePath stringByAppendingString:stickerFileName];
UIImage *Image = [UIImage imageWithContentsOfFile:stickerFullFilePath];
[cell.secondStickerImageButton setImage:Image forState:UIControlStateNormal];
[cell.secondStickerImageButton setTag:self.stickerIndex + 1];
[cell.secondStickerImageButton addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
NSLog(#"Tag is: %i",cell.secondStickerImageButton.tag);
//NSLog(#"filename is: %#",stickerFileName);
NSArray *stickerFileNameCoponents = [stickerFileName componentsSeparatedByString:#"_"];
NSLog(#"Sticker file name is: %#", stickerFileNameCoponents);
NSString *stickerName = [stickerFileNameCoponents objectAtIndex: 1];
cell.secondStickerName.text = [cell.secondStickerName.text stringByAppendingString:stickerName];
}
else
{
[cell.secondStickerImageButton setHidden:TRUE];
[cell.secondStickerName setHidden:TRUE];
}
}
self.stickerIndex +=2;
return cell;
}
-(void)buttonTapped:(UIButton *)button
{
int tag = button.tag;
//NSLog(#"Tag is %i", tag);
sobj = [TagSingleton singleObj];
sobj.buttonTag = [[NSNumber alloc] initWithInteger:tag];
[self performSegueWithIdentifier: #"StickerImageSegue" sender: self];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"StickerImageSegue"])
{
CatalogCategoriesStickerDetails *detailViewController = [segue destinationViewController];
detailViewController.stickerFileNames = self.categoryFileNames;
detailViewController.documentsDirectory = self.documentsDirectory;
}
}
I have solved the problem, the issue was that I was using my own indexing instead of connecting cells to [indexpath row].
Related
I am making an app in which i am using tableview and in each table cell i am using checkboxes. now i am stuck in this place that when checkbox is checked i want to get value of that table-cell. like i am showing messages id in table cell i want to get messages_Id of that cells whose checkboxes are checked. means if select 1 checkbox its message id is store in NSString and if i select 2 checkboxes then 2 messages of these checkboxes are store in string how it can be done.below is my sample code of tableview and check boxes action
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *tableviewidentifier = #"cell";
__block tablecellTableViewCell *cell= [self.activitiesTableView_ dequeueReusableCellWithIdentifier:tableviewidentifier];
if(cell==nil)
{
cell = [[tablecellTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:tableviewidentifier];
}if(indexPath.row == [self tableView:tableView numberOfRowsInSection:indexPath.section] - 1){
}
__block NSString *row = [NSString stringWithFormat:#"%ld",(long)indexPath.row];
cell.titlename.text=[[self.inboxmessagesarray objectAtIndex:indexPath.row]objectForKey:#"offerTitle"];
tocity.text=[[self.inboxmessagesarray objectAtIndex:indexPath.row]objectForKey:#"toCity"];
fromcity.text=[[self.inboxmessagesarray objectAtIndex:indexPath.row]objectForKey:#"fromCity"];
date.text=[[self.inboxmessagesarray objectAtIndex:indexPath.row]objectForKey:#"messageDate"];
time.text=[[self.inboxmessagesarray objectAtIndex:indexPath.row]objectForKey:#"messageTime"];
[cell.button setBackgroundImage:[UIImage imageNamed:#"uncheck.png"] forState:UIControlStateNormal];
[cell.button setImage:nil forState:UIControlStateNormal];
if ([self.checkimageArray containsObject:[self.lblArray objectAtIndex:indexPath.row]])
{
[cell.button setImage:[UIImage imageNamed:#"tick.png"]// here i am setting image
forState:UIControlStateNormal];
cell.contentView.backgroundColor=[UIColor colorWithRed:(245/255.0) green:(245/255.0) blue:(245/255.0) alpha:1];
}
else
{
cell.backgroundColor=[UIColor clearColor];
}
cell.button.tag=indexPath.row;
[cell.button addTarget:self action:#selector(checkButton:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
and below is my check button code
-(IBAction)checkButton:(UIButton *)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tblvie];
NSIndexPath *indexPath = [self.tblvie indexPathForRowAtPoint:buttonPosition];
if ([self.checkimageArray containsObject:[self.lblArray objectAtIndex:indexPath.row]]) {
[self.checkimageArray removeObject:[self.lblArray objectAtIndex:indexPath.row]];
self.titleLabel.text=#"";
}
else {
[self.checkimageArray addObject:[self.lblArray objectAtIndex:indexPath.row]];
self.titleLabel.text=[NSString stringWithFormat:#"%ld selected",(long)sender.tag+1];
}
[self.tblvie reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation: UITableViewRowAnimationFade];
}
and i want to get value of these checked boxes in this button
- (IBAction)menubtun:(id)sender {
}
there if want the cell info of selected cell, just handle the action method of tickButton in custom cell it self not in controller use below code define a protocol and define a delegate see the below code
in tablecellTableViewCell.h
#import <UIKit/UIKit.h>
#class tablecellTableViewCell;
#protocol CustomCellDelegate <NSObject>
- (void)checkBoxButtonSelected:(tablecellTableViewCell *)cell; //this is the custom delegate method
#end
#interface tablecellTableViewCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UIImageView *profileImageView; //i changed the name for conventions
#property (weak, nonatomic) IBOutlet UIButton *tickButton;
#property (weak, nonatomic) IBOutlet UILabel *nameLabel; //valuedate
#property (weak, nonatomic) IBOutlet UILabel *messageLabel;
#property (weak, nonatomic) IBOutlet UILabel *dateLabel;
#property (weak, nonatomic) IBOutlet UILabel *timeLabel;
#property (weak, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicatorView;
#property (weak, nonatomic) id<CustomCellDelegate> cellDelegate; //decleare a delegate hear
- (void)setFont:(UIFont *)font withString:(NSString *)title;
#end
and in tablecellTableViewCell.m all code is same but u have to connect a action to tickButton for example
#import "tablecellTableViewCell.h"
#implementation tablecellTableViewCell
//#synthesize button,image;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self)
{
}
return self;
}
- (void)awakeFromNib
{
// Initialization code
[super awakeFromNib];
[self setUp];
}
//...same code of yours no need to change just a action method of tick button is added extra
//in this call a delegate method by passing the entire cell itself
- (IBAction)checkButtonAction:(id)sender
{
if([self.cellDelegate respondsToSelector:#selector(checkBoxButtonSelected:)])
{
[self.cellDelegate checkBoxButtonSelected:self];//hear u are passing the enire cell to Fbinbox..controller
}
}
in the controller class .h file
//..same code just confirm to protocol
#interface inboxViewController : UIViewController<UITableViewDataSource,UITableViewDelegate,UIActionSheetDelegate,CustomCellDelegate> //confirm to protocol
{
int checkBoxesCount;
}
in .m file
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
__block tablecellTableViewCell *cell= [tableView dequeueReusableCellWithIdentifier:tableviewidentifier];
if(cell == nil)
{
cell = [[tablecellTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:tableviewidentifier];
}
if(indexPath.row == [self tableView:tableView numberOfRowsInSection:indexPath.section] - 1)
{
}
__block NSString *row = [NSString stringWithFormat:#"%ld",(long)indexPath.row];
cell.activityIndicatorView.hidden = NO;
[cell.activityIndicatorView startAnimating];
if([[[self.inboxmessagesarray objectAtIndex:indexPath.row]objectForKey:#"messageRead"] intValue]==0)
{
cell.contentView.backgroundColor=[UIColor colorWithRed:(245/255.0) green:(245/255.0) blue:(245/255.0) alpha:1];
}
else
{
cell.contentView.backgroundColor=[UIColor clearColor];
}
cell.messageLabel.text = [[self.inboxmessagesarray objectAtIndex:indexPath.row]objectForKey:#"toCity"];
cell.cellDelegate = self;//add this one line
//... rest same code but comment the action method of tick button
//..hear in the last
cell.tickButton.tag = indexPath.row;
// [cell.tickButton addTarget:self action:#selector(checkButton:) forControlEvents:UIControlEventTouchUpInside]; //comemnt this line this tickbutton action is in custom cell
}
//now define custom delegate method
- (void)checkBoxButtonSelected:(tablecellTableViewCell *)cell //in this cell contains every thing including message and all
{
//hear u are getting the entire cell
//now u can get the all info stored in this cell
NSIndexPath *indexPath = [self.activitiesTableView_ indexPathForCell:cell];
if ([self.checkimageArray containsObject:[self.lblArray objectAtIndex:indexPath.row]]) {
[self.checkimageArray removeObject:[self.lblArray objectAtIndex:indexPath.row]];
//....other stuff's
//cell.textLabel.text;
//..all info present in the cell
}
else
{
[self.checkimageArray addObject:[self.lblArray objectAtIndex:indexPath.row]];
//..do other stuff
NSString *selectedMessage = cell.messageLabel.text;
//cell.textLabel.text;
//..all info present in the cell
NSLog(#"SELECTED MESSAGE->%#",selectedMessage);
}
[self.activitiesTableView_ reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation: UITableViewRowAnimationFade];
}
I have a tableView which I get the content from Parse.com (an image, one title and one description) and I am using a UIView for my detailView. When a cell is tapped UIView comes in with an animation. I managed to get My title and description of events but I couldn't get the Image file.
How to pass the parsed image into the UIView?
Thanks.
Here is my .h file
#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#import "TableCell.h"
#interface ViewController : UIViewController <UITableViewDelegate> {
NSArray *events;
}
#property (weak, nonatomic) IBOutlet UITableView *newsTable;
#property (strong, nonatomic) IBOutlet UIView *detailView;
#property (strong, nonatomic) IBOutlet UILabel *InfoDetailLabel;
- (IBAction)backBtn:(id)sender;
#property (strong, nonatomic) IBOutlet UILabel *viewTitle;
Here is the .m file
#import "ViewController.h"
#import "TableCell.h"
#import "Reachability.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize newsTable;
- (BOOL)connected
{
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [reachability currentReachabilityStatus];
return !(networkStatus == NotReachable);
}
- (void)viewDidLoad
{
[super viewDidLoad];
//Pull to refresh
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:#selector(refresh:) forControlEvents:UIControlEventValueChanged];
[self.newsTable addSubview:refreshControl];
//Checking connection
if (![self connected])
{
// not connected
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Internet Connection Not Found" message:#"Please check your network settings!" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
} else
{
// connected, do some internet stuff
}
// Do any additional setup after loading the view, typically from a nib.
[self performSelector: #selector(retreiveFromParse)];
}
//pull to refresh
- (void)refresh:(UIRefreshControl *)refreshControl {
[refreshControl endRefreshing];
}
- (void) retreiveFromParse {
PFQuery *retrieveEvents = [PFQuery queryWithClassName:#"News"];
[retrieveEvents findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
events = [[NSArray alloc] initWithArray:objects];
}
[newsTable reloadData];
}];
}
//*********************Setup table of folder names ************************
//get number of sections in tableview
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
//get number of rows by counting number of folders
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return events.count;
}
//setup cells in tableView
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//setup cell
static NSString *CellIdentifier = #"EventCell";
TableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
PFObject *tempObject = [events objectAtIndex:indexPath.row];
cell.TitleLabel.text = [tempObject objectForKey:#"Event"];
cell.DescriptionLabel.text = [tempObject objectForKey:#"Description"];
// To get the image file from Parse class
PFFile *imageFile = [tempObject objectForKey:#"imageFile"];
PFImageView *imageView = [[PFImageView alloc] init];
imageView.file = imageFile;
[imageView loadInBackground:^(UIImage *img,NSError *error){
if(!error)
{
UIImageView *yourImageView = [[UIImageView alloc] init];
yourImageView.image = imageView.image;
/*OR*/
cell.imageView.image = imageView.image;
}}];
return cell;
}
//user selects folder to add tag to
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"cell tapped");
//For detail view
PFObject *tempObject = [ events objectAtIndex:indexPath.row];
NSLog(#"%#", tempObject.objectId);
_InfoDetailLabel.text = [tempObject objectForKey:#"detailinformation"];
[self animateDetailView];
_viewTitle.text = [tempObject objectForKey:#"Event"];
[self animateDetailView];
}
//for animation of detailview
- (void) animateDetailView {
[UIView animateWithDuration:0.3 animations:^{
_detailView.frame = CGRectMake(0, 0, 320, 518);
}];
}
//back button with animation
- (IBAction)backBtn:(id)sender {
[UIView animateWithDuration:0.3 animations:^{
_detailView.frame = CGRectMake(320, 0, 320, 518);
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
and my cell .h
#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#interface TableCell : UITableViewCell
#property (strong, nonatomic) IBOutlet UILabel *TitleLabel;
#property (strong, nonatomic) IBOutlet UILabel *DescriptionLabel;
#property (strong, nonatomic) IBOutlet PFImageView *imageView;
#end
Try,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"cell tapped");
//Assuming not reordering the cells after it loaded
TableCell *cell = (TableCell *)[tableView cellForRowAtIndexPath:indexPath];
[[yourDetailView imageView] setImage:[[cell imageView] image]];
.....
}
or you can use the same method loadInBackground: used in cellForRow in detailView also
This is weird, I know but my [UITableView reloadData] is not removing old cells, like this:
The mess you see happened after I clicked on the + button, came back and changed values again. plus button pushes the navigationController to an another controller, and after I came back with clicking on the back button and changed the value, this is what I see. How is it possible?? I used a custom view (subclassed from UIView), which I created as a UIStepper with a UILabel. Here is the codes, the controller.m, and the .h-.m files for the custom UIView.
controller.m
#interface ViewController ()
#property NSString *docsDir;
#property sqlite3 *DB;
#property NSArray *dirPaths;
#property NSString* databasePath;
#property (strong, nonatomic) IBOutlet UITableView *tableView;
#property BOOL isCreatedBefore;
#property NSArray *theList;
#end
#implementation ViewController
#synthesize docsDir;
#synthesize DB;
#synthesize dirPaths;
#synthesize databasePath;
- (void)viewDidLoad
{
[super viewDidLoad];
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: [NSString stringWithFormat:#"database.db"]]];
[self createDatabase];
self.theList = [self readAllEntries];
}
-(void) viewWillAppear:(BOOL)animated{
self.theList = [self readAllEntries];
[self.tableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.theList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{ SeriesObject * obj = [self.theList objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cellocan"];
UILabel *nameLabel = (UILabel *)[cell.contentView viewWithTag:1];
[nameLabel setText:obj.name];
CounterView *seasonCounter = [[CounterView alloc] initWithX:220 WithY:28 WithName:obj.name withCount:obj.session withCustomTag:indexPath.row];
seasonCounter.tag = 2;
CounterView *episodeCounter = [[CounterView alloc] initWithX:268 WithY:28 WithName:obj.name withCount:obj.episode withCustomTag:indexPath.row];
episodeCounter.tag = 4;
[cell.contentView addSubview:seasonCounter];
[cell.contentView addSubview:episodeCounter];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return YES if you want the specified item to be editable.
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
SeriesObject *obj = [self.theList objectAtIndex:indexPath.row];
[self deleteEntryWithID:obj.idd];
self.theList = [self readAllEntries];
[self.tableView reloadData];
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 88;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
______and more about reading from database or deleting; not about the view. (this is a very simple app, as a free time hobby; so I didn't spend time to follow MVC)
CounterView.h
#interface CounterView : UIView
#property NSString* name;
#property NSInteger count;
#property UILabel *label;
#property NSInteger customTag;
- (id)initWithX:(CGFloat)xPoint WithY:(CGFloat)yPoint WithName:(NSString*)newName withCount:(NSInteger)newCount withCustomTag:(NSInteger)newTag;
#end
CounterView.m
#interface CounterView()
#property NSString *docsDir;
#property sqlite3 *DB;
#property NSArray *dirPaths;
#property NSString* databasePath;
#end
#implementation CounterView
#synthesize docsDir;
#synthesize DB;
#synthesize dirPaths;
#synthesize databasePath;
- (id)initWithX:(CGFloat)xPoint WithY:(CGFloat)yPoint WithName:(NSString*)newName withCount:(NSInteger)newCount withCustomTag:(NSInteger)newTag
{
self = [super initWithFrame:CGRectMake(xPoint, yPoint, 24, 52)];
if (self) {
self.customTag = newTag;
self.count = newCount;
self.name = newName;
UIButton *btnUp = [[UIButton alloc] initWithFrame:CGRectMake(3, 2, 18, 12)];
[btnUp setImage:[UIImage imageNamed:#"top.png"] forState:UIControlStateNormal];
[btnUp addTarget:self action:#selector(increaseValue) forControlEvents:UIControlEventTouchUpInside];
UIButton *btnDown = [[UIButton alloc] initWithFrame:CGRectMake(3, 38, 18, 12)];
[btnDown setImage:[UIImage imageNamed:#"bottom.png"] forState:UIControlStateNormal];
[btnDown addTarget:self action:#selector(decreaseValue) forControlEvents:UIControlEventTouchUpInside];
self.label = [[UILabel alloc] initWithFrame:CGRectMake(0, 14, 24, 24)];
[self.label setText:[NSString stringWithFormat:#"%ld", (long)self.count]];
self.label.textAlignment = NSTextAlignmentCenter;
[self addSubview:btnUp];
[self addSubview:btnDown];
[self addSubview:self.label];
}
return self;
}
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents{
}
-(void) increaseValue{
self.count++;
[self.label setText:[NSString stringWithFormat:#"%ld", (long)self.count]];
}
-(void) decreaseValue{
self.count--;
[self.label setText:[NSString stringWithFormat:#"%ld", (long)self.count]];
}
____and some more database codes too..
In your cellForRowAtIndexPath: you are adding a subview every time. Cells are reused by UITableView, so when you reload you're getting a "dirty" cell. You need to check if the view is already there. If so, modify the view instead of adding one. Google "UITableViewCell viewWithTag" to see some sample code.
- (void)prepareForReuse
{
//remove your subviews here
[self.subViewToRemove removeFromSuperView];
}
I would recommend that you create a custom cell class derived from UITableViewCell and have it include your custom CounterView instances. In this case you won't need to add the subviews each time in your cellForRowAtIndexPath (Which is causing the problem you're having), you can instead pass it whatever values it requires.
after some modifications, using this in the cellForRowAtIndexpath: method solved everything. Thanks everyone.
if (cell != nil)
{
NSArray* subviews = [cell.contentView subviews];
for (UIView* view in subviews)
{
[view removeFromSuperview];
}
}
Whenever I search for something from a search bar, I get the correct results. When I click on those results, it links me to the same place that the original results would have linked me to. In other words, I have teacher a-e, I type in 'e', and get only the result 'e', but when I click on that cell, it links me to the teacher 'a' profile.
Here is what I have so far.
#import <UIKit/UIKit.h>
#interface ListTableViewController : UITableViewController
#end
---
#import "ListTableViewController.h"
#import "DetailsViewController.h"
#interface ListTableViewController () <UISearchDisplayDelegate>
#property (strong, nonatomic) NSArray *className;
#property (strong, nonatomic) NSArray *teacherName;
#property (strong, nonatomic) NSArray *blockNumber;
#property (strong, nonatomic) NSArray *myNew;
#property (strong, nonatomic) NSArray *searchResults;
#end
#implementation ListTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.className = [NSArray arrayWithObjects:#"Biology",#"English III",#"Chemistry",#"Algebra II",#"Morality", nil];
self.teacherName = [NSArray arrayWithObjects:#"Teacher A",#"Teacher B",#"Teacher C",#"Teacher D",#"Teacher E", nil];
self.blockNumber = [NSArray arrayWithObjects:#"B1",#"B3",#"B6",#"B2",#"B1", nil];
NSMutableArray *combinedArray = [[NSMutableArray alloc]init];
for (int i = 0; i < [self.className count]; i++)
{
NSString *combinedString = [NSString stringWithFormat:#"%# | %# | %#",[self.className objectAtIndex:i],[self.teacherName objectAtIndex:i],[self. blockNumber objectAtIndex:i]];
[combinedArray addObject:combinedString];
}
self.myNew = combinedArray;
}
- (void)filterContentForSearchText: (NSString *) searchText
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"SELF CONTAINS[cd] %#", searchText];
self.searchResults = [self.myNew filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString];
return YES;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.tableView) {
return [self.myNew count];
} else { // (tableView == self.searchDisplayController.searchResultsTableView)
return [self.searchResults count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (tableView == self.tableView) {
cell.textLabel.text = [self.myNew objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = [self.searchResults objectAtIndex:indexPath.row];
}
return cell;
}
#pragma mark - Table view delegate
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showDetails"]) {
DetailsViewController *dvc = segue.destinationViewController;
NSIndexPath *indexPath = nil;
if ([self.searchDisplayController isActive]) {
indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
dvc.sendLabel = [self.searchResults objectAtIndex:indexPath.row];
dvc.teachersendLabel = [self.teacherName objectAtIndex:indexPath.row];
return;
} else{
indexPath = [self.tableView indexPathForSelectedRow];
dvc.sendLabel = [self.myNew objectAtIndex:indexPath.row];
dvc.teachersendLabel = [self.teacherName objectAtIndex:indexPath.row];
return;
}
}
}
#end
In my DetailsViewController
#import <UIKit/UIKit.h>
#interface DetailsViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *label;
#property (strong, nonatomic) NSString *sendLabel;
#property (weak, nonatomic) IBOutlet UILabel *teacherlabel;
#property (strong, nonatomic) NSString *teachersendLabel;
#end
---
#implementation DetailsViewController
#synthesize label;
- (void)viewDidLoad
{
[super viewDidLoad];
self.teacherlabel.text = [NSString stringWithFormat:#"%#", self.teachersendLabel];
self.label.text = [NSString stringWithFormat:#"%#", self.sendLabel];
}
#end
Looking at your code it wouldn't seem there to be any problem. The are only two things I can think of:
1) I'm not sure how you're displaying the 'main' tableView and the search results one. Might it be that your touches are actually getting handled by the 'main' tableView? This might happen if you have the two tables aligned on top of each other and the bottom one is still visible and with userInteractionEnabled set to YES when the search one 'isActive'. In this case the view hierarchy should look similar to this:
- UIView
- UITableView (main)
- UITableView (search)
2) the use of -[UITableView indexPathForSelectedRow] in prepareForSegue:sender:. If you're using Storyboard the sender is the selected cell. You may want to check that the sender is an actual cell or an indexPath isKindOfClass. If the sender is an indexPath you can use it, if it's a cell you can call the method -[UITableView indexPathForCell:]. Using this approach you make sure your segue is actually triggering for the right event (e.g. you can programmatically select a cell, but this won't fire a segue and you can later decide to call -performSegueWithIdentifier:sender: and this would break your implementation).
Here are the ViewControllers again.
Here is my ViewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>
#property (copy, nonatomic) NSDictionary *firstTableView;
#property (copy, nonatomic) NSArray *firstTableViewKey;
#property (weak, nonatomic) IBOutlet UILabel *norskLabel;
#property (weak, nonatomic) IBOutlet UILabel *infinitivLabel;
#property (weak, nonatomic) IBOutlet UILabel *presensLabel;
#property (weak, nonatomic) IBOutlet UILabel *preteritumLabel;
#property (weak, nonatomic) IBOutlet UILabel *perfektumLabel;
#end
Here is my ViewController.m:
#import "ViewController.h"
static NSString *SectionsTableIdentifier = #"SectionsTableIdentifier";
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
UITableView *tableView = (id)[self.view viewWithTag:1];
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:SectionsTableIdentifier];
NSString *path = [[NSBundle mainBundle] pathForResource:#"SterkeVerb" ofType:#"plist"];
self.firstTableView = [NSDictionary dictionaryWithContentsOfFile:path];
self.firstTableViewKey = [[self.firstTableView allKeys] sortedArrayUsingSelector:#selector(compare:)];
tableView.backgroundColor = [UIColor clearColor];
tableView.opaque = NO;
tableView.backgroundView = nil;
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark -
#pragma mark Table View Data Source Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [self.firstTableViewKey count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSString *key = self.firstTableViewKey[section];
NSArray *nameSection = self.firstTableView[key];
return [nameSection count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
return self.firstTableViewKey[section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];
NSString *key = self.firstTableViewKey[indexPath.section];
NSArray *nameSection = self.firstTableView[key];
cell.textLabel.text = nameSection[indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0){
_norskLabel.text = #"å bake";
_infinitivLabel.text = #"zu backen";
_presensLabel.text = #"bäckt/backt";
_preteritumLabel.text = #"backte";
_perfektumLabel.text = #"hat gebacken";
}
else if (indexPath.row == 1){
_norskLabel.text = #"å motta";
_infinitivLabel.text = #"zu empfangen";
_presensLabel.text = #"empfängt";
_preteritumLabel.text = #"empfing";
_perfektumLabel.text = #"hat empfangen";
}
}
Ok, so i have my table view devided into sections(A-Z) and when i filled in the code it worked perfectly for the first section. BUT, when i pressed one of the cells in the next section, it showed the same information as the first cell in the first section. WHY?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0){
_norskLabel.text = #"å bake";
_infinitivLabel.text = #"zu backen";
_presensLabel.text = #"bäckt";
_preteritumLabel.text = #"backte";
_perfektumLabel.text = #"hat gebacken";
else if (indexPath.row == 1){
_norskLabel.text = #"å begynne";
_infinitivLabel.text = #"zu beginnen";
_presensLabel.text = #"beginnt";
_preteritumLabel.text = #"begann";
_perfektumLabel.text = #"hat begonnen";
}
}
If you set the text in tableview:didSelectRowAtIndexPath: it will just get overwritten when tableview:cellForRowAtIndexPath: is called
Inside tableview:didSelectRowAtIndexPath:, you need to access the data driving the table and change it at its source.
NSString *key = self.firstTableViewKey[indexPath.section];
NSArray *nameSection = self.firstTableView[key];
nameSection[indexPath.row] = #"New Value";