草庐IT

ios - 制作具有静态和属性前缀的 UITextField

coder 2024-01-14 原文

我想制作一个UITextField,它有一个静态前缀,用户不能编辑或删除,同时也带有一个灯灰色字体颜色。

文本字段的可编辑部分应始终以黑色显示。

例子如下:

它本质上是用于输入用户名,并带有一个固定的前缀域。


我已经尝试过将 textFieldShouldCleartextField:shouldChangeCharactersInRange:replacementString: 委托(delegate)方法与 NSMutableAttributedString 一起使用,但还没有尝试过能够破解它:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSMutableAttributedString *text = [textField.attributedText mutableCopy];

    [text addAttribute:NSForegroundColorAttributeName value:[UIColor grayColor] range:NSMakeRange(0, 7)];

    if (textField.text.length > 7)
    {    
        [text addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(7, textField.attributedText.length - 7)];
    }
    [text addAttribute:NSFontAttributeName value:[UIFont gothamFontForSize:textField.font.pointSize andWeight:kGothamLight] range:NSMakeRange(0, textField.attributedText.length)];


    return range.location > 6;
}

- (BOOL)textFieldShouldClear:(UITextField *)textField
{
    NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:@"kombit\\"];
    [text addAttribute:NSForegroundColorAttributeName value:[UIColor grayColor] range:NSMakeRange(0, 7)];
    [text addAttribute:NSFontAttributeName value:[UIFont gothamFontForSize:textField.font.pointSize andWeight:kGothamLight] range:NSMakeRange(0, text.length)];
    textField.attributedText = text;

    [textField setSelectedTextRange:[textField textRangeFromPosition:[textField endOfDocument] toPosition:[textField endOfDocument]]];

    return NO;
}

我确定有人已经做过类似的事情。

最佳答案

下面的代码从您的永久文本中创建一个属性字符串,将其着色为灰色,并将其添加到文本字段中。然后在shouldChangeCharactersInRange:中进行范围比较,判断范围是否在“kombit\”应该占据的区域内,如果不在,则传递黑色着色属性回到文本字段。

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

编辑:

好吧,我没想到会这么痛苦,坦率地说,我不好意思发布这段代码,因为它真的很脏,但它确实比以前做得更好.

我最后做的是创建一个属性来引用 BOOL 来保存文本是否应该更新(以阻止递归)并将目标添加到文本字段的 UIControlEventEditingChanged 控制事件在发生编辑时获得回调。

然后,由于某种原因,执行此操作的常规方法似乎都在这里不起作用,我通过在调用 resignFirstResponder 之后直接调用 becomeFirstResponder 将“光标”移动到文本字段的末尾,令人惊讶的是,这非常有效。我尚未确定文本大小略有变化的问题,但这应该只是添加其他属性以匹配您想要的字体大小的问题

抱歉,我无法再帮助解决这个问题,这是一个非常奇怪的问题。我通常不愿意提出这个建议,但在花了这么多时间尝试做一些本应微不足道的事情之后,我开始认为 NSAttributedString 中存在一些问题。不管怎样,如果这段代码最终能引导您找到答案,请告诉我,我会对解决方案非常感兴趣。

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

关于ios - 制作具有静态和属性前缀的 UITextField,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18333052/

有关ios - 制作具有静态和属性前缀的 UITextField的更多相关文章

  1. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  2. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  3. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  4. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  5. ruby - Nokogiri 剥离所有属性 - 2

    我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog

  6. ruby-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

  7. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  8. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  9. ruby-on-rails - Rails 3.1 中具有相同形式的多个模型? - 2

    我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#

  10. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

随机推荐