objective-c - 我怎样才能更改此代码以使其不违反 MVC 原则?

标签 objective-c ios model-view-controller uiviewcontroller

我正在制作一个化学 react 测验应用程序。该应用程序向用户提出问题,然后用户在两个单独的文本字段中输入 react 物和产物。

我有一个数据类,其中包含所有可能的测验问题。然后,根据特定的参数,数据类从可能的问题池中选择一定数量的问题,并将它们打乱成一个数组,quizQuestions

我还有一个 View Controller ,quizController。对于每个问题,都会加载一个新的 quizController 实例。 vc 需要数据来知道显示哪个问题,正确答案是什么等等。

这是我在数据和 vc 之间进行通信的原始解决方案。

我创建了一个数据类的实例,data。 我为第一个问题创建了vc1,并将data设置为vc1的属性,并将其标记设置为1,以便加载来自数据的第一个问题。

用户回答完第一个问题后,我创建了一个新的view controller,vc2,在vc1的方法中,让tag比上一个vc的多1所以第二个问题加载,并将 datavc1 的属性传递给 vc2 的。

然后我重复其他问题。

但是,这不是很好的设计,我正在寻找更好的解决方案。我不认为我可以使用类方法,因为 data 应该包含一组随机问题。下面是数据类的代码。

// the data class as it is now, designed for instance methods

- (id)init {
self = [super init];
if (self) {

    //Questions of the same type belong to a "ROW" (Reaction of Week)
    //individual questions
    // Items in array: (1)Question, (2)Reactants, (3)Products, (4)Elements for keyboard

    NSArray *R1Q1 = [[NSArray alloc] initWithObjects:@"Methanol is burned completely in air", @"2CH₃OH(l) + 3O₂(g)", @"2CO₂(g) + 4H₂O", @"C,H,O", nil];
    NSArray *R1Q2 = [[NSArray alloc] initWithObjects:@"Ammonia is burned in excess oxygen gas", @"4NH₃(g) + 7H₂O(l)", @"4NO₂(g) + 6H₂O(l)", @"N,H,O", nil];
    NSArray *R1Q3 = [[NSArray alloc] initWithObjects:@"Hydrogen sulfide gas is burned in excess oxygen gas", @"2H₂S(g) + 3O₂(g)", @"CO₂(g) + 2SO₂(g)", @"H,S,O", nil];

    NSArray *R2Q1 = [[NSArray alloc] initWithObjects:@"Solid potassium is added to a flask of oxygen gas", @"K(s) + O₂(g)", @"KO₂(s)", @"K,O", nil];
    NSArray *R2Q2 = [[NSArray alloc] initWithObjects:@"Sodium metal is dropped into a flask of pure water", @"2Na(s) + H₂O(l)", @"2Na⁺(aq) + 2OH⁻(aq) + H₂(g)", @"Na,H,O", nil];
    NSArray *R2Q3 = [[NSArray alloc] initWithObjects:@"A piece of lithium is heated strongly in oxygen", @"4Li(s) + O₂(g)", @"2Li₂O(s)", @"Li,O", nil];

    NSArray *R3Q1 = [[NSArray alloc] initWithObjects:@"Solutions of potassium chloride and silver nitrate are mixed", @"Ag⁺(aq) + Cl⁻(aq)", @"AgCl(s)", @"K,Cl,Ag,N,O", nil];
    NSArray *R3Q2 = [[NSArray alloc] initWithObjects:@"Solutions of iron(III) nitrate and sodium hydroxide are mixed", @"Fe³⁺(aq) + 3OH⁻(aq)", @"Fe(OH)₃(s)", @"Fe,N,O,Na,H", nil];
    NSArray *R3Q3 = [[NSArray alloc] initWithObjects:@"Solutions of nickel iodide and barium hydroxide are mixed", @"Ni²⁺(aq) + 2OH⁻(aq)", @"Ni(OH)₂(s)", @"Ni,I,Ba,OH", nil];
    // add rest

    //organize questions into groups
    row1 = [[NSArray alloc] initWithObjects:R1Q1, R1Q2, R1Q3, nil];
    row2 = [[NSArray alloc] initWithObjects:R2Q1, R2Q2, R2Q3, nil];
    row3 = [[NSArray alloc] initWithObjects:R3Q1, R3Q2, R3Q3, nil];
    //add rest

    // array containing all questions
    allRows = [[NSMutableArray alloc] initWithObjects:row1, row2, row3, nil];

    //in a real situation, needs to be given to class dynamically 
    self.maxRowNumber = 3;
    self.questionsPerRow = 2;
}

return self;
}

- (void)selectQuestions {

self.quizQuestions = [[NSMutableArray alloc] init];

for (int j = 0; j<self.maxRowNumber; j++) {
   //shuffle each row
    NSMutableArray *row = [NSMutableArray arrayWithArray:[allRows objectAtIndex:j]];
    [row shuffle];

    //add questions from each row
    for (int k = 0; k<self.questionsPerRow; k++)       
       [quizQuestions addObject:[row objectAtIndex:k]];

}

[quizQuestions shuffle];

}

查看 Controller 代码摘录

    # pragma mark Cell Setup
    //1st cell in tableview
    - (void) setUpEquationCell: (UITableView *) tableView  {

    equationCell = (EquationCell *) [tableView dequeueReusableCellWithIdentifier:@"equationCell"];

    if (equationCell == nil) {   
        NSArray *nib =   [[NSBundle mainBundle] loadNibNamed:@"EquationCell" owner:self options:nil];
        equationCell = (EquationCell*) [nib objectAtIndex:0];
        [equationCell.leftButton addTarget:self action:@selector(addDissociateCell) forControlEvents:UIControlEventTouchUpInside];
        [equationCell.rightButton addTarget:self action:@selector(addBalanceCell) forControlEvents:UIControlEventTouchUpInside];
    }

}

    - (void) setUpBalanceCell: (UITableView *) tableView  {
            //2nd cell in tableview

    balanceCell = (BalanceCell *) [tableView dequeueReusableCellWithIdentifier:@"balanceCell"];

    if (balanceCell == nil) {   
        NSArray *nib =   [[NSBundle mainBundle] loadNibNamed:@"BalanceCell" owner:self options:nil];
        balanceCell = (BalanceCell*) [nib objectAtIndex:0];

        // stores data from equation cell into model
        for (FormulaLabel *label in equationCell.leftView.equationOrder) 
            [leftData.equation addObject:label.text];                                                 

        for (FormulaLabel *label in equationCell.rightView.equationOrder)  
            [rightData.equation addObject:label.text];

        [leftData setUpBalancedEquation];
        [rightData setUpBalancedEquation];
        [self setUpView:balanceCell.leftView fromArray:leftData.equation toArray:leftBalanceItems];
        [self setUpView:balanceCell.rightView fromArray:rightData.equation toArray:rightBalanceItems];
        [self addBalanceTapMethodInArray:leftBalanceItems Data:leftData];
        [self addBalanceTapMethodInArray:rightBalanceItems Data:rightData];
    }

}
    - (void) setUpDissociateCell: (UITableView *) tableView  {
    dissCell = (DissociateCell *) [tableView dequeueReusableCellWithIdentifier:@"dissCell"];

    if (dissCell == nil) {   
        NSArray *nib =   [[NSBundle mainBundle] loadNibNamed:@"DissociateCell" owner:self options:nil];
        dissCell = (DissociateCell*) [nib objectAtIndex:0];

        leftData.disEquation = [[NSMutableArray alloc] init];
        rightData.disEquation = [[NSMutableArray alloc] init];

        // stores data from equation cell into model
        for (FormulaLabel *label in equationCell.leftView.equationOrder) 
            [leftData.disEquation addObject:label.text];                                                 

        for (FormulaLabel *label in equationCell.rightView.equationOrder)  
            [rightData.disEquation addObject:label.text];

        [self setUpView:dissCell.leftView fromArray:leftData.disEquation toArray:leftDisItems];
        [self setUpView:dissCell.rightView fromArray:rightData.disEquation toArray:rightDisItems];
        [self addDissTapToArray:leftDisItems fromData:leftData inView:dissCell.leftView];
        [self addDissTapToArray:rightDisItems fromData:rightData inView:dissCell.rightView];
        [dissCell.dissociateButton addTarget:self action:@selector(dissociate) forControlEvents:UIControlEventTouchUpInside];
        }
    [dissCell.rightButton addTarget:self action:@selector(addBalanceCell) forControlEvents:UIControlEventTouchUpInside];

}




    - (void)addDissociateCell {

    [cellOrder addObject:@"dissociateCell"];
    [table reloadData];
    NSIndexPath *myIndexPath = [NSIndexPath indexPathForRow:0 inSection:([cellOrder count]-1)];
    [table scrollToRowAtIndexPath:myIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
}


- (void) addDissTapToArray:(NSMutableArray*)viewOrder fromData:(EquationData*)data inView:(UIView*)view {

    NSString *leftOrRight;

    if (view == dissCell.leftView) 
        leftOrRight = @"left";    
    else 
        leftOrRight = @"right";

    for (int j=0; j < [viewOrder count]; j++) {


        if (j%2==0) {
            UIView *formulaView = [viewOrder objectAtIndex:j];
            //dissociate method
            FalseTarget *target = [[FalseTarget alloc] initWithVC:self leftOrRightView:leftOrRight];
            UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:target action:@selector(dissTap:)]; 
            [formulaView addGestureRecognizer:tap];

            // cancelling method
            FalseTarget *target2 = [[FalseTarget alloc] initWithVC:self Data:data ViewList:viewOrder view:view];
            UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:target2 action:@selector(dissLongTap:)];
            [formulaView addGestureRecognizer:longPress];
                  }

    }
}
- (void)addCompoundToLabel:(UIGestureRecognizer *)recognizer leftOrRight:(NSString*)leftRight{
    if( [recognizer state] == UIGestureRecognizerStateEnded ) {
        FormulaLabel* label = (FormulaLabel*)[recognizer view];  
        dissIndex = label.tag;
        dissCell.unDissociated.text = label.text;
        currentDissCellView = leftRight;
    }
}

- (void)dissociate {

    EquationData *data;
    NSMutableArray *viewOrder;
    UIView *view;

    if ([currentDissCellView isEqualToString:@"left"]) {
        data = leftData;
        viewOrder = leftDisItems;
        view = dissCell.leftView;
    }

    else {
        data = rightData;
        viewOrder = rightDisItems;
        view = dissCell.rightView;
    }

    FormulaLabel *c1 = [dissCell.leftTextField.equationOrder objectAtIndex:0];
    FormulaLabel *c2 = [dissCell.rightTextField.equationOrder objectAtIndex:0];
    [data updateDisEquationAtIndex:dissIndex withCompound1:c1.text Compound2:c2.text];

    for (UIView *view in viewOrder) 
        [view removeFromSuperview];

    [viewOrder removeAllObjects];
    [self setUpView:view fromArray:data.disEquation toArray:viewOrder];
    [self addDissTapToArray:viewOrder fromData:data inView:view];

}

- (void) cancelIons:(id)sender fromData:(EquationData *)data inView:(UIView *)view withViewList:(NSMutableArray *)viewlist {
    if( [sender state] == UIGestureRecognizerStateEnded ) {

        FormulaLabel* label = (FormulaLabel*)[sender view];  
        int index = label.tag;
        [data.disEquation removeObjectAtIndex:index];

        for (UIView *formulaView in viewlist) 
            [formulaView removeFromSuperview];

        [viewlist removeAllObjects];
        [self setUpView:view fromArray:data.disEquation toArray:viewlist];
        [self addDissTapToArray:viewlist fromData:data inView:view];


    }
}

    - (void)addBalanceCell {

    [cellOrder addObject:@"balanceCell"];
    [table reloadData];
    NSIndexPath *myIndexPath = [NSIndexPath indexPathForRow:0 inSection:([cellOrder count]-1)];
    [table scrollToRowAtIndexPath:myIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];

    leftBalanceItems = [[NSMutableArray alloc] init];
    rightBalanceItems = [[NSMutableArray alloc] init];
}

    - (void) addBalanceTapMethodInArray:(NSMutableArray *)balanceItems Data:(EquationData *)data {

    FalseTarget *target = [[FalseTarget alloc] initWithVC:self Data:data ViewList:balanceItems view:nil];

    for (UIView *view in balanceItems) {
        UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:target action:@selector(tap:)];
        [view addGestureRecognizer:tap];
    }

}


    - (void)updateBalanceLabelofSender:(UIGestureRecognizer*)sender fromData:(EquationData *)data inArray:(NSMutableArray *)balanceItems {

    FormulaLabel* label = (FormulaLabel*)[sender view];
    int oldWidth = label.frame.size.width;
    label.text = [data updateBalancedatIndex:label.tag];
    [label sizeToFit];
    int newWidth = label.frame.size.width;
    int difference = newWidth - oldWidth;
    int labelIndex = label.tag * 2;

    for (int j = 0; j<[balanceItems count]; j++) {
        // adjusts coordinate of  all views to the right of tapped item

        if (j > labelIndex){
            UIView *item = [balanceItems objectAtIndex:j];
            item.frame = CGRectMake(item.frame.origin.x + difference, item.frame.origin.y, item.frame.size.width, item.frame.size.height);
        }
    }
}


    - (void)setUpView:(UIView *)view fromArray:(NSMutableArray *)equationData toArray:(NSMutableArray *)balanceItems {

    int labelCount = 0; //label #
    int startingPoint = 5; //x vaiue where first label starts

    for (NSString *equationText in equationData) {

        //add text
        FormulaLabel *tempLabel = [[FormulaLabel alloc] initWithFrame:CGRectMake(startingPoint, 2, 10, 22)];
        tempLabel.text = equationText;
        [tempLabel sizeToFit];
        [view addSubview:tempLabel];
        tempLabel.tag = labelCount;
        [balanceItems addObject:tempLabel];
        //set location of '+'
        startingPoint = tempLabel.frame.origin.x + tempLabel.frame.size.width + 3;

        if (labelCount != [equationData count]-1) { //not the last label

            UILabel *plus = [[[UILabel alloc] initWithFrame:CGRectMake(startingPoint, 5, 10, 10)]autorelease];
            plus.text = @"+";
            plus.font = [UIFont systemFontOfSize:13];
            [plus sizeToFit];
            [view addSubview:plus];
            startingPoint = plus.frame.origin.x + plus.frame.size.width + 3;
            [balanceItems addObject:plus];
        }

        labelCount ++;
        [tempLabel release];
    }

}

最佳答案

为什么不能使用一个带有问题属性的 View Controller 类,在其中重载属性的 setter 方法以将 UI 更新为新数据:

在 QuestionViewController.h 文件中:

@property (retain, nonatomic) Question* myQuestionData;

在 QuestionViewController.m 中

-(void) setMyQuestionData:(Question*)newData {
   [myQuestionData autorelease];
   myQuestionData = [newData retain];
   [self updateUIElements];
}

关于objective-c - 我怎样才能更改此代码以使其不违反 MVC 原则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11009457/

相关文章:

ios - Dropbox 委托(delegate)方法不是第一次调用

c# - 我可以显示标签并使用户无法与 DropDownList 交互吗?

objective-c - 这个 cast 的 swift 等价物是什么?

ios - 将 UIButton 添加到 UICollectionViewCell 时的奇怪行为

ios - 向 UIView 添加带宽度的边框在外面显示小背景

ios - 如何检测用户正在输入消息?

ios - 展示广告时 Facebook 受众网络崩溃

iphone - 重复动画不同次数

iphone - Cocoa Touch 中的 MVC : How do the view and the model interact?

c# - 将 asp.net 页面转换为 Word 文档