Simplest for me was to subclass UITableViewCell and override the layoutSubviews.
Couldn’t find a reliable way to calculate the positions from just the label frames so just hardcoded the accessory width for in this case a UITableViewCellStyleValue1 cell with a UITableViewCellAccessoryDisclosureIndicator accessory type.
- (void)layoutSubviews
{
[super layoutSubviews];
CGFloat detailTextLabelWidth = [self.detailTextLabel.text sizeWithFont:self.detailTextLabel.font].width;
CGRect detailTextLabelFrame = self.detailTextLabel.frame;
if (detailTextLabelFrame.size.width <= detailTextLabelWidth && detailTextLabelWidth > 0) {
detailTextLabelFrame.size.width = detailTextLabelWidth;
CGFloat accessoryWidth = (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) ? 28.0f : 35.0f;
detailTextLabelFrame.origin.x = self.frame.size.width - accessoryWidth - detailTextLabelWidth;
self.detailTextLabel.frame = detailTextLabelFrame;
CGRect textLabelFrame = self.textLabel.frame;
textLabelFrame.size.width = detailTextLabelFrame.origin.x - textLabelFrame.origin.x;
self.textLabel.frame = textLabelFrame;
}
}