gresrun / GHSidebarNav

A clone of the new Facebook iOS UI paradigm
Apache License 2.0
607 stars 136 forks source link

Search result with variables #23

Closed mcodo closed 11 years ago

mcodo commented 11 years ago

Hi I have a question about the search menu. I use a webservice to get a JSON response witch is shown in the search result. My problem is that I can get it to show the text but only that. I have from JSON three variables/columns ( ID, Name, Function) How can I pass all these to the Search result? I want to show the name, and i want to have the ID and Function as hidden variables and be able to use these variables when tapping one of the result cells....

Is this possible in some way?

gresrun commented 11 years ago

The key to doing this is implementing all three of [GHSidebarSearchViewControllerDelegate searchResultsForText:withScope callback:], [GHSidebarSearchViewControllerDelegate searchResultCellForEntry:atIndexPath:inTableView:], and [GHSidebarSearchViewControllerDelegate searchResult:selectedAtIndexPath:] to work together.

A possible implementation for your case would work as follows: searchResultsForText:withScope callback: should perform the webservice call and pass to the callback an NSArray of NSDictionaries that each represent a row from your result: E.g.:

- (void)searchResultsForText:(NSString *)text withScope:(NSString *)scope callback:(SearchResultsBlock)callback {
    // TODO: Make a webservice call here
    // For now, just fake some results
    callback(@[
        @{
            @"id": @"foo", 
            @"name": @"bar", 
            @"function": @"doBaz"
        }, @{
            @"id": @"foo2", 
            @"name": @"bar2", 
            @"function": @"doBaz2"
        }
    ]);
}

searchResultCellForEntry:atIndexPath:inTableView: will get the NSDictionary for the row at the given index path. An example implementation would look like this:

- (UITableViewCell *)searchResultCellForEntry:(id)entry atIndexPath:(NSIndexPath *)indexPath inTableView:(UITableView *)tableView {
    static NSString const *identifier = @"MyCellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }
    NSDictionary *rowDict = (NSDictionary *)entry;
    cell.textLabel.text = rowDict[@"name"];
    return cell;
}

Finally, searchResult:selectedAtIndexPath: will also get the NSDictionary for the row at the selected index path. This is where you do whatever you need to when a search result is selected by the user. E.g.:

- (void)searchResult:(id)result selectedAtIndexPath:(NSIndexPath *)indexPath {
    NSDictionary *rowDict = (NSDictionary *)result;
    NSLog (@"Selected %@", rowDict);
    // TODO: Do what you need to do here
}
mcodo commented 11 years ago

Ahhhh,,, thank you so much :+1: I will try this tonight. BTW.. I love this project. Really good work :)

mcodo commented 11 years ago

This worked like a charm :) But this raised another question..... When i got this result in searchResult, how can I pass this on to the rootViewController without making a new instance of the rootViewController? I did like this but then the slidemenu button in top dont work....

}

gresrun commented 11 years ago

Well, first off, you don't want to call the following after you have initially created the app:

self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.rootViewController = rootmainControllerTemp;
[self.window makeKeyAndVisible];

That replaces the whole app window, which is most certainly not what you want. The GHRevealViewController you created is the object that manages what view controllers are displayed for the menu and for the content panel. What you'll want to do is set the contentViewController property of your revealController like so:

- (void)searchResult:(id)result selectedAtIndexPath:(NSIndexPath *)indexPath {
    NSDictionary *rowDict = (NSDictionary *)result;
    NSLog(@"Selected %@", rowDict);
    // I'm assuming 'aDictionary' has a purpose but you didn't use it in your example so, I'll keep it here
    NSDictionary *aDictionary = @{
        @"innID": row[@"ID"],
        @"innUniqueID": UniqueID,
        @"innReturnType": row[@"ReturnType"]
    };
    RevealBlock revealBlock = ^{
        [self.revealController toggleSidebar:!self.revealController.sidebarShowing 
                                    duration:kGHRevealSidebarDefaultAnimationDuration];
    };
    // NOTE: I see that you were trying to pass in a URL into the title.
    // I'm assuming that was because you wanted that information available to the view controller so it could load it or something. 
    // You should create a view controller for your own needs and have an NSURL property on that view controller for that purpose.
    // E.g.: NSURL *wallURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@/UserWall.aspx?id=%@&Uid=%@", YourDomainPrefix, rowDict[@"ID"], UniqueID]];
    UIViewController *rootVC = [[GHRootViewController alloc] initWithTitle:rowDict[@"Name"]
                                                           withRevealBlock:revealBlock];
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:rootVC];
    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self.revealController 
                                                                                 action:@selector(dragContentView:)];
    panGesture.cancelsTouchesInView = YES;
    [navController.navigationBar addGestureRecognizer:panGesture];
    self.revealController.contentViewController = navController;
}
mcodo commented 11 years ago

Hi and thanks again This seems to work, but when i press the cell in the seachresult it opens a viewcontroller but the slidemenu does not disappear. What do i have to do to make it disappear the same way as when pressing one of the menu items?

Regarding the URL in the initWithTitle I am using: I have a URL in the initWithTitle but that is just to pass an url along with the title. I placed another variable along with it:

gresrun commented 11 years ago

OK, I understand about the URL thing. FYI, it is good practice in Obj-C to have a name for the variable in the method name: initWithURL:withTitle:withRevealBlock: vs. initWithTitle::withRevealBlock:

As for the slide menu not disappearing, simply call [self.revealController toggleSidebar:NO duration:kGHRevealSidebarDefaultAnimationDuration]; at the end of your searchResult:selectedAtIndexPath: method.

PaddyDu commented 11 years ago

if [self.revealController toggleSidebar:NO duration:kGHRevealSidebarDefaultAnimationDuration]; was called, the rootVC's back button need to be clicked 2 times. I don't know why. It only happens in search model.

mcodo commented 11 years ago

To PaddyDU: Hi I have posted a question about this issue, but no answer yet. Have you found out how to hide the sidebarmenu when clicking on a search result? My full question is in issue no. #27

mcodo commented 11 years ago

Figured out the search issue. Se answer on issue no. #27

exister commented 11 years ago

Is there any solution for back button issue?