understanding TTNavigator - iphone

following situation:
in a TTTableViewController i added some Cells with URLs.
they are opening a class with #"tt://photos" for example. this works quite fine.
the first thing is, i saw some urls in TT Examples like #"tt/photos/1". is it possible to fetch this "1" in my photos class and say, for example okay, please open picture one, ore is this only another URL that was declared in TTNavigatior to open a specific Class?
the other thing is: is it possible to forward an object to the linked class?
clicking a cell opens #"tt://photos" (the linked class in my TTNavigator)
working with normal tableviews i can overwrite my init method and send an object with my initialize method, is this also possible by clicking my TTItems?
thanks!

figured it out myself, for those who need it:
First (passing "subURLs" in your navigator map)
navigating to an URL with #"tt://photos/firstphoto" is possible, you can fetch the "firstphoto" like this:
//Prepare your Navigator Map like this
[map from:#"tt://photos/(initWithNumber:)" toViewController:[PhotoVC class]];
In your PhotoVC you can access this Number:
-(void) initWithNumber: (NSString*)number {
NSLog(#"%#",number);
}
calling your View Controller with this url would look:
PhotoVC* controller = [[PhotoVC alloc] initWithNumber:#"1"];
[navigationController pushViewController:controller animated:YES];
[controller release];
Second (passing objects in an TTTableViewController)
its a bit tricky, but you dont have to Subclass anything.
first, nil the URL in the TableItem
[TTTableLink itemWithText:#"TTTableLink" URL:nil]
in your TTTableViewController write down this method
- (void)didSelectObject:(id)object atIndexPath:(NSIndexPath*)indexPath {
TTURLAction *urlAction = [[[TTURLAction alloc] initWithURLPath:#"tt://photos"] autorelease];
urlAction.query = [NSDictionary dictionaryWithObject:#"firstphoto" forKey:#"photo"];
urlAction.animated = YES;
[[TTNavigator navigator] openURLAction:urlAction];
}
now in your your PhotoVC you need something like this
- (id)initWithNavigatorURL:(NSURL*)URL query:(NSDictionary*)query {
if (self = [super init]) {
NSLog(#"%#",query);
}
return self;
}
and you are done ;)

I was trying to implement choise's answer, learned a lot, and eventually had to get the callouts showing up and keep the implementation with many urls simple, so here's what i did.
Keep URL in the TableItem,
Use this code in the TTTableViewController subclass.
- (void)didSelectObject:(id)object atIndexPath:(NSIndexPath*)indexPath {
NSLog(#"Its url is %#", [object URL]);
TTURLAction *urlAction = [[[TTURLAction alloc] initWithURLPath:(NSString *)[object URL]] autorelease];
urlAction.query = [NSDictionary dictionaryWithObject:self.user forKey:#"user"];
urlAction.animated = YES;
[[TTNavigator navigator] openURLAction:urlAction];
}
- (BOOL)shouldOpenURL:(NSString*)URL {
return NO;
}
That "shouldOpenURL:" was discovered looking through TTTableViewController, I tried it out, and it worked. Now the table view is not opening a duplicate view, and there are callouts!
Thanks choise!

Although choice's answer works for multiple params when u are creating the TTURLAction in code it is not very useful when u want to embed links to view controllers in your TTStyledLabel.One solution to that is to use multiple params in a single string.
<a href='app://view2/param1=value1&param2=value2&...'>LabelName</a>
if you want the code to parse such urls and get the params please feel free to send me a message and I will send you my parser classes.
(or you can build your own with NSScanner!)
Also dont forget to escape the &s otherwise TTStyledLabel would not like it!

You don't need to run this on current version 1.0.6.2 for TTTableViewController. The "URL" option is working as expected. If it's not working for you, then your URL is broken or your are calling the wrong function on your ViewController. The function you have to call through URL must return an id (be a constructor for a ViewController) of a ViewController. Then it'll work as expected.
I'll changed the example form choise to be like TTNavigator expect it to be.
Add a mapping, which TTNavigator will use to navigate:
//Prepare your Navigator Map like this
[map from:#"tt://photos/(initWithNumber:)" toViewController:[PhotoVC class]];
Create a TTTableLink (or TTStyledText, or other) with an URL set, which should mach your map:
[TTTableLink itemWithText:#"TTTableLink" URL:#"tt://photos/1"]
Add this to your PhotoVC to be called by TTNavigator on the given URL
-(id) initWithNumber: (NSString*)number {
if (self = [super init]) {
self.title = #"Some Title";
NSLog(#"%#",number);
}
return self;
}
You don't need to overwrite the function didSelectObject, as the TTNavigator will call your ViewController through defined constructor function tt://photos/(initWithNumber:)

Related

Initial text and paperclipped-URL for action in UIActivityViewController & UIActivityItemSource?

Finally been making it through Apple's (rather dismal) documentation on the new UIActivityViewController class and the UIActivityItemSource protocol, and I'm trying to send different data sets to different actions called from the activity view. To simplify things, I'm looking at two things.
A Facebook posting action, which should say "Check this out!" and also attach a URL to the post (with that cute little paperclip).
A Twitter posting action, which should say "Check this out, with #hashtag!" and also attach that same URL (with the same paperclip).
Here's the code I've got implemented right now.
- (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType {
if ([activityType isEqualToString:UIActivityTypePostToFacebook]) {
return #"Check this out!";
} else if ([activityType isEqualToString:UIActivityTypePostToTwitter]) {
return #"Check this out, with #hashtag!";
}
return #"";
}
- (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController {
return #"";
}
And then when I set up this activity view controller (it's in the same class), this is what I do.
UIActivityViewController *activityView = [[UIActivityViewController alloc] initWithActivityItems:#[self] applicationActivities:nil];
[self presentViewController:activityView animated:YES completion:nil];
My dilemma is how to attach that NSURL object. It's relatively easy when calling the iOS 6 SL-class posting modals; you just call the individual methods to attach a URL or an image. How would I go about doing this here?
I'll note that instead of returning NSString objects from -activityViewController:itemForActivityType, if I return just NSURL objects, they show up with that paperclip, with no body text in the post. If I return an array of those two items, nothing shows up at all.
Evidently it was as simple as this: passing in an array to the first argument of UIActivityViewController's init call, with each item in the array handling a different data type that will end up in the compose screen. self handles the text, and the second object (the NSURL) attaches the URL.
NSArray *items = #[self, [NSURL URLWithString:#"http://this-is-a-url.com"]];
UIActivityViewController *activityView = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:nil];
[self presentViewController:activityView animated:YES completion:nil];
Really wish there was more on this, but here it is.

Custom Detail Image View from Three20

I am pretty new with Three20. I have followed ray wenderlich's nice introduction to three20 and the examples within the three20 framework. When I click on a thumbnail in a thumbnail view (subclass of TTThumbsViewController) to launch a Details view, a standard Details image view (deployed by TTPhotoViewController or its super class). I would like to use my own implementation of a Details View instead of the default. I put the following code when I initiated the subclass of TTThumbsViewController and TTThumbsViewControllerDelegate method:
- (id)initWithDelegate:(id<TTThumbsViewControllerDelegate>)delegate {
[super initWithDelegate:delegate];
return self;
}
- (void)thumbsViewController: (TTThumbsViewController*)controller
didSelectPhoto: (id<TTPhoto>)photo {
[navigationController.pushViewController:photoDetailViewController
animated:Yes];
}
But the default TTPhotoViewController view still prevail. When I put a NSLog in the delegate method. I coud see the method was called. I think there is another delegate someone already set in TTThumViewController? Can someone recommend a way to display my detail photo view? Is there another thumbs view controller I can use? Any suggestion will be greatly appreciated.
I'm really new to all of this (coding, etc.) but I'll share what I've found. By looking up the definition of ttthumbsviewcontroller, I was able to find the following method(wrong term?):-
- (void)thumbsTableViewCell:(TTThumbsTableViewCell*)cell didSelectPhoto:(id<TTPhoto>)photo {
[_delegate thumbsViewController:self didSelectPhoto:photo];
BOOL shouldNavigate = YES;
if ([_delegate respondsToSelector:#selector(thumbsViewController:shouldNavigateToPhoto:)]) {
shouldNavigate = [_delegate thumbsViewController:self shouldNavigateToPhoto:photo];
}
if (shouldNavigate) {
NSString* URL = [self URLForPhoto:photo];
if (URL) {
TTOpenURLFromView(URL, self.view);
} else {
TTPhotoViewController* controller = [self createPhotoViewController];
controller.centerPhoto = photo;
[self.navigationController pushViewController:controller animated:YES];
}
}
}
In the else statement, I've found this calls the creation of the photoviewcontroller. By recalling this method (?) in the actual body of my own code and changing the body in the else statement I was able to add a custom detail view. Further down the definition of the ttthumbsnailviewcontroller, you can find that the creatPhotoViewController calls for an initiation of the PhotoViewController so calling that method(?) in the body of the code and initializing another view also works.
If someone can explain whether or not this is a good method of doing this (I have a feeling that is not), it would be appreciated. Also why does putting the method in the body of the code override the call there.

pass native object in URL

I was following the tutorial here.
The code I have is:
- (void) didSelectObject:(id) object atIndexPath:(NSIndexPath*) indexPath
{
Group * group = (Group *)((RKMappableObjectTableItem *) object).object;
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
group.unread = 0;
[self.tableView reloadData];
TTURLAction *action = [[[TTURLAction actionWithURLPath:#"tt://group"]
applyQuery:[NSDictionary dictionaryWithObject:group forKey:#"kParameterUser"]]
applyAnimated:YES];
[[TTNavigator navigator] openURLAction:action];
}
I have set the mapping as:
[map from:#"tt://group" toSharedViewController:[TopicsViewController class]];
and inside my TopicsViewController I have both tried:
- (id) initWithNavigatorURL:(NSURL*)URL query:(NSDictionary*)query {
but it didn't work. It's as if it can't find any mapping. Why is this? What am I doing wrong?
UPDATE:
Here's the updated code based on the suggestion:
TTURLAction *action = [[[TTURLAction actionWithURLPath:#"tt://group"]
applyQuery:[NSDictionary dictionaryWithObject:group forKey:#"kParameterUser"]]
applyAnimated:YES];
[[TTNavigator navigator] openURLAction:action];
[map from:#"tt://group?" toSharedViewController:[TopicsViewController class] selector:#selector(initWithNavigationURL:)];
- (id) initWithNavigatorURL:(NSURL*)URL query:(NSDictionary*)query
what am I doing wrong here?
You are not telling it what selector to cal! First, add a ? to the end of your mapping: #"tt://group?"
When you add any query dictionaries, they are sent like normal params in a url (?foo=bar&apple=orange).
Next, if you aren't going to use the selector as part of the URL mapping, use the from:toSharedViewController:selector: method to set the selector to the selector you wish to call.
I don't know three20 very well, I think however you first need to create an URL to the object you'd like to pass, which can be mapped.
It appears like three20 provides a category on nsobject which allows you to call:
NSString* url = [myFooObject URLValueWithName:#"barName"];
This method should be inherited from NSObject by almost any Framework Class.
See NSObjects to URLs in the chapter URL mapping methods from the tutorial you posted.

updating value of modal view variable

I'm trying to make a modal view which displays the champion of my app.
there's a NSMutableString variable called champ in modal view,
which is supposed to be updated by returnChamp function in main view.
the champ string is correctly set in main view,
but in modal view, the champ value appears as (null).
In fact, it seems it doesn't even go into the returnChamp function.
so apparently something wrong with my calling or implementing returnChamp,
but I have another function that does the similar, and that works fine.
could anyone please help me?
-(void) mainView{
.....
champ = [[currentPlayers objectAtIndex:playerIndex] retain];
NSLog(#"%#",champ);
modalWinner = [[winner alloc] init];
modalWinner.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:modalWinner animated:YES];
}
- (NSMutableString *) returnChamp{
NSLog(#"returnChamp");
return champ;
}
//in modalWinner
-(void) modalView{
..............
champName = [[NSMutableString alloc] init];
NSLog(#"%#", [(MainViewController *)self.parentViewController returnChamp]);
champName = [(MainViewController *)self.parentViewController returnChamp];
UIImage *champImage = [UIImage imageNamed:champName];
}
self.parentViewController is probably not actually a reference to your object. For some reason, it seems that the framework always insists on setting a UINavigationController as self.parentViewController - even for modals, and to the extent that it will create one if there isn't already one. This is probably going unnoticed because you're casting it to your MainViewController type.
You'll need to find a different way of making your original object available to be communicated with, or perhaps pass the appropriate value to the newly-instantiated controller before you present it.
For example, if you add a champName property to the modal class, you can do:
modalWinner = [[ModalWinnerViewController alloc] init];
modalWinner.champName = myValue; /* Set value before presenting controller */
[self presentModalViewController:modalWinner animated:YES];
There will probably be some code needed to update the UI with this value. The viewWillAppear method of the modal view controller is a good place for this as it is called by the framework immediately before the view is presented.
Note that this property-based approach could be used to keep a reference to your intended parent object, as well. And see here for a different approach to solving a similar problem.

initializing UIView subclass with parameters in iphone sdk?

Iam a newbiew to iPhone development. Version of my SDK is 2.2
In my code, UIViewController is used to change view dynamically once the app is launched, a method in the UIViewController is called to know which view should be initialized along with parameters, which goes to a 'switch-case' and assign a view to current view according to the parameter, like this:
case 1:
currentView = [[View01 alloc] init];
break;
case 2:
currentView = [[View02 alloc] init];
break;
and outside the switch-case:
[self.view addSubview:currentView.view];
I wonder f can pass a parameter along with initialization, like iniWithNibName or so? I need this because have to manipulate in the leaded view, according to the view from which its called.
Thanks.
One way to approach this is to modify your View01 and View02 classes to include an initWithParam: initialiser.
i.e. add
- (id) initWithParam:(NSString *)myParam;
to the #interface section and add
- (id) initWithParam:(NSString *)myParam {
if (self = [self init]) {
// handle or store 'myParam' somewhere for use later
}
return self;
}
to the #implementation section. Notice how the initWithParam: message internally calls the existing init. Obviously you could change the type, or number of parameters passed in as required.
Another approach would be to provide a property on your view class, so you could do something like the following:
currentView = [[View01 alloc] init];
currentView.myParam = #"SomeValue";
Which approach works the best will depend somewhat on your particular application needs.