Make UITextField which has a static and attributed prefix

我是研究僧i 提交于 2019-12-01 00:46:01

The code below creates an attributed string out of your permanent text, colors it gray, and adds it to a textfield. Then in shouldChangeCharactersInRange: a range comparison is done to determine whether or not the range is within the area that should be occupied by "kombit\", and if it isn't, a black coloring attribute is passed back to the text field.

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.textField setDelegate:self];

    NSString *fixedString = @"kombit\\";
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:fixedString];

    [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor lightGrayColor] range:NSMakeRange(0, fixedString.length)];

    [self.textField setAttributedText:attributedString];
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSRange substringRange = [textField.text rangeOfString:@"kombit\\"];

    if (range.location >= substringRange.location && range.location < substringRange.location + substringRange.length) {
        return NO;
    }

    NSMutableAttributedString *attString = [textField.attributedText mutableCopy];

    [attString addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(substringRange.length, textField.text.length - substringRange.length)];

    [textField setAttributedText:attString];

    return YES;
}

EDIT:

Okay, this isn't something I would have ever expected to be this big of a pain, and frankly I'm embarrassed to post this code because it's really dirty, but it does seem to be doing the job better than before.

What I ended up doing was creating a property to reference a BOOL to hold whether or not the text should be updates (to block the recursion) and adding a target to the text field's UIControlEventEditingChanged control event to get a callback when editing occurred.

Then, because for some reason none of the normal ways of doing this seem to be working here, I'm moving the "cursor" to the end of the text field by placing a call to becomeFirstResponder directly after a call to resignFirstResponder, and surprisingly this is pretty much working. There is an issue with the text size changing slightly that I have yet to identify, but it should just be a matter of adding additional attributes to match the font size you want

Sorry I couldn't be any more help in solving this, it is quite the curious problem. And I usually hate to suggest this, but after spending so much time trying to do something that should be trivial I'm starting to think there's something buggy going on in NSAttributedString. Anyway, let me know if this code eventually leads you to the answer, I'd be really interested in the solution.

@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (nonatomic, assign) BOOL shouldUpdateAttributes;



- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.textField setDelegate:self];
    [self.textField setSpellCheckingType:UITextSpellCheckingTypeNo];
    [self setShouldUpdateAttributes:YES];


    NSString *fixedString = @"kombit\\ ";
    [self.textField setText:fixedString];

    [self.textField addTarget:self action:@selector(textFieldDidChangeText:) forControlEvents:UIControlEventEditingChanged];
    [self textFieldDidChangeText:self.textField];
}

- (void)textFieldDidChangeText:(UITextField *)sender
{
    if (self.shouldUpdateAttributes) {
        [self setShouldUpdateAttributes:NO];

        NSString *fixedString = @"kombit\\ ";

        NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:sender.text];

        [attributedString setAttributes:@{NSForegroundColorAttributeName: [UIColor lightGrayColor]} range:NSMakeRange(0, fixedString.length)];
        [attributedString setAttributes:@{NSForegroundColorAttributeName: [UIColor blackColor]} range:NSMakeRange(fixedString.length, sender.text.length - fixedString.length)];

        [sender setAttributedText:attributedString];
        [sender resignFirstResponder];
        [sender becomeFirstResponder];
    }
}


- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    [self setShouldUpdateAttributes:YES];
    NSString *fixedString = @"kombit\\";
    NSRange substringRange = [textField.text rangeOfString:fixedString];

    if (range.location >= substringRange.location && range.location < substringRange.location + substringRange.length) {
        return NO;
    }

    return YES;
}

Put simply UILabel (styled like you want) to the left of UITextField and set rect for UITextField's text.

http://alwawee.com/wordpress/2013/02/18/uitextfield-edge-insets/

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!