UITextfield leftView / rightView dolgusu iOS7'de


94

İOS7'de bir UITextField'ın leftView ve rightView görünümleri metin alanı sınırına gerçekten yakındır.

Bu öğelere nasıl (yatay) dolgu ekleyebilirim?

Çerçeveyi değiştirmeyi denedim ama işe yaramadı

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

Lütfen, metin alanının metnine bunun gibi dolgu eklemekle ilgilenmediğimi unutmayın. UITextBorderStyleNone ile UITextField için Set dolgusu dolgu eklemekle ilgilenmediğimi unutmayın.



1
Hayır, bu bir metin alanında sol Görünüm olarak görüntülenen görüntüyü girintilemekle ilgilidir. Metnin kendisini girintili yapmamak. Onun kodunu deneyin ve bir görüntüye leftView ayarının, bu görüntüyü dolgu olmaksızın metin alanının sol kenarına yerleştirdiğini göreceksiniz. Çirkin görünüyor.
Taş

Yanıtlar:


91

Sadece bunun üzerinde çalışıyordum ve şu çözümü kullandım:

- (CGRect) rightViewRectForBounds:(CGRect)bounds {

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

Bu, görüntüyü iOS 7'de kenara sıkıştırmak yerine sağdan 10'a hareket ettirir.

Ek olarak, bu, UITextFieldaşağıdakiler tarafından oluşturulabilen bir alt sınıftaydı :

  1. UITextFieldVarsayılan yerine alt sınıf olan yeni bir dosya oluşturunNSObject
  2. - (id)initWithCoder:(NSCoder*)coderGörüntüyü ayarlamak için adlı yeni bir yöntem ekleyin

    - (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. İçe aktarmanız gerekebilir #import <QuartzCore/QuartzCore.h>

  4. rightViewRectForBoundsYukarıdaki yöntemi ekleyin

  5. Arayüz Oluşturucu'da, alt sınıf yapmak ve sınıf özniteliğini bu yeni alt sınıfın adına değiştirmek istediğiniz TextField'a tıklayın.


bunun için IBDesignable nasıl kullanılır?
riddhi

en son sürüm için veya bunu 2020'de görüntülüyorsanız, şu adresi ziyaret edin: stackoverflow.com/a/55041786/6596443
AKINNUBI ABIOLA SYLVESTER

167

Aşağıdakilerden yararlanan çok daha basit bir çözüm 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'te,

    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
Resmin boyutu tam çerçeveyle eşleşmiyorsa, merkez yerine ScaleAspectFit'i de kullanabilirsiniz.
Mihir Mehta

UIButton için örneğinizi kullandım (UIImageView yerine) türü InfoLight iken.
OhadM

".Center" yerine ".right" ifadesinin daha çok Kişiler uygulamasındaki gibi yerleşik bir Arama çubuğuna benzediğini fark ettim. Bu konuda harika bir çözüm, yayınladığınız için teşekkürler.
James Toomey

Veya tasarım rekreasyonunda kesin olmanız gerekiyorsa, görüntüyü .sola koyun ve ardından tam dolgu elde etmek için genişliği artırın
jovanjovanovic

5
Bu artık iOS 13 ve Xcode 11 Beta 7 ile çalışmıyor gibi görünüyor. Yine de iOS 11 / 12'de iyi çalışıyor.
PatrickDotStar

49

En kolay yol, leftView / righView'e bir UIView eklemek ve UIView'a bir ImageView eklemek, UIView içindeki ImageView kaynağını istediğiniz yerde ayarlamaktır, bu benim için bir cazibe gibi çalıştı. Sadece birkaç satır koda ihtiyacı var

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 işe yaramıyor ama bu cevap bir çekicilik gibi çalışıyor!
nigong

14

Bu, Swift için harika çalışıyor:

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' türünün değeri beklenen bağımsız değişken türüne 'UIImage? "dönüştürülemiyor

8

Bu benim için çalışıyor

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

Sana yardım etsin.


6

Bu çözümü seviyorum çünkü sorunu tek bir kod satırıyla çözüyor

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

Not: .. veya 2, QuartzCore a line eklemeyi düşünüyorsanız :)


1
Bu aynı zamanda sınırı da değiştirir
Softlion

1
ancak sağ dolgu ile sorunu çözmez sadece sol dolgu sorunu
carmen_munich

1
RightView.layer.sublayerTransform = CATransform3DMakeTranslation (-10.0f, 0.0f, 0.0f) kullanarak daha iyi bir sonuç aldım, ancak yöntem için +1
Thibaud David

Bunun ayrıca metin alanının "temizle" düğmesini sağa kaydıracağını ve bu düğmenin metin alanının kenarını geçmesine neden olabileceğini unutmayın. Temizle düğmesine ihtiyacınız yoksa, bu harika bir yaklaşımdır, aksi halde olmayabilir.
Tom Harrington

4

Bunu yapmanın en iyi yolu, UITextField alt sınıfını kullanarak ve .m dosyasında bir sınıf oluşturmaktır.

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

}

bunu yaparak film şeridinize veya xib'e gidin ve kimlik denetçisine tıklayın ve UITextfield'ı sınıf seçeneğinde kendi "CustomTextField" ile değiştirin.

Not: Metin alanı için yalnızca otomatik düzen ile dolgu verirseniz, uygulamanız çalışmayacak ve yalnızca boş ekran gösterecektir.


4

İmageView veya görüntüyü değiştirmek yerine, rightView için apple tarafından sağlanan bir yöntemi geçersiz kılabiliriz.

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

ve aynı şekilde sol görünüm için aşağıdaki işlevi geçersiz kılabiliriz.

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

}

3

Bunu bir yerde buldum ...

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

[self addSubview:itemDescription];

4
Bu, soruyu soranın aradığı şey olmayan metne sadece dolgu ekler. Net bir sol görüş istemiyor. LeftView olarak bir görüntünün görüntülenmesini istiyor.
Taş

Resmi paddingView'e ekleyebilirsiniz.
Matheus Weber

3

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

Şunları yapmak isteyeceksiniz:

  • Alt sınıf UITextField
  • Alt sınıflı metin alanına geçersiz kılma yöntemi yazın
  • Geçersiz kılma yönteminde, bir UIView görüntünüzden daha büyük
  • Görüntünüzü görünümün içine yerleştirin
  • Görünümü şuna ata: UITextField.rightView

2

İşte bir çözüm:

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

1

Özel bir UITextField sınıfı oluşturun ve UITextField yerine bu sınıfı kullanın. Geçersiz kıl - (CGRect) textRectForBounds: (CGRect) sınırları, ihtiyacınız olan doğrultuyu ayarlamak için

Misal

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

1

Aşağıdaki örnek, bir simge olan bir sol görünüme yatay dolgu eklemek içindir - UIViewmetin alanının sol görünümü olarak kullanmak istediğiniz herhangi birine dolgu eklemek için benzer yaklaşımı kullanabilirsiniz.

İç UITextFieldalt sınıf:

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

UITextFieldBurada bir alt sınıf olsak da , bunun en temiz yaklaşım olduğuna inanıyorum.


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

Eğer, UITextFieldbir içine gömülü ise , alt sınıfınızı kullanmasını UISearchBarnasıl söylersiniz ? UISearchBarUITextField
crishoj

1

Cevaplarınız için teşekkür ederim çocuklar, şaşırtıcı bir şekilde hiçbiri gerekli dolguyu sağlarken metin alanıma gerçekten doğru görüntü görüntüsünü sığdırmadı. sonra AspectFill modunu kullanmayı düşündüm ve mucizeler oldu. Gelecek arayanlar için kullandım:

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;

Görüntü görünümümün çerçevesindeki 35, emailTextfield'ımın yüksekliğini temsil ediyor, ihtiyaçlarınıza göre ayarlamaktan çekinmeyin.


1

Bu sorunu ben de yaşadım ve açık ara en kolay çözüm, görüntünün her bir tarafına dolgu eklemek için görüntünüzü değiştirmektir!

Sadece 10 piksel şeffaf dolgu eklemek için png resmimi değiştirdim ve hiç kodlama olmadan iyi çalışıyor!


1

LeftView olarak bir UIImageView kullanıyorsanız, bu kodu kullanmanız gerekir:

Dikkat: İç görünümü kullanmayınWillAppear veya 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 sınıfımda aşağıda gösterildiği gibi özel bir yöntem oluşturdum:

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

Şimdi bu yöntemi ( viewDidLoadyöntem) içinde çağırabilir ve bu yönteme herhangi bir yöntemimi gönderebilir TextFieldsve hem sağ hem de sol için dolgu ekleyebilir ve aşağıdaki gibi yalnızca bir satır kod yazarak metin ve arka plan renkleri verebilirim:

[self modifyTextField:self.firstNameTxtFld];

Bu iOS 7'de mükemmel çalıştı! Umarım bu hala iOS 8 ve 9'da çalışır!

Çok fazla Görünüm eklemenin, bu nesneyi biraz daha ağır hale getirebileceğini biliyorum. Ancak diğer çözümlerin zorlukları konusunda endişelendiğimde, kendimi bu yönteme karşı daha önyargılı ve bu şekilde kullanmak konusunda daha esnek buldum. ;)

Umarım bu yanıt başka birine başka bir çözüm bulmak için yararlı veya yararlı olabilir.

Şerefe!


1

Bu benim için tam aradığım gibi çalışıyor:

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

İOS 13 ve Xcode 11'den beri bizim için çalışan tek çözüm bu.

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

Yukarıdaki cevaplar benim için çalışmıyor, bu çalışıyor.
Mark Dylan B Mercado

1

// UITextField'ın Sağ görünümünü ayarla, hızlı 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

Bir numara: Sağ Görünüm olarak UITextField'a UIImageView içeren bir UIView ekleyin. Bu UIView boyut olarak daha büyük olmalıdır, şimdi UIImageView'ı soluna yerleştirin. Yani sağdan bir boşluk dolgusu olacak.

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

En kolay yol Textfield'ı Custom yerine RoundRect olarak değiştirmek ve sihri görmektir. :)


0

Swift2 için kullanıyorum

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

Basit yaklaşım:

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

Not: Yatay dolguya izin vermek için yükseklik genişlikten daha küçük olmalıdır.


0

Bunun eski bir gönderi olduğunu anlıyorum ve bu yanıt biraz benim kullanım durumuma özgü, ancak başkalarının da benzer bir çözüm araması durumunda yazdım. Bir UITextField'ın leftView veya rightView'unu taşımak istiyorum ancak bunlara resim koymuyorum ve sabit kodlanmış sabitler istemiyorum.

Kullanıcı arayüzüm, metin alanının temizle düğmesini gizlemeye ve temizle düğmesinin bulunduğu yerde bir UIActivityIndicatorView görüntülemeye çağırıyor.

Bir döndürücü ekliyorum rightView, ancak kutunun dışında (iOS 13'te) 20 piksel clearButton. ClearButton ve rightView'ın konumu herhangi bir zamanda Apple tarafından değiştirilebileceği için sihirli sayıları kullanmayı sevmiyorum. UI tasarım amacı, "temizle düğmesinin olduğu yerde döndürücüdür", bu nedenle benim çözümüm UITextField'ı alt sınıflara ayırmak ve geçersiz kılmaktı rightViewRect(forBounds).

override func rightViewRect(forBounds bounds: CGRect) -> CGRect {

    // Use clearButton's rectangle
    return self.clearButtonRect(forBounds: bounds)
}

Aşağıda çalışan bir örnek verilmiştir (Storyboard sans):

//------------------------------------------------------------------------------
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()
    }

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

}

//------------------------------------------------------------------------------
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.