Установить дополнение для UITextField с помощью UITextBorderStyleNone
Я хотел использовать пользовательский фон для моего UITextFields
. Это прекрасно работает, за исключением того, что я должен использовать UITextBorderStyleNone
, чтобы он выглядел красиво. Это заставляет текст придерживаться слева без каких-либо дополнений.
Можно ли настроить прописку вручную, чтобы она выглядела похожей на UITextBorderStyleRoundedRect
, за исключением использования моего пользовательского фонового изображения?
- 1
- 2
Я нашел аккуратный небольшой взлом, чтобы установить левый отступ для этой конкретной ситуации.
По сути, вы устанавливаете свойство UITextField
чтобы оно было пустым представлением размера UITextField
отступа:
UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)];
textField.leftView = paddingView;
textField.leftViewMode = UITextFieldViewModeAlways;
Работал как шарм для меня!
В Swift 3/Swift 4 это можно сделать, выполнив
let paddingView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 5, height: 20))
textField.leftView = paddingView
textField.leftViewMode = .always
Я создал эту реализацию категории и добавил ее в начало файла .m
.
@implementation UITextField (custom)
- (CGRect)textRectForBounds:(CGRect)bounds {
return CGRectMake(bounds.origin.x + 10, bounds.origin.y + 8,
bounds.size.width - 20, bounds.size.height - 16);
}
- (CGRect)editingRectForBounds:(CGRect)bounds {
return [self textRectForBounds:bounds];
}
@end
Основано на ссылке, которую предоставил Петр Бласак. Казалось, что проще создать целый новый подкласс, а затем проще добавить дополнительный UIView
. Тем не менее, кажется, что чего-то не хватает, чтобы не было возможности контролировать заполнение внутри текстового поля.
Решение Swift 2:
import UIKit
class CustomTextField: UITextField {
required init?(coder aDecoder: NSCoder){
super.init(coder: aDecoder)
}
override func textRectForBounds(bounds: CGRect) -> CGRect {
return CGRectMake(bounds.origin.x + 10, bounds.origin.y + 8, bounds.size.width - 20, bounds.size.height - 16);
}
override func editingRectForBounds(bounds: CGRect) -> CGRect {
return self.textRectForBounds(bounds);
}
}
версия Swift 3 для Xcode > 6, где вы можете редактировать значение вставки в интерфейсе Builder/Storyboard.
import UIKit
@IBDesignable
class FormTextField: UITextField {
@IBInspectable var inset: CGFloat = 0
override func textRect(forBounds bounds: CGRect) -> CGRect {
return bounds.insetBy(dx: inset, dy: inset)
}
override func editingRect(forBounds bounds: CGRect) -> CGRect {
return textRect(forBounds: bounds)
}
}
Хороший подход для добавления дополнения к UITextField заключается в подклассе и добавлении свойства edgeInsets. Затем вы устанавливаете edgeInsets, и UITextField будет нарисован соответствующим образом. Это также будет корректно работать с пользовательским набором leftView или rightView.
OSTextField.h
#import <UIKit/UIKit.h>
@interface OSTextField : UITextField
@property (nonatomic, assign) UIEdgeInsets edgeInsets;
@end
OSTextField.m
#import "OSTextField.h"
@implementation OSTextField
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
self.edgeInsets = UIEdgeInsetsZero;
}
return self;
}
-(id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if(self){
self.edgeInsets = UIEdgeInsetsZero;
}
return self;
}
- (CGRect)textRectForBounds:(CGRect)bounds {
return [super textRectForBounds:UIEdgeInsetsInsetRect(bounds, self.edgeInsets)];
}
- (CGRect)editingRectForBounds:(CGRect)bounds {
return [super editingRectForBounds:UIEdgeInsetsInsetRect(bounds, self.edgeInsets)];
}
@end
Изменение: все еще работает в iOS 11.3.1
В iOS 6 myTextField.leftView = paddingView;
вызывает проблему
Это решает проблему
myTextField.layer.sublayerTransform = CATransform3DMakeTranslation(5, 0, 0)
Для выровненного по правому краю текстового поля используйте CATransform3DMakeTranslation(-5, 0, 0)
как упомянуто latenitecoder в комментариях
Просто подкласс UITextField:
@implementation DFTextField
- (CGRect)textRectForBounds:(CGRect)bounds
{
return CGRectInset(bounds, 10.0f, 0);
}
- (CGRect)editingRectForBounds:(CGRect)bounds
{
return [self textRectForBounds:bounds];
}
@end
Это добавляет горизонтальное дополнение по 10 пунктов с каждой стороны.
Код цели C
MyTextField.h
#import <UIKit/UIKit.h>
@interface MyTextField : UITextField
@property (nonatomic) IBInspectable CGFloat padding;
@end
MyTextField.m
#import "MyTextField.h"
IB_DESIGNABLE
@implementation MyTextField
@synthesize padding;
-(CGRect)textRectForBounds:(CGRect)bounds{
return CGRectInset(bounds, padding, padding);
}
-(CGRect)editingRectForBounds:(CGRect)bounds{
return [self textRectForBounds:bounds];
}
@end
Основываясь на ответе Evil Trout, вы можете создать категорию, чтобы упростить ее использование в нескольких приложениях.
Заголовочный файл:
@interface UITextField (PaddingText)
-(void) setLeftPadding:(int) paddingValue;
-(void) setRightPadding:(int) paddingValue;
@end
Файл реализации:
#import "UITextField+PaddingText.h"
@implementation UITextField (PaddingText)
-(void) setLeftPadding:(int) paddingValue
{
UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, paddingValue, self.frame.size.height)];
self.leftView = paddingView;
self.leftViewMode = UITextFieldViewModeAlways;
}
-(void) setRightPadding:(int) paddingValue
{
UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, paddingValue, self.frame.size.height)];
self.rightView = paddingView;
self.rightViewMode = UITextFieldViewModeAlways;
}
@end
Пример использования
#import "UITextField+PaddingText.h"
[self.YourTextField setLeftPadding:20.0f];
Надеюсь, он поможет вам в ребятах.
Приветствия
- Создать текстовое поле Пользовательский
PaddingTextField.swift
import UIKit
class PaddingTextField: UITextField {
@IBInspectable var paddingLeft: CGFloat = 0
@IBInspectable var paddingRight: CGFloat = 0
override func textRectForBounds(bounds: CGRect) -> CGRect {
return CGRectMake(bounds.origin.x + paddingLeft, bounds.origin.y,
bounds.size.width - paddingLeft - paddingRight, bounds.size.height);
}
override func editingRectForBounds(bounds: CGRect) -> CGRect {
return textRectForBounds(bounds)
}}
Быстрая версия:
extension UITextField {
@IBInspectable var padding_left: CGFloat {
get {
LF.log("WARNING no getter for UITextField.padding_left")
return 0
}
set (f) {
layer.sublayerTransform = CATransform3DMakeTranslation(f, 0, 0)
}
}
}
Чтобы вы могли присвоить значение в IB
Вы не можете установить дополнение. Вместо этого есть UIView
, у которого есть фоновое изображение и UITextField
внутри него. Установите ширину UITextField
как UIViewWidth-(paddingSize x 2)
и высоту аналогично, а затем установите ее в точке paddingSize,paddingSize
.
Просто подкласс UITextField как это (Swift version):
import UIKit
class CustomTextField: UITextField {
override func textRectForBounds(bounds: CGRect) -> CGRect {
return CGRectInset(bounds, 25.0, 0)
}
override func editingRectForBounds(bounds: CGRect) -> CGRect {
return self.textRectForBounds(bounds)
}
}
Это добавляет горизонтальное дополнение к 25.0 с обеих сторон.
Я основывался на решении Nate, но потом обнаружил, что это вызывает проблемы, когда вы используете свойства leftView/rightView, поэтому его лучше настраивать супер-реализацию, поскольку она учитывает представление влево/вправо.
- (CGRect)textRectForBounds:(CGRect)bounds {
CGRect ret = [super textRectForBounds:bounds];
ret.origin.x = ret.origin.x + 5;
ret.size.width = ret.size.width - 10;
return ret;
}
- (CGRect)editingRectForBounds:(CGRect)bounds {
return [self textRectForBounds:bounds];
}
Здесь, как достичь этого в SWIFT
@IBOutlet weak var yourTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
let paddingView = UIView(frame: CGRectMake(0, 0, 10, self.yourTextField.frame.height))
yourTextField.leftView = paddingView
yourTextField.leftViewMode = UITextFieldViewMode.Always
}
}
Версия Swift 2.0:
let paddingView: UIView = UIView(frame: CGRectMake(0, 0, 5, 20))
textField.leftView = paddingView
textField.leftViewMode = UITextFieldViewMode.Always;
^ эти предложения отлично подходят для тех, кто программно создает интерфейс.
Но для тех из нас, кто использует построитель интерфейса Xcode, есть два LAZY EASY WAYS:
-
проще: поместите UIImageView за текстовое поле
-
проще всего: измените стиль рамки на свой простой черный квадрат (второй слева), затем добавьте свое изображение в качестве фонового изображения. Изображение имеет приоритет над квадратом, поэтому вы все равно получаете отступы, необходимые для обычного изображения, без квадрата, на который на самом деле нарисован.
EDIT: вы также можете использовать черную сферу (третий вариант слева при выборе UITextBox в IB), он не работает с очень правым стилем "графической сферы".
Обновленная версия для Swift 3:
@IBDesignable
class FormTextField: UITextField {
@IBInspectable var paddingLeft: CGFloat = 0
@IBInspectable var paddingRight: CGFloat = 0
override func textRect(forBounds bounds: CGRect) -> CGRect {
return CGRect(x: bounds.origin.x + paddingLeft, y: bounds.origin.y, width: bounds.size.width - paddingLeft - paddingRight, height: bounds.size.height)
}
override func editingRect(forBounds bounds: CGRect) -> CGRect {
return textRect(forBounds: bounds)
}
}
Лучший способ сделать это - просто создать класс, используя подкласс 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" в опции класса.
Примечание. Если вы просто передаете прописку с автоматическим макетом для текстового поля, ваше приложение не будет запускаться и отображать только пустой экран.
Решение Swift 3
class CustomTextField: UITextField {
override func textRect(forBounds bounds: CGRect) -> CGRect {
return CGRect(x: bounds.origin.x + 10, y: bounds.origin.y + 8, width: bounds.size.width - 20, height: bounds.size.height - 16)
}
override func editingRect(forBounds bounds: CGRect) -> CGRect {
return self.textRect(forBounds: bounds)
}
}
Установить дополнение для UITextField с помощью UITextBorderStyleNone: Swift
Основываясь на @Evil Trout, большинство проголосовавших ответов я создал собственный метод в моем классе ViewController, как показано ниже:
- (void) modifyTextField:(UITextField *)textField
{
UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)];
textField.leftView = paddingView;
textField.leftViewMode = UITextFieldViewModeAlways;
textField.rightView = paddingView;
textField.rightViewMode = UITextFieldViewModeAlways;
[textField setBackgroundColor:[UIColor whiteColor]];
[textField setTextColor:[UIColor blackColor]];
}
Теперь я могу вызвать этот метод внутри (метод viewDidLoad) и отправить любой из моих текстовых полей этому методу и добавить дополнение для правого и левого и предоставить цвета текста и фона, написав только одну строку кода следующим образом:
[self modifyTextField:self.firstNameTxtFld];
Это отлично работает на iOS 7! Я знаю, что добавление слишком большого количества представлений может сделать это немного более тяжелым классом для загрузки. Но когда мы обеспокоены трудностью других решений, я оказался более предвзятым к этому методу и более гибким с использованием этого способа.;)
Спасибо за хак "Злая форель"! (Лук)
Я думал, что должен обновить этот фрагмент кода ответа с помощью Swift:
Так как Swift позволяет нам писать расширения для существующих классов, напишите их таким образом.
extension UITextField {
func addPaddingToTextField() {
let paddingView: UIView = UIView.init(frame: CGRectMake(0, 0, 8, 20))
self.leftView = paddingView;
self.leftViewMode = .Always;
self.rightView = paddingView;
self.rightViewMode = .Always;
self.backgroundColor = UIColor.whiteColor()
self.textColor = UIColor.blackColor()
}
}
Использование:
self.firstNameTxtFld.addPaddingToTextField()
Надеюсь, это было бы полезно для кого-то другого!
Ура!
override func rightViewRectForBounds(bounds: CGRect) -> CGRect {
let rightViewBounds = super.rightViewRectForBounds(bounds)
return CGRectMake(CGRectGetMinX(rightViewBounds) - 10, CGRectGetMinY(rightViewBounds), CGRectGetWidth(rightViewBounds), CGRectGetHeight(rightViewBounds))
}
Над кодом code right padding для rightView
UITextField
.
Если кто-то ищет версию Swift 4.0
то extension
ниже работает. Он имеет Left
и Right
отступ для UITextField
. На самом деле это IBInspectable
для конфигурации раскадровки. Вы можете установить значение непосредственно из Интерфейсного Разработчика/Раскадровки. Это проверенный код в версии Swift 4.0 и Xcode 9.0
Имейте в виду, что если вы хотите включить Clear Button
на том же UITextField
то вы должны оставить Right Padding пустым.
import UIKit
extension UITextField {
@IBInspectable var paddingLeft: CGFloat {
get {
return leftView!.frame.size.width
}
set {
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: newValue, height: frame.size.height))
leftView = paddingView
leftViewMode = .always
}
}
@IBInspectable var paddingRight: CGFloat {
get {
return rightView!.frame.size.width
}
set {
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: newValue, height: frame.size.height))
rightView = paddingView
rightViewMode = .always
}
}
}
Решение Brody работало идеально для меня. Мне пришлось добавлять боковые виды в текстовое поле и добавлять дополнительные дополнения. Поэтому, реализуя пользовательское свойство UIEdgeInsets в подкласс UITextField, мне удалось выполнить задачу. Я собираюсь использовать этот новый подкласс во всех моих проектах.
Вот код Swift для заполнения в UITextfield
func txtPaddingVw(txt:UITextField) {
let paddingView = UIView(frame: CGRectMake(0, 0, 10, 10))
txt.leftViewMode = .Always
txt.leftView = paddingView
}
и вызовите с помощью
self.txtPaddingVw(txtPin)
textField.layer.borderWidth = 3;
добавит границу, которая работала как дополнение для меня.
вы можете использовать категорию. set padding влево и вправо
UITextField + Padding.h
@interface UITextField (Padding)
@property (nonatomic, assign) CGFloat paddingValue;
@property (nonatomic, assign) CGFloat leftPadding;
@property (nonatomic, assign) CGFloat rightPadding;
//overwrite
-(CGRect)textRectForBounds:(CGRect)bounds;
-(CGRect)editingRectForBounds:(CGRect)bounds;
@end
UITextField + Padding.m
#import "UITextField+Padding.h"
#import <objc/runtime.h>
static char TAG_LeftPaddingKey;
static char TAG_RightPaddingKey;
static char TAG_Left_RightPaddingKey;
@implementation UITextField (Padding)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
-(CGRect)textRectForBounds:(CGRect)bounds {
CGFloat offset_Left=0;
CGFloat offset_Right=0;
if (self.paddingValue>0) {
offset_Left=self.paddingValue;
offset_Right=offset_Left;
}else{
if (self.leftPadding>0){
offset_Left=self.leftPadding;
}
if (self.rightPadding>0){
offset_Right=self.rightPadding;
}
}
if (offset_Left>0||offset_Right>0) {
return CGRectMake(bounds.origin.x+ offset_Left ,bounds.origin.y ,
bounds.size.width- (offset_Left+offset_Right), bounds.size.height-2 );
}else{
return bounds;
}
}
-(CGRect)editingRectForBounds:(CGRect)bounds {
return [self textRectForBounds:bounds];
}
#pragma clang diagnostic pop
#pragma maek -setter&&getter
- (CGFloat)paddingValue
{
return [objc_getAssociatedObject(self,&TAG_Left_RightPaddingKey) floatValue];
}
-(void)setPaddingValue:(CGFloat)paddingValue
{
objc_setAssociatedObject(self, &TAG_Left_RightPaddingKey, @(paddingValue), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(CGFloat)leftPadding
{
return [objc_getAssociatedObject(self,&TAG_LeftPaddingKey) floatValue];
}
-(void)setLeftPadding:(CGFloat)leftPadding
{
objc_setAssociatedObject(self, &TAG_LeftPaddingKey, @(leftPadding), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(CGFloat)rightPadding
{
return [objc_getAssociatedObject(self,&TAG_RightPaddingKey) floatValue];
}
-(void)setRightPadding:(CGFloat)rightPadding
{
objc_setAssociatedObject(self, &TAG_RightPaddingKey, @(rightPadding), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
вы можете установить дополнение как self.phoneNumTF.paddingValue = 10.f; или self.phoneNumTF.leftPadding = 10.f;
@Хороший ответ на форель. Я использую этот подход уже довольно давно. Единственное, чего ему не хватает, это "работа с многочисленными текстовыми полями". Я пробовал другие подходы, но, похоже, не работает.
Подклассификация UITextField просто для добавления отступов не имеет для меня никакого смысла. Итак, я повторил все UITextFields, чтобы добавить дополнение.
-(void) addPaddingToAllTextFields:(UIView*)view {
for(id currentView in [view subviews]){
if([currentView isKindOfClass:[UITextField class]]) {
// Change value of CGRectMake to fit ur need
[currentView setLeftView:[[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 20)]];
[currentView setLeftViewMode:UITextFieldViewModeAlways];
}
if([currentView respondsToSelector:@selector(subviews)]){
[textfieldarray addObjectsFromArray:[self addPaddingToAllTextFields:currentView]];
}
}
}
Версия Swift 3:
class CustomTextField:UITextField{
required init?(coder aDecoder: NSCoder){
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
override func textRect(forBounds bounds: CGRect) -> CGRect {
return CGRect.init(x: bounds.origin.x + 8, y: bounds.origin.y, width: bounds.width, height: bounds.height)
}
override func editingRect(forBounds bounds: CGRect) -> CGRect {
return self.textRect(forBounds:bounds)
}
}
Лучшим решением, которое я нашел до сих пор, является категория. То, как я добавляю 5-точечное дополнение влево и вправо:
@implementation UITextField (Padding)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
- (CGRect)textRectForBounds:(CGRect)bounds {
return CGRectMake(bounds.origin.x + 5, bounds.origin.y,
bounds.size.width - 10, bounds.size.height);
}
- (CGRect)editingRectForBounds:(CGRect)bounds {
return [self textRectForBounds:bounds];
}
#pragma clang diagnostic pop
@end
#pragma только для удаления раздражающих предупреждений
Другое соображение состоит в том, что если у вас есть более одного UITextField
, где вы добавляете дополнение, нужно создать отдельный UIView
для каждого текстового поля, потому что они не могут быть разделены.
- 1
- 2
Другие вопросы по меткам objective-c iphone padding uitextfield или Задайте вопрос