I have two response from the server( longitude and latitude). This response is save and display to the Table cell. When clicking the cell, there is a map with the location given by the server. How can i update the location of the map (move the marker) depending on the server given response?
Here is my code in map:
#interface ChildDetailViewController ()
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#end
#implementation ChildDetailViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.mapView.delegate = self;
// Do any additional setup after loading the view.
MapAnnotation *mapPoint = [[MapAnnotation alloc] init];
mapPoint.coordinate = CLLocationCoordinate2DMake([self.appDelagate.latitude doubleValue], [self.appDelagate.longitude doubleValue]);
mapPoint.title = self.appDelagate.name;
mapPoint.mapimage = self.appDelagate.image;
// Add it to the map view
[self.mapView addAnnotation:mapPoint];
// Zoom to a region around the pin
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(mapPoint.coordinate, 500, 500);
[self.mapView setRegion:region];
}
#pragma mark - MKMapViewDelegate
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
MKPinAnnotationView *view = nil;
static NSString *reuseIdentifier = #"MapAnnotation";
// Return a MKPinAnnotationView with a simple accessory button
view = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentifier];
if(!view)
{
view = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
view.canShowCallout = YES;
view.animatesDrop = YES;
}
return view;
}
Here is the code in Table Cell:
#import "ChildListViewController.h"
#import "AppDelegate.h"
#import "Child.h"
#import "ChildDetailViewController.h"
#interface ChildListViewController ()
{
NSArray *_child_info;
//NSString *locationName;
}
#end
#implementation ChildListViewController
- (IBAction)unwindchild:(UIStoryboardSegue *)segue
{
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self dismissViewControllerAnimated:YES completion:nil];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSLog(#"Pumasok ba?");
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"TableIdentifier";
AppDelegate *appDelegate = [_child_info objectAtIndex:indexPath.row];
Child *cell = (Child *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"Child" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.childName.text = appDelegate.name;
cell.childbeaconID.text = appDelegate.beacon_id;
cell.childstatus.text = appDelegate.status;
cell.childLoclong.text = appDelegate.longitude;
cell.childLoclat.text = appDelegate.latitude;
cell.serverCreatedDate.text = appDelegate.server_created_date;
cell.childimageview.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:
[NSURL URLWithString:appDelegate.image]]];
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_child_info count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 119;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (appDelegate.name != nil)
{
[self performSegueWithIdentifier:(#"a") sender:(self)];
}
else
{
NSLog(#"No Data %#", appDelegate.name);
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier]isEqualToString:#"a"])
{
ChildDetailViewController *vc = segue.destinationViewController;
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
vc.appDelagate = [_child_info objectAtIndex:indexPath.row];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
Parse the server response
AppDelegate.m
NSDictionary *fetchedDictionary =[userPushInfo objectForKey:#"aps"];
NSDictionary *fetchedDictionaryalert = [fetchedDictionary objectForKey:#"alert"];
NSDictionary *fetchedDictionarybody = [fetchedDictionaryalert objectForKey:#"body"];
NSDictionary *fetchedDictionaryresult = [fetchedDictionarybody objectForKey:#"student_event"];
for (NSDictionary *user in fetchedDictionaryresult)
{
beacon_device_name =[user objectForKey:#"beacon_device_name"];
image =[user objectForKey:#"image"];
latitude = [user objectForKey:#"latitude"];
longitude =[user objectForKey:#"longitude"];
server_created_date = [user objectForKey:#"server_created_date"];
status =[user objectForKey:#"status"];
}
you can update by doing this after you get the response
[self.mapView removeAnnotations:self.mapView.annotations];
MapAnnotation *mapPoint = [[MapAnnotation alloc] init];
mapPoint.coordinate = CLLocationCoordinate2DMake([newLatitude doubleValue], [newLongitude doubleValue]);
mapPoint.title = self.appDelagate.name;
mapPoint.mapimage = self.appDelagate.image;
// Add it to the map view
[self.mapView addAnnotation:mapPoint];
// Zoom to a region around the pin
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(mapPoint.coordinate, 500, 500);
[self.mapView setRegion:region];
you can communicate within the view controllers by using Notification Center,put the first in your child view controller,and second after parse your response.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(updateLocation) name:AppDelegateReceiveTheLocation object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:AppDelegateReceiveTheLocation object:nil userInfo:nil];
Related
I'm trying to get a list of bluetooth devices nearby and display it in a UItableview.
Originally I have this written in one view controller file using storyboard, and it worked, but now I'm separating the files to TableViewController, TableDelegate and TableDataSource, and writing this programmatically, and I'm not sure how to split the file up into 3 and have it work. This is what I have so far. It compiles, but CBCentralManager never scans the devices and call the centralManagerDidUpdateState function
The original code:
MasterViewController.m
#import "MasterViewController.h"
#import "DetailViewController.h"
#interface MasterViewController ()
#property NSMutableArray *objects;
#end
#implementation MasterViewController
#pragma mark - CBCentralManagerDelegate
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSString *localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
if ([localName length] > 0) {
if (![_foundPeripherals containsObject:peripheral]) {
NSLog(#"Found: %#", localName);
[_foundPeripherals addObject:peripheral];
[_adData addObject:advertisementData];
[_RSSI addObject:RSSI];
[self.tableView reloadData];
//peripheral.delegate = self;
}
}
}
// method called whenever the device state changes.
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
if ([central state] == CBCentralManagerStatePoweredOn) {
NSLog(#"CoreBluetooth BLE hardware is powered on and ready");
NSArray *services = #[kDFUServiceUUID, kGuinnessServiceUUID, kHeartrateServiceUUID, kBatteryServiceUUID, kDeviceInfoServiceUUID];
NSDictionary *scanOptions = #{CBCentralManagerScanOptionAllowDuplicatesKey:#(YES)};
[self.centralManager scanForPeripheralsWithServices:services options:scanOptions];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
self.deviceData = nil;
_foundPeripherals = [[NSMutableArray alloc] init];
_adData = [[NSMutableArray alloc] init];
_RSSI = [[NSMutableArray alloc] init];
CBCentralManager *centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
self.centralManager = centralManager;
}
- (void)viewWillDisappear:(BOOL)animated {
[_centralManager stopScan];
NSLog(#"Scanning stopped");
[super viewWillDisappear:animated];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Segues
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDate *object = self.objects[indexPath.row];
[[segue destinationViewController] setDetailItem:object];
}
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.foundPeripherals count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"SimpleTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:simpleTableIdentifier];
}
CBPeripheral *peripheral=[_foundPeripherals objectAtIndex:indexPath.row];
cell.textLabel.text = peripheral.name;
return cell;
}
#end
New, separated code that doesn't work.
TableViewController.m
#import "TableViewController.h"
#import "TableDataSource.h"
#import "TableDelegate.h"
#interface TableViewController () {
TableDataSource *_dataSource;
TableDelegate *_delegate;
}
#end
#implementation TableViewController
- (void)loadView {
self.view = [[UIView alloc] init];
self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
UITableView *tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain];
tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
self.view = tableView;
_dataSource = [[TableDataSource alloc] init];
_delegate = [[TableDelegate alloc] init];
_delegate.controller = self;
self.tableView.dataSource = _dataSource;
self.tableView.delegate = _delegate;
[self.tableView registerClass: [UITableViewCell class] forCellReuseIdentifier: #"device"];
}
- (void)viewDidLoad {
[super viewDidLoad];
[_dataSource getBluetoothDevices];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"reloadTable"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(checkRes:) name:#"reloadTable" object:nil];
}
-(void)checkRes:(NSNotification *)notification
{
if ([[notification name] isEqualToString:#"reloadTable"])
{
[self.tableView reloadData];
}
}
TableDelegate.h
#import <UIKit/UIKit.h>
#import CoreBluetooth;
#interface TableDelegate : NSObject <UITableViewDelegate, CBCentralManagerDelegate, CBPeripheralDelegate>
#property (nonatomic, weak) UIViewController *controller;
#end
TableDelegate.m
#import "TableDelegate.h"
#import "TableDataSource.h"
#import "DetailViewController.h"
#interface TableDelegate () {
TableDataSource *_dataSource;
}
#end
#implementation TableDelegate
- (instancetype)initWithDataSource:(TableDataSource *)dataSource {
self = [super init];
if (!self) return nil;
_dataSource = dataSource;
return self;
}
// method called whenever the device state changes.
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
if ([central state] == CBCentralManagerStatePoweredOn) {
NSLog(#"CoreBluetooth BLE hardware is powered on and ready");
NSArray *services = #[kDFUServiceUUID, kGuinnessServiceUUID, kHeartrateServiceUUID, kBatteryServiceUUID, kDeviceInfoServiceUUID];
NSDictionary *scanOptions = #{CBCentralManagerScanOptionAllowDuplicatesKey:#(YES)};
[_dataSource.centralManager scanForPeripheralsWithServices:services options:scanOptions];
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath: indexPath animated: YES];
DetailViewController *detail = [[DetailViewController alloc] init];
[_controller.navigationController pushViewController: detail animated: YES];
}
#end
TableDataSource.m
#import "TableDataSource.h"
#import "TableViewController.h"
#import "TableDelegate.h"
#interface TableDataSource () {
TableDelegate *_delegate;
}
#end
#implementation TableDataSource
- (instancetype)initWithDelegate:(TableDelegate *)delegate {
self = [super init];
if (!self) return nil;
_delegate = delegate;
return self;
}
- (void)getBluetoothDevices
{
_foundPeripherals = [[NSMutableArray alloc] init];
_adData = [[NSMutableArray alloc] init];
_RSSI = [[NSMutableArray alloc] init];
CBCentralManager *centralManager = [[CBCentralManager alloc] initWithDelegate:_delegate queue:nil];
self.centralManager = centralManager;
}
// method called whenever you have successfully connected to the BLE peripheral
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
}
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSString *localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
if ([localName length] > 0) {
if (![_foundPeripherals containsObject:peripheral]) {
NSLog(#"Found: %#", localName);
[_foundPeripherals addObject:peripheral];
[_adData addObject:advertisementData];
[_RSSI addObject:RSSI];
[[NSNotificationCenter defaultCenter] postNotificationName:#"reloadTable" object:self];
//peripheral.delegate = self;
}
}
}
// method called whenever the device state changes.
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
if ([central state] == CBCentralManagerStatePoweredOn) {
NSLog(#"CoreBluetooth BLE hardware is powered on and ready");
NSArray *services = #[kDFUServiceUUID, kGuinnessServiceUUID, kHeartrateServiceUUID, kBatteryServiceUUID, kDeviceInfoServiceUUID];
NSDictionary *scanOptions = #{CBCentralManagerScanOptionAllowDuplicatesKey:#(YES)};
[self.centralManager scanForPeripheralsWithServices:services options:scanOptions];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
[self getBluetoothDevices];
return [self.foundPeripherals count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"device";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:simpleTableIdentifier];
}
CBPeripheral *peripheral=[_foundPeripherals objectAtIndex:indexPath.row];
cell.textLabel.text = peripheral.name;
return cell;
}
#end
I am having trouble with the initWithCoder: method. In the line which reads
item.text = [NSString stringWithFormat:#"Item for %#", list.name];
"Item for" does not print out to the screen. list.name prints out fine.
What is the problem?
#import "AllListsViewController.h"
#import "Checklist.h"
#import "ChecklistViewController.h"
#import "ChecklistItem.h"
#interface AllListsViewController ()
#end
#implementation AllListsViewController
{
NSMutableArray *_lists;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
if ((self = [super initWithCoder:aDecoder])) {
_lists = [[NSMutableArray alloc] initWithCapacity:20];
Checklist *list;
list = [[Checklist alloc] init];
list.name = #"Birthdays";
[_lists addObject:list];
list = [[Checklist alloc] init];
list.name = #"Groceries";
[_lists addObject:list];
list = [[Checklist alloc] init];
list.name = #"Cool Apps";
[_lists addObject:list];
list = [[Checklist alloc] init];
list.name = #"To Do";
[_lists addObject:list];
for(Checklist *list in _lists) {
ChecklistItem *item = [[ChecklistItem alloc] init];
item.text = [NSString stringWithFormat:#"Item for %#", list.name];
[list.items addObject:item];
}
}
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.
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_lists count];
}
- (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];
}
Checklist *checklist = _lists[indexPath.row];
cell.textLabel.text = checklist.name;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Checklist *checklist = _lists[indexPath.row];
[self performSegueWithIdentifier:#"ShowChecklist" sender:checklist];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
[_lists removeObjectAtIndex:indexPath.row];
NSArray *indexPaths = #[indexPath];
[tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"ShowChecklist"])
{
ChecklistViewController *controller = segue.destinationViewController;
controller.checklist = sender;
}
else if ([segue.identifier isEqualToString:#"AddChecklist"]) {
UINavigationController *navigationController = segue.destinationViewController;
ListDetailViewController *controller = (ListDetailViewController *)navigationController.topViewController;
controller.delegate = self;
controller.checklistToEdit = nil;
}
}
#pragma mark - ListDetailViewControllerDelegate methods
- (void)listDetailViewControllerDidCancel:(ListDetailViewController *)controller
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)listDetailViewController:(ListDetailViewController *)controller didFinishAddingChecklist:(Checklist *)checklist
{
NSInteger newRowIndex = [_lists count];
[_lists addObject:checklist];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:newRowIndex inSection:0];
NSArray *indexPaths = #[indexPath];
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)listDetailViewController:(ListDetailViewController *)controller didFinishEditingChecklist:(Checklist *)checklist
{
NSInteger index = [_lists indexOfObject:checklist];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.text = checklist.name;
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
UINavigationController *navigationController = [self.storyboard instantiateViewControllerWithIdentifier:#"ListNavigationController"];
ListDetailViewController *controller = (ListDetailViewController *)navigationController.topViewController;
controller.delegate = self;
Checklist *checklist = _lists[indexPath.row];
controller.checklistToEdit = checklist;
[self presentViewController:navigationController animated:YES completion:nil];
}
#end
You're not displaying the proper object if you want the string with Item for ... to be displayed on your cell. Currently, from what I can see, your data structure looks like this:
_lists (Array):
[
list (Checklist):
{
name (String): #"Birthdays", // 0
items (Array):
[
item (ChecklistItem):
{
text (String): #"Item for Birthdays" // 1
}
]
},
list (Checklist):
etc.
]
It appears that you're setting your cell's textLabel to _lists[indexPath.row].name, which I've commented at // 0 in the structure above. If you're wanting to get to the Item for ... (commented at // 1) string, you'll need to do:
_lists[indexPath.row].items[0].text
I'm assuming that it will be at index 0, unless you happen to be adding other data to what I assume to be the NSMutableArray *items object in your ChecklistItem.
Am having protocol errors in AllListsViewController.m, but can't figure out why. Also have some other errors which I have commented out.
AllListsViewController.m
#import "AllListsViewController.h"
#import "ChecklistViewController.h"
#import "Checklist.h"
#import "ChecklistItem.h"
#interface AllListsViewController ()
#end
#implementation AllListsViewController
/* Method 'listDetailViewController:didFinishAddingChecklist' in protocol not implemented
Method 'listDetailViewController:didFinishEditingChecklist' in protocol not implemented
Method 'listDetailViewControllerDidCancel:' in protocol not implemented
*/
{
NSMutableArray *_lists;
}
-(NSString *)documentsDirectory
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths firstObject];
return documentsDirectory;
}
-(NSString *)dataFilePath
{
return [[self documentsDirectory] stringByAppendingPathComponent:#"Checklists.plist"];
}
-(void)saveChecklistItems
{
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:_lists forKey:#"Checklists"];
[archiver finishEncoding];
[data writeToFile:[self dataFilePath] atomically:YES];
}
-(void)loadChecklists
{
NSString *path = [self dataFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
NSData *data = [[NSData alloc] initWithContentsOfFile:path];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
_lists = [unarchiver decodeObjectForKey:#"Checklists"];
[unarchiver finishDecoding];
} else {
_lists = [[NSMutableArray alloc] initWithCapacity:20];
}
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
if ((self = [super initWithCoder:aDecoder])) {
_lists = [[NSMutableArray alloc] initWithCapacity:20];
Checklist *list;
list = [[Checklist alloc] init];
list.name = #"Birthdays";
[_lists addObject:list];
list = [[Checklist alloc] init];
list.name = #"Groceries";
[_lists addObject:list];
list = [[Checklist alloc] init];
list.name = #"Cool Apps";
[_lists addObject:list];
list = [[Checklist alloc] init];
list.name = #"To Do";
[_lists addObject:list];
for (Checklist *list in _lists) {
ChecklistItem *item = [[ChecklistItem alloc] init];
item.text = [NSString stringWithFormat:#"Item for %#", list.name];
[list.items addObject:item];
[self loadChecklists];
}
return self;
}
- (void)viewDidLoad // Use of undeclared identifier '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.
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [_lists count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
Checklist *checklist = _lists[indexPath.row];
cell.textLabel.text = checklist.name;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Checklist *checklist = _lists[indexPath.row];
[self performSegueWithIdentifier:#"ShowChecklist" sender:checklist];
}
#pragma mark - Table View Delegate Protocol
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not 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
{
[_lists removeObjectAtIndex:indexPath.row];
NSArray *indexPaths = #[indexPath];
[tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
}
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"ShowChecklist"]) {
ChecklistViewController *controller = segue.destinationViewController;
controller.checklist = sender;
}
else if ([segue.identifier isEqualToString:#"AddChecklist"]) {
UINavigationController *navigationController = segue.destinationViewController;
ListDetailViewController *controller = (ListDetailViewController *)navigationController.topViewController;
controller.delegate = self;
controller.checklistToEdit = nil;
}
}
-(void)listDetailViewControllerDidCancel:(ListDetailViewController *)controller
{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)listDetailViewController:(ListDetailViewController *)controller didFinishAddingChecklist:(Checklist *)checklist
{
NSInteger newRowIndex = [_lists count];
[_lists addObject:checklist];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:newRowIndex inSection:0];
NSArray *indexPaths = #[indexPath];
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)listDetailViewController:(ListDetailViewController *)controller didFinishEditingChecklist:(Checklist *)checklist
{
NSInteger index = [_lists indexOfObject:checklist];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.text = checklist.name;
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
UINavigationController *navigationController = [self.storyboard instantiateViewControllerWithIdentifier:#"ListNavigationController"];
ListDetailViewController *controller = (ListDetailViewController *)navigationController.topViewController;
controller.delegate = self;
Checklist *checklist = _lists[indexPath.row];
controller.checklistToEdit = checklist;
[self presentViewController:navigationController animated:YES completion:nil];
}
#end // Missing "end" | Expected "}"
AllListsViewController.h
#import <UIKit/UIKit.h>
#import "ListDetailViewController.h"
#interface AllListsViewController : UITableViewController <ListDetailViewControllerDelegate>
#end
ListDetailViewController.h
#import <UIKit/UIKit.h>
#class ListDetailViewController;
#class Checklist;
#protocol ListDetailViewControllerDelegate <NSObject>
-(void)listDetailViewControllerDidCancel:(ListDetailViewController *)controller;
-(void)listDetailViewController:(ListDetailViewController *)controller didFinishAddingChecklist:(Checklist *)checklist;
-(void)listDetailViewController:(ListDetailViewController *)controller didFinishEditingChecklist:(Checklist *)checklist;
#end
#interface ListDetailViewController : UITableViewController
#property (nonatomic, weak) IBOutlet UITextField *textField;
#property (nonatomic, weak) IBOutlet UIBarButtonItem *doneBarButton;
#property (nonatomic, weak) id <ListDetailViewControllerDelegate> delegate;
#property (nonatomic, strong) Checklist *checklistToEdit;
-(IBAction)cancel;
-(IBAction)done;
#end
Based on the fact that you are getting errors about a missing end and "expected '}', it sounds like you have mismatched curly brackets in your code. This sort of thing is really hard to spot by looking at code, but quite easy in Xcode. double-tap on each opening curly brace and Xcode will select the entire contents of the block up to the closing brace. Do that in your AllListsViewController.m file until you find the opening curly brace that does not have a corresponding closing brace.
I want to implement a UISearchDisplayController in a UIViewController, hence there is no UITableView implemented. I created the UISearchBar and UISearchDisplayController and implemented the corresponding delegate methods.
When I run the app and try searching, the table view that should be shown with the search results do not appear. To explain more my app UI, the UIViewController has a map and the search bar is placed in the navigation controller.
What I understood for now, it seems like I should implement a table view in order to be reused for the search results. However, there is no place/need to place a table view. What can I do to fix this? Any hints?
Here is the code how I implemented everything:
- (void)viewDidLoad{
[super viewDidLoad];
// Do any additional setup after loading the view.
_search = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
[_search setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[_search setPlaceholder:#"Search"];
self.navigationItem.titleView = _search;
_searchArray = [[NSMutableArray alloc] initWithObjects:#"Hi", nil];
_searchDisplay = [[UISearchDisplayController alloc] initWithSearchBar:_search contentsController:self];
_searchDisplay.delegate = self;
_searchDisplay.searchResultsDataSource = self;
_searchDisplay.searchResultsDelegate = self;
[_searchDisplay setActive:YES animated:YES];
filteredResults = [[NSMutableArray alloc] init];}
-(void) filterForSearchText:(NSString *) text scope:(NSString *) scope
{
[filteredResults removeAllObjects]; // clearing filter array
NSPredicate *filterPredicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#",text]; // Creating filter condition
filteredResults = [NSMutableArray arrayWithArray:[_searchArray filteredArrayUsingPredicate:filterPredicate]]; // filtering result
NSLog(#"search %#", filteredResults);
}
#pragma mark - UISearchDisplayDelegate Methods
-(BOOL) searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterForSearchText:searchString scope:[[[[self searchDisplayController] searchBar] scopeButtonTitles] objectAtIndex:[[[self searchDisplayController] searchBar] selectedScopeButtonIndex] ]];
return YES;
}
-(BOOL) searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption
{
[self filterForSearchText:self.searchDisplayController.searchBar.text scope:
[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]];
return YES;
}
#import <UIKit/UIKit.h>
#import "RoleDetailTVC.h" // so this class can be an RoleDetailTVCDelegate
#import "CoreDataTableViewController.h" // so we can fetch
#import "Role.h"
#interface RolesTVC : CoreDataTableViewController <RoleDetailTVCDelegate>
#property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
#property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#property (strong, nonatomic) Role *selectedRole;
#property (nonatomic, retain) NSMutableArray *searchResults;
#end
#import "RolesTVC.h"
#import "Role.h"
#import "ModelCell.h"
#import <QuartzCore/QuartzCore.h>
#interface RolesTVC ()
{
NSMutableArray *objects;
}
#end
#implementation RolesTVC
#synthesize fetchedResultsController = __fetchedResultsController;
#synthesize managedObjectContext = __managedObjectContext;
#synthesize selectedRole;
#synthesize searchResults;
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
objects = [[NSMutableArray alloc]init];
if(self){
for (int i=1; i<100; i++) {
NSString *str = [NSString stringWithFormat:#"This is the fabulous Row %d",i];
[objects addObject:str];
}
}
return self;
}
//This function is where all the magic happens
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
//1. Setup the CATransform3D structure
CATransform3D rotation;
rotation = CATransform3DMakeRotation( (90.0*M_PI)/180, 0.0, 0.7, 0.4);
rotation.m34 = 1.0/ -600;
//2. Define the initial state (Before the animation)
cell.layer.shadowColor = [[UIColor blackColor]CGColor];
cell.layer.shadowOffset = CGSizeMake(10, 10);
cell.alpha = 0;
cell.layer.transform = rotation;
cell.layer.anchorPoint = CGPointMake(0, 0.5);
//!!!FIX for issue #1 Cell position wrong------------
if(cell.layer.position.x != 0){
cell.layer.position = CGPointMake(0, cell.layer.position.y);
}
//4. Define the final state (After the animation) and commit the animation
[UIView beginAnimations:#"rotation" context:NULL];
[UIView setAnimationDuration:0.8];
cell.layer.transform = CATransform3DIdentity;
cell.alpha = 1;
cell.layer.shadowOffset = CGSizeMake(0, 0);
[UIView commitAnimations];
}
//Helper function to get a random float
- (float)randomFloatBetween:(float)smallNumber and:(float)bigNumber {
float diff = bigNumber - smallNumber;
return (((float) (arc4random() % ((unsigned)RAND_MAX + 1)) / RAND_MAX) * diff) + smallNumber;
}
- (UIColor*)colorFromIndex:(int)index{
UIColor *color;
//Purple
if(index % 3 == 0){
color = [UIColor colorWithRed:0.93 green:0.01 blue:0.55 alpha:1.0];
//Blue
}else if(index % 3 == 1){
color = [UIColor colorWithRed:0.00 green:0.68 blue:0.94 alpha:1.0];
//Blk
}else if(index % 3 == 2){
color = [UIColor blackColor];
}
else if(index % 3 == 3){
color = [UIColor colorWithRed:0.00 green:1.0 blue:0.00 alpha:1.0];
}
return color;
}
#pragma mark -
#pragma mark Fetched Results Controller section
- (void)setupFetchedResultsController
{
// 1 - Decide what Entity you want
NSString *entityName = #"Role"; // Put your entity name here
//NSLog(#"Setting up a Fetched Results Controller for the Entity named %#", entityName);
// 2 - Request that Entity
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];
[request setFetchLimit:100];
// 3 - Filter it if you want
//request.predicate = [NSPredicate predicateWithFormat:#"Role.name = Blah"];
// 4 - Sort it if you want
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"name"
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)]];
// 5 - Fetch it
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
[self performFetch];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self setupFetchedResultsController];
}
/**
* iCloud
*
* #param note Check PersonTVC
*/
- (void)reloadFetchedResults:(NSNotification*)note {
//NSLog(#"Underlying data changed ... refreshing!");
[self performFetch];
}
- (void)viewDidLoad
{
[ADVThemeManager customizeTableView:self.tableView];
[self.tableView reloadData];
/*
* Refresh this view whenever data changes iCloud
*/
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(reloadFetchedResults:)
name:#"RolesTVCSomethingChanged"
object:[[UIApplication sharedApplication] delegate]];
}
- (void)viewDidUnload
{
/**
* iCloud
*
*/
[[NSNotificationCenter defaultCenter] removeObserver:self];
/**
* Search Function
*/
self.searchResults = nil;
}
#pragma mark -
#pragma mark - Table view delegate
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"RolesCell";
ModelCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ModelCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
// Configure the cell...
Role *role = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.nameLbl.text = role.name;
cell.zoneLbl.text = role.zones;
cell.checkoutLbl.text = role.checkout;
//Set the accessory type.
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
//Configure the cell font
cell.zoneLbl.font = [UIFont fontWithName:#"eurostile-oblique" size:18.0];
cell.nameLbl.font = [UIFont fontWithName:#"eurostile-oblique" size:18.0];
cell.checkoutLbl.font = [UIFont fontWithName:#"eurostile-oblique" size:18.0];
return cell;
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView)
{
return [self.searchResults count];
}
else
{
return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 75.f;
}
#pragma mark -
#pragma mark Table view Methods
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.tableView beginUpdates]; // Avoid NSInternalInconsistencyException
// Delete the role object that was swiped
Role *roleToDelete = [self.fetchedResultsController objectAtIndexPath:indexPath];
//NSLog(#"Deleting (%#)", roleToDelete.name);
[self.managedObjectContext deleteObject:roleToDelete];
[self.managedObjectContext save:nil];
// Delete the (now empty) row on the table
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self performFetch];
[self.tableView endUpdates];
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(#"Error! %#",error);
abort();
}
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"Add Role Segue"])
{
// NSLog(#"Setting RolesTVC as a delegate of RoleDetailTVC");
RoleDetailTVC *roleDetailTVC = segue.destinationViewController;
roleDetailTVC.delegate = self;
// NSLog(#"Creating a new role and passing it to RoleDetailTVC");
Role *newRole = [NSEntityDescription insertNewObjectForEntityForName:#"Role"
inManagedObjectContext:self.managedObjectContext];
roleDetailTVC.role = newRole;
// Hide bottom tab bar in the detail view
roleDetailTVC.hidesBottomBarWhenPushed = YES;
}
else if ([segue.identifier isEqualToString:#"Role Detail Segue"])
{
// NSLog(#"Setting RolesTVC as a delegate of RoleDetailTVC");
RoleDetailTVC *roleDetailTVC = segue.destinationViewController;
roleDetailTVC.delegate = self;
// Store selected Role in selectedRole property
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
self.selectedRole = [self.fetchedResultsController objectAtIndexPath:indexPath];
// NSLog(#"Passing selected role (%#) to RoleDetailTVC", self.selectedRole.name);
roleDetailTVC.role = self.selectedRole;
// Hide bottom tab bar in the detail view
roleDetailTVC.hidesBottomBarWhenPushed = YES;
}
else {
// NSLog(#"Unidentified Segue Attempted!");
}
}
- (void)theSaveButtonOnTheRoleDetailTVCWasTapped:(RoleDetailTVC *)controller
{
// do something here like refreshing the table or whatever
// close the delegated view
[controller.navigationController popViewControllerAnimated:YES];
}
// Override to support conditional rearranging of the table view.
-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath: (NSIndexPath *) indexPath {
return YES;
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath {
return YES;
}
- (void)didReceiveMemoryWarning
{
UIAlertView *alertDialog;
alertDialog = [[UIAlertView alloc]
initWithTitle:NSLocalizedString(#"Memory Problem", #"Hafıza Problemi")
message: NSLocalizedString(#"Please Close Some Applications!", #"Hafıza Problemi")
delegate: nil
cancelButtonTitle: #"Ok"
otherButtonTitles: nil];
[alertDialog show];
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#end
I'm trying to load my UITableView with distance from current location. I'm taking small steps in just trying to get the Latitude to load into the UITableView. My NSLog is reading the correct Lat/Long, but my Table is reading 0.000. At this point I'm not sure if it's my memory management or something else. Please help.
My ViewController.h
#import <UIKit/UIKit.h>
#import "CoreLocation/CoreLocation.h"
#interface TulsaMasterViewController : UITableViewController <CLLocationManagerDelegate>
{
NSArray *_barInfo;
CLLocationManager *lm;
NSString *currentLat;
}
#property (nonatomic, strong) NSArray *barInfo;
#property (nonatomic, strong) NSString *currentLat;
#end
My ViewController.m
#import "TulsaMasterViewController.h"
#import "TulsaDetailViewController.h"
#import "Bars.h"
#import "BarDatabase.h"
#implementation TulsaMasterViewController
#synthesize barInfo = _barInfo;
#synthesize currentLat = _currentLat;
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"%f", newLocation.coordinate.latitude);
NSLog(#"%f", newLocation.coordinate.longitude);
currentLat = [NSString stringWithFormat:#"%f", newLocation.coordinate.latitude];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSString *msg = [[NSString alloc]initWithString:#"Error obtaining location"];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Error" message:msg delegate:nil cancelButtonTitle:#"Done" otherButtonTitles:nil];
[alert show];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.barInfo 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];
}
//Get the object from the array.
Bars *barObj = [self.barInfo objectAtIndex:indexPath.row];
//Set the coffename.
cell.textLabel.text = barObj.barName;
cell.detailTextLabel.text = [NSString stringWithFormat:#"%f", currentLat];
// Set up the cell
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ShowDetails"]) {
TulsaDetailViewController *detailViewController = [segue destinationViewController];
detailViewController.detailItem = [self.barInfo objectAtIndex:[self.tableView indexPathForSelectedRow].row];
}
}
- (void)awakeFromNib
{
[super awakeFromNib];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.barInfo = [BarDatabase database].barInfo;
lm = [[CLLocationManager alloc] init];
lm.delegate = self;
[lm startUpdatingLocation];
}
#end
You need to update your tableview when the didUpdateToLocation method is called