How to delete objects from NSArray through tableview in Objective C? - objective-c

First of I like to start with I am new to Objective C and this is my first time developing in it. For some reason I got stuck on how to delete objects from my NSArray through my tableview (with objects in it). Tryed some diffrent things but seems I am a bit stuck... What shall I pu in the code below?
bookmarks.m
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]withRowAnimation:YES];
[tableView reloadData];
}
Bookmarks.h
#import <UIKit/UIKit.h>
#import "ShowTaskViewController.h"
#import "Bookmark.h"
#interface BookmarksViewController : UITableViewController <UITableViewDelegate,UITableViewDataSource>
{
NSArray *bookmarks;
}
#property (nonatomic, retain) NSArray *bookmarks;
#end

The tableView doesn't manage your content. You have to do that yourself. When the user taps delete on a row, you have to remove that item from your array and notifiy the table view to delete the cell (with an animation).
I recommend you change your data array into an NSMutableArray. Then you can do this:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
[bookmarks removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:YES];
}
Alternatively you could temporarily create an NSMutableArray.
NSMutableArray *mutableBookmarks = [NSMutableArray arrayWithArray:bookmarks];
[mutableBookmarks removeObjectAtIndex:indexPath.row];
self.bookmarks = [NSArray arrayWithArray:mutableBookmarks];

Related

How Passing indexPath.row between views?

I have table view, and I want to send the indexPath.row(index of selected row) to another view.
ProfesorViewController.m
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SCProfesoresCellTableViewCell *cell = (SCProfesoresCellTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
rowselected = indexPath.row;
}
ProfesorViewController.h
#interface ProfesorViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property long rowselected;
#end
I want to receive value of rowselected variable:
ProfesorDetailViewController.m
#synthesize rowselected;
- (void)viewDidLoad {
NSLog(#"BANDERA DE LA FILA %ld", rowselected);
}
ProfesorDetailViewController.h
#interface ProfesorDetailViewController : UIViewController
#property long rowselected;
#end
But the value of rowselected is always 0.
I don't know how to send the value of variable.
You have two classes with properties with the same name, but you never assign the value of one to the value of the other. At some point you need to take your instance of ProfesorDetailViewController and set rowselected on it, likely when initializing it.
ProfesorDetailViewController *detailViewController = [[ProfesorDetailViewController alloc] init];
detailViewController.rowselected = self.rowselected;
I can not understand where to pass data between ProfesorViewController and ProfesorDetailViewController so pass data between to view controller
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ProfesorDetailViewController *profesor=[[ProfesorDetailViewController alloc]initWithNibName:#"ProfesorDetailViewController" bundle:nil];
rowselected=indexPath.row;
search.Selected=_selected;
[self.navigationController pushViewController:profesor animated:YES];
}
Now you get the value of selected row index in ProfesorDetailViewController viewController properly..

Push to viewcontroller and parse data

I have a simple UITableView which is suppose to push to a new Viewcontroller. When the Cell is pressed it should push to the new viewcontroller and send what number of row has been pushed. Is there a way to obtain this?
This is what i have at the moment, which dosent do anything.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
YoutubeViewController *youtubeViewController = [[YoutubeViewController alloc] initWithNibName:#"YoutubeViewController" bundle:nil];
[self.navigationController pushViewController:youtubeViewController animated:YES];
}
Do like this
This method is the delegate that will be called when a the user selects a cell in tableview
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//Write code here to push your viewcontroller
YourViewController *controller=[[YourViewController alloc]initWithNibName:#"YourViewController" bundle:[NSBundle mainBundle]];
controller.selectedRowValue = indexPath.row;
[self presentViewController:controller animated:YES completion:NULL];
}
In YourViewController.h
#interface YourViewController : UIViewController
#property int selectedRowValue;
#end
In YourViewController.m
#implementation YourViewController
#synthesize selectedRowValue;
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"Selected Row %d",selectedRowValue);
}
Check protocol of UITableViewController delegate https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html.
Method You are looking for
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
yes do one thing
create property of integer type in your YoutubeViewController
like this
#property int selectedRowValue;
after that syntsize it in YoutubeViewController.m class
// YoutubeViewController.m
#implementation YoutubeViewController
#synthesize selectedRowValue
now you come class where ur table is and make some changes to it as shown bellow
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
YoutubeViewController *youtubeViewController = [[YoutubeViewController alloc] initWithNibName:#"YoutubeViewController" bundle:nil];
youtubeViewController.selectedRowValue=indexPath.row;
[self.navigationController pushViewController:youtubeViewController animated:YES];
}
now every thing done to check index value selected in youtube class NSLogout the value
//YoutubeViewController.m
- (void)viewDidLoad
{
// nslogout the value to check
NSLog(#"yours data selected from table%d",selectedRowValue);
}
now every thing done .
enjoy coding
Even you dont want this you can go by creating Constructor or by storing the value to NSUserDefaults

Filling Customized tableviewcell Xcode

I am developing an iOS application, there are data as strings i retrieved from a server using RestKit. data retrieved successfully and i can print it using NSlog. so i want to view these data in the below tableviewcell.
so how to implement the tableviewcell to be filled by the list of devices, description and date that i retrieved from the server using RestKit.
Thanks in advance.
You need to create custom UITableViewCell
Loop through data array in your UITableViewController
In - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath you must alloc/init your class
But as #FaddishWorm say's it will take some time
create your custom cell with xib.
#interface YourCustomCell : UITableViewCell
#property(nonatomic, strong) IBOutlet UILabel* deviceNameLbl;
#property(nonatomic, strong) IBOutlet UILabel* desciptionLbl;
#property(nonatomic, strong) IBOutlet UILabel* dateLbl;
#end
#implementation
#synthesize deviceNameLbl ,.......
......
then in your view controller where you want to display this cell.
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
static NSString* cellIdentifier = #"YourCustomCell";
YourCustomCell *cell = (YourCustomCell*)[tableView dequeueReusableCellWithIdentifier:cellType];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:cellIdentifier owner:nil options:nil];
cell = (YourCustomCell*)[nib objectAtIndex:0];
}
//yourDataArray is a array contains NSDictionary
cell.deviceNameLbl = [[yourDataArray objectAtIndex:indexPath.row]objectForKey#"deviceName"];
cell.desciptionLbl = [[yourDataArray objectAtIndex:indexPath.row]objectForKey#"description"];
cell.dateLbl = [[yourDataArray objectAtIndex:indexPath.row]objectForKey#"date"];
return cell;
}
you set your cell height
tableView.rowHeight=height_you_want;
or
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return your_row_height;
}
Inside cellForRowAtIndexPath: You can created three UILabel, modify (background text font color size etc) and add them as subview to the cell or cell.contentView
UILabel *lbl=[[UILabel alloc]initWithFrame:CGRectMake(<#CGFloat x#>, <#CGFloat y#>, <#CGFloat width#>, <#CGFloat height#>)];
lbl.text=#"Your text";
lbl.backgroundColor=[UIColor clearColor];
[cell addSubview:lbl];
//use this accessory type
cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
This is easy, but takes a bit of time. You need to get your backend data into arrays (or something similar) - inside a class that extends UITableViewController, then hook up your UILabels as outlets, and in the tableView:cellForRowAtIndexPath function, you can pull assign the data to a cell at a particular index.
cell.deviceDescription.text = [myDataArray objectAtIndex:[indexPath row];

Is it possible to create a static tableview in a storyboard and add it programmatically later? (iOS5, XCode 4)

I'm trying to create a couple of small, static tableviews and add them to a panel that I have which slides in and out. The panel is created programmatically so I can't lay the tableviews out inside it via storyboard, and anyway I'm not sure if this is possible anyhow: It seems the only way you can lay out static tableviews that work is in a tableviewcontroller, which takes up the whole screen.
If you can't tell I'm pretty new to iOS dev so if I'm not understanding some fundamental concepts here please feel free to explain.
Of course is possible. Here is how it can be done:
Drag a TableViewController to your storyboard.
Set its Size to Freeform, add an identifier and uncheck Resize View From NIB
Select the tableview and set its content to Static Cells. Design your cells.
Set its size
Now, wherever you need to instantiate it do it like this:
// I am using a UITableViewController as an example here
// you probably would like to set your actual controller subclass instead
UITableViewController *tableViewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"staticTv"];
UITableView *tableView = tableViewController.tableView;
[self.view addSubview:tableView]; // Or add it to whatever view
Enjoy :)
A UITableViewController isn't necessary to provide the functionality you need to manage a UITableView. I think what you're looking for is the "Delegate" pattern. Any UIViewController can be assigned to be the delegate of the UITableView. For example, I have a "static" table that shows some options in an app I am working on:
#interface LBOptionsViewController : UIViewController <UITableViewDataSource,
UITableViewDelegate>
If you're creating your table views programmatically, you'll probably either be creating them in viewDidLoad or loadView (if you're creating the actual view yourself). After you've created your tableView, assign the delegates:
self.tableView.delegate = self;
self.tableView.dataSource = self;
Then your UIViewController subclass will receive the data delegate messages like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Not sure if this helps you. I have not played with Storyboards much yet.
EDIT: #Alladinian has the right answer! If you're using an property for the view controller make sure you allocate it if you need it to be called by other methods.
I've yet to find a usefully reason to use static table view cells over dynamic. Table views were pretty scary when I started iOS programming. I used sqlite in my first app YIKES.
So yeah, you should just import the UITableView Data Source and Delegate and follow up by adding the table view to your panel (assuming it's a uiview and you can add the table view as a subview).
Anyways in your ViewController.h include UITableViewDataSource and UITableViewDelegate.
#interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
Next, add properties for a UITableView and an NSMutableArray:
#property (strong, nonatomic) UITableView* tableView;
#property (strong, nonatomic) NSMutableArray* tableViewContents;
In your ViewController's .m:
#synthesize tableView;
#synthesize tableViewContents;
inside ViewDidLoad:
self.tableViewContents = [NSMutableArray arrayWithObjects:#"Cell 1",#"Cell 2",#"Cell 3",nil];
[self.tableView setDelegate:self]
[self.tableView setDatasource:self]
In the .m file:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.tableViewContents.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSUInteger row = [indexPath row];
index = row;
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
}
cell.textLabel.text = [tableViewContents objectAtIndex:row];
return cell;
}

Can't reload Table View in tab bar controller

Hi I have a tab tab controller and my first tab includes a view with:
3 text fields
a submit button
a tableView
Once I fill in the text fields I click submit and it adds the information to my managedObjectContext which is an sqlite database (CoreData).
As soon as I click submit I want the tableView to reload to include the added object. Currently my tableView will display the data in the database but it will only add the new row when I stop and re-run the simulator
This is the code for when the add button is tapped, it is here that I can't get the reload tableView working because it says tableView is an undeclared identifier, what have i missed?
-(IBAction)addButtonTapped:(id)sender {
NSLog (#"Add Button Tapped");
NSLog(#"Adding %# units of item code %# at $%# each",quantityTextField.text,productTextField.text,priceTextField.text);
Products_MarketAppDelegate* delegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext* managedObjectContext = delegate.managedObjectContext;
NSManagedObject* newProduct;
newProduct = [NSEntityDescription insertNewObjectForEntityForName:#"Product" inManagedObjectContext:managedObjectContext];
[newProduct setValue:productTextField.text forKey:#"itemCode"];
[newProduct setValue:quantityTextField.text forKey:#"quantity"];
[newProduct setValue:priceTextField.text forKey:#"price"];
if ([managedObjectContext hasChanges])
NSLog(#"Managed Object Changed");
NSError* error;
[managedObjectContext save:&error];
// Insert Reload Table Code Here
// ** I have tried the following and it gives an error "Use of undeclared identifier 'tableView'"
//[tableView reloadData];
//[self.tableView reloadData];
}
As you can see below I have added the UITableViewDelegate & UITableViewDataSource in the header file. I have also hooked up the tableview in IB so that the delegate and datasource connections are linked to file's owner.
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#interface FirstViewController : UIViewController
<UIApplicationDelegate, UITableViewDataSource,UITableViewDelegate,NSFetchedResultsControllerDelegate>
{
IBOutlet UITextField *productTextField;
IBOutlet UITextField *quantityTextField;
IBOutlet UITextField *priceTextField;
NSMutableArray *items;
NSFetchedResultsController *fetchedResultsController;
}
#property (nonatomic, retain) NSMutableArray *items;
#property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
-(IBAction)addButtonTapped:(id)sender;
#end
This is the code to fill the tableView which works correctly
#pragma mark TableView
-(NSInteger)numberOfSectionsInTableView: (UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell
Product* productItem =[fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:#"%# x %# # $%#",productItem.quantity,productItem.itemCode,productItem.price];
return cell;
}
I have searched for answers on this site and on others but I must be doing something different and the solutions aren't helping me
Your UIViewController does not currently have an instance variable pointing to your tableview. Set one up:
#property (nonatomic, retain) IBOutlet UITableView *myTableView;
Remember to synthesize this in your .m
#synthesize myTableView;
Then in your code you can call
[self.myTableView reloadData];
You might have got confused by looking at code examples that use a UITableViewController instead of a UIViewController. The UITableViewController already has an instance variable called tableView, so your subclass wouldn't need it's own tableView instance variable declared. But you're using a UIViewController, so you must declare a tableView instance variable.
Thanks #MattyG for all your help. At first I wasn't sure if I was going against the norm and thats why it wasn't working.
I ended up solving the problem due to your suggestions & it works perfectly! I used the debugger and found that that although we had created a property for the table I had not created an IBOutlet and linked it in my nib file with:
IBOutlet UITableView *myTableView;
I guess this meant that I was telling myTableView to reload but it wasn't hooked up to my table and thus couldn't use the datasource methods.