Widoki leftView i rightView UITextField na iOS7 są naprawdę blisko granicy pola tekstowego.
Jak mogę dodać (poziome) wypełnienie do tych elementów?
Próbowałem zmodyfikować ramkę, ale nie zadziałało
uint padding = 10;//padding for iOS7
UIImageView * iconImageView = [[UIImageView alloc] initWithImage:iconImage];
iconImageView.frame = CGRectMake(0 + padding, 0, 16, 16);
textField.leftView = iconImageView;
Proszę zauważyć, że nie jestem zainteresowany dodawaniem dopełnienia do tekstu pola tekstowego, jak to Ustaw dopełnienie dla UITextField z UITextBorderStyleNone
ios
objective-c
uitextfield
poniżej zera
źródło
źródło
Odpowiedzi:
Właśnie nad tym pracowałem i korzystałem z tego rozwiązania:
- (CGRect) rightViewRectForBounds:(CGRect)bounds { CGRect textRect = [super rightViewRectForBounds:bounds]; textRect.origin.x -= 10; return textRect; }
Spowoduje to przesunięcie obrazu z prawej strony o 10 zamiast ściśnięcia obrazu przy krawędzi w systemie iOS 7.
Dodatkowo było to w podklasie
UITextField
, którą można utworzyć za pomocą:UITextField
zamiast domyślnejNSObject
Dodaj nową metodę o nazwie,
- (id)initWithCoder:(NSCoder*)coder
aby ustawić obraz- (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; }
Być może będziesz musiał zaimportować
#import <QuartzCore/QuartzCore.h>
Dodaj
rightViewRectForBounds
powyższą metodęW programie Interface Builder kliknij pole tekstowe, które chcesz utworzyć podklasę, i zmień atrybut klasy na nazwę nowej podklasy
źródło
Znacznie prostsze rozwiązanie, które wykorzystuje
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;
W 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
źródło
Najłatwiej jest dodać UIView do leftView / righView i dodać ImageView do UIView, dostosować pochodzenie ImageView wewnątrz UIView, gdziekolwiek chcesz, to działało dla mnie jak urok. Potrzebuje tylko kilku wierszy kodu
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];
źródło
UIViewContentMode
nie działa, ale ta odpowiedź działa jak urok!Działa to świetnie w 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
źródło
To działa dla mnie
UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 20)]; self.passwordTF.leftView = paddingView; self.passwordTF.leftViewMode = UITextFieldViewModeAlways;
Niech ci to pomoże.
źródło
Podoba mi się to rozwiązanie, ponieważ rozwiązuje problem za pomocą jednej linii kodu
myTextField.layer.sublayerTransform = CATransform3DMakeTranslation(10.0f, 0.0f, 0.0f);
Uwaga: .. lub 2, jeśli rozważasz włączenie linii QuartzCore :)
źródło
Najlepszym sposobem na to jest po prostu utworzenie klasy przy użyciu podklasy UITextField w pliku .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; }
robiąc to, przejdź do swojego storyboardu lub xib i kliknij inspektora tożsamości i zastąp pole UITextfield własną opcją „CustomTextField” w klasie.
Uwaga: Jeśli po prostu podasz dopełnienie z automatycznym układem dla pola tekstowego, Twoja aplikacja nie będzie działać i pokaże tylko pusty ekran.
źródło
Zamiast manipulować imageView lub image, możemy zastąpić metodę dostarczoną przez Apple dla rightView.
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 }}
w ten sam sposób możemy nadpisać poniższą funkcję dla widoku z lewej strony.
override func leftViewRect(forBounds bounds: CGRect) -> CGRect { /*return as per requirement*/ }
źródło
Znalazłem to gdzieś ...
UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)]; paddingView.backgroundColor = [UIColor clearColor]; itemDescription.leftView = paddingView; itemDescription.leftViewMode = UITextFieldViewModeAlways; [self addSubview:itemDescription];
źródło
Szybki 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 } }
Będziesz chciał:
UITextField
UIView
większy niż twój obrazUITextField.rightView
źródło
Oto jedno rozwiązanie:
UIView *paddingTxtfieldView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 42)]; // what ever you want txtfield.leftView = paddingTxtfieldView; txtfield.leftViewMode = UITextFieldViewModeAlways;
źródło
Utwórz niestandardową klasę UITextField i użyj tej klasy zamiast UITextField. Zastąp - (CGRect) textRectForBounds: (CGRect) bounds, aby ustawić prostą, której potrzebujesz
Przykład
- (CGRect)textRectForBounds:(CGRect)bounds{ CGRect textRect = [super textRectForBounds:bounds]; textRect.origin.x += 10; textRect.size.width -= 10; return textRect; }
źródło
Poniższy przykład dotyczy dodawania poziomego dopełnienia do widoku z lewej strony, który jest ikoną - możesz użyć podobnego podejścia do dodawania dopełnienia do dowolnego
UIView
, którego chcesz użyć jako lewego widoku pola tekstowego.UITextField
Podklasa wewnętrzna :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)); }
Chociaż jesteśmy
UITextField
tutaj podklasą , uważam, że jest to najczystsze podejście.źródło
- (CGRect)rightViewRectForBounds:(CGRect)bounds { return CGRectMake(bounds.size.width - 40, 0, 40, bounds.size.height); }
źródło
UITextField
jest osadzony w aUISearchBar
, jak powiedzieć,UISearchBar
aby używał twojejUITextField
podklasy?dziękuję wam za odpowiedzi, ku mojemu zdziwieniu żadna z nich tak naprawdę nie pasowała do mojego pola tekstowego we właściwym widoku, jednocześnie zapewniając wymagane wypełnienie. potem pomyślałem o użyciu trybu AspectFill i zdarzyły się cuda. dla przyszłych poszukiwaczy, oto czego użyłem:
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;
35 w ramce mojego imageview reprezentuje wysokość mojego emailTextfield, nie krępuj się dostosować go do swoich potrzeb.
źródło
Sam miałem ten problem i zdecydowanie najłatwiejszym rozwiązaniem jest zmodyfikowanie obrazu, aby po prostu dodać dopełnienie z każdej strony obrazu!
Właśnie zmieniłem mój obraz png, aby dodać 10-pikselowe przezroczyste wypełnienie i działa dobrze, bez żadnego kodowania!
źródło
Jeśli używasz UIImageView jako leftView, musisz użyć tego kodu:
Uwaga: nie używaj inside viewWillAppear ani 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; }
źródło
Utworzyłem niestandardową metodę w mojej klasie ViewController, jak pokazano poniżej:
- (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; }
Teraz mogę wywołać tę metodę wewnątrz (
viewDidLoad
metoda) i wysłać dowolną z moichTextFields
do tej metody i dodać dopełnienie dla prawej i lewej strony oraz nadać tekstowi i kolorom tła, pisząc tylko jedną linię kodu w następujący sposób:[self modifyTextField:self.firstNameTxtFld];
To działało idealnie na iOS 7! Mam nadzieję, że to nadal działa również na iOS 8 i 9!
Wiem, że dodanie zbyt dużej liczby widoków może spowodować, że ładowanie tego obiektu będzie nieco cięższe. Ale kiedy martwiłem się o trudności w innych rozwiązaniach, stwierdziłem, że jestem bardziej skłonny do tej metody i bardziej elastyczny w używaniu jej. ;)
Mam nadzieję, że ta odpowiedź może być pomocna lub przydatna w znalezieniu innego rozwiązania dla kogoś innego.
Twoje zdrowie!
źródło
To działa dla mnie tak, jak szukam:
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 }
źródło
Od iOS 13 i Xcode 11 jest to jedyne rozwiązanie, które działa dla nas.
// 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 } }
źródło
// Ustaw widok z prawej strony UITextField, swift 4.2
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
źródło
Jedna sztuczka: Dodaj UIView zawierający UIImageView do UITextField jako rightView. Ten UIView musi być większy, teraz umieść UIImageView po lewej stronie. Więc będzie dopełnienie przestrzeni od prawej strony.
// 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;
źródło
Najłatwiej jest po prostu zmienić pole tekstowe na RoundRect zamiast na niestandardowe i zobaczyć magię. :)
źródło
dla Swift2 używam
... 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 ...
źródło
... textField.rightView = UIImageView(image: ...) textField.rightView?.contentMode = .top textField.rightView?.bounds.size.height += 10 textField.rightViewMode = .always ...
źródło
Proste podejście:
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
Uwaga: wysokość powinna być mniejsza niż szerokość, aby umożliwić dopełnienie w poziomie.
źródło
Zdaję sobie sprawę, że to stary post i ta odpowiedź jest nieco specyficzna dla mojego przypadku użycia, ale opublikowałem ją na wypadek, gdyby inni szukali podobnego rozwiązania. Chcę przenieść leftView lub rightView UITextField, ale nie umieszczam w nich obrazów i nie chcę żadnych stałych zakodowanych na stałe.
Mój interfejs użytkownika wymaga ukrycia przycisku czyszczenia pola tekstowego i wyświetlenia UIActivityIndicatorView, w którym znajduje się przycisk czyszczenia.
Dodaję spinner do
rightView
, ale po wyjęciu z pudełka (na iOS 13) jest on przesunięty o 20 pikseli w prawo odclearButton
. Nie lubię używać magicznych liczb, ponieważ pozycja clearButton i rightView może ulec zmianie w dowolnym momencie przez Apple. Założeniem projektu interfejsu użytkownika jest „spinner, w którym znajduje się przycisk czyszczenia”, więc moim rozwiązaniem było utworzenie podklasy UITextField i zastąpienierightViewRect(forBounds)
.override func rightViewRect(forBounds bounds: CGRect) -> CGRect { // Use clearButton's rectangle return self.clearButtonRect(forBounds: bounds) }
Poniżej znajduje się działający przykład (bez Storyboard):
//------------------------------------------------------------------------------ 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() } //------------------------------------------------------------------------------ } //------------------------------------------------------------------------------
źródło