2

最初の ViewController を使用して、Single View Application としてプロジェクトを作成します。プロジェクトに subViewController を追加します。両方のビュー コントローラーに、パン ジェスチャを使用した UIImageView が追加されました。
それはviewController.mで動作しますが、それがsubViewControllerに追加され、サブビューがサブビューとしてView Controllerに追加されると、プログラムは「Exc_bad_access」でクラッシュするだけです..

誰にも解決策がありますか?

ここに私のコードがあります:

ViewController.m

#import "ViewController.h"
#import "SubViewController.h"

//#define SUB

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

#ifdef SUB
    SubViewController *sb = [[SubViewController alloc] init];
    [self.view addSubview:sb.view];
#else
    UIImageView* img_ = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"monkey_1.png"]];
    img_.userInteractionEnabled = YES;
    UIPanGestureRecognizer *stampPanGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
    [stampPanGesture setMinimumNumberOfTouches:1];
    [stampPanGesture setMaximumNumberOfTouches:1];
    [img_ addGestureRecognizer:stampPanGesture];
    img_.center = self.view.center;
    [self.view addSubview:img_];
#endif
}


- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
    CGPoint translation = [recognizer translationInView:self.view];
    recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
                                         recognizer.view.center.y + translation.y);
    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];

}

SubViewController.m

#import "SubViewController.h"
@interface SubViewController ()

@end

@implementation SubViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];


    UIImageView* img_ = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"monkey_1.png"]];
    img_.userInteractionEnabled = YES;
    UIPanGestureRecognizer *stampPanGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
    [stampPanGesture setMinimumNumberOfTouches:1];
    [stampPanGesture setMaximumNumberOfTouches:1];
    [img_ addGestureRecognizer:stampPanGesture];
    img_.center = self.view.center;
    [self.view addSubview:img_];
}


- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
    CGPoint translation = [recognizer translationInView:self.view];
    recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
                                         recognizer.view.center.y + translation.y);
    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];

}
4

1 に答える 1

2

これがARCコードであると仮定すると、問題は、サブビューのビューコントローラーを作成し、そのビューを取得しているのに、コントローラー自体がスコープから外れて割り当てが解除されることです。

差し迫った修正はSubViewController *sb、メインビューコントローラーのクラスのインスタンス変数を作成することです。そうすれば、スコープから外れたり、背後で割り当てが解除されたりすることはありません。

これでクラッシュはおそらく修正されますが、全体像の問題は、ビューコントローラのビューを取得してサブビューとして追加するのではなく、コントローラ自体では何もしないということです。これを行うと、たとえば、さまざまなことが正しく機能しない可能性があります(たとえば、回転イベントがサブビューに到達しない、iOSがビューコントローラーと通信する必要があるものがサブビューのコントローラーによって受信されない可能性があります。世界のdidReceiveMemoryWarning状況はそうするでしょう、など)。要するに、Appleはこれに反対するようアドバイスし、ビュー階層とビューコントローラ階層の同期を維持することをお勧めします。

したがって、新しいビューに移行する場合は、pushViewControllerまたはを介して移行する必要がありますpresentViewController。万が一、これが実際にサブビューである場合(たとえば、前のビューの一部が画面に残り、子ビューが画面の一部のみを占める)、ViewControllerContainmentを使用できます。封じ込めの詳細については、 WWDC2011セッション102を参照してください。しかし、それは間違いなくあなたがやろうとしていることに対してやり過ぎです。サブビューをプッシュ/提示することは、おそらく論理的な解決策です。

于 2012-07-07T07:13:42.573 に答える