【问题标题】:UITextfield leftView/rightView padding on iOS7iOS7 上的 UITextfield leftView/rightView 填充
【发布时间】:2013-10-22 15:43:20
【问题描述】:

iOS7 上 UITextField 的 leftView 和 rightView 视图非常接近文本框的边框。

如何为这些项目添加一些(水平)填充?

我尝试修改框架,但没有成功

uint padding = 10;//padding for iOS7
UIImageView * iconImageView = [[UIImageView alloc] initWithImage:iconImage];    
iconImageView.frame = CGRectMake(0 + padding, 0, 16, 16);
textField.leftView = iconImageView;

请注意,我对向文本字段的文本添加填充不感兴趣,例如 Set padding for UITextField with UITextBorderStyleNone

【问题讨论】:

  • 不,这是询问在文本字段中缩进显示为 leftView 的图像。不缩进文本本身。试试他的代码,你会看到将 leftView 设置为图像会将图像放在文本字段的左边缘,没有填充。看起来很丑。

标签: ios objective-c uitextfield


【解决方案1】:

也许您可以设置一个空视图并将您的视图嵌入为子视图:

let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 50.0, height: 50.0))
imageView.contentMode = .center
imageView.image = UIImage(named: "ic_dropdown")
let emptyView = UIView(frame: CGRect(x: 0, y: 0, width: 50.0, height: 50.0))
emptyView.backgroundColor = .clear
emptyView.addSubview(imageView)
self.documentTypeTextLabel.rightView = emptyView
self.documentTypeTextLabel.rightViewMode = .always

愉快的编码

【讨论】:

    【解决方案2】:

    使用 swift 4.2 设置 UITextField 的右视图

    TxtPass.rightViewMode = UITextField.ViewMode.always
    let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 18, height: 18))
    imageView.contentMode = UIView.ContentMode.scaleAspectFit
    let image = UIImage(named: "hidepass")
    imageView.image = image
    let rightView = UIView(frame: CGRect(x: 0, y: 0, width: 28, height: 18))
    rightView.addSubview(imageView)
    rightView.contentMode = UIView.ContentMode.left
    TxtPass.rightView = rightView
    

    【讨论】:

      【解决方案3】:

      自 iOS 13 和 Xcode 11 以来,这是唯一适合我们的解决方案。

      // Init of custom UITextField
      override init(frame: CGRect) {
          super.init(frame: frame)
      
          if let size = myButton.imageView?.image?.size {
              myButton.frame = CGRect(x:0, y: 0, width: size.width, height: size.height)
      
              let padding: CGFloat = 5
              let container = UIView(frame: CGRect(x:0, y: 0, width: size.width + padding, height: size.height))
              container.addSubview(myButton)
      
              myButton.translatesAutoresizingMaskIntoConstraints = false
              NSLayoutConstraint.activate([
                  myButton.topAnchor.constraint(equalTo: container.topAnchor),
                  myButton.leftAnchor.constraint(equalTo: container.leftAnchor),
                  myButton.bottomAnchor.constraint(equalTo: container.bottomAnchor),
                  myButton.rightAnchor.constraint(equalTo: container.rightAnchor, constant: -padding),
              ])
      
              textField.rightViewMode = .always
              textField.rightView = container
          }
      }
      

      【讨论】:

        【解决方案4】:

        一个更简单的解决方案,它利用了contentMode

            arrow = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"down_arrow"]];
            arrow.frame = CGRectMake(0.0, 0.0, arrow.image.size.width+10.0, arrow.image.size.height);
            arrow.contentMode = UIViewContentModeCenter;
        
            textField.rightView = arrow;
            textField.rightViewMode = UITextFieldViewModeAlways;
        

        在 Swift 3 中,

            let arrow = UIImageView(image: UIImage(named: "arrowDrop"))
            if let size = arrow.image?.size {
                arrow.frame = CGRect(x: 0.0, y: 0.0, width: size.width + 10.0, height: size.height)
            }
            arrow.contentMode = UIViewContentMode.center
            self.textField.rightView = arrow
            self.textField.rightViewMode = UITextFieldViewMode.always
        

        【讨论】:

        • 您也可以使用 ScaleAspectFit 代替 center ...如果图像的大小与确切的框架不匹配。
        • 我将你的示例用于 UIButton(而不是 UIImageView),而它的类型是 InfoLight。
        • 我发现“.right”而不是“.center”使它看起来更像是一个内置的搜索栏,例如联系人应用程序中的搜索栏。很好的解决方案,感谢发布。
        • 或者如果您需要在设计中精确,请将图像放在 .left 上,然后增加宽度以实现精确填充
        • 这似乎不再适用于 iOS 13 和 Xcode 11 Beta 7。但在 iOS 11/12 上运行良好。
        【解决方案5】:

        我意识到这是一篇旧帖子,这个答案有点针对我的用例,但我发布它以防其他人正在寻求类似的解决方案。我想移动 UITextField 的 leftView 或 rightView 但我没有将图像放入其中并且不想要任何硬编码常量。

        我的 UI 要求隐藏文本字段的清除按钮并显示清除按钮所在的 UIActivityIndi​​catorView。

        我向rightView 添加了一个微调器,但开箱即用(在iOS 13 上)它被移动到clearButton 右侧20 像素。我不喜欢使用幻数,因为 clearButton 和 rightView 的位置随时可能被 Apple 更改。 UI 设计意图是“清除按钮所在的微调器”,所以我的解决方案是继承 UITextField 并覆盖 rightViewRect(forBounds)

        override func rightViewRect(forBounds bounds: CGRect) -> CGRect {
        
            // Use clearButton's rectangle
            return self.clearButtonRect(forBounds: bounds)
        }
        

        以下是一个工作示例(无情节提要):

        //------------------------------------------------------------------------------
        class myCustomTextField: UITextField {
        
            override func rightViewRect(forBounds bounds: CGRect) -> CGRect {
        
                // Use clearButton rectangle
                return self.clearButtonRect(forBounds: bounds)
            }
        }
        
        //------------------------------------------------------------------------------
        class myViewController: UIViewController {
        
            var activityView: UIActivityIndicatorView = {
                let activity = UIActivityIndicatorView()
                activity.startAnimating()
                return activity
            }()
        
            @IBOutlet weak var searchTextField: myCustomTextField!
        
            //------------------------------------------------------------------------------
            // MARK: - Lifecycle
            //------------------------------------------------------------------------------
            override func viewDidLoad() {
        
                super.viewDidLoad()
        
                searchTextField.rightView = activityView
                searchTextField.rightViewMode = .never // Hide spinner
                searchTextField.clearButtonMode = .never // Hide clear button
        
                setupUIForTextEntry()
            }
        
            // ...
            // More code to switch between user text entry and "search progress" 
            // by calling setupUI... functions below
            // ...
        
            //------------------------------------------------------------------------------
            // MARK: - UI
            //------------------------------------------------------------------------------
            func setupUIForTextEntry() {
        
                // Hide spinner
                searchTextField.rightViewMode = .never
        
                // Show clear button
                searchTextField.clearButtonMode = .whileEditing
                searchTextField.becomeFirstResponder()
            }
        
            //------------------------------------------------------------------------------
            func setupUIForSearching() {
        
                // Show spinner
                searchTextField.rightViewMode = .always
        
                // Hide clear button
                searchTextField.clearButtonMode = .never
                searchTextField.resignFirstResponder()
            }
        
            //------------------------------------------------------------------------------
        
        }
        
        //------------------------------------------------------------------------------
        

        【讨论】:

          【解决方案6】:

          这对我有用,就像我正在寻找的那样:

          func addImageViewInsideMyTextField() {
              let someView = UIView(frame: CGRect(x: 0, y: 0, width: 40, height: 24))
              let imageView = UIImageView(image: UIImage(named: "accountImage"))
              imageView.frame = CGRect(x: 16, y: 0, width: 24, height: 24)
              imageView.contentMode = .scaleAspectFit
              someView.addSubview(imageView)
          
              self.myTextField.leftView = someView
              self.myTextField.leftViewMode = .always
          }
          

          【讨论】:

            【解决方案7】:

            斯威夫特 5

            class CustomTextField: UITextField {
                func invalidate() {
                    let errorImage =  UIImageView(image: UIImage(named: "errorImage"))
                    errorImage.frame = CGRect(x: 8, y: 8, width: 16, height: 16)
                    rightView = UIView(frame: CGRect(x: 0, y: 0, width: 32, height: 32))
                    rightView?.addSubview(errorImage)
                    rightViewMode = .always
                }
            }
            

            你会想要:

            • 子类UITextField
            • 在 子类文本字段
            • 在invalidate方法中,创建一个UIView 比你的图片大
            • 将图像放在视图中
            • 分配 查看UITextField.rightView

            【讨论】:

              【解决方案8】:

              简单的方法:

              textField.rightViewMode = .always
              let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 25, height: 15))
              textField.contentMode = .scaleAspectFit
              imageView = UIImage(named: "imageName")
              textField.rightView = imageView
              

              注意:高度应小于宽度以允许水平填充。

              【讨论】:

                【解决方案9】:
                ...
                textField.rightView = UIImageView(image: ...)
                textField.rightView?.contentMode = .top
                textField.rightView?.bounds.size.height += 10
                textField.rightViewMode = .always
                ...
                

                【讨论】:

                  【解决方案10】:

                  我们可以覆盖苹果为 rightView 提供的方法,而不是操作 imageView 或 image。

                  class CustomTextField : UITextField { 
                  
                  override func rightViewRect(forBounds bounds: CGRect) -> CGRect {
                      let offset = 5
                      let width  = 20
                      let height = width
                      let x = Int(bounds.width) - width - offset
                      let y = offset
                      let rightViewBounds = CGRect(x: x, y: y, width: width, height: height)
                      return rightViewBounds
                  }}
                  

                  同样的方式,我们可以为左视图覆盖下面的 func。

                  override func leftViewRect(forBounds bounds: CGRect) -> CGRect {
                      /*return as per requirement*/
                  
                  }
                  

                  【讨论】:

                    【解决方案11】:

                    对于 Swift2 ,我使用

                    ...
                            self.mSearchTextField.leftViewMode = UITextFieldViewMode.Always
                            let searchImg = UIImageView(image: UIImage(named: "search.png"))
                            let size = self.mSearchTextField.frame.height
                            searchImg.frame = CGRectMake(0, 0, size,size)
                            searchImg.contentMode = UIViewContentMode.ScaleAspectFit
                            self.mSearchTextField.leftView = searchImg
                    ...
                    

                    【讨论】:

                      【解决方案12】:

                      最简单的方法就是将 Textfield 更改为 RoundRect 而不是 Custom,然后看看它的神奇之处。 :)

                      【讨论】:

                        【解决方案13】:

                        这对 Swift 非常有用:

                        let imageView = UIImageView(image: UIImage(named: "image.png"))
                        imageView.contentMode = UIViewContentMode.Center
                        imageView.frame = CGRectMake(0.0, 0.0, imageView.image!.size.width + 20.0, imageView.image!.size.height)
                        textField.rightViewMode = UITextFieldViewMode.Always
                        textField.rightView = imageView
                        

                        【讨论】:

                        • 无法将'string'类型的值转换为预期的参数类型'UIImage?"
                        【解决方案14】:

                        我在 ViewController 类中创建了一个自定义方法,如下所示:

                        - (void) modifyTextField:(UITextField *)textField
                        {
                            // Prepare the imageView with the required image
                            uint padding = 10;//padding for iOS7
                            UIImageView * iconImageView = [[UIImageView alloc] initWithImage:iconImage];    
                            iconImageView.frame = CGRectMake(0 + padding, 0, 16, 16);
                        
                            // Set the imageView to the left of the given text field.
                            textField.leftView = iconImageView;
                            textField.leftViewMode = UITextFieldViewModeAlways;
                        }
                        

                        现在我可以在内部调用该方法(viewDidLoad 方法)并将我的任何TextFields 发送到该方法,并为左右添加填充,只需编写一行代码即可提供文本和背景颜色,如下:

                        [self modifyTextField:self.firstNameTxtFld];
                        

                        这在 iOS 7 上完美运行!希望这仍然适用于 iOS 8 和 9!

                        我知道添加太多 View 可能会使加载的对象更重。但是当担心其他解决方案的困难时,我发现自己更倾向于这种方法,并且使用这种方式更灵活。 ;)

                        希望这个答案可能对其他人找出另一种解决方案有所帮助或有用。

                        干杯!

                        【讨论】:

                          【解决方案15】:

                          如果你使用 UIImageView 作为 leftView 那么你必须使用这个代码:

                          注意:不要在 viewWillAppear 或 viewDidAppear 中使用

                          -(UIView*)paddingViewWithImage:(UIImageView*)imageView andPadding:(float)padding
                          {
                              float height = CGRectGetHeight(imageView.frame);
                              float width =  CGRectGetWidth(imageView.frame) + padding;
                          
                              UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
                          
                              [paddingView addSubview:imageView];
                          
                              return paddingView;
                          }
                          

                          【讨论】:

                            【解决方案16】:

                            我自己也遇到过这个问题,到目前为止,最简单的解决方案是修改您的图像以简单地在图像的每一侧添加填充!

                            我刚刚更改了我的 png 图像以添加 10 像素的透明填充,并且效果很好,根本不需要编码!

                            【讨论】:

                              【解决方案17】:

                              这对我有用

                              UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 20)];
                              self.passwordTF.leftView = paddingView;
                              self.passwordTF.leftViewMode = UITextFieldViewModeAlways;
                              

                              希望对你有帮助。

                              【讨论】:

                                【解决方案18】:

                                感谢你们的回答,令我惊讶的是,他们都没有真正为我的文本字段提供正确的视图图像,同时仍然提供所需的填充。然后我想到了使用 AspectFill 模式,奇迹发生了。对于未来的寻求者,这是我使用的:

                                UIImageView *emailRightView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 35, 35)];
                                emailRightView.contentMode = UIViewContentModeScaleAspectFill;
                                emailRightView.image = [UIImage imageNamed:@"icon_email.png"];
                                emailTextfield.rightViewMode = UITextFieldViewModeAlways;
                                emailTextfield.rightView = emailRightView;
                                

                                我的 imageview 框架中的 35 代表我的 emailTextfield 的高度,请随意调整以适应您的需要。

                                【讨论】:

                                  【解决方案19】:
                                  - (CGRect)rightViewRectForBounds:(CGRect)bounds
                                  {
                                      return CGRectMake(bounds.size.width - 40, 0, 40, bounds.size.height);
                                  }
                                  

                                  【讨论】:

                                  • 如果UITextField 嵌入在UISearchBar 中,你如何告诉UISearchBar 使用你的UITextField 子类?
                                  【解决方案20】:

                                  最好的方法是使用 UITextField 的子类和 .m 文件创建一个类

                                    #import "CustomTextField.h"
                                    #import <QuartzCore/QuartzCore.h>
                                    @implementation CustomTextField
                                  
                                  
                                  - (id)initWithCoder:(NSCoder*)coder 
                                   {
                                  self = [super initWithCoder:coder];
                                  
                                  if (self) {
                                  
                                      //self.clipsToBounds = YES;
                                      //[self setRightViewMode:UITextFieldViewModeUnlessEditing];
                                  
                                      self.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0,15,46)];
                                      self.leftViewMode=UITextFieldViewModeAlways;
                                        }
                                  
                                  return self;
                                  
                                  }
                                  

                                  通过这样做转到您的故事板或 xib 并单击身份检查器并将 UITextfield 替换为您自己的“CustomTextField”类选项。

                                  注意:如果您只是为文本字段提供自动布局填充,那么您的应用程序将不会运行并且只显示空白屏幕。

                                  【讨论】:

                                    【解决方案21】:

                                    我喜欢这个解决方案,因为它用一行代码解决了问题

                                    myTextField.layer.sublayerTransform = CATransform3DMakeTranslation(10.0f, 0.0f, 0.0f);
                                    

                                    注意:.. 或 2 如果您考虑包含 QuartzCore 一行:)

                                    【讨论】:

                                    • 这也会移动边框
                                    • 但没有解决右填充的问题,只有左填充的问题
                                    • 我使用 rightView.layer.sublayerTransform = CATransform3DMakeTranslation(-10.0f, 0.0f, 0.0f) 获得了更好的结果,但该方法 +1
                                    • 请记住,这也会将文本字段的“清除”按钮向右移动,这会将其推过文本字段的边缘。如果您不需要清除按钮,这是一个很好的方法,否则可能不需要。
                                    【解决方案22】:

                                    下面的示例是为恰好是图标的左视图添加水平填充 - 您可以使用类似的方法将填充添加到您想用作文本字段左视图的任何UIView

                                    UITextField 子类内部:

                                    static CGFloat const kLeftViewHorizontalPadding = 10.0f;
                                    
                                    @implementation TextFieldWithLeftIcon
                                    {
                                      UIImage *_image;
                                      UIImageView *_imageView;
                                    }
                                    
                                    - (instancetype)initWithFrame:(CGRect)frame image:(UIImage *)image
                                    {
                                      self = [super initWithFrame:frame];
                                      if (self) {
                                        if (image) {
                                          _image = image;
                                          _imageView = [[UIImageView alloc] initWithImage:image];
                                          _imageView.contentMode = UIViewContentModeCenter;
                                          self.leftViewMode = UITextFieldViewModeAlways;
                                          self.leftView = _imageView;
                                        }
                                      }
                                      return self;
                                    }
                                    
                                    #pragma mark - Layout 
                                    
                                    - (CGRect)leftViewRectForBounds:(CGRect)bounds
                                    {
                                      CGFloat widthWithPadding = _image.size.width + kLeftViewHorizontalPadding * 2.0f;
                                      return CGRectMake(0, 0, widthWithPadding, CGRectGetHeight(bounds));
                                    }
                                    

                                    虽然我们在这里是UITextField 的子类,但我相信这是最干净的方法。

                                    【讨论】:

                                      【解决方案23】:

                                      这是一种解决方案:

                                       UIView *paddingTxtfieldView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 42)]; // what ever you want 
                                       txtfield.leftView = paddingTxtfieldView;
                                       txtfield.leftViewMode = UITextFieldViewModeAlways;
                                      

                                      【讨论】:

                                      • 问题是关于向左/右视图添加填充,您正在用您的解决方案替换左视图和右视图!
                                      【解决方案24】:

                                      最简单的方法是将 UIView 添加到 leftView/righView 并将 ImageView 添加到 UIView ,在 UIView 内任意位置调整 ImageView 的原点,这对我来说就像一个魅力。只需要几行代码

                                      UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 5, 26, 26)];
                                      imgView.image = [UIImage imageNamed:@"img.png"];
                                      
                                      UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 32, 32)];
                                      [paddingView addSubview:imgView];
                                      [txtField setLeftViewMode:UITextFieldViewModeAlways];
                                      [txtField setLeftView:paddingView];
                                      

                                      【讨论】:

                                      • UIViewContentMode 不起作用,但这个答案就像一个魅力!
                                      【解决方案25】:

                                      一个技巧:将一个包含 UIImageView 的 UIView 添加到 UITextField 作为 rightView。这个 UIView 必须更大,现在把 UIImageView 放在它的左边。所以从右边会有一个空格。

                                      // Add a UIImageView to UIView and now this UIView to UITextField - txtFieldDate
                                      UIView *viewRightIntxtFieldDate = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 30)]; 
                                      // (Height of UITextField is 30px so height of viewRightIntxtFieldDate = 30px)
                                      UIImageView *imgViewCalendar = [[UIImageView alloc] initWithFrame:CGRectMake(0, 10, 10, 10)];
                                      [imgViewCalendar setImage:[UIImage imageNamed:@"calendar_icon.png"]];
                                      [viewRightIntxtFieldDate addSubview:imgViewCalendar];
                                      txtFieldDate.rightViewMode = UITextFieldViewModeAlways;
                                      txtFieldDate.rightView = viewRightIntxtFieldDate;
                                      

                                      【讨论】:

                                        【解决方案26】:

                                        创建一个自定义 UITextField 类并使用该类而不是 UITextField。 Override - (CGRect) textRectForBounds:(CGRect)bounds 来设置你需要的矩形

                                        例子

                                        - (CGRect)textRectForBounds:(CGRect)bounds{
                                             CGRect textRect = [super textRectForBounds:bounds];
                                             textRect.origin.x += 10;
                                             textRect.size.width -= 10;
                                             return textRect;
                                        }
                                        

                                        【讨论】:

                                          【解决方案27】:

                                          我自己正在研究这个并使用了这个解决方案:

                                          - (CGRect) rightViewRectForBounds:(CGRect)bounds {
                                          
                                              CGRect textRect = [super rightViewRectForBounds:bounds];
                                              textRect.origin.x -= 10;
                                              return textRect;
                                          }
                                          

                                          这会将图像从右侧移动 10,而不是在 iOS 7 中将图像挤压到边缘。

                                          此外,这是UITextField 的子类,可以通过以下方式创建:

                                          1. 创建一个新文件,它是UITextField 的子类,而不是默认的NSObject
                                          2. 添加一个名为- (id)initWithCoder:(NSCoder*)coder的新方法来设置图像

                                            - (id)initWithCoder:(NSCoder*)coder {
                                                self = [super initWithCoder:coder];
                                            
                                                if (self) {
                                            
                                                    self.clipsToBounds = YES;
                                                    [self setRightViewMode:UITextFieldViewModeUnlessEditing];
                                            
                                                    self.leftView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"textfield_edit_icon.png"]];
                                                }
                                            
                                                return self;
                                            }
                                            
                                          3. 您可能需要导入#import &lt;QuartzCore/QuartzCore.h&gt;

                                          4. 在上面添加rightViewRectForBounds方法

                                          5. 在 Interface Builder 中,单击您想要子类化的 TextField 并将类属性更改为这个新子类的名称

                                          【讨论】:

                                          【解决方案28】:

                                          我在某个地方找到了这个……

                                          UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)];
                                          paddingView.backgroundColor = [UIColor clearColor];
                                          itemDescription.leftView = paddingView;
                                          itemDescription.leftViewMode = UITextFieldViewModeAlways;
                                          
                                          [self addSubview:itemDescription];
                                          

                                          【讨论】:

                                          • 这只是为文本添加了填充,这不是提问者想要的。他不想要清晰的leftView。他希望将图像显示为 leftView。
                                          • 在paddingView中添加图片即可。
                                          猜你喜欢
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 2021-03-12
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          相关资源
                                          最近更新 更多