使用" objectAtindex"时如何增加索引对于数组中的字典

时间:2014-07-21 23:02:11

标签: ios objective-c arrays

所以我们有一个带有一系列字典的plist。 Array是allCategories,它目前有两个词典作为问题。每个字典都有一组字符串。目标是,当你按下按钮时,它将检查它是否正确,如果是这样,在allCategory数组中增加currentQuestion和setTitle以及新字典的图片。然而,这不起作用,我们不知道如何解决它。到目前为止,它认识到它是正确的问题,它应该改变它,但是没有显示任何东西。如果我们使currentQuestion = 1并删除currentQuestion ++,我们点击按钮就可以完美地运行。我们希望它根据它是否正确而增加。

 - (IBAction)showPic
{


    NSDictionary *picturesDictionary = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Property List" ofType:@"plist"]]; //sets the proper plist file

    allCategory = [picturesDictionary objectForKey:@"AllCategory"]; //Sets the array allCategory

    currentQuestion++; //There are currently 2 dictionaries acting as the questions.
    NSDictionary *QuestionNumber = [allCategory objectAtIndex:currentQuestion];    answerKey = [QuestionNumber objectForKey:@"correctAnswer"];
    correctAnswer = [QuestionNumber objectForKey:answerKey]; //the two lines above determine what the correct answer is based on the plist.

    if([self.buttonOutlet.currentTitle isEqualToString:correctAnswer]) //this is where the comparison is made.
    {

        NSLog(@"currentQuestion:%d", currentQuestion);
        //the button titles should change to the next dictionary in allCategory, however it wont change.
        self.Label.text = @"This is working";

    }
    else if(currentQuestion != 0){
        [self.buttonOutlet setTitle: [QuestionNumber objectForKey:@"A"] forState:UIControlStateNormal];
        [self.buttonTwo setTitle: [QuestionNumber objectForKey:@"B"] forState:UIControlStateNormal];
        [self.buttonThree setTitle: [QuestionNumber objectForKey:@"C"] forState:UIControlStateNormal];
        [self.buttonFour setTitle: [QuestionNumber objectForKey:@"D"] forState:UIControlStateNormal];

        UIImage *img = [UIImage imageNamed: [QuestionNumber objectForKey:@"fileName"]];
        [imageHolder setImage:img];
        self.Label.text = @"This is correct";



    }
    else {
        self.Label.text = @"This is not correct";
    }

}

这是plist

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"    "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
  <dict>
    <key>AllCategory</key>
    <array>
        <dict>
            <key>fileName</key>
            <string>gta.jpg</string>
            <key>A</key>
            <string>gta</string>
            <key>B</key>
            <string>COD</string>
            <key>C</key>
            <string>LOL</string>
            <key>D</key>
            <string>Watchdogs</string>
            <key>correctAnswer</key>
            <string>A</string>
        </dict>
        <dict>
            <key>fileName</key>
            <string>LOL.jpg</string>
            <key>A</key>
            <string>Watchdogs</string>
            <key>B</key>
            <string>La Noir</string>
            <key>C</key>
            <string>Dota 2</string>
            <key>D</key>
            <string>fifa</string>
            <key>correctAnswer</key>
            <string>D</string>
        </dict>
       </array>
     </dict>
    </plist>

2 个答案:

答案 0 :(得分:1)

您需要删除

int currentQuestion = 0;

并将其设置在IBAction之外的某处,否则每次按下该按钮时,它都会将currentQuestion重置为0.

为什么要为答案创建密钥

answerKey = [QuestionNumber objectForKey:@"correctAnswer"];
correctAnswer = [QuestionNumber objectForKey:answerKey];

你应该能够直接访问它

correctAnswer = [QuestionNumber objectForKey:@"correctAnswer"];

并摆脱answerKey

答案 1 :(得分:0)

这实际上归结为可变范围问题。 .h文件中定义的属性对于类中的所有方法是全局可见的,并且对于子类或使用您的类的任何外部类都是可见的。这些是可见的公共属性,以便将来可能重复使用您的方法的其他人可以将信息传递到您的方法中,而无需知道内部的功能。您还可以在.m文件的顶部有一个接口部分。这适用于类似.h文件在类中具有全局范围的方法,但是对于使用您的类的其他类,它们是不可见的。通过使用self,可以在方法中访问这两种类型的属性。字首。在方法内部定义的变量仅在该方法内可见,并且不需要self。字首。局部变量具有它们所处方法的寿命。每次重新输入方法时,都会创建该变量的新实例。

在您的情况下,currentQuestion被定义为方法内的局部变量。每次进入它时,都会创建变量并将其初始化为零。通过做meda所说的并将其移到你的方法之外,它是一个全局属性,可以通过你的类中的所有方法看到。在viewDidLoad中初始化它或在viewcontrollers生命中早期初始化的另一个方法时,将其设置为零一次,然后像在方法的if语句中那样递增它。

将它移到if语句的底部并没有真正帮助,因为你似乎没有在if语句中的任何地方引用它(除非我错过了一个),但将它移到底部确实如此消除if语句中显示事物的任何混淆。从这个角度来看,这很好。

试试这个:

#import "exViewController.h"

@interface exViewController ()
@property (nonatomic) NSInteger currentQuestion;
@property (weak, nonatomic) IBOutlet UILabel *Label;
@property (weak, nonatomic) IBOutlet UIImageView *imageHolder;
@property (weak, nonatomic) IBOutlet UIButton *buttonOutlet;
@property (weak, nonatomic) IBOutlet UIButton *buttonTwo;

@property (weak, nonatomic) IBOutlet UIButton *buttonThree;
@property (weak, nonatomic) IBOutlet UIButton *buttonFour;
@property (nonatomic,strong) NSDictionary *picturesDictionary;
@property (nonatomic,strong) NSArray *allCategory;
@property (nonatomic,strong) NSDictionary *QuestionNumber;

@end

@implementation exViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // we have to initialize the screen with the first question.
    // There isn't any reason to re-initialize these every time you pick an answer do
    // do it up here in viewDidLoad
    self.picturesDictionary = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"PropertyList" ofType:@"plist"]]; //sets the proper plist file

    self.allCategory = [self.picturesDictionary objectForKey:@"AllCategory"]; //Sets the array allCategory


    // Initialize currentQuestion to 0
    self.currentQuestion=0;

    // I put the statements to display the question into another method so they wouldn't
    // have to be put in the code multiple times.  Makes it easier to maintain.
    [self displayQuestion:self.currentQuestion];
}

// display question takes one arguement, the value for currentQuestion  so it's going
// to display the question associated with whatever index is.
- (void) displayQuestion:(NSInteger) index
{
    // get questionNumber like you did before, but using index which we passed into this method.
    self.QuestionNumber = [self.allCategory objectAtIndex:index];
    self.picturesDictionary = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"PropertyList" ofType:@"plist"]]; //sets the proper plist file

    self.allCategory = [self.picturesDictionary objectForKey:@"AllCategory"]; //Sets the array allCategory

    [self.buttonOutlet setTitle: [self.QuestionNumber objectForKey:@"A"] forState:UIControlStateNormal];
    [self.buttonTwo setTitle: [self.QuestionNumber objectForKey:@"B"] forState:UIControlStateNormal];
    [self.buttonThree setTitle: [self.QuestionNumber objectForKey:@"C"] forState:UIControlStateNormal];
    [self.buttonFour setTitle: [self.QuestionNumber objectForKey:@"D"] forState:UIControlStateNormal];
    UIImage *img = [UIImage imageNamed: [self.QuestionNumber objectForKey:@"fileName"]];
    [self.imageHolder setImage:img];
}

//This was your old showPic method.  I added the sender parameter being sent to it.
// it points to the button that was clicked.
- (IBAction)showPicture:(UIButton *)sender
{
    NSDictionary *QuestionNumber = [self.allCategory objectAtIndex:self.currentQuestion];
    NSString *answerKey = [QuestionNumber objectForKey:@"correctAnswer"];
    NSString *correctAnswer = [QuestionNumber objectForKey:answerKey]; //the two lines above determine what the correct answer is based on the plist.
    NSLog(@"answerkey=%@",answerKey);
    NSLog(@"Correctanswer=%@",correctAnswer);
    NSLog(@"sender=%@",sender.description);

    //remember we are now passing in the address of the button that we clicked so we
    //can just checking sender(the button).titleLabel.text and see if it's equalto the correct answer.

    if(![sender.titleLabel.text isEqualToString:correctAnswer])
    {
        // wrong answer
        NSLog(@"currentQuestion:%d", self.currentQuestion);
        self.Label.text = @"Wrong Answer";
    }
    else {
        // right answer go to next question
        self.currentQuestion++;

        // make sure we don't go outside our bounds past the last question.
        if(self.currentQuestion<[self.allCategory count]) {
            self.Label.text = @"This is correct!! Next question";
            // call the method to display the question using the incremented currentQuestion.
            [self displayQuestion:self.currentQuestion];
        } else {
            self.Label.text = @"Correct answer end of test";
        }
    }
}
@end