How to get value from UITableViewCell - ios

I'm having a problem in getting a value in uitableviewcell.
first of all, i have a label on my cell which I've created a tap gesture on it. What i want to do is on tapping that label, viewUser method will be call and it will get the details of that cell being tapped.
Here is my code:
on cellForRowAtIndexPath:
cell.userNameLabel.text = [[_workflowList objectAtIndex:indexPath.row] userName];
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(viewUser:)];
tapGestureRecognizer.numberOfTapsRequired = 1;
[cell.userNameLabel addGestureRecognizer:tapGestureRecognizer];
cell.userNameLabel.userInteractionEnabled = YES;
Now, when i call my ontap method which is viewUser:
- (IBAction)viewUser:(id)sender {
//this should not be hard coded
//data should come from cell.
//usernamelabel or i will get the index selected
//and get the details in my array
// like this --> [_workflowList objectAtIndex:index]
WorkflowProfileViewController *chkDtl = [[WorkflowProfileViewController alloc]init];
chkDtl.name = #"USER, USER USER"; ;
chkDtl.phoneNo = #"09173210836";
chkDtl.email = #"romelync#sxchange.com";
[self.navigationController pushViewController:chkDtl animated:YES];
}
Please help me on this.

The best option would be to use UITableView delegate method tableView:didSelectRowAtIndexpath: as below:
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
WorkflowProfileViewController *chkDtl = [[WorkflowProfileViewController alloc]init];
chkDtl.name=[[_workflowList objectAtIndex:indexPath.row] userName];
[self.navigationController pushViewController:chkDtl animated:YES];
}
Don't forget to set delegate of your tableView.
UPDATE: Then I think you want to do something like below. In your cellForRowAtaIndexPath: add following:
cell.userNameLabel.tag=indexPath.row;
And in viewUser method:
UITapGestureRecognizer *tap=(UITapGestureRecognizer*)sender;
WorkflowProfileViewController *chkDtl = [[WorkflowProfileViewController alloc]init];
chkDtl.name=[[_workflowList objectAtIndex:tap.view.tag] userName];
[self.navigationController pushViewController:chkDtl animated:YES];

When creating UILable you could put the tag value as row number
lable.tag = indexPath.row
In your method then retrieve label and look for tag value.

Something like below will get the cell you are tapping (replace swipe with tap):
- (void)handleSwipeRight:(UISwipeGestureRecognizer *)gestureRecognizer{
CGPoint location = [gestureRecognizer locationInView:self.tableView];
NSIndexPath *swipedIndexPath = [self.tableView indexPathForRowAtPoint:location];
self.currentSwipedCell = [self.tableView cellForRowAtIndexPath:swipedIndexPath];
}
Havent tested it yet but:
-(void)viewUser:(UITapGestureRecognizer):gestureRecognizer{
CGPoint location = [gestureRecognizer locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
self.currentTappedCell = [self.tableView cellForRowAtIndexPath:indexPath];
NSLog(self.currentTappedCell.name); // If you have a custom cell with a name property
}

Definitely you should use the proper delegate methods instead implementing UITapGestureRecognizer on an UITableViewCell. Then you can get the informations you want pretty easily:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *theUserNameYouWantToGet = [_workflowList objectAtIndex:[indexPath row]];
}
EDIT:
If you want that action not to work for the whole cell, you could subclass UITableViewCell, add properties to it and implement your own delegate protocol to that cell:
#protocol JWTableViewCellDelegate;
#interface JWTableViewCell : UITableViewCell
#property (nonatomic, retain) NSString *username;
#property (nonatomic, assign) id<JWTableViewCellDelegate>delegate;
#end
#protocol JWTableViewCell <NSObject>
- (void)tableViewCellDidClickUsername:(JWTableViewCell *)cell;
#end
#implementation JWTableViewCell
- (void)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
[self setupView];
}
return self;
}
// if you use a prototyping NIB
- (void)awakeFromNib {
[self setupView];
}
- (void)setupView {
// add gesture recognizer
}
- (void)handleGesture {
if ([_delegate respondsToSelector:#selector(tableViewCellDidClickUsername:)]) {
[_delegate tableViewCellDidClickUsername:self];
}
}
Then use this in your viewController:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
JWTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"reuseID" forIndexPath:indexpath];
[cell setUsername:#"Paul"];
[cell setDelegate:self];
}
- (void)tableViewCellDidClickUsername:(JWTableViewCell *)cell {
NSString *theUserNameYouWantToGet = [cell username];
  }

Related

How to change height of custom cell on button's click?

I have an issue regarding height of custom cell. I need to increase the height of cell when one button on cell was clicked. her I know to use two methods (heightforrow and didselectrow) for it but I am confuse that when I clicked on button that time custom method for button action is called and I am using those two methods in controller.I attached my code:
in customcell.m
- (IBAction)btnRestPlusClicked:(id)sender
{
UIButton *btn = (id)sender;
btn.selected =!btn.selected;
if (btn.selected)
{
NSLog(#"selected");
// _viewExtraScheduleAmount.hidden = FALSE;//I need to make this event on button action and same time increase the height of cell.
}
else
{
btn.tag = 0;
// _viewExtraScheduleAmount.hidden = TRUE;
}
now I need that when button clicked that time only that row's height will increase.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//if (ceel.btnRestPlusClicked.selected)
//{
// return 100;
// }
// return 60;
I know I am wrong here but how to use this method?
}
Please can any one help me out from this?
Thanks
Create NSMutableDictionary inside of UIViewController where you will store NSIndexPath of btnRestPlusClicked cells.
Then track when button plus selected in each cell:
In CustomCell.h
#protocol CustomCellDelegate;
#interface CustomCell : UITableViewCell
#property (nonatomic, weak) id<CustomCellDelegate> delegate;
#end
#protocol CustomCellDelegate <NSObject>
- (void)customCellButtonPlusSelected:(CustomCell*)cell;
#end
In CustomCell.m
- (IBAction)btnRestPlusClicked:(id)sender
{
[self.delegate customCellButtonPlusSelected:self];
}
In UIViewController when you create cell for cellForRowAtIndexPath add:
cell.delegate = self
and conform UIViewController to CustomCellDelegate
-(void)customCellButtonPlusSelected:(CustomCell*)cell {
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
NSString *key = [NSString stringWithFormat:#"%li:%li", indexPath.section, indexPath.row];
[buttonPlusClickedDictionary setObject:#"1" forKey:key];
[self.tableView reloadRowsAtIndexPaths:#[indexPath]];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *key = [NSString stringWithFormat:#"%li:%li", indexPath.section, indexPath.row];
if ([buttonPlusClickedDictionary objectForKey:key]) {
return 100;
}
return 60;
}
Try adding a boolean variable as class member. Set it when you click the button.
Reload the table view at the end of - (IBAction)btnRestPlusClicked:(id)sender
In - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath change the height of tableview cell if boolean variable is set.
The problem is not the implementation of heightForRowAtIndexPath: but in getting the runtime to call heightForRowAtIndexPath: again, so that it can discover that your cell height has changed. To do that, your button should tell the table view to reloadData.
You can change the height of your selected cell when you tap on that cell button like
ViewController.h
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
{
IBOutlet UITableView *myTableView;
}
#end
ViewController.m
#interface ViewController ()
#end
#implementation ViewController {
NSArray *tableData;
int currentselection;
int cellno;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
currentselection = -1;
tableData = [NSArray arrayWithObjects:#"Egg Benedict", #"Mushroom Risotto", #"Full Breakfast", #"Hamburger", #"Ham and Egg Sandwich", #"Creme Brelee", #"White Chocolate Donut", #"Starbucks Coffee", nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [tableData count];
}
- (CGFloat)tableView:(UITableView )tableView heightForRowAtIndexPath:(NSIndexPath )indexPath {
int rowHeight;
if ([indexPath row] == currentselection) {
rowHeight = 200;
} else {
rowHeight = 50;
}
return rowHeight;
}
- (UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"SimpleTableItem";
NSInteger myInteger = indexPath.row;
cellno = (int) myInteger;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
// add custom expand height button
UIButton *addFriendButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
addFriendButton.frame = CGRectMake(200.0f, 5.0f, 75.0f, 30.0f);
[addFriendButton setTitle:#"Add" forState:UIControlStateNormal];
[cell addSubview:addFriendButton];
[addFriendButton addTarget:self action:#selector(addHeight:) forControlEvents:UIControlEventTouchUpInside];
[addFriendButton setTag:cellno];
return cell;
}
- (IBAction) addHeight:(UIButton *)sender {
NSInteger myInteger = sender.tag;
currentselection = (int) myInteger;
[myTableView beginUpdates];
[myTableView endUpdates];
}

Unrecognized selector sent to instance UITableViewCell

i have looked up the same questions, but the answers given don't seem to fix my problem.
I'm creating an app where you can add and remove your school marks. In my view controller i have created a UITableView. Within there there's a custom UITableViewCell, called TableViewCell. To delete a cell i need to get it's row. I try that by using the following code in the TableViewCell class:
- (IBAction)DeleteMark:(id)sender {
UITableView *superTableView = [self superview];
NSIndexPath *path = [superTableView indexPathForCell:self];
NSInteger *index = [path row];
NSLog([NSString stringWithFormat:#"%#", index]);
}
When i run the code it shows the following error:
-[UITableViewWrapperView indexPathForCell:]: unrecognized selector sent to instance 0xa825a00
As i said before i tried the solutions given on the forums, but none of them worked.
EDIT
Here's my code for cellForRowAtIndexPath
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
float weight = [[_editableClass.markWeights objectAtIndex:indexPath.row]floatValue];
float mark = [[_editableClass.classMarks objectAtIndex:indexPath.row]floatValue];
cell.MarkTextLabel.text = [NSString stringWithFormat:#"%.1f", mark];
cell.MarkWeight.text = [NSString stringWithFormat:#"%.1f", weight];
[cell.DeleteButton setTag:indexPath.row];
return cell;
}
To do something like what you are after you could try to set up a delegate to pass back the cell object so you can find the index from the tableView. I have tried to make an example below. For tidiness I have omitted import statements.
ViewController header file
#interface subClassViewController : UIViewController<UITableViewDataSource, UITableViewDelegate,TableViewCellDelegate>
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#end
ViewController implementation file
#implementation subClassViewController
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
//setup cell...
cell.delegate = self;
return cell;
}
- (void)deletePressedOnCell:(UITableViewCell *)cell
{
NSInteger index = [self.tableView indexPathForCell:cell].row;
// do something with index
}
#end
TableViewCell header file
#protocol TableViewCellDelegate
- (void)deletePressedOnCell:(UITableViewCell *)cell;
#end
#interface TableViewCell : UITableViewCell
#property (weak, nonatomic) id<TableViewCellDelegate>delegate;
#end
TableViewCell implementation file
#implementation TableViewCell
- (IBAction)DeleteMark:(id)sender
{
[self.delegate deletePressedOnCell:self];
}
#end
In your UITableview Delegate method cellForRowAtIndexPath set tag of your button:-
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
.....
cell.yourdeletebutton.tag=indexPath.row;
}
Now in your delete method it looks like:-
- (IBAction)DeleteMark:(id)sender {
UIButton *tappedButton = (UIButton*)sender;
DeleteIndex=tappedButton.tag;
NSLog(#"delete row at indexpath :%#", DeleteIndex]);
}
You can use by [sender tag],
[cell.btnDelete setTag:indexPath.row];
[cell.btnDelete addTarget:self action:#selector(DeleteMark:) forControlEvents:UIControlEventTouchUpInside];
Method,
- (IBAction) DeleteMark:(id)sender {
NSInteger *index = [sender tag];
NSLog([NSString stringWithFormat:#"%#", index]);
// Your Code...
//For Eg.
Object *obj = [YOUR_ARRAY objectAtIndex:[sender tag]];
// You'll get object of particular index.
// Your Code...
}
Thanks.
You shouldn't rely on [[[[sender superview] superview] superview] superview], what if Apple decide to make some changes and add/remove another layer of subview.
The idea with tags is not ideal neither.
I would recommended you to use delegate pattern or blocks.
Please have a look how closures works. Note that it's written in swift but it could be easily translated to Objective-C.
In your TableViewCell add handler property:
var buttonPressHandler: (() -> ())?
Add IBAction which must be connected to button touch event (you could do it in storyboard):
#IBAction func buttonPressed(sender: AnyObject) {
// Call handler when button is pressed
buttonPressHandler?()
}
In cellForRowAtIndexPath you only needs to set up the handler:
cell.buttonPressHandler = {
print("Button pressed: \(indexPath.row)")
}
Get the index path of the row using following code
- (void)tapped:(UIButton *) sender {
UITableViewCell * tCell;
NSComparisonResult order = [[UIDevice currentDevice].systemVersion compare: #"7.2" options: NSNumericSearch];
if (order == NSOrderedDescending) {
tCell = (BusinessFavoriteCell *)[[[[sender superview] superview] superview] superview];
} else {
tCell = (BusinessFavoriteCell *)[[[sender superview] superview] superview];
}
NSIndexPath * iPath = [self.tableView indexPathForCell:tCell];
}
Here, tCell is the UITableViewCell which is loaded in cellForRowIndexpath method.

Adding UILongPressGestureRecognizer to UIButton inside custom UITableViewCell

I have a custom cell with various IBOutlets, but on one button I want to add a UILongPressGestureRecognizer for long press gestures. Here is my code (btw outlets are connected correctly and the IBAction method of the button is called correctly):
MyCustomCell.h
#interface MyCustomCell : UITableViewCell
#property (strong, nonatomic) IBOutlet UIButton *myButton;
#property (strong, nonatomic) UILongPressGestureRecognizer *longPressGestureRecognizer;
#end
MyCustomCell.m
- (void)awakeFromNib
{
// Initialization code
self.longPressGestureRecognizer = nil;
}
MyViewController.m
#import MyCustomCell.h
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"MyCell";
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
if (!cell){
cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
cell.longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPressGestures:)];
cell.longPressGestureRecognizer.minimumPressDuration = 1.0f;
cell.longPressGestureRecognizer.allowableMovement = 300.0f;
[cell.myButton addGestureRecognizer:cell.longPressGestureRecognizer];
}
- (void)handleLongPressGestures:(UIGestureRecognizer *)recognizer
{
if ([recognizer.view isKindOfClass:[UIButton class]]){
if (recognizer.state == UIGestureRecognizerStateBegan){
NSLog(#"Long press began");
} else if (recognizer.state = UIGestureRecognizerStateEnded){
NSLog(#"Long press ended");
}
}
}
The problem is handleLongPressGestures: method is never called.
the longPressGestureRecognizer should be a property on the controller and not the view(MyCustomCell). Move the property over to MyViewController and try again. My guess is something weird is happening when it queues and dequeues the MyCustomCell.
Objects(cells) for reuse should be lightweight. In this case, the longPressGestureRecognizer's target is the view controller and is nasty.
Try out this way
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"MyCell";
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
if (!cell){
cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
if ([[cell gestureRecognizers] count]<1) {
UILongPressGestureRecognizer *longPressGestureRecognizer;
longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPressGestures:)];
longPressGestureRecognizer.minimumPressDuration = 1.0f;
longPressGestureRecognizer.allowableMovement = 300.0f;
longPressGestureRecognizer.delegate = self;
[cell.myButton addGestureRecognizer:cell.longPressGestureRecognizer];
}
}
This type of code works for me.
Try This!
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UILongPressGestureRecognizer *LongPress=[[UILongPressGestureRecognizer alloc]initWithTarget:self action:#selector(handleLongPressGestures:)];
LongPress.minimumPressDuration = 1.0f;
LongPress.allowableMovement = 300.0f;
[cell.myButton addGestureRecognizer:LongPress];
}
- (void)handleLongPressGestures:(UIGestureRecognizer *)recognizer
{
if ([recognizer.view isKindOfClass:[UIButton class]]){
if (recognizer.state == UIGestureRecognizerStateBegan){
NSLog(#"Long press began");
}
else if (recognizer.state = UIGestureRecognizerStateEnded)
{
NSLog(#"Long press ended");
}
}
}

Show if tableview cell have been clicked before?

I'm developing an app with a news feed.
This is a PFQueryTableView loading content from parse.com.
I also have a detail ViewController attached with a segue.
My question is:
How can I show that there is a cell that hasn't been clicked before?
Like in the Mail application in IOS.
Here's a picture:
http://i.stack.imgur.com/vO2N3.png
- (id)initWithCoder:(NSCoder *)aCoder
{
self = [super initWithCoder:aCoder];
if (self) {
// Custom the table
// The className to query on
self.parseClassName = #"Nyhet";
// The key of the PFObject to display in the label of the default cell style
self.textKey = #"Rubrik";
// Whether the built-in pull-to-refresh is enabled
self.pullToRefreshEnabled = YES;
// Whether the built-in pagination is enabled
self.paginationEnabled = YES;
// The number of objects to show per page
self.objectsPerPage = 10;
}
return self;
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleDefault;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Change button color
sidebarButton.tintColor = [UIColor whiteColor];
// Set the side bar button action. When it's tapped, it'll show up the sidebar.
sidebarButton.target = self.revealViewController;
sidebarButton.action = #selector(revealToggle:);
// Set the gesture
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (PFQuery *)queryForTable
{
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
// If no objects are loaded in memory, we look to the cache first to fill the table
// and then subsequently do a query against the network.
/* if ([self.objects count] == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}*/
[query orderByDescending:#"Prioritering"];
return query;
}
// Override to customize the look of a cell representing an object. The default is to display
// a UITableViewCellStyleDefault style cell with the label being the first key in the object.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *simpleTableIdentifier = #"RecipeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
UILabel *nameLabel = (UILabel*) [cell viewWithTag:101];
nameLabel.text = [object objectForKey:#"Rubrik"];
UILabel *prepTimeLabel = (UILabel*) [cell viewWithTag:102];
prepTimeLabel.text = [object objectForKey:#"Detaljer"];
return cell;
}
- (void) objectsDidLoad:(NSError *)error
{
[super objectsDidLoad:error];
NSLog(#"error: %#", [error localizedDescription]);
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
RecipeDetailViewController *destViewController = segue.destinationViewController;
PFObject *object = [self.objects objectAtIndex:indexPath.row];
Recipe *recipe = [[Recipe alloc] init];
recipe.name = [object objectForKey:#"Rubrik"];
recipe.prepTime = [object objectForKey:#"Text"];
recipe.detaljer = [object objectForKey:#"Detaljer"];
recipe.rubriker = [object objectForKey:#"Rubrik"];
destViewController.recipe = recipe;
}
}
#end
I think it's better use custom UITableViewCell example:
CustomTableViewCell.h
#interface CustomTableViewCell : UITableViewCell
#property(assign) bool beforeClicked
#end
CustomTableViewCell.m
#import CustomTableViewCell.h
#implementation CustomTableViewCell
#synthesize beforeClicked;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
#end
And, example:
CustomTableViewCell.h //add this header
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *simpleTableIdentifier = #"RecipeCell";
CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = (CustomTableViewCell *)[[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
UILabel *nameLabel = (UILabel*) [cell viewWithTag:101];
nameLabel.text = [object objectForKey:#"Rubrik"];
UILabel *prepTimeLabel = (UILabel*) [cell viewWithTag:102];
prepTimeLabel.text = [object objectForKey:#"Detaljer"];
cell.beforeClicked = NO;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *myCell = [tableView cellForRowAtIndexPath:indexPath];
myCell.beforeClicked = YES;
}
Two solutions come to mind.
The simpler solution would be using an NSMutableArray to hold all visited cells. In didSelectRowAtIndexPath: do this :
if (![visitedCellsArray containsObject:[NSNumber numberWithInt:indexPath.row]])
[visitedCellsArray addObject:[NSNumber numberWithInt:indexPath.row]];
Then set a backgroundColor to your cell (just a suggestion, you may use any UI indicator - dot, color, etc) in your cellForRowAtIndexPath:
Second, might not be conducive to your purpose. I don't really know if the dictionary you are using is mutable or not, and whether adding keys will have any effect on your flow of control. But If adding a key is possible, add a key like #"seen" and set it with [NSNumber numberWithBool:YES] in didSelectRowAtIndexPath:, and in cellForRowAtIndexPath: add appropriate UI indication based on the value of this key. This method is better memory wise.
I'd give your PFReceipt objects a property BOOL new.
Then just get and set that property and in cellForRow you set the font based on the vale of the property.
clean and even persistent.
...
so to reiterate:
modify PFReceipt object to have a property new
modify - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
...
cell.clickedBefore = !receipe.new;
mark receipes as no longer new when shown
...
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
...
PFObject *object = [self.objects objectAtIndex:indexPath.row];
selectedCell.clickedBefore = !object.new;
None of the solutions provided take into account that there may be more than one user of the app. If you store a "read" or "new" property in the object, this will only show if ANYBODY has read it. So if Jane reads it, Mark will see it as read.
To handle this separately for all users, you need another parse class to handle reading status. This gets a little complex to implement, but it is the only way to solve it all on the server.
Another option would be to store a read status list on every client. This means some kind of local persistent store that knows what recipes are read, and compare this to the data fetched from Parse.

Set an `UIImageView` to not highlighted on a custom UITableViewCell

I'm developing an iOS application with latest SDK.
I have a UITableView with a custom UITableViewCell:
#interface FavouriteCell : UITableViewCell
#property (unsafe_unretained, nonatomic) IBOutlet UIImageView *selectIcon;
#property (unsafe_unretained, nonatomic) IBOutlet UILabel *favName;
#property (nonatomic) BOOL checked;
+ (NSString *)reuseIdentifier;
#end
On selectIcon I set two images from normal and highlighted. When I do cell.checked = !selected; on tableView:didSelectRowAtIndexPath: it works perfectly.
But when I try to reset every selected cell on clearSelectedFavourites:, it doesn't work.
#interface FavViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, NSFetchedResultsControllerDelegate, UIAlertViewDelegate>
{
#private
NSMutableArray* _favsSelected;
BOOL* _isOnEditingMode;
}
// ######### FavViewController implementation ##############
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
self.title = NSLocalizedString(#"Favoritos", #"Favoritos");
self.tabBarItem.image = [UIImage imageNamed:#"fav"];
_favsSelected = [[NSMutableArray alloc] init];
_isOnEditingMode = NO;
}
return self;
}
- (UITableViewCell* )tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"cellForRowAtIndexPath");
static NSString* CellIdentifier = #"FavCell";
FavouriteCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:#"FavouriteCell" owner:self options:nil];
cell = _favCell;
self.favCell = nil;
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.favName.font = [UIFont systemFontOfSize:15.0f];
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
#pragma mark - UITableViewDelegate methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"didSelectRowAtIndexPath: %#", indexPath);
if (tableView.isEditing)
{
BOOL selected = NO;
if ((_favsSelected != nil) && ([_favsSelected count] > 0))
selected = ([_favsSelected indexOfObject:indexPath] != NSNotFound);
FavouriteCell* cell =
(FavouriteCell*)[tableView cellForRowAtIndexPath:indexPath];
NSLog(cell.checked ? #"Yes" : #"No");
cell.checked = !selected;
if (selected)
[_favsSelected removeObject:indexPath];
else
[_favsSelected addObject:indexPath];
}
}
- (IBAction)editFavList:(id)sender
{
NSLog(#"edit button clicked!");
if ([_favList isEditing])
{
[self clearSelectedFavourites];
[_favList setEditing:NO animated:YES];
[_editButton setImage:[UIImage imageNamed:#"ButtonEdit.png"] forState:UIControlStateNormal];
}
else
{
[_favList setEditing:YES animated:YES];
[_editButton setImage:[UIImage imageNamed:#"done_button.png"] forState:UIControlStateNormal];
}
}
- (void)clearSelectedFavourites
{
for(int index = 0; index < [_favsSelected count]; index++)
{
NSIndexPath* indexPath = (NSIndexPath*)[_favsSelected objectAtIndex:index];
FavouriteCell* cell = (FavouriteCell*)[self tableView:_favList cellForRowAtIndexPath:indexPath];
cell.checked = NO;
}
[_favsSelected removeAllObjects];
}
- (void)configureCell:(FavouriteCell *)cell
atIndexPath:(NSIndexPath *)indexPath
{
NSManagedObject *object = nil;
object = [self.favListFetchedResultsController objectAtIndexPath:indexPath];
cell.favName.text = [[object valueForKey:#"name"] description];
}
Do you know why?
I have tried to set selectIcon to not hightlighted manually, but it doesn't work, and that code if the latest test I did.
I have also tested this: [cell setHighlighted:NO]; on clearSelectedFavourites: and it doesn't work.
You are not showing us your custom [self configureCell:cell atIndexPath:indexPath]; function, so I cannot know what's going on.
However a few things first:
The cells on the TableView are being reused.
So you cell select state needs to be set every time for each cell.
Also on your clearSelectedFavourites function, you are getting a reference to all selected cells, then clear their selection, which is pointless, because the cells are going to be reused.
You only need to loop through the visible UITableView cells and change their selection status, then clear your _favsSelected array...
- (void)clearSelectedFavourites
{
NSArray *cells = [self.tableView visibleCells];
for (FavouriteCell *cell in cells)
{
cell.checked = NO;
//might not be needed, or might be needed
[cell setNeedsDisplay];
}
[_favsSelected removeAllObjects];
}
Finally on your configureCell function, you should check if the cell should be checked or not, based on your _favsSelected array entries and just select it or not.
Edit
In your configureCell function you should check if the cell needs to be checked or not:
- (void)configureCell:(FavouriteCell *)cell
atIndexPath:(NSIndexPath *)indexPath
{
NSManagedObject *object = nil;
object = [self.favListFetchedResultsController objectAtIndexPath:indexPath];
cell.favName.text = [[object valueForKey:#"name"] description];
cell.checked = [_favsSelected containsObject:indexPath];
}
You can do like this :
[tbl beginUpdates];
/* call you method with animation */
[tbl endUpdates];
[tbl reloadData];

Resources