9

注釈付きの MKMapView (UIPopoverControllerDelegate でもあります) があります。この MapView には、MKTestMapView.hファイルで、@interface でUIPopoverController* popoverController定義された と@property (nonatomic, retain) UIPopoverController* popoverController;、セクションの外側で定義された があり@interfaceます。このコントローラーは@synthesizedMKTestMapView.mファイルにあり、- (void)deallocセクションで公開されています。この MapView の Annotations にはrightCalloutAccessoryView、次のものが定義されています。

- (void)mapView:(MKMapView *)mapView2 annotationView:(MKAnnotationView *)aview calloutAccessoryControlTapped:(UIControl *)control{

...

CGPoint leftTopPoint = [mapView2 convertCoordinate:aview.annotation.coordinate toPointToView:mapView2];

int boxDY=leftTopPoint.y;
int boxDX=leftTopPoint.x;
NSLog(@"\nDX:%d,DY:%d\n",boxDX,boxDY);

popoverController = [[UIPopoverController alloc] initWithContentViewController:controller];
popoverController.delegate = self;
CGSize maximumLabelSize = CGSizeMake(320.0f,600.0f);

popoverController.popoverContentSize = maximumLabelSize;

CGRect rect = CGRectMake(boxDX, boxDY, 320.0f, 600.0f);

[popoverController presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];


...

}

ここからが楽しい部分です。まず、 と を同じサイズにする必要があるかどうかわかりませmaximumLabelSizerect。私はpopovercontrollerが初めてなので、これを耳で演奏しています..

さて、ポップオーバーが表示されます。今それを却下します。mapView2 の任意の場所をクリックすると、ポップオーバーが消えます...しかし、ユーザーが何かを変更した場合は、ビューのボタンをクリックする必要があります。うーん!

ドキュメントは次のことを示しています。

プログラムでポップオーバーを閉じるには、ポップオーバー コントローラーの DismissPopoverAnimated: メソッドを呼び出します。

さて、ここに問題があります: popoverController がどのように機能するかの定義により、表示されたポップオーバーのビューをクリックする (ボタンをクリックする) ことになりますが、このポップオーバー ビューを起動dismissPopoverAnimated:したコントローラーのメソッドをトリガーする必要があります。 MKTestMapView.mファイル内。popoverController

さて、すべてのことを言いましたが、覚えておいて[popoverController release]ください。

- (void)dealloc {
 [popoverController release];
 [mapView release];
    [super dealloc];
}

だから、ボタンの中で次のことをするだけですか(面倒ですが、うまくいくかもしれません):

(私のポップオーバービューがTableViewであると仮定します)

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
MKTestMapView * mKTestMapView = [[MKTestMapView alloc] init];
[[mKTestMapView popoverController].dismissPopoverAnimated:YES];
}

ここに私の問題があります:上記のことを行うと、画面上にある既存のビューにreference(そのようなことがある場合)、つまりその popoverController の所有者であるビューが表示されるかどうかわかりません。それが同じくらい簡単であれば

[[[self parentView] popoverController].dismissPopoverAnimated:YES];

それも正しい構文ではないと思うので、私は自分自身を撃ちます!

これは簡単なはずですが、道に迷っています。(おそらく、私が学んでいるほど多くの iPad の違いに不満を感じているだけでしょう)。

誰かもっと説明できますか?

4

2 に答える 2

18

同じ問題がありました...ポップオーバーによって読み込まれたビューの上部にきちんとした「閉じる」ボタン(X)がありましたが、機能しませんでした。私のユニバーサルアプリでは、新しいビューとして表示されるため、コードはそのままです。

私が今やったことは、detailedPinView (ポップオーバーが読み込まれるビュー) に次を追加したことです。

detailedPinView.h ファイルで:

@interface detailedPinView : UIViewController {
    [...]   
    UIPopoverController *popover;
    [...]
}

-(void)setPopover:(UIPopoverController*)aPopover;

detailedPinView.m ファイルで:

- (void)setPopover:(UIPopoverController*)aPopover
{
    popover = aPopover;
}

X ボタンは IBAction を使用してビューを閉じます。

detailedPinView.m ファイルで:

-(IBAction)releaseDetailedView:(UIButton *)sender
{
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
    {
        if (popover != nil)
        {
            [popover dismissPopoverAnimated:YES];
        }
        else {
            NSLog(@"Nothing to dismiss");
        }
    }
    else{
        [self.parentViewController dismissModalViewControllerAnimated: YES];
    }
}

my map と popover ビューをロードするクラスに、次のコードを追加しました。

[...]
-(void)mapView:(MKMapView *)theMapView annotationView:(MKAnnotationView *)pin calloutAccessoryControlTapped:(UIControl *)control
{   
    UIViewController *detailController = [[detailedPinView alloc] initWithNibName:@"detailedPinView" 
                                                                           bundle:nil 
                                                                   annotationView:pin];

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
    {

        UIPopoverController* aPopover = [[UIPopoverController alloc] initWithContentViewController:detailController];
        [aPopover setDelegate:self];
        [aPopover setPopoverContentSize:CGSizeMake(320, 320) animated:YES];

        [detailController setPopover:aPopover];
        [detailController release];

        [mapView deselectAnnotation:pin.annotation animated:YES];

        self.popoverController = aPopover;

        [mapView setCenterCoordinate:pin.annotation.coordinate animated:YES];

        [self.popoverController presentPopoverFromRect:CGRectMake(382,498,0,0) inView:self.view  permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
    }
    else
    {
        [self presentModalViewController: detailController animated:YES];
    }


    [detailController release];
}
[...]

それがあなたが望んでいた答えだったかどうかはわかりませんが、それを行うには少し厄介な方法かもしれません...しかし、タイムスケジュールを与えることは魅力のように機能しました:)

于 2010-05-09T21:08:41.327 に答える
1

これが別の簡単な解決策です。

ポップオーバーを明確に非表示にするには、次の手順に従う必要があることがわかりました。

  1. ポップオーバーを閉じます。
  2. ポップオーバーによってロードされたビューを解放します。

iOS8 より前は、ほとんどの人が最初にポップオーバーによって読み込まれたビューを解放し、次にプログラムでポップオーバーを閉じていました。ただし、iOS8 では、手順を逆に実行します。

iOS8より前、ポップオーバーを閉じる私のコード

// creating a popover loading an image picker
picker = [[UIImagePickerController alloc] init];
...
pickerPopover = [[UIPopoverController alloc] initWithContentViewController:picker];
[pickerPopover presentPopoverFromRect:aFrame inView:aView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

// dismissing the popover
[picker.view removeFromSuperview]; // (1) release a view loaded by a popover
[picker release], picker = nil;

if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ) {
    [pickerPopover dismissPopoverAnimated:YES]; // (2) dismiss the popover
}

iOS8 では、破棄コードの部分を次のように変更する必要があります。

if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ) {
    [pickerPopover dismissPopoverAnimated:YES];  // (2) dismiss the popover first
}

[picker.view removeFromSuperview]; // (1) and then release the view loaded by the popover
[picker release], picker = nil;
于 2014-09-18T07:29:25.907 に答える