填写空白模型

时间:2011-10-27 07:05:15

标签: iphone objective-c ios uiwebview uitextview

我一直在试图为我的这个新应用找出正确的模型。这就是事情。我需要创建一个考试类型的应用程序。该应用程序将有一个“语法”部分,需要填写空白方法的段落。所以它看起来像这样。

    "Lorem ipsum dolor sit amet, _________________ , sed do eiusmod tempor 
     _______ ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud 
     exercitation ullamco _________________ ex ea commodo consequat. Duis aute 
     irure dolor in reprehenderit in voluptate velit esse _______ dolore eu fugiat nulla 
     pariatur. ____________ sint occaecat cupidatat non proident, sunt in culpa qui   
     officia deserunt mollit anim id est laborum."

现在,该段落来自服务器。我们将空白标记为{#},因此当我在应用上显示时,我会将其替换为“ _ __ _ ”w / c等同于uitextfield。问题是我不知道如何解决这个问题。我可以将所有内容放在uitextview中吗?我应该如何处理空白?我不认为我可以用uiwebview来做这件事因为我点击它们后我需要更新空白的内容。请帮忙。

3 个答案:

答案 0 :(得分:2)

我的要求也一样,但我用原生代码解决了这个问题,UILabel& UIView,所有这些都是通过循环中的实用完成的。请考虑以下文字。

很久以前_____有一个名叫达摩克里斯的人。他的一个朋友最终_____是一个小城市的统治者。达摩克利斯心想,'我的朋友____多么幸运。他____现在是统治者。他必须____美好的时光。

其中每项工作都被视为UILabel空格,视为UIView。正确的选项在有序列表中,如下所示。

(lldb) po self.card.questionDataModel.fillAnswers
<__NSArrayI 0x6000008798c0>(
lived,
became,
is,
is,
must be having
)

查看代码。

此方法为空格及其选项

呈现整个UI
    - (void)prepareUIForFillInBlankQuestionType {

    self.totalOptionCount = self.card.questionDataModel.fillAnswers.count;

    CGFloat leading = 8;
    CGFloat trailing = 8;

    if ([NSRUtilities isNilOREmptyString:self.card.questionDataModel.question] == NO) {

        NSAttributedString* titleAttributedString = [[ConstantTools sharedData] convertHTMLToString:self.card.questionDataModel.question];
        NSString* titleString = titleAttributedString.string;

        // Holds all blank UIView (empty spaces)
        NSMutableArray* blankViewContainerList = [NSMutableArray new];

        // Full string will be separate by spaces so that each work can for single instance of UILabel
        NSArray* blankSpaceSeperatedList = [titleString componentsSeparatedByString:@" "];

        CGFloat fillViewWidth = CGRectGetWidth(self.fillBlankContainerView.frame);

        CGFloat labelX = 8;
        CGFloat labelY = 8;
        CGFloat labelHeight = 25;

        NSInteger underscoreIndex = 0;
        for (NSString* text in blankSpaceSeperatedList) {

            CGFloat fillContainerWidth = (fillViewWidth - (trailing + leading));

            // inputs NSString instance, will return back its UILabel for all words in a sentence
            UILabel* textLabel = [self labelFromText:text];

            if ((labelX + textLabel.frame.size.width) < fillContainerWidth) {

                if ([text containsString:@"__"]) {

                    CGFloat answerWidth = CGRectGetWidth(self.fillBlankContainerView.frame) *  FILL_FRAME_RATIO; // 0.4

                    UIView* blankView = [[UIView alloc] initWithFrame:CGRectMake(labelX,
                                                                                 labelY,
                                                                                 answerWidth,
                                                                                 labelHeight)];

                    CALayer* bottomLayer = [CALayer layer];
                    [bottomLayer setFrame:CGRectMake(0, labelHeight - 1, CGRectGetWidth(blankView.frame), 1)];
                    [bottomLayer setBackgroundColor:[UIColor whiteColor].CGColor];
                    [blankView.layer addSublayer:bottomLayer];

                    [blankView setTag:(600 + underscoreIndex)];
                    underscoreIndex++;

                    if (labelX + CGRectGetWidth(blankView.frame) >= fillContainerWidth) {
                        labelX = leading;
                        labelY += labelHeight;
                        [blankView setFrame:CGRectMake(labelX, labelY, answerWidth, labelHeight)];
                    }
                    [self.fillBlankContainerView addSubview:blankView];

                    [blankViewContainerList addObject:blankView];

                    labelX += answerWidth;
                }
                else {
                    CGRect labelFrame = textLabel.frame;
                    labelFrame.origin.x = labelX;
                    labelFrame.origin.y = labelY;
                    [textLabel setFrame:labelFrame];
                    [self.fillBlankContainerView addSubview:textLabel];

                    labelX += textLabel.frame.size.width;
                }

            }
            else{
                labelX = leading;
                labelY += labelHeight;

                if ([text containsString:@"__"]) {

                    CGFloat answerWidth = CGRectGetWidth(self.fillBlankContainerView.frame) *  FILL_FRAME_RATIO; 

                    UIView* blankView = [[UIView alloc] initWithFrame:CGRectMake(labelX,
                                                                                 labelY,
                                                                                 answerWidth,
                                                                                 labelHeight)];

                    CALayer* bottomLayer = [CALayer layer];
                    [bottomLayer setFrame:CGRectMake(0, labelHeight - 1, CGRectGetWidth(blankView.frame), 1)];
                    [bottomLayer setBackgroundColor:[UIColor whiteColor].CGColor];
                    [blankView.layer addSublayer:bottomLayer];

                    [blankView setTag:(600 + underscoreIndex)];
                    underscoreIndex++;

                    if (labelX + CGRectGetWidth(blankView.frame) >= fillContainerWidth) {
                        labelX = leading;
                        labelY += labelHeight;
                        [blankView setFrame:CGRectMake(labelX, labelY, answerWidth, labelHeight)];
                    }

                    [self.fillBlankContainerView addSubview:blankView];
                    [blankViewContainerList addObject:blankView];
                    labelX += answerWidth;

                }
                else {

                    CGRect labelFrame = textLabel.frame;
                    labelFrame.origin.x = labelX;
                    labelFrame.origin.y = labelY;
                    [textLabel setFrame:labelFrame];
                    [self.fillBlankContainerView addSubview:textLabel];

                    labelX += textLabel.frame.size.width;
                }
            }
        }

        self.blankViewContaninerList = blankViewContainerList;


        // It has all the options which will dragged on empty spaces
        NSMutableArray* optionList = [NSMutableArray new];

        if ([NSRUtilities isNilOREmptyString:self.card.questionDataModel.A] == NO) {
            NSAttributedString* attributedStringA = [[ConstantTools sharedData] convertHTMLToString:self.card.questionDataModel.A];
            NSString* optionA = [NSRUtilities trimNewlineCharacterFromString:attributedStringA.string];
            [optionList addObject:optionA];
        }


        if ([NSRUtilities isNilOREmptyString:self.card.questionDataModel.B] == NO) {
            NSAttributedString* attributedStringB = [[ConstantTools sharedData] convertHTMLToString:self.card.questionDataModel.B];
            NSString* optionB = [NSRUtilities trimNewlineCharacterFromString:attributedStringB.string];
            [optionList addObject:optionB];
        }


        if ([NSRUtilities isNilOREmptyString:self.card.questionDataModel.C] == NO) {
            NSAttributedString* attributedStringC = [[ConstantTools sharedData] convertHTMLToString:self.card.questionDataModel.C];
            NSString* optionC = [NSRUtilities trimNewlineCharacterFromString:attributedStringC.string];
            [optionList addObject:optionC];
        }


        if ([NSRUtilities isNilOREmptyString:self.card.questionDataModel.D] == NO) {
            NSAttributedString* attributedStringD = [[ConstantTools sharedData] convertHTMLToString:self.card.questionDataModel.D];
            NSString* optionD = [NSRUtilities trimNewlineCharacterFromString:attributedStringD.string];
            [optionList addObject:optionD];
        }


        if ([NSRUtilities isNilOREmptyString:self.card.questionDataModel.E] == NO) {
            NSAttributedString* attributedStringE = [[ConstantTools sharedData] convertHTMLToString:self.card.questionDataModel.E];
            NSString* optionE = [NSRUtilities trimNewlineCharacterFromString:attributedStringE.string];
            [optionList addObject:optionE];
        }

        CGFloat optionsYPoint = labelY + 50;

        for (NSInteger optionIndex = 0 ; optionIndex < optionList.count ; optionIndex++) {

            NSString* option = optionList[optionIndex];
            UILabel* optionLabel = [self optionLabelFromText:option index:optionIndex];

            if (optionIndex % 2 == 0) {
                // Fall out on left side

                CGFloat centerPoint = (CGRectGetWidth(self.fillBlankContainerView.frame) / 4);
                CGFloat optionsCenterPoint = (CGRectGetWidth(optionLabel.frame) / 2);

                CGFloat x = centerPoint - optionsCenterPoint;
                CGFloat y = optionsYPoint;
                CGFloat width = CGRectGetWidth(optionLabel.frame);
                CGFloat height = 25;

                [optionLabel setFrame:CGRectMake(x, y, width, height)];
                [self.fillBlankContainerView addSubview:optionLabel];

                // struct optionRect
                optionLabel.tag                     = optionIndex;
                optionRect[optionIndex].origin      = optionLabel.frame.origin;
                optionRect[optionIndex].size        = optionLabel.frame.size;
                optionRect[optionIndex].center      = optionLabel.center;

            }
            else {
                // Fall out on right side

                CGFloat centerPoint = CGRectGetWidth(self.fillBlankContainerView.frame) -(CGRectGetWidth(self.fillBlankContainerView.frame) / 4);
                CGFloat optionsCenterPoint = (CGRectGetWidth(optionLabel.frame) / 2);

                CGFloat x = centerPoint - optionsCenterPoint;
                CGFloat y = optionsYPoint;
                CGFloat width = CGRectGetWidth(optionLabel.frame);
                CGFloat height = 25;

                [optionLabel setFrame:CGRectMake(x, y, width, height)];
                [self.fillBlankContainerView addSubview:optionLabel];

                // struct optionRect
                optionLabel.tag                     = optionIndex;
                optionRect[optionIndex].origin      = optionLabel.frame.origin;
                optionRect[optionIndex].size        = optionLabel.frame.size;
                optionRect[optionIndex].center      = optionLabel.center;

                optionsYPoint += 40;
            }
        }      
    }
}

这些方法将准备UILabel out NSString

- (UILabel*)labelFromText:(NSString*)text {

    UIFont* boldFont = [UIFont boldSystemFontOfSize:15];
    NSAttributedString* labelString = [[NSAttributedString alloc ] initWithString:text
                                                                       attributes:@{NSFontAttributeName:boldFont}];

    CGRect cellRect = [labelString boundingRectWithSize:CGSizeMake(MAXFLOAT, 30)
                                                options:NSStringDrawingUsesLineFragmentOrigin context:nil];

    CGFloat width = cellRect.size.width + 10;

    UILabel* textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, 25)];
    [textLabel setText:text];
    [textLabel setTextColor:[UIColor whiteColor]];   
    return textLabel;
}

- (UILabel*)optionLabelFromText:(NSString*)text index:(NSInteger)index{

    UIFont* regularFont = [UIFont systemFontOfSize:14];
    CGFloat width = CGRectGetWidth(self.view.frame) * FILL_FRAME_RATIO; // 0.4;

    UILabel* optionLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, 25)];
    [optionLabel setText:text];
    [optionLabel setFont:regularFont];
    [optionLabel setTextColor:[UIColor whiteColor]];
    [optionLabel setTextAlignment:NSTextAlignmentCenter];
    [optionLabel setBackgroundColor:[UIColor lightTextColor]];

    [optionLabel.layer setBorderColor:[UIColor whiteColor].CGColor];
    [optionLabel.layer setBorderWidth:1.0];
    [optionLabel.layer setCornerRadius:2.0];
    [optionLabel.layer setMasksToBounds:YES];
    [optionLabel setUserInteractionEnabled:YES];

    UIPanGestureRecognizer* panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGestureForFillInBlank:)];
    [optionLabel addGestureRecognizer:panGesture];

    return optionLabel;
}

此方法将有助于拖拽和删除功能

    - (void)handlePanGestureForFillInBlank:(UIPanGestureRecognizer*)sender{

        __block BOOL isDragOnBlank = NO;

        NSInteger tag = sender.view.tag;
        OptionsFrame senderRect = optionRect[tag];

        if (sender.state == UIGestureRecognizerStateBegan) {

        }
        else if (sender.state == UIGestureRecognizerStateChanged) {
            CGPoint translation = [sender translationInView:sender.view];
            sender.view.center = CGPointMake(sender.view.center.x + translation.x, sender.view.center.y + translation.y);
            [sender setTranslation:CGPointZero inView:sender.view];
        }
        else if (sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateCancelled) {

            for (UIView* blankView in self.blankViewContaninerList) {
                if (CGRectIntersectsRect(sender.view.frame, blankView.frame) && blankView.tag != -999) {
                    __weak typeof(self) weakSelf = self;
                    UILabel* selectedLabel = (UILabel*)sender.view;

                    [self computeAnswerFromSelectedLabel:selectedLabel blankView:blankView onCompletion:^(BOOL isCorrectAnswer, NSString *selectedAnswer) {
                        if (isCorrectAnswer) {

                            [selectedLabel setUserInteractionEnabled:NO];

                            blankView.tag = -999;   // Indicates that blank view already contains one label (blank space is already filled)

                            [UIView animateWithDuration:0.25 animations:^{
                                [sender.view setCenter:blankView.center];
                            } completion:^(BOOL finished) {
                                if (weakSelf.correctAnswerCount == weakSelf.totalOptionCount) {
// Your custom logic goes here, after all option dragged on their respective places.
                                }
                            }];
                        }
                        else{
                            [UIView animateWithDuration:0.25 animations:^{
                                [sender.view setFrame:CGRectMake(senderRect.origin.x, senderRect.origin.y, senderRect.size.width, senderRect.size.height)];
                            }];
                        }
                        isDragOnBlank = YES;
                    }];
                }
            }
            if(!isDragOnBlank) {
                [UIView animateWithDuration:0.25 animations:^{
                    [sender.view setFrame:CGRectMake(senderRect.origin.x, senderRect.origin.y, senderRect.size.width, senderRect.size.height)];
                }];
            }
        }
    }

此方法将告诉您拖动的选项空格是正确还是错误

- (void)computeAnswerFromSelectedLabel:(UILabel*)selectedLabel
                             blankView:(UIView*)blankView
                          onCompletion:(void(^)(BOOL isCorrectAnswer, NSString* selectedAnswer))onCompletion {

    NSInteger tagIndex = (blankView.tag - 600);

    NSString* correctAnswer  = self.card.questionDataModel.fillAnswers[tagIndex];
    NSString* selectedAnswer = selectedLabel.text;

    if ([correctAnswer isEqualToString:selectedAnswer]) {

        self.correctAnswerCount++;

        if (onCompletion) {
            onCompletion(YES, selectedAnswer);
        }
    }
    else {
        self.wrongAnswerCount++;

        // Shake the container view if dragging is wrong.
        [self shakeView:self.fillBlankContainerView withOffest:8];
        if(onCompletion){
            onCompletion(NO, selectedAnswer);
        }        
    }
}

enter image description here

请随意使用代码&amp;欢迎改进:)

继续编码!

答案 1 :(得分:0)

您可以使用UIWebView。并且为了更新空白的内容,您可以在HTML页面内编写javascript并将其与空白的onselect事件绑定。

您可以查看我的回答iOS UIWebView Javascript - insert data -receive callbacks?

了解有关与webview进行通信的更多信息。 (即从Objective C执行javascript,反之亦然)


评论更新

是的,您可以从外部将字符串传递给Webview,

[webViewInstance stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"displayTheStringInBlank(%@)", stringValue]];

并编写一个JS函数是你的HTML文件来获取并在空白处显示字符串,

function displayTheStringInBlank(stringValue)
{
//Write code to use the string in the blank
document.getElementById("yourInputIdElement").value = stringValue;

}

答案 2 :(得分:0)

我有时会在NSMutableStrings中使用特殊标签作为替换字符串的占位符,然后根据需要使用代码替换它们......

if ([cStr rangeOfString:@"MYTAG"].location != NSNotFound)
    [cStr replaceCharactersInRange:[cStr rangeOfString:@"MYTAG"] withString:myNewString];

如果你需要任何好的格式,那么使用UIWebView就可以了。