How to programmatically assign noise to button from UITableView in another ViewController? - ios

I have an array of sounds that populates a TableView. When a user selects one of them, I want to assign that sound to a button in another view controller. That view controller is currently working with a "default" sound that is assigned to the button. What is the best way to do this?
edit I've edited to show my changes, but still doesn't seem to work. Any thoughts?
pickSound.m
#interface pickSound ()
#end
#implementation pickSound
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.titleObjectsArray = #[#"Horn", #"Dog Barking", #"Whistle", #"Funny Noises",];
self.soundObjectsArray = #[#"horn.wav", #"bark1.wav", #"whistle.wav", #"funny.wav",];
// Do any additional setup after loading the view.
}
-(void)viewDidAppear: (BOOL)animated{
[self.navigationController setNavigationBarHidden:NO animated:YES];
[super viewWillAppear:YES];
}
#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 [self.titleObjectsArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier =#"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
UIButton *previewSound = [[UIButton alloc]init];
UIImage *btnImage = [UIImage imageNamed:#"PlayButtonPNG.png"];
[previewSound setImage:btnImage forState:UIControlStateNormal];
cell.textLabel.text = [self.titleObjectsArray objectAtIndex:indexPath.row];
return cell;
}
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row ==0)
{
sound = #"Horn";
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqual:#"pickedSound"]) {
ViewController *cameraVC = (ViewController *)segue.destinationViewController;
cameraVC.soundId = sound;
}
}
ViewController.m (where button to play sound is located)
#import "ViewController.h"
#import "pictureViewController.h"
#import <AVFoundation/AVFoundation.h>
#interface ViewController ()
#end
#synthesize soundId;
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.soundId = soundId;
if ([soundId isEqualToString:#"horn"]){
NSURL *makeNoiseURL = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"horn" ofType:#".wav"]];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)makeNoiseURL, &SoudID);
} else {
NSURL *makeNoiseURL = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"horn" ofType:#".wav"]];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)makeNoiseURL, &SoudID);
}
}
- (IBAction)makeNoise:(id)sender {
AudioServicesPlaySystemSound(SoudID);
}

Create an NSString property in your ViewController class and set it when you make a selection in TableView. Remove that hard coded resource loading from viewDidLoad and use this property for resource name.

I figured it out. I created an NSString that is assigned the value of whichever row is selected. Pass that string to the 2nd VC using prepareforsegue. use if statement to assign sound to play to button based on NSString Sound.
**picksound.m **
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.selectedIndexPath = [self.titleObjectsArray objectAtIndex:indexPath.row];
if ([self.selectedIndexPath isEqual:#"Horn"]) {
sound = #"Horn";
} else if ([self.selectedIndexPath isEqual: #"Dog Barking"]) {
sound = #"Dog Barking";
}
[self performSegueWithIdentifier:#"newVC" sender:self];
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
DestinationVC *controller = segue.destinationViewController;
controller.selectedSound = sound;
}
viewcontroller.m
- (IBAction)playSound:(id)sender {
if ([selectedSound isEqualToString:#"Horn"]) {
NSURL *makeNoiseURL = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"horn" ofType:#".wav"]];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)makeNoiseURL, &SoudId);
AudioServicesPlaySystemSound(SoudId);
} else if ([selectedSound isEqualToString:#"Dog Barking"]) {
NSURL *makeNoiseURL = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"bark1" ofType:#".wav"]];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)makeNoiseURL, &SoudId);
AudioServicesPlaySystemSound(SoudId);
}
}

Related

Identifying and then loading/reloading a specific tableView

I have a viewcontroller set up on my storyboard, and I have inserted a tableView inside this view controller. I want to do a [self.tableView reloadData].
This is what my viewController.m looks like. My tableView is an IBOutlet called sharedView, hence the names in the methods, but I am doing something wrong as on viewDidLoad when I call configureView, and subsequently [self.sharedView reloadData]; the data doesn't show up inside the table.
#import "DetailViewController.h"
#import "sharedUsersTable.h"
#interface DetailViewController ()
- (void)configureView;
#end
#implementation DetailViewController
#pragma mark - Managing the detail item
- (void)setDetailItem:(id)newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
}
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
self.detailDescriptionLabel.text = [[self.detailItem objectForKey:#"lock_name"] description];
activeUsers = [self.detailItem objectForKey:#"active_shared_users"];
[self.sharedView reloadData];
//NSLog(#"Info: %#", activeUsers);
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self configureView];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSString *)sharedView:(UITableView *)sharedView titleForHeaderInSection:(NSInteger)section {
return #"Shared with";
}
- (NSInteger)sharedView:(UITableView *)sharedView numberOfRowsInSection:(NSInteger)section
{
return activeUsers.count;
}
- (sharedUsersTable *)sharedView:(UITableView *)sharedView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"sharedUser";
sharedUsersTable *cell = [sharedView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[sharedUsersTable alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *key;
NSString *name;
NSString *email;
// NSString *permission;
key = [activeUsers objectAtIndex:indexPath.row];
name = [key objectForKey:#"shared_user_name"];
email = [key objectForKey:#"email"];
NSLog(#"Info: %#", name);
cell.textLabel.text = [NSString stringWithFormat:#"%#", name];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#", email];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
#end
You should add info about protocols that Your VC is implementing:
#interface DetailViewController () <UITableViewDataSource, UITableViewDelegate>
- (void)configureView;
#end
and then:
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
self.detailDescriptionLabel.text = [[self.detailItem objectForKey:#"lock_name"] description];
activeUsers = [self.detailItem objectForKey:#"active_shared_users"];
/* I assume that Your table view is self.sharedView though You should change the name and I assume that it is connected to VC */
self.sharedView.dataSource = self;
self.sharedView.delegate = self;
[self.sharedView reloadData];
//NSLog(#"Info: %#", activeUsers);
}
}
You can also set data source and delegate directly in storyboard - I think that You have to ctrl+drag from table view to vc. Sorry if this is not correct - I do not use IB for quite some time no - only code.
And one more thing - read this:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intf/UITableViewDataSource
And change method names to be exactly the same as in the protocol - If You do not It won't work.
For better undesstanding data sources and delegates try:
https://developer.apple.com/library/ios/documentation/userexperience/conceptual/tableview_iphone/CreateConfigureTableView/CreateConfigureTableView.html
You mentioned that you are using a UIViewController and not UITableViewController. If you are using UIViewController then you will need to implement UITableViewDelegate and UITableViewDataSourceDelegate. You will also need to connect those delegates either through code or using the interface builder or Storyboard.

Getting a"No Known instance method for selector" error and I have no idea why

I'm trying to pass the 'eventId' value from my tableview to another view controller using the segue.
TableViewController.m
#import "TableViewController.h"
#import "EventCell.h"
#interface TableViewController ()
#end
#implementation TableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
-(NSArray *)content
{
if (!_content) {
_content = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Data" ofType:#"plist"]];
}
return _content;
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
// Return the number of rows in the section.
return [self.content count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
EventCell *cell = (EventCell *)[tableView dequeueReusableCellWithIdentifier:#"EventCell"];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"EventCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.eventImage.image = [UIImage imageNamed: [[self.content objectAtIndex:indexPath.row]valueForKey:#"picturename" ] ];
cell.eventName.text = [[self.content objectAtIndex:indexPath.row] valueForKey:#"name"];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//return height of cell
return 155;
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"EventDetails" sender:self];
}
// In a story board-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"EventDetails"]){
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSString *id = [[self.content objectAtIndex:indexPath.row] objectForKey:#"id"];
[[segue destinationViewController] setEventId:id];
//[segue destinationViewController];
}
}
"[[segue destinationViewController] setEventId:id];" is giving the error of "No Known instance method for selector 'setEventId'"
Below is "DetailsViewController.h" and "DetailsViewController.m" for the view I am attempting to segue to.
DetailsViewController.h
#import <UIKit/UIKit.h>
#interface DetailsViewController : UIViewController <UISplitViewControllerDelegate>
#property (copy,nonatomic) NSString *eventId;
#end
DetailsViewController.m
#import "DetailsViewController.h"
#interface DetailsViewController ()
#end
#implementation DetailsViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I hope someone can at least give a hint to what's going on with that error.
Educated guess: You did forgot to #import DetailsViewController.h in TableViewController.
Xcode got a bit picky about those messages to id lately. It now complains if it does not know such a method at all. So #import the file.
I would make it explicit though:
DetailsViewController *detailsViewController = [segue destinationViewController];
detailsViewController.eventId = #"your id";
But if you #import the correct file it should work as well, because [segue destinationViewController] returns id.
When I said id here I meant id, not your variable that is named id.
If it is the compiler giving you the error, you should be able to do the following:
DetailsViewController *detailsViewController = segue.destinationViewController;
[detailsViewController setEventId:id];
Also make sure you import the DetailsViewController header.
If the error is happening while running the application, it may be because your segue isn't returning a DetailsViewController instance, so you should double-check your storyboard to make sure the correct type is given to the view controller with that identifier.

TableviewController delegate not returning value

I have a tableview controller that is a static table used for request data. When someone selects a row, it displays a new tableview controller with options using a modal segue, the user selects a option and then presses the 'hecho' (done) button and the value should be returned to the first table view controller, but it just not happening. If I inspect the delegate it just says null. What could I be doing wrong?
The story board
First table
AgregarCitaTableViewController.h
#import <UIKit/UIKit.h>
#import "SeleccionarPacienteTableViewController.h"
#interface AgregarCitaTableViewController : UITableViewController <SeleccionarPacienteTableViewControllerDelegate>
#end
AgregarCitaTableViewController.m
#import "AgregarCitaTableViewController.h"
#import "SeleccionarPacienteTableViewController.h"
#interface AgregarCitaTableViewController ()
{
NSDictionary *datosPaciente;
}
#end
#implementation AgregarCitaTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)paciente:(NSDictionary *)paciente
{
datosPaciente = paciente;
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
cell.detailTextLabel.text = [datosPaciente objectForKey:#"nombre"];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if( [segue.identifier isEqualToString:#"listaPacientes"] )
{
SeleccionarPacienteTableViewController *viewController = segue.destinationViewController;
viewController.delegate = self;
}
}
Second Table
SeleccionarPacienteTableViewController.h
#protocol SeleccionarPacienteTableViewControllerDelegate <NSObject>
-(void)paciente:(NSDictionary *)paciente;
#end
#interface SeleccionarPacienteTableViewController : UITableViewController
{
id delegate;
}
#property(nonatomic,assign)id<SeleccionarPacienteTableViewControllerDelegate> delegate;
#end
SeleccionarPacienteTableViewController.m
#import "SeleccionarPacienteTableViewController.h"
#interface SeleccionarPacienteTableViewController ()
{
NSMutableArray *todosPacientes;
NSDictionary *paciente;
NSInteger checkmarkedRow;
}
#end
#implementation SeleccionarPacienteTableViewController
#synthesize delegate = _delegate;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
UIBarButtonItem *hecho = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(hecho)];
[[self navigationItem] setRightBarButtonItem:hecho];
UIBarButtonItem *cancelar = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(cancelar)];
[[self navigationItem] setLeftBarButtonItem:cancelar];
//Llamada asincrona, cargar las citas
[self performSelectorInBackground:#selector(cargarDatos) withObject:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
// Return the number of rows in the section.
return todosPacientes.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
NSDictionary *object;
object = todosPacientes[indexPath.row];
cell.textLabel.text = [object objectForKey:#"nombre"];
if(checkmarkedRow == indexPath.row){
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Guardar nombre del paciente selccionado
paciente = todosPacientes[indexPath.row];
// In cellForRow... we check this variable to decide where we put the checkmark
checkmarkedRow = indexPath.row;
// We reload the table view and the selected row will be checkmarked
[tableView reloadData];
// We select the row without animation to simulate that nothing happened here :)
[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
// We deselect the row with animation
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void) cargarDatos
{
//Path donde se encuentra el plist con los datos
NSString *path = [[NSBundle mainBundle]pathForResource:#"pacientes" ofType:#"plist"];
//Guardamos las citas en un NSMutableArray
todosPacientes = [[NSMutableArray alloc]initWithContentsOfFile:path];
}
- (void) hecho
{
/*Is anyone listening
if([delegate respondsToSelector:#selector(paciente:)])
{
//send the delegate function with the amount entered by the user
[delegate paciente:paciente];
}*/
[self.delegate paciente:paciente];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void) cancelar
{
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
Solution:
Im not really sure how it worked or even if this is the real solution. I used the anwer of Hani Ibrahim and it didn't work but what he said was right. Then i just changed [delegate paciente:paciente] in the hecho method for [self.delegate paciente:paciente] and it worked.
I hope this can help someone.
The problem is that your seque display UINavigationController and not SeleccionarPacienteTableViewController
Change this method
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if( [segue.identifier isEqualToString:#"listaPacientes"] )
{
SeleccionarPacienteTableViewController *viewController = segue.destinationViewController;
viewController.delegate = self;
}
}
to be
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if( [segue.identifier isEqualToString:#"listaPacientes"] )
{
UINavigationController *navController = segue.destinationViewController;
SeleccionarPacienteTableViewController *viewController = [navController.viewControllers objectAtIndex:0];
viewController.delegate = self;
}
}
You have another problem
When doing this
#property(nonatomic,assign)id<SeleccionarPacienteTableViewControllerDelegate> delegate;
and this
#synthesize delegate = _delegate;
Then Your property will work with an instance variable called '_delegate' as you are saying #synthesize delegate = _delegate;
However this code
#interface SeleccionarPacienteTableViewController : UITableViewController
{
id delegate;
}
defines a new instance variable called delegate which is completely different than your property
So to access your property you can use self.delegate or _delegate and NOT delegate as it is another instance variable !
I think the problem is in prepareForSegue. The destinationViewController is a UINavigationController and not a SeleccionarPacienteTableViewController.
You have to access the first child of the destinationViewController to get your SeleccionarPacienteTableViewController.
Replacing segue.destinationViewController with [segue.destinationViewController topViewController] will probably solve your problem.

IOS Second App - + Button disappeared

Im new to IOS app programming - I went though the iOS second app tutorial (the bird sighting one) and I have 2 issues when I get to the end and any pointers would be most appreciated.
The + button on the main view has disappeared and I dont understand why? Which part of code governs this?
When selecting the pigeon bird in the main view, the detail view comes up but with detail still in all the items, so Bird Name is still detail, location is still detail etc.
Any help would be greatly appreciated.
Thanks
Edit - Added the .h and .m code for the masterviewcontroller
.h
#import <UIKit/UIKit.h>
#class BirdSightingDataController;
#interface BirdsMasterViewController : UITableViewController
#property (strong, nonatomic) BirdSightingDataController *dataController;
- (IBAction)done:(UIStoryboardSegue *)segue;
- (IBAction)cancel:(UIStoryboardSegue *)segue;
#end
.m
#import "BirdsMasterViewController.h"
#import "BirdsDetailViewController.h"
#import "BirdSightingDataController.h"
#import "BirdSighting.h"
#import "AddSightingViewController.h"
#implementation BirdsMasterViewController
- (void)awakeFromNib
{
[super awakeFromNib];
self.dataController = [[BirdSightingDataController alloc] init];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.rightBarButtonItem.accessibilityHint = #"Adds a new bird sighting event";
// 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 - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.dataController countOfList];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"BirdSightingCell";
static NSDateFormatter *formatter = nil;
if (formatter == nil) {
formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterMediumStyle];
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
BirdSighting *sightingAtIndex = [self.dataController objectInListAtIndex:indexPath.row];
[[cell textLabel] setText:sightingAtIndex.name];
[[cell detailTextLabel] setText:[formatter stringFromDate:(NSDate *)sightingAtIndex.date]];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return NO;
}
- (IBAction)done:(UIStoryboardSegue *)segue
{
if ([[segue identifier] isEqualToString:#"ReturnInput"]) {
AddSightingViewController *addController = [segue sourceViewController];
if (addController.birdSighting) {
[self.dataController addBirdSightingWithSighting:addController.birdSighting];
[[self tableView] reloadData];
}
[self dismissViewControllerAnimated:YES completion:NULL];
}
}
- (IBAction)cancel:(UIStoryboardSegue *)segue
{
if ([[segue identifier] isEqualToString:#"CancelInput"]) {
[self dismissViewControllerAnimated:YES completion:NULL];
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ShowSightingDetails"]) {
BirdsDetailViewController *detailViewController = [segue destinationViewController];
detailViewController.sighting = [self.dataController objectInListAtIndex:[self.tableView indexPathForSelectedRow].row];
}
}
#end

UITableView won't update while active

I have an array of objects, and i use following code to get in in the tableview
[source addObjectsFromArray:[UDdelegate naturArray]];
[[self tableView]reloadData];
My application fetch some data on location change, and that data is the objects in my naturArray. source is the list's datasource.
My problem is that if my list view is active while it is fetching the data, the list isn't updated. If i go to the main menu and back into the listView the data appear.
Is there a way to get the list to update while its active ?
Thanks.
Edit: Full code
VisListe.h:
#class UdINaturenAppDelegate;
#class POI;
#class webDetailView;
#interface VisListe : UITableViewController<UITableViewDelegate,UITableViewDataSource>
#property (nonatomic, retain,readwrite) IBOutlet NSMutableArray *dataSourceArray;
#property (strong, nonatomic) UdINaturenAppDelegate *UDdelegate;
#property (strong, nonatomic) POI *poi;
#property (strong, nonatomic) webDetailView *webView;
#property (strong, nonatomic) IBOutlet UITableView *tabel;
-(void)updateList;
-(NSString*)parseURL:(NSString*)url;
#end
VisListe.m:
#implementation VisListe
#synthesize dataSourceArray = source;
#synthesize UDdelegate;
#synthesize poi=_poi;
#synthesize webView = _webView;
#synthesize tabel = _tabel;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.navigationItem.title = NSLocalizedString(#"Poi List", nil);
UDdelegate = (UdINaturenAppDelegate*) [UIApplication sharedApplication].delegate;
source = [[NSMutableArray alloc]init];
_webView = [[webDetailView alloc] initWithNibName:#"webDetailView" bundle:nil];
[self updateList];
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
//[source addObjectsFromArray:[UDdelegate naturArray]];
}
- (void)viewDidUnload
{
[self setTabel:nil];
[super viewDidUnload];
self.dataSourceArray = nil; // this will release and set to nil
source = nil;
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
NSLog(#"unload");
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self updateList];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
// to determine specific row height for each cell, override this.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return ([indexPath row] == 0) ? 60.0 : 60.0;
}
// to determine which UITableViewCell to be used on a given row.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//return [UDdelegate naturArray].count;
return [source count];
}
//
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
_poi = [source objectAtIndex:indexPath.row];
cell.textLabel.text = [_poi title];
cell.detailTextLabel.text = [NSString stringWithFormat:#"Afstand: %f m.", [_poi dist]];
//[cell.imageView setImage:<#(UIImage *)#>];
return cell;
}
#pragma mark -
#pragma mark UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
_poi = [source objectAtIndex:indexPath.row];
NSLog(#"%#",[_poi title]);
NSString* u = [self parseURL:[_poi webUrl]];
[_webView setIncUrl:u];
[[self navigationController] pushViewController:_webView animated:YES];
}
-(NSString*)parseURL:(NSString*)url{
NSString* s = [url stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}
-(void)updateList{
[source removeAllObjects];
[source addObjectsFromArray:[UDdelegate naturArray]];
[_tabel reloadData];
}
-(UIImage*)setImgFromUrl:(NSString*)url{
NSURL *newurl = [NSURL URLWithString: url];
UIImage *image = [UIImage imageWithData: [NSData dataWithContentsOfURL: newurl]];
return image;
}
When the location is fetched the updateList method is called from the AppDelegate.m
Turned out that it was just me who was a little impatient. the [_tabel reloadData] method is just a little "heavy" to call, so the list was in fact updated, but it just took a little while to update.

Resources