iOS7의 UITextfield leftView / rightView 패딩


94

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;

UITextBorderStyleNone을 사용하여 UITextField에 대한 패딩 설정 과 같이 텍스트 필드의 텍스트에 패딩을 추가하는 데 관심이 없습니다.



1
아니요, 이것은 텍스트 필드에서 leftView로 표시된 이미지를 들여 쓰는 것에 대해 묻습니다. 텍스트 자체를 들여 쓰지 않습니다. 그의 코드를 시도하면 leftView를 이미지로 설정하면 해당 이미지가 패딩없이 텍스트 필드의 왼쪽 가장자리에 배치되는 것을 볼 수 있습니다. 못 생겼어.
stone

답변:


90

이 작업을 직접 수행하고이 솔루션을 사용했습니다.

- (CGRect) rightViewRectForBounds:(CGRect)bounds {

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

이렇게하면 iOS 7에서 이미지가 가장자리에 밀착되는 대신 오른쪽에서 10 씩 이미지가 이동합니다.

또한 이것은의 하위 클래스에 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 <QuartzCore/QuartzCore.h>

  4. rightViewRectForBounds위 의 방법 추가

  5. Interface Builder에서 하위 클래스를 만들려는 TextField를 클릭하고 클래스 속성을이 새 하위 클래스의 이름으로 변경합니다.


IBDesignable을 사용하는 방법은 무엇입니까?
riddhi

최신 버전을 확인하거나 2020 년에보고있는 경우 다음을 방문하십시오. stackoverflow.com/a/55041786/6596443
AKINNUBI ABIOLA SYLVESTER

167

다음을 활용하는 훨씬 간단한 솔루션 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;

스위프트 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

1
이미지 크기가 정확한 프레임과 일치하지 않는 경우 Center 대신 ScaleAspectFit도 사용할 수 있습니다.
Mihir Mehta

유형이 InfoLight 인 동안 UIButton (UIImageView 대신)에 대한 예제를 사용했습니다.
OhadM

".center"대신 ".right"가 연락처 앱에있는 것과 같은 기본 제공 검색 막대처럼 보이게한다는 것을 발견했습니다. 이에 대한 훌륭한 해결책, 게시 해 주셔서 감사합니다.
James Toomey

또는 디자인 재현에서 정확해야하는 경우 이미지를
.left에 넣은

4
iOS 13 및 Xcode 11 Beta 7에서는 더 이상 작동하지 않는 것 같습니다.하지만 iOS 11/12에서는 잘 작동합니다.
PatrickDotStar 2019 년

49

가장 쉬운 방법은 leftView / righView에 UIView를 추가하고 UIView에 ImageView를 추가하고 원하는 곳 어디에서나 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 작동하지 않지만이 대답은 매력처럼 작동합니다!
nigong

14

이것은 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

'문자열'유형의 값을 예상 인수 유형 'UIImage?'로 변환 할 수 없습니다.

7

이것은 나를 위해 작동합니다

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

그것이 당신을 도울 수 있기를 바랍니다.


6

이 솔루션은 한 줄의 코드로 문제를 해결하기 때문에 좋아합니다.

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

참고 : .. 또는 2 줄에 QuartzCore 포함을 고려하는 경우 :)


1
이것은 또한 국경을 이동합니다
Softlion 2015

1
하지만 바로 패딩 만 왼쪽 패딩 문제 문제가 해결되지 않습니다
carmen_munich

1
rightView.layer.sublayerTransform = CATransform3DMakeTranslation (-10.0f, 0.0f, 0.0f)를 사용하여 더 나은 결과를 얻었지만 방법은 +1
Thibaud David

이렇게하면 텍스트 필드의 "지우기"버튼이 오른쪽으로 이동하여 텍스트 필드의 가장자리를 넘어갈 수 있습니다. 지우기 버튼이 필요하지 않은 경우 이것은 훌륭한 접근 방식이며 그렇지 않으면 그렇지 않을 수도 있습니다.
톰 해링턴

4

이를 수행하는 가장 좋은 방법은 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로 이동하여 ID 검사기를 클릭하고 클래스 옵션에서 UITextfield를 자신의 "CustomTextField"로 바꿉니다.

참고 : 텍스트 필드에 자동 레이아웃으로 채우기 만하면 애플리케이션이 실행되지 않고 빈 화면 만 표시됩니다.


4

imageView 또는 image를 조작하는 대신 rightView에 대해 apple에서 제공하는 메서드를 재정의 할 수 있습니다.

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*/

}

3

어딘가에서 찾았어요 ...

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

[self addSubview:itemDescription];

4
그것은 단지 질문자가 찾는 것이 아닌 텍스트에 패딩을 추가합니다. 그는 명확한 leftView를 원하지 않습니다. 그는 leftView로 표시되는 이미지를 원합니다.
석재

paddingView에 이미지를 추가하기 만하면됩니다.
Matheus Weber

3

스위프트 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
  • 서브 클래 싱 된 텍스트 필드 안에 무효화 메소드 작성
  • 무효화 방법에서 UIView 이미지보다 더 크게 만듭니다.
  • 뷰 내부에 이미지 배치
  • 보기 할당 UITextField.rightView

2

다음은 한 가지 해결책입니다.

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

1

사용자 정의 UITextField 클래스를 만들고 UITextField 대신 해당 클래스를 사용합니다. 재정의-(CGRect) textRectForBounds : (CGRect) bounds를 사용하여 필요한 사각형을 설정합니다.

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

1

아래 예는 아이콘 인 왼쪽보기에 수평 패딩을 추가하는 것입니다. 유사한 접근 방식 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이것이 가장 깨끗한 접근 방식이라고 생각합니다.


1
- (CGRect)rightViewRectForBounds:(CGRect)bounds
{
    return CGRectMake(bounds.size.width - 40, 0, 40, bounds.size.height);
}

UITextField가에 포함 된 경우 하위 클래스 를 사용하도록 UISearchBar어떻게 UISearchBar지시 UITextField합니까?
crishoj

1

귀하의 답변에 감사드립니다. 놀랍게도 그들 중 어느 누구도 필요한 패딩을 제공하면서 내 텍스트 필드에 올바른 뷰 이미지를 실제로 맞추지 못했습니다. 그런 다음 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의 높이를 나타내므로 필요에 따라 자유롭게 조정하십시오.


1

나도이 문제를 겪었고 지금까지 가장 쉬운 해결책은 이미지를 수정하여 이미지의 각면에 패딩을 추가하는 것입니다!

방금 내 png 이미지를 변경하여 10 픽셀의 투명 패딩을 추가했는데 코딩 없이도 잘 작동합니다!


1

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

1

다음과 같이 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;
}

이제 ( viewDidLoadmethod) 내부에서 해당 메서드를 호출하고 해당 메서드 에 내 모든 것을 보내고 TextFields오른쪽과 왼쪽에 패딩을 추가하고 다음과 같이 코드 한 줄만 작성하여 텍스트와 배경색을 지정할 수 있습니다 .

[self modifyTextField:self.firstNameTxtFld];

이것은 iOS 7에서 완벽하게 작동했습니다! 이것이 iOS 8 및 9에서도 여전히 작동하기를 바랍니다!

뷰를 너무 많이 추가하면로드 할 개체가 약간 더 무거워 질 수 있다는 것을 알고 있습니다. 그러나 다른 솔루션의 어려움에 대해 걱정할 때이 방법에 더 편향되어 있고이 방법을 사용하는 것이 더 유연하다는 것을 알게되었습니다. ;)

이 답변이 다른 사람에게 다른 해결책을 찾는 데 도움이되거나 유용하기를 바랍니다.

건배!


1

이것은 내가 찾는 것처럼 나를 위해 작동합니다.

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
}

1

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

위의 답변은 나를 위해 작동하지 않습니다.
Mark Dylan B Mercado

1

// UITextField의 Rightview 설정, swift 4.2TxtPass.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


0

한 가지 트릭 : 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;

0

가장 쉬운 방법은 Textfield를 Custom 대신 RoundRect로 변경하고 마법을 보는 것입니다. :)


0

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

0
...
textField.rightView = UIImageView(image: ...)
textField.rightView?.contentMode = .top
textField.rightView?.bounds.size.height += 10
textField.rightViewMode = .always
...

0

간단한 접근 방식 :

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

참고 : 가로 패딩을 허용하려면 높이가 너비보다 작아야합니다.


0

나는 이것이 오래된 게시물이라는 것을 알고 있으며이 답변은 내 사용 사례에 약간 한정되어 있지만 다른 사람들이 유사한 솔루션을 찾고있는 경우 게시했습니다. UITextField의 leftView 또는 rightView를 이동하고 싶지만 이미지를 넣지 않고 하드 코딩 된 상수를 원하지 않습니다.

내 UI는 텍스트 필드의 지우기 버튼을 숨기고 지우기 버튼이있는 UIActivityIndicatorView를 표시해야합니다.

에 스피너를 추가 rightView했지만 기본적으로 (iOS 13에서) .NET Framework의 오른쪽으로 20 픽셀 이동합니다 clearButton. 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()
    }

    //------------------------------------------------------------------------------

}

//------------------------------------------------------------------------------
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.