Go to another viewcontroller after click on a pin mapkit - ios6

I have multi pin on my map (about restaurants, hotels etc..), on that pins I have an "arrow" (rightcalloutaccessoryview). The coordinates are stored on the sqlite database.
I can get the coordinates and the right id when I click on the pin then I'm checking on the DB where are that coordinates.
Objective: When I click on the a hotel pin I want to go to that detail ViewController (that loads with the id of that hotel)
Any ideias?

yes try the below example code. here i used to differentiate annotation (pin) with their titles. and used map view delegate methods
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control
{
NSLog(#"accessory button tapped for annotation %#", [view.annotation title]);
if([[view.annotation title] isEqualToString:#"one"])
{
// Push to another view controller code here
}
}
 

Related

Azure maps layers are getting on top of each other

I'm using azure map.
What's happening is that I have 2 layers. A layer that have Circles and a layer with polygons.
I have a functionality in which a popup appear when I click on a specific circle.
The issue occur when I add the polygon layer after the circle layer.
It's like the polygon layer is being drawn on top of the circle layer. In which it prevent the popup from appearing when clicking on the circle.
Here's how I'm adding the polygon layer:
showFetchedResultOnMap(facilities) {
const self = this;
if (facilities && facilities.length > 0) {
self.cleanRestrictionLayer();
//Create a data source and add it to the map.
self.datasource = new atlas.source.DataSource();
self.map.sources.add(self.datasource);
//Add a data set to the data source.
self.CleanMap();
//Create a data source and add it to the map.
var datasource = new atlas.source.DataSource();
self.map.sources.add(datasource);
self.map.imageSprite.add(self.chosenCategory, 'assets/svg/' + self.chosenCategory + '.svg')
.then(function () {
facilities.forEach(cat => {
datasource.add(new atlas.data.Feature(new atlas.data.Point([cat.longitude, cat.latitude])));
});
//Add a layer for rendering point data as symbols.
self.map.layers.add(new atlas.layer.SymbolLayer(datasource, self.chosenCategory, {
iconOptions: {
//Pass in the id of the custom icon that was loaded into the map resources.
image: self.chosenCategory,
//Optionally scale the size of the icon.
size: 0.1
}
}));
});
}
}
Anyone have an Idea about how I can fix this??
I'm not seeing a polygon layer in the code you provided. That said, when you add layers to the map, the order in which you add them is the z-index by default. Last one added goes on top. That said, when adding the layer using the map.layers.add function, there is a second parameter you can add in which can be another layer or layer id. When this is specified the layer you are adding will be inserted below that second specified layer. Here is the doc on this: https://learn.microsoft.com/en-us/javascript/api/azure-maps-control/atlas.layermanager?view=azure-maps-typescript-latest#add-layer---layer----string---layer-
Here is a short example:
map.layers.add(new atlas.layers.BubbleLayer(datasource, 'myBubbles'));
map.layers.add(new atlas.layers.PolygonLayer(datasource, 'myPolygons'), 'myBubbles');

LOV not displaying drop down values after fetching values via ViewCriteria

I have created a LOV which is dependent on OrganizationId and ManagerId . It should display EmployeeName.
Flow is : User select Organization then Manager(It is also an LOV) and then he can see EmployeeName.
public void applyReleaseRuleValues(){
ViewObject projectCostingTaskName =this.getProjCostingTaskVA().getViewObject();
try{
projectCostingTaskName.setNamedWhereClauseParam("bindInvOrgId",releaseOrganizationId);
projectCostingTaskName.setNamedWhereClauseParam("bindProjectId",releaseManagerId);
projectCostingTaskName.setNamedWhereClauseParam("bindTaskId",releaseEmployeeId);
}catch (oracle.jbo.NoDefException e) {
;
}
projectCostingTaskName.executeQuery();
Row pjcTask=projectCostingTaskName.first();
String setPjcTaskId=(String)pjcTask.getAttribute("EmployeeName");
setAttributeInternal(EMPLOYEENAME,setPjcTaskId );
I don't think it's an UIProject issue as Manager & Employee Name is getting displayed.In Manager LOV is visible but not for Employee.
Any suggestions?
I think you are going about trying to achieve this in the harder way. There is a much easier way to achieve Cascaded List Of Values, via simple View Object query and drag and drop on the form from the controller. If this all you want, in that case check this out:
https://waslleysouza.com.br/en/2014/10/defining-cascading-list-values-adf/
or
http://jjzheng.blogspot.com/2010/06/implement-cascading-lists-of-values-in.html
or
this video: https://www.youtube.com/watch?v=nXwL2_RP7AQ
If you need something more complex, please add it to the question

Azure maps clustering

I noticed in a recent iteration of Azure maps, pins can be added to a datasource which can be applied to a map's source -
var dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);
dataSource.add(pins);
where pins is a collection of atlas.data.Feature elements.
The pins are successfully rendered onto the page in the correct locations, but they are clustered.
I don't want them clustered. At any given zoom level, I want to see all of my pins.
I tried to instantiate the datasource object like this (unclustered) -
var dataSource = new atlas.source.DataSource(null, {
cluster: false
});
but that didn't work.
At what level is the clustering set?
Clustering is turned off by default on the data source. What you are seeing is collision detection occurring between the symbols. This can be displayed by setting the allowOverlap and ignorePlacement icon options of the symbol layer.
var layer = new atlas.layer.SymbolLayer(datasource, null, {
iconOptions: {
allowOverlap: true,
ignorePlacement: true
}
});

collectionView, didSelectItemAtIndexPath issue

I have an interesting issue with collectionView, specifically, didSelectItemAtIndexPath.
My app has one particular view with a background image, which is accessed via an SQL. Within that view is a popover, with a collectionView, to change the parent view's background, and access other "sets" available for purchase.
My issue is with the changing of the background. All items display correctly in the collection view and the parent's background will change as it should. The problem is that the item selected is not the one that displays, even though via NSLog, I can see that the correct image is being selected and passed back to the parent. There is a corresponding NSLog in the parent, which shows the same image id as the popover's NSLog.
The first item in the collectionView, when tapped, will change the background of the parent to white, as if there was no image available. Tapping the second cell will display the first cell's image. Tapping the third cell will display the second cell's image... and so on. There are 15 images available to select from.
This is the didSelect method:
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
if ([_currentView isEqualToString:#"New_Journal"])
{
MyAppDelegate *appDelegate = (MyAppDelegate *)[UIApplication.sharedApplication delegate];
// to get the variable back to the parent
appDelegate.loadBackgroundID = indexPath.row;
// interact with the SQL via _settingsDao
[_settingsDao updateJournalBackgroundId:_journalId withBackgroundId:appDelegate.loadBackgroundID];
NSLog(#"Selected background: %d", indexPath.row);
// notification to let EntryView know the background has changed
[NSNotificationCenter.defaultCenter postNotificationName:#"aBackgroundChanged" object:self];
}
}
Edit to show SQL interaction method:
-(void)updateJournalBackgroundId:(int)journalID withBackgroundId:(int)newBackgroundId
{
NSString *query = #"UPDATE BgIconBorderSettings SET background_id = ? WHERE journal_id = ?";
FMDatabase *db = [dbUtils sharedDB];
[db executeUpdate:query,[NSNumber numberWithInt:newBackgroundId],[NSNumber numberWithInt:journalID]];
if([db hadError])
{
NSLog(#"Error %d: %#",[db lastErrorCode],[db lastErrorMessage]);
}
}
Anyone have any ideas on how to get the correct image of the tapped cell to display? Thanks for any assistance in solving this issue.
As jhilgert pointed out... it was the SQL database. It started at 1 and not 0. Changed the ids and it works as expected.

How to properly add and delete objects to tableview with custom tableviewcells?

I'm currently developing an app that behaves like the Messages.app. The MasterViewController is the main view where it loads a table of the contact name, time and a snippet of the most recent message. When you tap a specific cell, it slides to the DetailViewController where it loads the messages I sent to the contact with the latest, complete message. Hitting the back button goes back to the MasterViewController. Tapping the rightBarButtonItem opens up a ComposeViewController (modal) where the user can compose a message to a specific contact. The difference of this app to the default Messages.app is that it has a delay timer before the message is sent. The ComposeViewController has a textfield to input the message, button to select a contact, button to pick a time delay, button to send, button to cancel the timer, and a button to dismiss the ModalViewController.
I removed the ability to send an actual SMS message entirely. I just presented the user with an alert view telling him/her that the message was sent and if he/she wants to compose a new one. Hitting Cancel will dismiss the ModalViewController and go back to the MasterViewController.
Problem is, I can't make the rows appear on the table and also have the ability to add and remove cells in the table.
Here's some code inside my MasterViewController's viewDidLoad:
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Delete button to delete messages
UIBarButtonItem *deleteBarButtonItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemTrash
target:self
action:#selector(deleteText)];
self.navigationItem.leftBarButtonItem = deleteBarButtonItem;
// Compose button to go to compose messages
UIBarButtonItem *composeBarButtonItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemCompose
target:self
action:#selector(composeText)];
self.navigationItem.rightBarButtonItem = composeBarButtonItem;
[deleteBarButtonItem release];
[composeBarButtonItem release];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *message = [defaults objectForKey:kMessageText];
NSString *contactname = [defaults objectForKey:kContactNameText];
NSString *timestamp = [defaults objectForKey:kTimeStampText];
[messageDetails initWithObjectsAndKeys:contactname, kContactNameKey, message, kContactMsgKey, timestamp, kContactTimeKey, nil];
NSMutableArray *messageInfo = [[NSMutableArray alloc] initWithObjects:messageDetails, nil];
self.messagesList = messageInfo;
[messageInfo release];
[super viewDidLoad];
Here's the code in cellForRowAtIndexPath:
CustomCellViewController *customCell = (CustomCellViewController *)[tableView dequeueReusableCellWithIdentifier:#"CustomCellViewController"];
if (customCell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCellViewController"
owner:self
options:nil];
for (id oneObject in nib) if ([oneObject isKindOfClass:[CustomCellViewController class]])
customCell = (CustomCellViewController *)oneObject;
}
NSUInteger row = [indexPath row];
NSDictionary *messages = [self.messagesList objectAtIndex:row];
customCell.nameLabel.text = [messages objectForKey:kContactNameKey];
customCell.nameLabel.textColor = [UIColor whiteColor];
customCell.messageLabel.text = [messages objectForKey:kContactMsgKey];
customCell.messageLabel.textColor = [UIColor lightGrayColor];
customCell.timeLabel.text = [messages objectForKey:kContactTimeKey];
customCell.timeLabel.textColor = [UIColor blueColor];
customCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return customCell;
Here's the code for deleting cells:
- (void)tableView:(UITableView *)tableView commitEditingStyle(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// Delete the row from the data source.
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]withRowAnimation:UITableViewRowAnimationFade];
[messagesList removeObjectAtIndex:indexPath.row];
[self.tableView reloadData];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
Your final code snippet where you are creating a new instance of the master view controller is the problem.
This is not the view controller you are looking for. Since you've presented the detail view controller modally, you can access the master controller via the parentViewController property of the detail controller:
MasterViewController *master = (MasterViewController*)self.parentViewController;
Other design patterns that are typically used in this situation:
Create the new object in your master controller and insert the row in your table before passing the new object to the detail controller for updating
Create a delegate protocol for the detail controller, which your master controller conforms to. Set the detail controllers delegate to the master controller when pushing it
The latter is almost what you are doing for all practical purposes, except your detail controller knows more than it needs to about the master controller (i.e you are importing the whole master .h file rather than just knowing it conforms to a protocol).
Regarding your data structure, I don't understand how you expect to have multiple rows in here - you store one message in user defaults and then create an array with that message. I know you don't intend to use defaults to store this in the end, but I would expect to see an array of dictionaries stored in defaults under a single key, and then each dictionary represents a row in your table, with the various details stored as strings in the dictionary against your message, contact name keys etc.
You have to make a mutable version of the array returned from defaults as it always returns an immutable array.
In your cellForRow... method you'd then get the appropriate dictionary from the array and populate the cell from it.
When adding a new row you'd create a new dictionary to pass to your detail controller.
When deleting a row you'd remove the relevant dictionary from the array.

Resources