【问题标题】:Why is my delegation between two vc's not working?为什么我在两个 vc 之间的代表团不起作用?
【发布时间】:2012-11-08 00:58:52
【问题描述】:

我有两个视图控制器。我的第一个是我的菜单,其中包含我的高分和一个按钮,它对我的​​第二个视图控制器执行模态搜索,这是我的游戏。每当我的玩家击败他的高分而输掉游戏时,我希望它在菜单上更新。

现在,当我的玩家输掉游戏时,我创建了一个带有 2 个按钮的 UIAlertView,第一个是主菜单,第二个是重启。这是我尝试通过委托更新我的高分的简化代码。

        @protocol highScoreProtocol <NSObject>

        -(void)updateHighScore:(int) score;


        @end

        @interface ViewController : UIViewController <UIAlertViewDelegate> //i have this delegate implemented because i have a uiialertview
        @property (nonatomic) int score;
        @property (nonatomic, weak) id <highScoreProtocol> delegateHighScore;



        @implementation ViewController
        @synthesize score=_score;
        @synthesize delegateHighScore=_delegateHighScore;

            -(void)lostGame{
            [self.delegateHighScore updateHighScore:self.score]; //this is where i try to call the method that should update my high score if necessary but this doesn't actually work
        UIAlertView *losingScreen=[[UIAlertView alloc]initWithTitle:@"Game Over" message:[NSString stringWithFormat:@"Your Score Is %d", self.score] delegate:self cancelButtonTitle:@"Main Menu" otherButtonTitles:@"Restart", nil]; //once the user loses the game i have an alert view show giving the option to either restart the game or go to the main menu where the high score is
            }

        -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
              if (buttonIndex==0) {
                 //here i'm segueing back to my main menu because he would have pressed the 'main menu' button  [self performSegueWithIdentifier:@"MainMenu" sender:self];

            } else if (buttonIndex==1){
                //here i just reset my attributes and reset my level because he would have pressed the 'restart button'
            }
        }

    @end

            @interface MenuVC : UIViewController <highScoreProtocol>
            @property (weak, nonatomic) IBOutlet UILabel *labelHighScore; //the labelhighscore is the highscore number

            @end


@implementation MenuVC

- (void)viewDidLoad
{
    [super viewDidLoad];
    ViewController *vc=[[ViewController alloc]init];
    vc.delegateHighScore=self;//here is set the delegate as myself which i think i'm supposed to do for some reason

}

-(void)updateHighScore:(int)score{
    if (score>[self.labelHighScore.text integerValue]) { 
        self.labelHighScore.text=[NSString stringWithFormat:@"%d", score];
    }
    NSLog(@"does this method even run");

// this is the method that updates the highscore which I want to run
// but it doesn't, notice I even made an 'nslog' to see if the method
// even runs but I never ever even got a log out in the debugger,
// so this method never runs.
}

如果我只是需要一点帮助,或者如果我做的每件事都完全错误并且以错误的方式执行此任务,请说。

【问题讨论】:

  • vc 为零吗?我不知道该 init 方法是否正确创建了您的视图控制器。
  • 你如何从 MenuVC 呈现 ViewController,你能显示那个代码吗?
  • 我只有一个按钮,可以模态地连接到它

标签: iphone ios xcode delegates


【解决方案1】:

这不起作用,因为:

ViewController *vc=[[ViewController alloc]init];
vc.delegateHighScore=self;

实例化一个新的视图控制器,它与你正在与之交互的控制器完全无关。

我假设您正在使用情节提要,因此,为您的视图控制器创建一个标识符(在界面构建器上 -> 选择您的视图控制器 -> 身份检查器选项卡 -> 在上面写着情节提要 ID 的地方写一个名称)

然后添加这个而不是之前的代码:

ViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"yourIdentifier"];
vc.delegateHighScore = self;

编辑:

将此添加到您的按钮操作(但从界面构建器中删除 segue 并从 viewDidLoad 中删除此代码

ViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"yourIdentifier"];
vc.delegateHighScore = self;
[self presentModalViewController:vc animated:YES];

【讨论】:

  • 您在使用界面生成器对吗?添加 NSLog(@"%@",vc);在那些代码行之间,以确保它不是零。
  • 这意味着您分配了错误的代表。您的界面构建器标识符必须在 ViewController 窗口上设置,而不是在 MenuVC 窗口上
  • 你必须更具体。它不再运行了?您还必须错过解释错误。这可能就是您所看到的调用顺序。
  • 我刚刚注意到,您的委托可能正在被实例化然后被释放,因为您没有保留它。从按钮中删除模态转换(在界面构建器中)并为此按钮添加一个actino。按钮操作应与我提供的修改后的答案相同。
  • [self presentViewController:vc 动画:YES 完成:nil];当一个方法被弃用时,只需单击它,您就可以在右侧面板上看到它应该被替换的内容。顺便说一句,即使它已被弃用,大多数方法仍然有效。
【解决方案2】:

由于您在 viewDidLoad 方法中创建了一个局部变量 vc,这与您在创建模态 segue 的按钮方法中创建的变量不同。那不是设置委托的正确位置。使用您创建(或拥有)的任何引用,将您自己设置为该按钮方法中的委托,以访问您正在使用的 ViewController 实例。如果您需要更多信息或代码示例,请发布该按钮方法,以便我了解您的操作方式。

编辑后:然后你应该实现 prepareForSegue:sender: 并这样做:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    [(ViewController *)[segue destinationViewController] setDelegate:self];
}

【讨论】:

  • 我的菜单 vc 是第一个加载的 vc,在它上面我只有一个在情节提要上创建的开始按钮,我控制将按钮拖到我的游戏 vc 模态
猜你喜欢
  • 1970-01-01
  • 2015-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-04
  • 1970-01-01
  • 1970-01-01
  • 2014-01-23
相关资源
最近更新 更多