填空模型

发布于 2024-12-12 07:03:41 字数 802 浏览 0 评论 0原文

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

    "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 做到这一点,因为我需要在点击空白后更新它们的内容。请帮忙。

I've been trying to figure out the correct model for this new app of mine. Here's the thing. I need to create an exam type app. The app will have a "Grammar" section which requires a paragraph with fill in the blanks approach. So it will look like this.

    "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."

Now, the paragraph is coming from the server. We mark the blanks as {#} so when I display it on the app I will replace it with "____" w/c is equivalent to a uitextfield. The problem is I've no idea how to go about this. Can I put everything in a uitextview? how should I deal with the blanks? And I dont think I can do this with uiwebview coz I need the update the contents of the blanks once I tap on them. Please help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

和我恋爱吧 2024-12-19 07:03:41

我的要求也是一样的,但我用本机代码解决了它,使用 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 输出 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);
        }        
    }
}

在此处输入图像描述

请随意使用代码 &我们非常欢迎改进 :)

继续编码!

My requirement was also same, but I solved it in native code, with UILabel & UIView, all of it done through pragmatically within a loop. Consider the below text.

Once upon a time there _____  a man called Damocles. A friend of his eventually _____  the ruler of a small city. Damocles thought, ‘How lucky my friend ____. He ____  now a ruler. He must ____  a great time. 

In which each work is treated as UILabel empty spaces treated as UIView. The correct options are in ordered list as show below.

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

Check out code.

This methods renders entire UI for empty spaces and its options

    - (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;
            }
        }      
    }
}

These methods will prepare 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;
}

This Method will help in drag & drop functionality

    - (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)];
                }];
            }
        }
    }

This Method will tell you dragged option empty space is correct or wrong

- (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

Please feel free to use code & improvements are happily welcome :)

Keep coding!

○愚か者の日 2024-12-19 07:03:41

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

您可以看看我的答案 iOS UIWebView Javascript - 插入数据- 接收回调?

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


更新注释

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

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

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

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

}

You can use UIWebView. And for updating the contents of the blanks you can write javascript inside the HTML pages and bind it with onselect event of the blanks.

You can have a look at my answer iOS UIWebView Javascript - insert data -receive callbacks?

to know more about communicating with a webview. (i.e. executing javascript from Objective C and vice versa)


Update for the comment

Yes, you can pass a string to the webview from outside ,

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

and write a JS function is your HTML file to get and display the string in the blank,

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

}
风透绣罗衣 2024-12-19 07:03:41

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

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

如果您需要任何类型的良好格式,使用 UIWebView 将是最佳选择。

I sometimes use special tags in NSMutableStrings as placeholders for replacement strings, then replace them as needed with code like...

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

If you need any kind of nice formatting, using UIWebView would be the way to go.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文