iOS 仿学习强国填空答题

先上图看看这是不是你想要的


IMG_3943.PNG

本方法依赖 yytext Masonry 需要pod引入
pod 'Masonry'
pod 'YYText'
我们后台给的数据格式是 ##### “这是第一个填空{2},这是第三个填空{3}这个填空比较多{7}数据库来啦”。其中 {2}表示有两个空格要填 ,{3}表示有三个空格要填
首先定义一个YYLabel,用于显示答题的题目,并且后续会包含填空的空格

self.contentLabel = [[YYLabel alloc] initWithFrame:CGRectMake(10, 80, CZTVSCREEN_WIDTH - 10*2, 50)];
    self.contentLabel.numberOfLines = 0;
    [self.view addSubview:self.contentLabel];
    [self.contentLabel mas_updateConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(@40);
        make.left.equalTo(@10);
        make.right.mas_equalTo(self.view).offset(-10);
        make.bottom.equalTo(self.view).offset(-200);
    }];

其次,我们通过正则匹配的每一个{x},然后计算出需要的总填空组数和每一组的填空的空格数'

#pragma 特定字符串替换为UIButton
-(void)replaceStrWithImageAllString:(NSString *)titleString {
    self.allGroupArr = [NSMutableArray arrayWithCapacity:0];
    NSMutableAttributedString *alertAttributedString = [[NSMutableAttributedString alloc] initWithString:titleString];
    NSString *regexStr =@"\\{[a-zA-Z0-9\\/\\u4e00-\\u9fa5]+\\}";//正则匹配,获取{X},表示数字
    NSError *error =nil;
    NSRegularExpression *re = [NSRegularExpression regularExpressionWithPattern:regexStr options:NSRegularExpressionCaseInsensitive error:&error];
    if(!re) { //没有匹配到{x}
        return;
    }
    
    // 正则匹配后的数组
    NSArray *resultArray = [re matchesInString:titleString options:0 range:NSMakeRange(0, titleString.length)];
    NSInteger i = 0; //
    //根据匹配范围来用UITextField进行相应的替换
    for(NSTextCheckingResult *match in resultArray) {
        //获取数组元素中得到range
        NSRange range = [match range];
        //获取原字符串中对应的值
        NSString *subStr = [titleString substringWithRange:range];  //匹配到的{x} x表示数字
//        NSLog(@" 获取原字符串中对应的值 ===  %@",subStr);
        NSDictionary *rangDic = [self getRangeStr:[alertAttributedString string] findText:subStr];
        if (rangDic) {
            NSInteger subLocation = [[rangDic objectForKey:@"location"] integerValue]; //初始位置
            NSInteger lengthNum = [[rangDic objectForKey:@"length"] integerValue];//需要替换的长度
            NSInteger orignLengthNum = [[rangDic objectForKey:@"orignLength"] integerValue]; //原始的长度
            NSMutableAttributedString *tempStr = [[NSMutableAttributedString alloc] init];
            NSMutableArray *tempGroupArray = [NSMutableArray arrayWithCapacity:0];
            for (NSInteger j = 0; j < lengthNum ; j++) {
                
                UIButton *spaceBtn = [UIButton buttonWithType:UIButtonTypeCustom];
                spaceBtn.frame = CGRectMake(5, 0, 27, 27);
                spaceBtn.tag = j + 100 + i * 100;
                spaceBtn.layer.borderColor = [UIColor colorWithRed:235/255.0 green:235/255.0 blue:235/255.0 alpha:1].CGColor;
                spaceBtn.titleLabel.textAlignment = NSTextAlignmentCenter;
                spaceBtn.backgroundColor = [UIColor colorWithRed:243/255.0 green:244/255.0 blue:246/255.0 alpha:1];
                [spaceBtn setTitleColor:[UIColor colorWithRed:78/255.0 green:200/255.0 blue:109/255.0 alpha:1] forState:UIControlStateNormal];
                [spaceBtn addTarget:self action:@selector(spaceBtnAction:) forControlEvents:UIControlEventTouchUpInside];
                [tempGroupArray  addObject:spaceBtn];
                
                NSMutableAttributedString *imageText = [NSMutableAttributedString yy_attachmentStringWithContent:spaceBtn contentMode:UIViewContentModeScaleAspectFit attachmentSize:CGSizeMake(37, 27) alignToFont:[UIFont systemFontOfSize:16] alignment:YYTextVerticalAlignmentCenter]; // 图片转化为特殊字符
                [tempStr appendAttributedString:imageText];
            }
            [self.allGroupArr addObject:tempGroupArray];
            [alertAttributedString replaceCharactersInRange:NSMakeRange(subLocation , orignLengthNum) withAttributedString:tempStr];
        }
        i +=1;
    }

    NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc] init];
    paraStyle.lineSpacing = 8; //设置行间距
    [alertAttributedString addAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16],
                                           NSForegroundColorAttributeName:[UIColor blackColor],
                                           NSParagraphStyleAttributeName:paraStyle
                                         } range:NSMakeRange(0, alertAttributedString.length)];
    self.contentLabel.attributedText = alertAttributedString;
    
}
#pragma mark - 查找子字符串在父字符串的所有位置,需要的空格数量
- (NSDictionary *)getRangeStr:(NSString *)text findText:(NSString *)findText {
    if (findText == nil && [findText isEqualToString:@""]) {
        return nil;
    }
    NSString *tempfindText = [findText stringByReplacingOccurrencesOfString:@"{" withString:@""];
    tempfindText = [tempfindText stringByReplacingOccurrencesOfString:@"}" withString:@""];
    NSInteger lengthNumber = [tempfindText integerValue];
    NSRange rang = [text rangeOfString:findText]; //获取第一次出现的range
    if (rang.location != NSNotFound && rang.length != 0) {
        NSDictionary *rangDic  = @{@"location":@(rang.location), @"length":@(lengthNumber), @"orignLength":@(findText.length)};
        return rangDic;
    }
    return nil;
}
#pragma mark - 点击每个button
- (void)spaceBtnAction:(UIButton *)sender {
    // textField第一响应
    [_textField becomeFirstResponder];
//    NSLog(@" 当前选中按钮的tag值  === %ld", (long)sender.tag);
    _currentGroupTag = floor(sender.tag / 100) - 1;
//    NSLog(@" 向下取整后的分组tag值  === %ld", (long)_currentGroupTag);
    [self changeBtnUnselectedState];
    [self changeBtnSelectedState];
}

// 改变选中分组内按钮的未选中状态
- (void)changeBtnUnselectedState {
    // 把其他的置spaceBtn为未选中状态
    for (NSInteger i = 0 ; i < self.allGroupArr.count; i++ ) {
        if (i != _currentGroupTag) {
            NSMutableArray *unselectedGroupArray = [self.allGroupArr objectAtIndex:i];
            for (UIButton *unselectedBtn in unselectedGroupArray) {
                unselectedBtn.layer.borderWidth = 0;
            }
        }
    }
}

以上只是纯展示,重点来了,为了让我们能够编辑每个图片,我是使用了一个textField放在了顶部(后期你们使用的时候,可以把textField背景色,光标,等等设置为透明就行了)
然后我们通过创建多个参数,来设置并单独控制每组空格的输入

- (void)loadTextField {
    _textField = [[UITextField alloc] init];
    _textField.textColor = [UIColor blackColor];
    _textField.delegate = self;
    _textField.backgroundColor = UIColor.orangeColor;
    [self.view addSubview:_textField];
    [_textField mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(@50);
        make.left.equalTo(@20);
        make.right.mas_equalTo(self.view).offset(-20);
        make.height.equalTo(@40);
    }];
}
// 改变选中分组内按钮的选中状态
- (void)changeBtnSelectedState {
    // 拼接所选分组下,所有已填写内容
    _currentGroupWriteStr = @"";
    // 当前选中的btn所在分组数组
    NSMutableArray *selectedGroupArray = [self.allGroupArr objectAtIndex:_currentGroupTag];
    // 赋值所选分组下的所有数量
    _currentSeleectedGroupNumber = selectedGroupArray.count;
    // 遍历改变按钮选中状态
    for (NSInteger i = 0; i < selectedGroupArray.count; i++) {
        UIButton *selectedBtn = [selectedGroupArray objectAtIndex:i];
        if (selectedBtn.currentTitle.length == 0) {
            selectedBtn.layer.borderWidth = 1;
            break;
        } else {
            _currentGroupWriteStr = [NSString stringWithFormat:@"%@%@",_currentGroupWriteStr,selectedBtn.currentTitle];
            if (i == selectedGroupArray.count - 1) { //最后一个
                selectedBtn.layer.borderWidth = 1;
            } else {
                selectedBtn.layer.borderWidth = 0;
            }
        }
    }
    _textField.text = _currentGroupWriteStr;
}
#pragma mark - UITextFieldDelegate
/**
 正在编辑的文字:textField.text
 将要改变的字符范围:range.length 输入时或直接点击文字选择栏现有文字时:0 编辑后确认时:非0
 将要替换成的字符串:string
 */
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
//    NSLog(@" 正在编辑的文字 =====  %@",textField.text);
//    NSLog(@" 将要改变的字符范围 =====  %ld",range.length);
//    NSLog(@" 将要替换成的字符串 =====  %@",string);
//    NSLog(@" 将要替换成的字符串的字符长度 =====  %ld",string.length);
    // string.length: 0-正在删除
    if (string.length == 0) { //正在删除
        if (_textField.text.length != 0 && _currentGroupWriteStr.length == _textField.text.length) { //删除字符串
            _currentGroupWriteStr = [_currentGroupWriteStr substringWithRange:NSMakeRange(0, _currentGroupWriteStr.length - 1)];
            //给btn赋值
            [self textFieldDeleteBtnTitle];
        }
        return YES;
    }
    if (range.length != 0) { //编辑后确认
        BOOL isChange = [self textFieldShouldChangeWithStr:string];
        return isChange;
    } else {
//        NSLog(@"输入的类型:%@",);
        unichar commitChar = [string characterAtIndex:0];
        if ((commitChar>10122)&&(commitChar<10131)) {
//            NSLog(@"这里是苹果输入法九宫格");
            //中文编辑过程的特殊字符➎ 此处代码不要删除
            // 2 10123 3 10124 4 10125 5 10126 610127 7 10128 8 10129 9 10130
        } else { //全键盘
//            NSLog(@"这里是苹果输入法全键盘");
            if ([[_textField.textInputMode primaryLanguage] isEqual:@"zh-Hans"]) { //中文
                if ([self isThirdPartyKeyboard]) { //第三方输入法
//                    NSLog(@"第三方输入法");
                    BOOL isChange = [self textFieldShouldChangeWithStr:string];
                    return isChange;
                } else { //苹果输入法不填充
//                    NSLog(@"苹果输入法");
                    return YES;
                }
            } else {
                BOOL isChange = [self textFieldShouldChangeWithStr:string];
                return isChange;
            }

        }
    }
    return YES;
}

#pragma mark -判断当前输入法是否你是非苹果输入法
- (BOOL)isThirdPartyKeyboard {
    UITextInputMode *currentInputMode = [[UIApplication sharedApplication] textInputMode];
    NSString *currentInputModeClass = NSStringFromClass([currentInputMode class]);
    if ([currentInputModeClass isEqualToString:@"UIKeyboardExtensionInputMode"]) {
        return YES;
    }
    return NO;
}
- (BOOL)textFieldShouldChangeWithStr:(NSString *)string {
    //当前编辑文字大于选中分组的数量
    //且大于已填写数量
    if ((_textField.text.length + string.length) > _currentSeleectedGroupNumber) {
        // 已填写 < 分组内的空格
        if (_currentGroupWriteStr.length < _currentSeleectedGroupNumber) {
            NSString *contentStr = [NSString stringWithFormat:@"%@%@",_currentGroupWriteStr,string];
            if (contentStr.length > _currentSeleectedGroupNumber) {
                _currentGroupWriteStr = [contentStr substringWithRange:NSMakeRange(0, _currentSeleectedGroupNumber)];
            } else {
                _currentGroupWriteStr = contentStr;
            }
            _textField.text = _currentGroupWriteStr;
            //给btn赋值
            [self textFieldChangeBtnTitle];
        }
        return NO;
    } else {
        _currentGroupWriteStr = [NSString stringWithFormat:@"%@%@",_currentGroupWriteStr,string];
        //给btn赋值
        [self textFieldChangeBtnTitle];
    }
    return YES;
}

// textField输入改变按钮状态
- (void)textFieldChangeBtnTitle {
    // 当前选中的btn所在分组数组
    NSMutableArray *selectedGroupArray = [self.allGroupArr objectAtIndex:_currentGroupTag];
    // 遍历改变按钮选中状态
    for (NSInteger i = 0; i < selectedGroupArray.count; i++) {
        UIButton *selectedBtn = [selectedGroupArray objectAtIndex:i];
        if (i < _currentGroupWriteStr.length) {
            NSString *titleStr = [_currentGroupWriteStr substringWithRange:NSMakeRange(i, 1)];
            [selectedBtn setTitle:titleStr forState:UIControlStateNormal];
            [selectedBtn setTitleColor:[UIColor colorWithRed:78/255.0 green:200/255.0 blue:109/255.0 alpha:1] forState:UIControlStateNormal];
        }
        if (selectedBtn.currentTitle.length == 0) {
            selectedBtn.layer.borderWidth = 1;
            break;
        } else {
            if (i == selectedGroupArray.count - 1) { //最后一个
                selectedBtn.layer.borderWidth = 1;
            } else {
                selectedBtn.layer.borderWidth = 0;
            }
        }
    }
}

// textField删除改变按钮状态
- (void)textFieldDeleteBtnTitle {
    // 当前选中的btn所在分组数组
    NSMutableArray *selectedGroupArray = [self.allGroupArr objectAtIndex:_currentGroupTag];
    // 遍历改变按钮选中状态
    for (NSInteger i = 0; i < selectedGroupArray.count; i++) {
        UIButton *selectedBtn = [selectedGroupArray objectAtIndex:i];
        if (i == _currentGroupWriteStr.length) {
            [selectedBtn setTitle:@"" forState:UIControlStateNormal];
            selectedBtn.layer.borderWidth = 1;
        } else {
            selectedBtn.layer.borderWidth = 0;
        }
    }
}

最后来个demo链接

你可能感兴趣的:(iOS 仿学习强国填空答题)