Alexandre
Alexandre

Reputation: 410

Display a popover view from dynamic prototype cells

I'm developing an Ipad app with a custom split view. In the master view I have a tableViewController. I add items in this one with an add button in the navigation bar. This button is linked (i work with storyboard) with a popover segue to an other tableViewController that contains a few cells to enter datas. A button “save” dismiss the popover view an add item in the list of the masterView. What I want to do next is link master view’s prototype cells to an other view to enable the user to edit the selected item. I want to link this view with a popover segue (just like with the add button) and there‘s where is the problème : I get an red issue from xcode : Couldn't compile connection: => anchorView => > .

This a sample of my code that works fine. I would like to do pretty the same when I tap on a cell for editing.

The masterSplitView table

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"assetCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    // Configure the cell...
    AssetModel *myAssetModel = [self.arrayAsset objectAtIndex:indexPath.row];
    cell.textLabel.text = myAssetModel.name;
   // cell.textLabel.text = @"test";

    return cell;

}

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

    if([segue.identifier isEqualToString:@"addAssetSegue"]){
        AddAssetTVC *addAssetTVC = segue.destinationViewController;
        addAssetTVC.delegate = self;

        UIStoryboardPopoverSegue* popoverSegue = (UIStoryboardPopoverSegue*)segue;
        [addAssetTVC setPopoverController:[popoverSegue popoverController]];

    }

}

- (void) theSaveButtonOnTheAddAssetTVCWasTapped:(AddAssetTVC *)controller{
    [controller.navigationController popViewControllerAnimated:YES];
    [self reloadCache];
    [self.tableView reloadData];
    [self viewDidLoad];
}

And the save method of the add view :

- (IBAction)save:(id)sender{
    [popoverController dismissPopoverAnimated:YES];
    NSLog(@"Telling the ADDASSET Delegate that Save was tapped on the AddAssetTVC");

    {...unrevelant coredata methods}

    [self.delegate theSaveButtonOnTheAddAssetTVCWasTapped:self];
}

Thanks you for reading,

Alexandre

Upvotes: 5

Views: 7403

Answers (3)

Santhosh
Santhosh

Reputation: 691

Based on @Rich's answer but with PopoverPresentationController and in Swift.

override func perform() {
    let svc = self.sourceViewController as! yourSourceViewController
    let pvc = self.destinationViewController as! yourPresentedViewController

    // Present the view controller using the popover style
    pvc.modalPresentationStyle = UIModalPresentationStyle.Popover
    svc.presentViewController(pvc, animated: true, completion: nil)

    // Get the popover presentation controller and configure it
    let cell = svc.tableView.cellForRowAtIndexPath(svc.tableView.indexPathForSelectedRow!)
    let presentationController = pvc.popoverPresentationController
    presentationController!.permittedArrowDirections = .Any
    presentationController!.sourceView = svc.tableView
    presentationController!.sourceRect = cell!.frame
}

Upvotes: 0

Rich
Rich

Reputation: 41

I had the same problem. Solved it by using a custom segue. In the class's prepare method:

  1. Grab the source view controller which is either a custom controller or a UITableViewController
  2. Grab the destination controller
  3. Create a UIPopoverController initialized with the destination controller
  4. Get the cell of the currently selected row
  5. Store the popover as a property on the destination controller (that way you can dismiss it and it will not be deallocated)
  6. Present the popover using the cell's frame as the CGRect
  7. Set the size of the popover because it will be max sized otherwise

Here's some sample code:

UITableViewController *tvc = (UITableViewController *)self.sourceViewController;
DetailsViewController *details = (DetailsViewController *)self.destinationViewController;    
UITableViewCell *cell = [tvc.tableView cellForRowAtIndexPath:[tvc.tableView indexPathForSelectedRow]];

UIPopoverController *pop = [[UIPopoverController alloc] initWithContentViewController:details];

details.popoverController = pop;

CGSize size = CGSizeMake(640, 460);
pop.popoverContentSize = size;


[pop presentPopoverFromRect:cell.frame
                     inView:tvc.tableView 
   permittedArrowDirections:UIPopoverArrowDirectionUp | UIPopoverArrowDirectionDown 
                   animated:YES];

Upvotes: 4

user589642
user589642

Reputation: 396

I have been able to do this with minimal coding. Try this:

  1. I added a button to my Toolbar or Nav Bar. This is a dummy button that will be the Anchor for your Popover. Disable the button (uncheck Enable). You use the same button for multiple tableviews. I use the Organizer icon image in the button to simulate drill down, or you can set a custom image or title for each in the didSelectRowAtIndex method before calling performSegueWithIdentifier... Explained later...
  2. Then connect the button to your Popover view. Obviously set the type to Popover
  3. Tap the Segue arrow and name the Segue, for this example: "SegToDetail".
  4. Now in the Master / Parent code with the tableview add the method, didSelectRowAtIndex... In that method you can set what the button looks. Most importantly you call: [self performSegueWithIdentifier:@"SegToDetail"... And thats it...
  5. Now you can pass any information in the prepareForSegue methods as in any segue transition.

Upvotes: 0

Related Questions