UIPopover arrow not repositioned correctly on rotation

This bug was resolved in iOS 9.3.

This is one of those bug reports where a picture is worth a thousand words. The scenario is a basic collection view layout showing a grid of cells. Each cell contains a UILabel showing the cell row number for ease of reference:

Now suppose I want to show a popover view that is presented from one of the collection view cells. The code for that will be something like this:

[self.uylPopoverController presentPopoverFromRect:cell.frame
   inView:self.collectionView
   permittedArrowDirections:UIPopoverArrowDirectionAny
   animated:YES];

The appearance of the popover is shown below when it is presented from the cell at row 3:

This is fine until you rotate the device with the popover visible. By default the popover controller hides the popover and then shows it again when the rotation finishes. Unfortunately since my collection view layout repositions the cells the popover ends up pointing to the wrong cell. So for example here is the appearance with the device in portrait with the popover presented from cell 3:

Now if you rotate the device to landscape cell 3 moves to the top right hand corner and the popover ends up pointing to cell 4:

You can help the popover controller position the popover correctly by implementing the UIPopoverControllerDelegate method popoverController:willRepositionPopoverToRect:inView:. This method is new in iOS 7 and allows you to return a new position for the popover:

- (void)popoverController:(UIPopoverController *)popoverController willRepositionPopoverToRect:(inout CGRect *)rect inView:(inout UIView *__autoreleasing *)view
{
  if (self.uylPopoverController == popoverController)
  {
    NSArray *selectedItems = self.collectionView.indexPathsForSelectedItems;
    NSIndexPath *itemPath = (NSIndexPath *)[selectedItems lastObject];
    if (itemPath)
    {
      UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:itemPath];
      if (cell)
      {
        CGRect requiredRect = cell.frame;
        *rect = requiredRect;
      }
    }
  }
}

In this case I get the currently selected cell from the collection view controller and return the cell frame that at this point has already been moved into the new position. At first glance this seems to work if I happen to select the right cell. For example if I select cell 4:

On rotation the newly presented popover is correctly repositioned so that it still appears to have been presented from cell 4:

However if I select a cell where the relative position of the popover to the cell changes it does not work so well. For example, if I have a situation where the popover is presented from cell 3 in portrait mode it appears to the right of the cell with the arrow in the popover pointing to the left, back to cell 3:

When the device is rotated the popover is repositioned to follow the new position of cell 3. However since cell 3 is now much closer to the edge of the display the popover position relative to the cell must change. It is now presented to the left of cell 3 but the arrow which should be directed to the right where cell 3 is now positioned instead points to the left:

A close up screenshot of the popover makes the problem easier to see:

At time of writing I have not found a workaround for this problem. This bug was resolved iniOS 9.3. The original bug report was 14995477 (also on Open Radar at rdar://14995477). The orginal Xcode project to reproduce the problem is archived in my code repository. See Collection for further details.