Select row in UITableView - xcode

I'm pretty new to xcode development and I cannot figure out how to select a row and give label/action I want. I'm using something i found on the internet, sample code with a customized uitableview with 3 rows:
opLabel1.text = [NSString stringWithFormat:#"HeliosMedica",[indexPath section]];
bottomLabel1.text = [NSString stringWithFormat:#"Centrumedical.", [indexPath section]];
I want each row to have different content and also give them a hyperlink. Can anyone tell me where how I can do that.
Appreciate very much your help.

Read the Apple Documents for UITableViewDelegate Protocol Reference. You want to understand some of the basic methods there, including tableView:didSelectRowAtIndexPath:
You probably already have implemented some of the UITableView class methods, in order to get a table to just show up on our screen, including numberOfSections, numberOfSections:and insertRowsAtIndexPaths:withRowAnimation:. These are called by the tableview object and your code executes to meet the tableView's needs.
Here is some sample code you can start with to open a url when the tableView:didSelectRowAtIndexPath:method is executed.
myURL = [arrayOfURLs objectAtIndex:indexPath.row];
[[UIApplication sharedApplication] openURL:myURL];
You will have to initialize the array, first.

Related

xcode change label's text after presentViewController

as always relying on this community wich is always really helpful!
I really don't understand why my code isn't working, i am playing the game in ViewControllerA for example, there is "movements" and more stuff shown,wich are labels with int variables shown, this ones give me no problem because they change correctly,when the game is completed i want to show the score and more...
So i created another ViewController to do it, ViewControllerB for the example, the thing is that A and B Viewcontrollers belong to the SAME class, so i should be able to use the same variables, methods and everything ( actually i do that already and it's working fine)
I created IBOutlet for some labels, this ones belong to B. I am using presentViewcontroller method to show it up,the labels don't get anything changed, here is the code:
NSString *moviments = [NSString stringWithFormat:#"%d",TotalMovements];
NSString *score = [NSString stringWithFormat:#"%d",TotalPoints];
NSString *levelToShow = [NSString stringWithFormat:#"%d",PlayingLevel];
[movementsToShowOnCompletedScreen setText:moviments];
[scoreToShowOnCompletedScreen setText:score];
[levelToShowOnCompletedScreen setText:levelToShow];
UIStoryboard *winOFLevelStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [winOFLevelStoryboard instantiateViewControllerWithIdentifier:#"mainGame"];
[self presentViewController:vc animated:YES completion:^{
/*I have tried to add the same code from above setting the labels text
labels here, same result...
*/
}];
The labels don't get its text changed.
This is it, i hope with all of this you can find out what's going on here, the IBOutlets are fine, i even changed programmatically the frame of those labels before so that can't be the problem, outlets are fine.
If you need more code or anyhthing just let me know!
Thanks for your time !
Well, i found it...just in case anyone has the same problem. It solves it but not the way i wanted to so if anyone knows the good way please let me know.
Since those belong to the same class i have just copied/pasted this lines shown below to my viewdidload method, now labels are changing when they have to but i really think this is a really poor solution.
Thanks again!

self.tableView reloadData not working in viewWillAppear

I have an Xcode app that creates a tableview and then populates this with data from an sqlite database, this works perfectly and allows me to push data to a new view and delete etc,
This tableview is the first view loaded on a tab bar controller. The problem arises when i move to another view on the same controller, i.e. create an athlete, in this view i can add a new athlete to the database (which works fine) but when i go back to the tableview on the tab bar controller, the table is the same, i have to log out and log back in to see the change in the table,
I have tried [self.tableView reloadData] in the viewWillAppear function but this does nothing. I know that the function is getting called as i have placed an NSLog in their just for peace of mind.
I have found what i think may be the solution on here but i cant get it to work!
viewWillAppear, viewDidAppear not being called, not firing
i will post my code below and a screen shot of the storyboard as im convinced it is my poor way of setting up controllers that has caused this error. Any help would be much appreciated as i am now at the meltdown stage :D
-(void)viewWillAppear:(BOOL)animated {
//[super viewWillAppear:animated];
//[self.tabBarController viewWillAppear:animated];
[self.tableView reloadData];
NSLog(#"i just ran viewwillAppear");
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
athleteObject *athObj3 = [athletes objectAtIndex:indexPath.row];
athleteIdDelete = athObj3.athId;
[self openDatabase];
[self deleteAthleteFromDataBase];
[athletes removeObjectAtIndex:indexPath.row];
[tableView reloadData];
}
reloadData works in my commitEditing function (this updates the tableview when i delete an entry via a swipe)
any help would be much appreciated, il post the screen shot below.
(cant figure out how to load a screenshot if its even possible)
It looks like athletes (a NSMutableArray I assume) is not being updated in viewWillAppear. Have you tried running the selector that populates the array from the database before calling reloadData?
Hope that helps!
I'm assuming you're setting the number of rows/sections in your code based on how many objects are returned from a database.
Set a breakpoint at this method, and get the count each time the compiler breaks. You are probably not getting any objects from the database, and therefore the compiler never runs the rest of the table view dataSource methods.

UITableView Row Persistance - why does "didSelectRowAtIndexPath" crash

I have a UITableView that stores the selected row in User Defaults. The tableView is part of a menu structure that may be reloaded during the lifetime of the application, hence I want the persistence between loads. In viewDidLoad, this UserDefault is checked for existence, and I call
NSIndexPath *path = [NSIndexPath indexPathForRow:row inSection:0];
[self.tableView selectRowAtIndexPath:path animated:NO scrollPosition:(UITableViewScrollPositionMiddle)];
This works fine, as expected. However, it doesn't actually select the row, it just highlight's it. If I subsequently call
[self tableView:self.tableView didSelectRowAtIndexPath:path];
I get a crash - "unrecognised selector sent to instance". Why?
[self tableView:self.tableView didDeselectRowAtIndexPath:path] will call YOUR implementation of the deselection method (which is defined in UITableViewDelegate).
You get a crash since you didn't implement it in your delegate.
You should call:
[self.tableView deselectRowAtIndexPath:path animated:NO];
The UITableView works via two delegate protocols, UITableViewDelegate and UITableViewDataSource. The class that defines your UITableView should implement these protocols and you should set the delegate and datasource of the UITableView to "self". You should not call the protocol methods directly which is most likely the reason for your crash.
In order to select a particular row based on your data model (User Default), you will need to set the UITableViewCell selected property to "YES" in the tableView:cellForRowAtIndexPath: for the row that is being rendered.
I recommend going through this tutorial to help you understand UITableView's better.
http://www.iosdevnotes.com/2011/10/uitableview-tutorial/

IBPlugin: Adding additional objects on drag from IB Library

I have a list view class that just like NSCollectionView requires an additional prototype item and a prototype view to be of any use.
When dropping an NSCollectionView from the library in Interface Builder those two helper items are automatically created. However I couldn't find a single official Apple document dealing with this use case (describing how its done).
Digging thru the Apple Dev Guides I could however find "ibDidAddToDesignableDocument:".
With the following code I managed to get my auxiliary items created on drop from library:
- (void)ibDidAddToDesignableDocument:(IBDocument *)document {
[super ibDidAddToDesignableDocument:document];
NSView *prototypeView = [[[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 300, 65.0)] autorelease];
DLListViewItem *prototypeViewItem = [[[DLListViewItem alloc] initWithNibName:nil bundle:nil] autorelease];
[document addObject:prototypeViewItem toParent:nil];
[document addObject:prototypeView toParent:nil];
[document connectOutlet:#"view" ofSourceObject:prototypeViewItem toDestinationObject:prototypeView];
[document connectOutlet:#"listView" ofSourceObject:prototypeViewItem toDestinationObject:self];
[document connectOutlet:#"prototypeItem" ofSourceObject:self toDestinationObject:prototypeViewItem];
}
However…
…IB adds those aux items for NSCollectionView only on the actual initial drag from the library, not on any other call of "ibDidAddToDesignableDocument:", such as when embedding, copying or duplicating the item. (while my method would, and on all)
This makes me wonder whether Apple actually uses "ibDidAddToDesignableDocument:" for this and if I'm on the right track with this at all.
How does one imitate this properly? I'm having a hard time trying to distinguish between different contexts for "ibDidAddToDesignableDocument:". Anybody successfully done this?
Unfortunately none of Google, Google Code, GitHub, or the documentation revealed anything helpful, so I'm in desperate need of help here. :(
Thanks in advance!
Edit: Oh great, this question just brought me the tumbleweed badge, yay! Not.
I'm more into useful answers actually, but thanks anyway ;)
I struggled with this on a plugin I did myself a while ago. In my case I was able to check a property of the object to see if it had been initialized already and skip adding the auxilliary objects in that case. I believe BWToolkit uses some internal checking that is similar. Couldn't you check your object's 'prototypeItem' property to see if you need to skip creating your aux objects?

How do I set the default selection for NSTreeController at startup?

The Background
I've built a source list (similar to iTunes et al.) in my Cocoa app.
I've got an NSOutlineView, with Value
column bound to arrangedObjects.name
key path of an NSTreeController.
The NSTreeController accesses
JGSourceListNode entities in a Core
Data store.
I have three subclasses of
JGSourceListNode - JGProjectNode,
JGGroupNode and JGFolderNode.
I have selectedIndexPaths on NSTreeController bound to an NSArray called selectedIndexPaths in my App Delegate.
On startup, I search for group nodes and if they're not found in the core data store I create them:
if ([allGroupNodes count] == 0) {
JGGroupNode *rootTrainingNode = [JGGroupNode insertInManagedObjectContext:context];
[rootTrainingNode setNodeName:#"TRAIN"];
JGProjectNode *childUntrainedNode = [JGProjectNode insertInManagedObjectContext:context];
[childUntrainedNode setParent:rootTrainingNode];
[childUntrainedNode setNodeName:#"Untrained"];
JGGroupNode *rootBrowsingNode = [JGGroupNode insertInManagedObjectContext:context];
[rootBrowsingNode setNodeName:#"BROWSE"];
JGFolderNode *childFolder = [JGFolderNode insertInManagedObjectContext:context];
[childFolder setNodeName:#"Folder"];
[childFolder setParent:rootBrowsingNode];
[context save:nil];
}
What I Want
When I start the app, I want both top level groups to be expanded and "Untrained" to be highlighted as shown:
My Window http://synapticmishap.co.uk/Window.jpeg
The Problem
I put the following code in the applicationDidFinishLaunching: method of the app delegate:
[sourceListOutlineView expandItem:[sourceListOutlineView itemAtRow:0]];
[sourceListOutlineView expandItem:[sourceListOutlineView itemAtRow:2]];
NSIndexPath *rootIndexPath = [NSIndexPath indexPathWithIndex:0];
NSIndexPath *childIndexPath = [rootIndexPath indexPathByAddingIndex:0];
[self setSelectedIndexPaths:[NSArray arrayWithObject:childIndexPath]];
but the outline view seems to not have been prepared yet, so this code does nothing.
Ideally, eventually I want to save the last selection the user had made and restore this on a restart.
The Question
I'm sure it's possible using some crazy KVO to observe when the NSTreeController or NSOutlineView gets populated then expand the items and change the selection, but that feels clumsy and too much like a work around.
How would I do this elegantly?
Elegantly? This isn't elegant but it's how I'm doing it. I just do it manually. At app quit I write this value to user defaults:
lastSelectedRow = [outlineView selectedRow]
Then at app launch I run this in app did finish launching:
[self performSelector:#selector(selectLastNoteOrCreateDefaultNote) withObject:nil afterDelay:1];
Notice I just use a delay because I noticed the same as you that "the outline view seems to not have been prepared yet". Then in that selector I use this.
[outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:lastSelectedRow] byExtendingSelection:NO];
It works but better (more elegant) solutions are welcome from me too.

Resources