ricky3350
ricky3350

Reputation: 1738

UITableViewCell accessoryView frame width/height zero

I am trying to show a UIPopoverController from a UITableViewCell accessoryView when the accessory is tapped. I use:

[self.popover presentPopoverFromRect:[[tableView cellForRowAtIndexPath:indexPath] accessoryView].frame inView:tableView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

But the problem: ...accessoryView].frame is {{0, 0}, {0, 0}}, so the popover shows at the top left of the screen. Why does this happen? How do I get the actual frame of the accessoryView?


I am using:

Please let me know if you need any more code to answer, and I will try to get it for you. Thanks in advance!

Upvotes: 4

Views: 4320

Answers (3)

Mone
Mone

Reputation: 46

it's because cell.accessoryView is null. cell.accessoryView only returns custom accessoryView.

Upvotes: 3

DenVog
DenVog

Reputation: 4286

I never got the frame or bounds for the accessoryView, but this combination ultimately allowed me to fake it and got what I needed. A position near the right of the row (i.e. accessoryButton that updates the popover location after rotate.

- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
   StackPropertiesTableViewController *stackPropertiesTableViewController = [[StackPropertiesTableViewController alloc] init];
   UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:stackPropertiesTableViewController];
   self.stackPropertiesPopoverController = [[UIPopoverController alloc] initWithContentViewController:navController];
   [self.stackPropertiesPopoverController setDelegate:self];
   TableViewCell *cell = (TableViewCell *)[tableView cellForRowAtIndexPath:indexPath];

    // Works for faking the display from Info accessoryView, but doesn't update it's location after rotate
    CGRect contentViewFrame = cell.contentView.frame;
    CGRect popRect = CGRectMake(contentViewFrame.origin.x + contentViewFrame.size.width, contentViewFrame.size.height/2.0, 1, 1);
    [self.stackPropertiesPopoverController presentPopoverFromRect:popRect inView:cell permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    // Need this so popover knows which row it's on after rotate willRepositionPopoverToRect
    [self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
}

This is needed to update the position of the popover relative to the row width after rotate. Don't forget to declare UIPopoverControllerDelegate

- (void)popoverController:(UIPopoverController *)popoverController willRepositionPopoverToRect:(inout CGRect *)rect inView:(inout UIView *__autoreleasing *)view
{        
   if (self.stackPropertiesPopoverController == popoverController)
   {
      NSIndexPath *itemPath = self.tableView.indexPathForSelectedRow;
      if (itemPath)
         {
           TableViewCell *cell = (TableViewCell *)[self.tableView cellForRowAtIndexPath:itemPath];
           if (cell)
              {
                 CGRect contentViewFrame = cell.contentView.frame;
                 CGRect popRect = CGRectMake(contentViewFrame.origin.x + contentViewFrame.size.width, contentViewFrame.size.height/2.0, 1, 1);
                 *rect = popRect;
               }
          }
    }
}

Upvotes: 0

Yariv Nissim
Yariv Nissim

Reputation: 13343

The frame of the accessoryView in within the UITableViewCell coordinate system. You need to convert it to the TableView coordinate system using a method on UIView: -convertRect:fromView:.

Call [tableView convertRect:accessoryView.frame fromView:cell] // Code not tested

Upvotes: 0

Related Questions