35

私は常にこの方法で tableView 内のセルからポップオーバーを表示しようとします:

[myPopover presentPopoverFromRect:cell.frame inView:self.tableView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

しかし、私は UIPopoverArrowDirectionRight または Left を使用できません。これは、iPad の位置 (縦または横) によっては、ポップオーバーが別の場所に表示されるためです。

ポップオーバーを正しい方法で表示していますか?

PS: テーブル ビューは、splitView の detailView にあります。

4

11 に答える 11

50

rectForRowAtIndexPath メソッドを使用して、セルからフレームを取得しています。正解です。ただし、テーブルビューは、より大きな iPad ビューのサブビューである可能性が最も高いため、ポップオーバーが座標を取得すると、より大きなビューにあると見なされます。これが、ポップオーバーが間違った場所に表示される理由です。

たとえば、行の CGRect は (0,40,320,44) です。テーブルビューのそのフレームを対象とするポップオーバーの代わりに、メイン ビューのそのフレームを対象とします。

フレームをテーブルの相対座標からより大きなビューの座標に変換することで、この問題を解決しました。

コード:

CGRect aFrame = [self.myDetailViewController.tableView rectForRowAtIndexPath:[NSIndexPath indexPathForRow:theRow inSection:1]];
[popoverController presentPopoverFromRect:[self.myDetailViewController.tableView convertRect:aFrame toView:self.view] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];

この問題を探している他の人に役立つことを願っています。

于 2010-12-22T19:31:41.123 に答える
22

今日この問題に遭遇し、より簡単な解決策を見つけました。
ポップオーバーをインスタンス化するときは、セルのコンテンツ ビューを指定する必要があります。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIViewController *aViewController = [[UIViewController alloc] init];
    // initialize view here

    UIPopoverController *popoverController = [[UIPopoverController alloc] 
        initWithContentViewController:aViewController];
    popoverController.popoverContentSize = CGSizeMake(320, 416);
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    [popoverController presentPopoverFromRect:cell.bounds inView:cell.contentView 
        permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

    [aView release];
    // release popover in 'popoverControllerDidDismissPopover:' method
}
于 2011-05-10T20:41:37.457 に答える
4

アクセサリーの横にポップオーバーをポップするには、このコードを使用できます:)

私はこれをより高度な用途に使用します:

  1. カスタム accesoryView (cell.accesoryView) を検索します
  2. 空の場合、セルにある場合、生成された accesoryView (UIButton) を見つけます
  3. UIButton が存在しない場合は、セル コンテンツ ビュー (UITableViewCellContentView) を見つけます。
  4. セル コンテンツ ビューが存在しない場合は、セル ビューを使用します。

UIActionSheetまたはUIPopoverControllerに使用できます。

これが私のコードです:

UIView *accessoryView       = cell.accessoryView; // finds custom accesoryView (cell.accesoryView)
if (accessoryView == nil) {
    UIView *cellContentView = nil;

    for (UIView *accView in [cell subviews]) {
        if ([accView isKindOfClass:[UIButton class]]) {
            accessoryView   = accView; // find generated accesoryView (UIButton) 
            break;
        } else if ([accView isKindOfClass:NSClassFromString(@"UITableViewCellContentView")]) {
            // find generated UITableViewCellContentView                
            cellContentView = accView; 
        }
    }
    // if the UIButton doesn't exists, find cell contet view (UITableViewCellContentView)           
    if (accessoryView == nil) { 
        accessoryView   = cellContentView; 
    }
    // if the cell contet view doesn't exists, use cell view
    if (accessoryView == nil) {
        accessoryView   = cell; 
    }
}

[actionSheet showFromRect:accessoryView.bounds inView:accessoryView animated:YES];

iOS 4.3 から 5.1 でテスト済み

カスタムメソッドとして使用するのが最適です:

-(UIView*)getViewForSheetAndPopUp:(UITableViewCell*)cell;

そしてメソッドコード:

-(UIView*)getViewForSheetAndPopUp:(UITableViewCell*)cell {
UIView *accessoryView = cell.accessoryView;

if (accessoryView == nil) {
    UIView *cellContentView = nil;

    for (UIView *accView in [cell subviews]) {
        if ([accView isKindOfClass:[UIButton class]]) {
            accessoryView = accView;
            break;
        } else if ([accView isKindOfClass:NSClassFromString(@"UITableViewCellContentView")]) {              
            cellContentView = accView;
        }
    }       

    if (accessoryView == nil) {
        accessoryView   = cellContentView;
    }
    if (accessoryView == nil) {
        accessoryView   = cell;
    }
}

return accessoryView;
}
于 2012-06-21T17:52:25.587 に答える
3

私もこの問題に遭遇しました。私にとっての解決策は、返される四角形の幅を単純に変更することでしたCGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath

CGRect rect = [aTableView rectForRowAtIndexPath:indexPath];

//create a 10 pixel width rect at the center of the cell

rect.origin.x = (rect.size.width - 10.0) / 2.0; 
rect.size.width = 10.0;  

[self.addExpensePopoverController presentPopoverFromRect:rect inView:aTableView permittedArrowDirections:UIPopoverArrowDirectionAny  animated:YES]; 

これにより、セル内の中央に四角形が作成されます。このようにして、ポップオーバーはそれ自体を配置するのに適した場所を見つける可能性が高くなります。

于 2010-11-15T15:48:32.607 に答える
2

私は同じ種類の問題を抱えていました、これが私が使用した回避策です:

  • UITableViewCellで、セルの特定のボタンにアクション(NIBからセルを生成するときのIBActions)を追加しました。
  • 次に、アクションセレクターを模倣するCellActionDelegateプロトコルを定義しました。これには、ボタン(送信者)とセル(自己)があります。
  • 次に、splitViewControllerのdetailViewControllerがこのプロトコルを実装し、セルの座標からその座標に変換します。

ここにコードの例

MyCustomTableViewCell.mの場合:

   -(IBAction)displaySomeCellRelativePopover:(id)sender{
        //passes the actions to its delegate
        UIButton *button = (UIButton *)sender;
        [cellActionDelegate displaySomeCellRelativePopoverWithInformation:self.info
                                                               fromButton:button 
                                                                 fromCell:self];   
   }

そして、MyDetailViewController.mで:

-(void)displaySomeCellRelativePopoverWithInformation:(MyCellInformationClass *)info
                                          fromButton:(UIButton *)button 
                                            fromCell:(UIView *)cell{

UIPopoverController * popoverController = nil;

//create your own UIPopoverController the way you want

//Convert your button/view frame

CGRect buttonFrameInDetailView = [self.view convertRect:button.frame fromView:cell];

//present the popoverController
[popoverController presentPopoverFromRect:buttonFrameInDetailView
                               inView:self.view permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];]


//release objects created...
}

PS:もちろん、「アクション」はIBActionである必要はなく、ポップオーバーが発生するフレームはUIButtonである必要はありません。単一のUIViewが適しています:)

于 2010-07-06T13:58:10.257 に答える
1

ここに私にとってうまくいく簡単な解決策があります

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    CGRect rect=CGRectMake(cell.bounds.origin.x+600, cell.bounds.origin.y+10, 50, 30);
    [popOverController presentPopoverFromRect:rect inView:cell permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

}
于 2011-12-07T13:23:24.487 に答える
1

受け入れられた回答は現在コンパイルできません。

CGRect rect =[tableView rectForRowAtIndexPath:indexPath]; //This is how to get the correct position on the tableView    
UIPopoverPresentationController *popController = [controller popoverPresentationController];
popController.sourceRect = rect;
popController.permittedArrowDirections = 0;  //Here there is no arrow. It is my app's need
popController.delegate = self;
popController.sourceView = self.tableView;
popController.sourceView.backgroundColor = [UIColor yellowColor];
于 2018-09-14T12:08:47.727 に答える
1

セル フレームは 0,0,width,size のようなものになります。tableView に対して相対的な X と Y を持つとは思えません...使用したい - (CGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath forこれ、これはtableViewに関連するセルの正しいフレームを返すはずです...ここにリンクがありますUITableView ref

于 2010-06-10T16:32:15.750 に答える
0

これは私がやった方法であり、完全に正常に動作します。

RidersVC *vc = [RidersVC ridersVC];
vc.modalPresentationStyle = UIModalPresentationPopover;
vc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
UIPopoverPresentationController *popPresenter = [vc popoverPresentationController];
popPresenter.sourceView = vc.view;
popPresenter.barButtonItem= [[UIBarButtonItem alloc] initWithCustomView:button];
popPresenter.backgroundColor = [UIColor colorWithRed:220.0f/255.0f green:227.0f/255.0f blue:237.0f/255.0f alpha:1.0];
[self.parentVC presentViewController:vc animated:YES completion:NULL];
于 2014-10-21T10:21:33.720 に答える