2

ポップアップ効果を取得しようとしていますが、別のビュー コントローラーでポップアップ ビューを設計して、xib を使用してそれを実行できるようにしたいと考えています。

presentViewController または pushViewController を使用して背景を透明に設定すると、ウィンドウの背景色が表示されます。

このコードを試して、サブビューをナビゲーションコントローラーのビューに追加して、情報ビューが画面全体を透明な背景でカバーできるようにしました。また、カバーするタブバーもあります。

InfoVC *vc = [[InfoVC alloc] initWithNibName:@"InfoVC" bundle:nil];
[self.navigationController.view addSubview:vc.view];

私の問題は、InfoVC を閉じようとすると、InfoVC 内にあり、EXC_BAD_ACCESS メッセージでアプリがクラッシュします。

[self.view removeFromSuperview];

編集:

クラッシュを止める方法を見つけましたが、InfoVC を MainVC のプロパティとして設定しました。クラッシュの理由は、InfoVC 内のアクションで「self.view」を呼び出したときに、self が MainVC 内の InfoVC であることを認識していないためだと思います。

4

4 に答える 4

2
InfoVC *vc = [[InfoVC alloc] initWithNibName:@"InfoVC" bundle:nil];
[self.navigationController.view addSubview:vc.view];

いやいやいやいや。決してそれをしないでください。

ビュー コントローラーのビューを別のビュー コントローラーのビュー内に配置する (または後で削除する) には、これを行うための組み込み機能が付属していない場合 (UISplitViewController の方法、またはナビゲーション コントローラーがビュー コントローラー内でプッシュおよびポップされるビュー コントローラーのビューを管理する方法)。

お客様のコンテナ コントローラについてお読みください。私の本の例の1つはここにあります:

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/ch19p556containerController/p476containerController/ViewController.m

于 2012-12-19T04:59:20.677 に答える
1

「モーダル」に表示されたビューコントローラが表示された後、現在表示されているビューコントローラの下のビューが削除されます。これによりメモリが節約され、レンダリングが容易になります。ただし、あなたの場合は、「モーダル」に表示されたビューの背後にウィンドウが表示されることにもなります。

自然で、一見論理的に見える次のステップは、あるビューコントローラのビューを取得し、それを別のビューコントローラに詰め込むことです。ただし、ご存知のとおり、これには問題があります。新しく挿入されたビューがビュー階層によって安全に保持されるため、安全ですが、新しいビューコントローラはそれほど幸運ではなく、すぐに割り当てが解除されます。したがって、この新しいビューがそのコントローラーに接続しようとすると、がEXC_BAD_ACCESS発生してクラッシュします。繰り返しになりますが、回避策の1つは、元のViewControllerに新しいViewControllerへの強力な参照を保持させることです。そして、これはうまくいく可能性があります...ひどく。を取得する可能性はまだ十分にありますUIViewControllerHierarchyInconsistencyException

もちろん、IBで作成した小さなビューを追加したいだけの場合は、ビューコントローラを「File's Owner」として使用する必要はありません。ファイルからビューのインスタンスを作成する例はたくさんありxibます。

ここでのより興味深い質問は、「アップルはそれをどのように/行うのか?」です。Appleは一貫して、ビューコントローラはカプセル化された作業単位の正しいコントローラであると言っています。たとえば、彼らTWTweetComposeViewController、あなたはそれを提示し、それは浮かんでいるようです。どのように?

私の頭に浮かぶこれを達成するための最初の方法は、明確ではない明確な背景を持つことです。つまり、提示されたビューコントローラが表示される前に画面の画像を作成し、それを提示されたビューが削除される前の背景として設定します。だから例えば(続く説明):

QuickSheetViewController.xib

ここに画像の説明を入力してください

QuickSheetViewController.h

#import <UIKit/UIKit.h>
@interface QuickSheetViewController : UIViewController
- (IBAction)dismissButtonPressed:(id)sender;
@end

QuickSheetViewController.m

#import "QuickSheetViewController.h"
#import <QuartzCore/QuartzCore.h>
@implementation QuickSheetViewController {
    UIImage *_backgroundImage;
}
-(void)renderAndSaveBackgroundImageFromVC:(UIViewController *)vc{
    UIGraphicsBeginImageContext(vc.view.bounds.size);
    [vc.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    _backgroundImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}
-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    // save an image of the current view, and set our background to clear so we can see the slide-in.
    [self renderAndSaveBackgroundImageFromVC:self.presentingViewController];
    self.view.backgroundColor = [UIColor clearColor];
}
-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    // Time to use our saved background image.
    self.view.backgroundColor = [UIColor colorWithPatternImage:_backgroundImage];
}
-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    // Set our background to clear so we can see the slide-out.
    self.view.backgroundColor = [UIColor clearColor];
}
- (IBAction)dismissButtonPressed:(id)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
@end

この例の大部分は、renderAndSaveBackgroundImageFromVC:メソッドに依存しています。ここでは、グラフィックスコンテキストを作成して、これからカバーしようとしているビューをレンダリングしてから、UIImage後で(でviewDidAppear)背景として使用するためのを作成します。

今、単にそれを次のように使用します:

QuickSheetViewController *newVC = [[QuickSheetViewController alloc] initWithNibName:nil bundle:nil];
[self presentViewController:newVC animated:YES completion:nil];

アニメーションが発生するのに十分な時間だけ背景が透けて見えるので、保存した画像を使用して、表示されているビューの削除を非表示にします。

于 2012-12-20T15:26:42.987 に答える
1

サブビューを削除することはできませんUIView。サブビュー自体をスーパービューから削除する必要があります。サブビューを簡単にループして、そのように削除することができます

for (UIView *view in vc.view.subviews) {
  [view removeFromSuperview];
}

参照用ドキュメント: http://developer.apple.com/library/ios/#documentation/uikit/reference/uiview_class/uiview/uiview.html

于 2012-12-19T04:51:52.690 に答える
1

スーパービューからビューを削除するために次を使用すべきではありませんか?

[vc.view removeFromSuperview];
于 2012-12-19T04:22:18.127 に答える