3

私はこれでまったく新しいです.....事前に申し訳ありません。10個のViewコントローラーを含むアプリをxCodeで作成しました。各Viewコントローラーには画像ビューと丸い長方形のボタンがあります。

ビューのボタンを押すと他の9つのビューのいずれかにセグエするように設定したいのですが、ロードされるビューはランダムである必要があります。

私がこれまでにしたこと:

-ストーリーボードに10個のビューコントローラを配置し、それぞれのクラスをシーン1〜10に設定しました

-scene1-10という名前のObjective-Cクラスを10個作成しました-ViewControllers(.hおよび.mファイル)

-私はこのファッションでそれらの間にセグエを作成しましたシーン1->シーン2->シーン3->シーン4->シーン5->シーン6->7シーン->シーン8->シーン9->シーン10->シーン1

-私は各セグエのクラスをsegue1-10に設定し、それらが行くシーンにちなんで名前を付けました(シーン1とシーン2の間のセグエはsegue2になります)

-すべての.hファイルを次のようにしました(シーン#はファイルによって異なります):

#import <UIKit/UIKit.h>

@interface scene1 : UIViewController

- (IBAction) randomButton;

@end

-すべての.mファイルを次のようにしました(シーン#はビューによって異なります)

#import "scene1.h"

@interface scene1 ()

@end

@implementation scene1

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}
- (IBAction) randomButton : (id) sender
{
    int i = arc4random() % 10;
    if(i == 1)
    {
        [self performSegueWithIdentifier: @"segue1" 
                                  sender: self];
    }
    else if(i == 2)
    {
        [self performSegueWithIdentifier: @"segue2" 
                              sender: self];
    }
    else if(i == 3)
    {
        [self performSegueWithIdentifier: @"segue3" 
                                  sender: self];
    }
    else if(i == 4)
    {
        [self performSegueWithIdentifier: @"segue4" 
                                  sender: self];
    }
    else if(i == 5)
    {
        [self performSegueWithIdentifier: @"segue5" 
                                  sender: self];
    }
    else if(i == 6)
    {
        [self performSegueWithIdentifier: @"segue6" 
                                  sender: self];
    }
    else if(i == 7)
    {
        [self performSegueWithIdentifier: @"segue7" 
                                  sender: self];
    }
    else if(i == 8)
    {
        [self performSegueWithIdentifier: @"segue8" 
                                  sender: self];
    }
    else if(i == 9)
    {
        [self performSegueWithIdentifier: @"segue9" 
                                  sender: self];
    }
    else
    {
        [self performSegueWithIdentifier: @"segue10" 
                                  sender: self];
    }
}
- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

@end

-各ViewControllerにリストされている受信アクション「randomButton」をViewControllerのボタンにリンクしました

何が起こるのですか:

各.mファイルの「@implementationscene1」行に「IncompleteImplementation」警告が表示されますが、アプリはビルドおよびロードされます。

ボタンを押すとロードされるとアプリがフリーズし、xCodeのデバッグウィンドウが次のようにポップアップ表示されます。

2012-05-05 07:11:11.789 randomTester[2448:f803] -[scene1 randomButton]: unrecognized                     selector sent to instance 0x686d370
2012-05-05 07:11:11.792 randomTester[2448:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[scene1 randomButton]: unrecognized selector sent to instance 0x686d370'
*** First throw call stack:
(0x13cc022 0x155dcd6 0x13cdcbd 0x1332ed0 0x1332cb2 0x13cde99 0x1914e 0x190e6 0xbfade 0xbffa7 0xbed8a 0x3e2cf 0x3e5e6 0x24dc4 0x18634 0x12b6ef5 0x13a0195 0x1304ff2 0x13038da 0x1302d84 0x1302c9b 0x12b57d8 0x12b588a 0x16626 0x1f5d 0x1ec5)
terminate called throwing an exception(lldb)

私はこれを完全に間違っている可能性があることに気づきました。私はあちこちを検索しましたが、必要なものを正確に見つけることができないため、同様のコードのビットをつなぎ合わせる必要がありました。

貴重な時間とご支援をありがとうございました!



アップデート

わかりました、ラウンド2:

皆さんは素晴らしいです。私がIBActionの宣言と実装でそれを行ったことに、私はまったく気づいていませんでした。これですべての実装エラーが修正されました。しかし、私には根本的な問題があるようです。

私の.hファイルは次のようになります。

#import <UIKit/UIKit.h>

@interface scene1 : UIViewController

- (IBAction) randomButton;

@end

私の.mハエは次のようになります:

#import "scene1.h"

@interface scene1 ()

@end

@implementation scene1

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)randomButton
{
    int i = arc4random() % 10 + 1;
    NSString *segueIdentifier = [NSString stringWithFormat:@"segue%d", i];
    [self performSegueWithIdentifier:segueIdentifier sender:self];

}- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

@end

実装エラーはなく、正常にビルドされますが、ボタンを押すとアプリがフリーズし、xCodeのデバッグウィンドウが次のようにポップアップ表示されます。

2012-05-05 13:00:09.236 randomTester[2699:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:     'Receiver (<scene1: 0x6868f90>) has no segue with identifier 'segue5''
*** First throw call stack:
(0x13cb022 0x155ccd6 0xdd61b 0x2592 0x13cce99 0x1814e 0x180e6 0xbeade 0xbefa7 0xbdd8a 0x3d2cf 0x3d5e6 0x23dc4 0x17634 0x12b5ef5     0x139f195 0x1303ff2 0x13028da 0x1301d84 0x1301c9b 0x12b47d8 0x12b488a 0x15626 0x224d 0x21b5)
terminate called throwing an exception(lldb) 

アプリがscene1ビューコントローラーを表示していて、「segue5」(新しいIBActionによって呼び出されたランダムなセグエ)が表示されていないことは明らかです。これは、上記の質問の最初の部分で説明したように、シーン2に移動するセグエが1つしかないため、シーン1ビューコントローラーにセグエ5がないためです。

これを修正するために、segue1-10のクラスを使用してscene1に10個のセグエを作成しました。セグエ2-10をシーン2-10にそれぞれ接続しました。私はランダムであり、したがってそれ自体を指しているので、ボタンがsegue1を呼び出すことができるのは論理的であるように思われます。シーン1からシーン1に移動するセグエを作成できなかったため、シーン2に2番目のセグエを作成し、それにsegue1のクラスを指定しました。

エラーはなく、アプリは読み込まれますが、ボタンを押すとアプリがフリーズし、デバッグ時に次のように表示されます。

2012-05-05 13:45:04.467 randomTester[2803:f803] -[scene1 randomButton:]: unrecognized selector sent to instance 0x68b3760
2012-05-05 13:45:04.479 randomTester[2803:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:     '-[scene1 randomButton:]: unrecognized selector sent to instance 0x68b3760'
*** First throw call stack:
(0x13cb022 0x155ccd6 0x13cccbd 0x1331ed0 0x1331cb2 0x13cce99 0x1814e 0x180e6 0xbeade 0xbefa7 0xbdd8a 0x3d2cf 0x3d5e6 0x23dc4     0x17634 0x12b5ef5 0x139f195 0x1303ff2 0x13028da 0x1301d84 0x1301c9b 0x12b47d8 0x12b488a 0x15626 0x224d 0x21b5)
terminate called throwing an exception(lldb) 

質問1: これを機能させるためにこれらのセグエをどのように設定する必要があるかについてのアイデアはありますか?

質問2:次の ことを行う方がよいでしょうか。

-それぞれ画像ビューとボタンを備えたscene1-10という名前の10個のビューコントローラを作成します

-各開始セグエのボタンをsceneRandomizerという名前の11番目のビューコントローラーに設定します(これらのセグエクラスは提供しません)

-シーンランダムライザーからシーン1〜10に戻る10個のセグエを接続します(クラスはセグエ1〜10になります)

-「sceneRandomizer」にコードを記述して
、リダイレクトのように1〜10のグループからランダムなセグエを自動的に開始します(どのように記述すればよいかわかりません。

理論的には、これにより、呼び出されたセグエが、それを呼び出したビューコントローラーに存在しなかった場合に発生した2番目のエラーが軽減されます。

この代替設定が機能する場合、あるセグエから別のセグエにそのような重大な遅延が発生しますか?




アップデート

それは今働いています

ついにこれが機能するようになりました。これは「ラウンドアバウト」の方法のようで、これを行うにははるかに効率的で受け入れられている方法があると確信していますが、これは私が行ったことです。

.hと.mのコードは前回の試行と同じですが、明確にするために繰り返します。

私の.hファイルは次のようになります。

#import <UIKit/UIKit.h>

@interface scene1 : UIViewController

- (IBAction) randomButton;

@end

私の.mファイルは次のようになります。

#import "scene1.h"

@interface scene1 ()

@end

@implementation scene1

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)randomButton
{
    int i = arc4random() % 10 + 1;
    NSString *segueIdentifier = [NSString stringWithFormat:@"segue%d", i];
    [self performSegueWithIdentifier:segueIdentifier sender:self];

}- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

@end

私が違うことをした:

今回は、11個のビューコントローラーをストーリーボードにドラッグしました。

  • 1つを「startPage」、他の名前を「scene1-10」と名付けました。

  • 1つの.hファイルと1つの.mファイル(上記のようにコード化)を作成し、StartPage.hと
    StartPage.mという名前を付けました。

  • ストーリーボード上の11個のビューすべてのクラスを1つのビューコントローラー(StartPage)に設定しました

  • 私は10のセグエを作りました。1つはStartPageから10のシーンのそれぞれに行きます。

  • シーン1から10のセグエを作成し、1つはシーン1から他の9つのシーンのそれぞれに移動し、それらにsegue2-10のクラス(彼らが行くシーンにちなんで名付けられました)を与えまし
    シーン1からシーン2に2番目のセグエを作成し、単にセグエ1のクラスを与えました。

  • 他の9つのシーンのそれぞれについて最後のステップを繰り返しました

これは機能します。エラーなしでビルドおよび実行されます。StartPageが最初に表示されます。ボタンを押すと、グループからランダムなビューが読み込まれ(シーン1-10)、結果のビューでボタンを押すと、グループから別のビューがランダムに読み込まれます。

この方法で行うことの欠点は、すべてのセグエをセットアップするのにかかる時間です。このストーリーボードには、11のビュー間の動きを制御する110のセグエがあります。.....それは私が二度と戻れない私の人生の1時間です。

私のような初心者の場合:

この方法を使用する場合は、セグエ識別子に名前を付けるときに非常に注意してください。シーン5のセグエをレイアウトしていて、誤って2つのセグエにsegue2という名前を付け、1つのセグエに名前を付けるのを忘れたとします。エンドユーザーがシーン5を使用していて、ランダムボタンがsegue3を呼び出すと、シーン5にはsegue3という名前のセグエがないため、アプリがクラッシュします。シーン5にいるときにたまたまsegue3を呼び出さない限り、すべてがうまく機能しているように見えるため、テスト中にこのようなエラーを見つけるのは非常に難しいため、これについてのみ言及します。

私が知らないこの方法を使用することの欠点を誰かが見つけた場合は、それを提起してください。そして、あなたがより良い方法を持っているなら、私はすべての耳です:)

4

3 に答える 3

2

エラーとコンパイラの警告は、randomButtonを実装すると言っても、実際には実装していないことを示しています。

実装しています

-(void)randomButton:(id)sender;これはと同じではありません-(void)randomButton;

2つの異なる署名。どちらかの側をもう一方の側に一致させると、うまくいくはずです。

于 2012-05-05T12:41:24.970 に答える
1

メソッドの宣言と実装はrandomButton同じシグニチャを持つ必要があります。したがって、.hファイルで次のように宣言する必要があります。

- (IBAction)randomButton:(id)sender;

または.m、次のようにファイル内で変更します。

- (IBAction)randomButton
{
    int i = arc4random() % 10;
    // ...
}

補足として、次の値を使用してセグエ識別子を生成することにより、コードを簡略化できますi

- (IBAction)randomButton
{
    int i = arc4random() % 10 + 1;
    NSString *segueIdentifier = [NSString stringWithFormat:@"segue%d", i];
    [self performSegueWithIdentifier:segueIdentifier sender:self];
}

また、生成された行をからにi値を生成するように変更したことに注意してください。元のコードはからまでの値を生成します。11009

于 2012-05-05T12:40:25.023 に答える
0

私は以前、単一の親からのモーダルviewControllersを使用してこのようなことをしていました。ボタンを押すと、parentViewにdismissModalViewControllerを指示し、次に親のviewWillAppearで、乱数とpushModalViewControllerを生成します。私はすべてxibsで行ったので、モーダルセグエを使用してどのように処理するかわかりません。あなたがそれを理解したら、私たちに知らせてください。

于 2012-05-06T22:07:52.980 に答える