Граница UITextField только для нижней стороны
Я хотел бы сохранить границу в нижней части только в UITextField
.
Но я не знаю, как мы можем держать его на нижней стороне.
не могли бы вы посоветовать мне?
15 ответов:
Новый Подход: (Рекомендуется)
в конце концов, я нашел еще один способ сделать это, это более простой и удобный. Но единственное условие-это
UITextField
должен содержать макет авто.я использую язык визуального форматирования (VFL) здесь, это позволит добавить строку в любой
UIControl
.Вспомогательный Метод:
вы можете добавить этот вспомогательный метод в свой глобальный вспомогательный класс(я использовал метод глобального класса) или в том же контроллер вида (с использованием метода экземпляра).
typedef enum : NSUInteger { LINE_POSITION_TOP, LINE_POSITION_BOTTOM } LINE_POSITION; - (void) addLineToView:(UIView *)view atPosition:(LINE_POSITION)position withColor:(UIColor *)color lineWitdh:(CGFloat)width { // Add line UIView *lineView = [[UIView alloc] init]; [lineView setBackgroundColor:color]; [lineView setTranslatesAutoresizingMaskIntoConstraints:NO]; [view addSubview:lineView]; NSDictionary *metrics = @{@"width" : [NSNumber numberWithFloat:width]}; NSDictionary *views = @{@"lineView" : lineView}; [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[lineView]|" options: 0 metrics:metrics views:views]]; switch (position) { case LINE_POSITION_TOP: [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[lineView(width)]" options: 0 metrics:metrics views:views]]; break; case LINE_POSITION_BOTTOM: [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[lineView(width)]|" options: 0 metrics:metrics views:views]]; break; default: break; } }
использование:
[self addLineToView:self.textField atPosition:LINE_POSITION_TOP withColor:[UIColor darkGrayColor] lineWitdh:0.5];
С Помощью Swift:
вспомогательный метод:
enum LINE_POSITION { case LINE_POSITION_TOP case LINE_POSITION_BOTTOM } func addLineToView(view : UIView, position : LINE_POSITION, color: UIColor, width: Double) { let lineView = UIView() lineView.backgroundColor = color lineView.translatesAutoresizingMaskIntoConstraints = false // This is important! view.addSubview(lineView) let metrics = ["width" : NSNumber(value: width)] let views = ["lineView" : lineView] view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[lineView]|", options:NSLayoutFormatOptions(rawValue: 0), metrics:metrics, views:views)) switch position { case .LINE_POSITION_TOP: view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[lineView(width)]", options:NSLayoutFormatOptions(rawValue: 0), metrics:metrics, views:views)) break case .LINE_POSITION_BOTTOM: view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[lineView(width)]|", options:NSLayoutFormatOptions(rawValue: 0), metrics:metrics, views:views)) break default: break } }
использование:
self.addLineToView(view: textField, position:.LINE_POSITION_BOTTOM, color: UIColor.darkGray, width: 0.5)
Старый Подход:
этот ответ будет работать отлично, если вы создадите
UITextField
объект программно.Примечание: если
UITextField
объект создается в раскадровке тогда установите егоBorder Style
свойствоNone
в Инспекторе атрибутов раскадровки.следующая переменная
textField
объектUITextField
управление, в котором будет установлена нижняя граница.Swift код:
let border = CALayer() let width = CGFloat(2.0) border.borderColor = UIColor.darkGray.cgColor border.frame = CGRect(x: 0, y: textField.frame.size.height - width, width: textField.frame.size.width, height: textField.frame.size.height) border.borderWidth = width textField.layer.addSublayer(border) textField.layer.masksToBounds = true
Код Цели C:
CALayer *border = [CALayer layer]; CGFloat borderWidth = 2; border.borderColor = [UIColor darkGrayColor].CGColor; border.frame = CGRectMake(0, textField.frame.size.height - borderWidth, textField.frame.size.width, textField.frame.size.height); border.borderWidth = borderWidth; [textField.layer addSublayer:border]; textField.layer.masksToBounds = YES;
Xamarin кода:
var border = new CALayer(); nfloat width = 2; border.BorderColor = UIColor.Black.CGColor; border.Frame = new CoreGraphics.CGRect(0, textField.Frame.Size.Height - width, textField.Frame.Size.Width, textField.Frame.Size.Height); border.BorderWidth = width; textField.Layer.AddSublayer(border); textField.Layer.MasksToBounds = true;
многие пользователи имели проблемы с Автоматический Макет и некоторые люди не были возможность визуализации границы UITextField. Вот решение:
если вы пишете ниже код в
viewDidLoad()
метод, чем это время вы не получите кадр для текстового поля, так что граница не будет отображаться должным образом.чтобы получить правильный кадр для границы, переопределите
viewDidLayoutSubviews()
и написать код в нем.
viewDidLayoutSubviews()
метод вызывается после загрузки всех вложенных представлений в представление.не забывайте, что этот метод вызывается несколько раз, и это не является частью жизненного цикла ViewController, поэтому будьте осторожны при использовании этого.
Если вы хотите сделать не зная кадров заранее без разделения на подклассы:
Swift 4.x/Swift 3.x
extension UITextField { func setBottomBorder() { self.borderStyle = .none self.layer.backgroundColor = UIColor.white.cgColor self.layer.masksToBounds = false self.layer.shadowColor = UIColor.gray.cgColor self.layer.shadowOffset = CGSize(width: 0.0, height: 1.0) self.layer.shadowOpacity = 1.0 self.layer.shadowRadius = 0.0 } }
называй как
yourTextField.setBottomBorder()
из любого места, не убедившись в правильности кадров.результат выглядит так:
Вы можете создать подкласс
UITextField
как показано ниже:class TextField : UITextField { override var tintColor: UIColor! { didSet { setNeedsDisplay() } } override func draw(_ rect: CGRect) { let startingPoint = CGPoint(x: rect.minX, y: rect.maxY) let endingPoint = CGPoint(x: rect.maxX, y: rect.maxY) let path = UIBezierPath() path.move(to: startingPoint) path.addLine(to: endingPoint) path.lineWidth = 2.0 tintColor.setStroke() path.stroke() } }
extension UITextField { func setBottomBorder(color:String) { self.borderStyle = UITextBorderStyle.None; let border = CALayer() let width = CGFloat(1.0) border.borderColor = UIColor(hexString: color)!.CGColor border.frame = CGRect(x: 0, y: self.frame.size.height - width, width: self.frame.size.width, height: self.frame.size.height) border.borderWidth = width self.layer.addSublayer(border) self.layer.masksToBounds = true } }
а потом просто сделать это:
yourTextField.setBottomBorder(color: "#3EFE46")
ни одно из этих решений не оправдало моих ожиданий. Я хотел подкласс текстовое поле, так как я не хочу, чтобы установить границу вручную все время. Я тоже хотел изменить цвет границы например, на ошибку. Так вот мое решение с
Anchors
:class CustomTextField: UITextField { var bottomBorder = UIView() override func awakeFromNib() { // Setup Bottom-Border self.translatesAutoresizingMaskIntoConstraints = false bottomBorder = UIView.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) bottomBorder.backgroundColor = UIColor(rgb: 0xE2DCD1) // Set Border-Color bottomBorder.translatesAutoresizingMaskIntoConstraints = false addSubview(bottomBorder) bottomBorder.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true bottomBorder.leftAnchor.constraint(equalTo: leftAnchor).isActive = true bottomBorder.rightAnchor.constraint(equalTo: rightAnchor).isActive = true bottomBorder.heightAnchor.constraint(equalToConstant: 1).isActive = true // Set Border-Strength } }
---- дополнительно ----
чтобы изменить цвет, добавьте sth вот так в
CustomTextField Class
:@IBInspectable var hasError: Bool = false { didSet { if (hasError) { bottomBorder.backgroundColor = UIColor.red } else { bottomBorder.backgroundColor = UIColor(rgb: 0xE2DCD1) } } }
и чтобы вызвать ошибку, вызовите это после создания экземпляра из CustomTextField
textField.hasError = !textField.hasError
надеюсь, что это поможет кому-то;)
С
[txt.layer setBackgroundColor: [[UIColor whiteColor] CGColor]]; [txt.layer setBorderColor: [[UIColor grayColor] CGColor]]; [txt.layer setBorderWidth: 0.0]; [txt.layer setCornerRadius:12.0f]; [txt.layer setMasksToBounds:NO]; [txt.layer setShadowRadius:2.0f]; txt.layer.shadowColor = [[UIColor blackColor] CGColor]; txt.layer.shadowOffset = CGSizeMake(1.0f, 1.0f); txt.layer.shadowOpacity = 1.0f; txt.layer.shadowRadius = 1.0f;
Свифт
txt.layer.backgroundColor = UIColor.white.cgColor txt.layer.borderColor = UIColor.gray.cgColor txt.layer.borderWidth = 0.0 txt.layer.cornerRadius = 5 txt.layer.masksToBounds = false txt.layer.shadowRadius = 2.0 txt.layer.shadowColor = UIColor.black.cgColor txt.layer.shadowOffset = CGSize.init(width: 1.0, height: 1.0) txt.layer.shadowOpacity = 1.0 txt.layer.shadowRadius = 1.0
вы можете создать это расширение вне класса и заменить ширину с любой borderWidth вы хотите.
Swift 4
extension UITextField { func setBottomBorder(withColor color: UIColor) { self.borderStyle = UITextBorderStyle.none self.backgroundColor = UIColor.clear let width: CGFloat = 1.0 let borderLine = UIView(frame: CGRect(x: 0, y: self.frame.height - width, width: self.frame.width, height: width)) borderLine.backgroundColor = color self.addSubview(borderLine) } }
Оригинал
extension UITextField { func setBottomBorder(borderColor: UIColor) { self.borderStyle = UITextBorderStyle.None self.backgroundColor = UIColor.clearColor() let width = 1.0 let borderLine = UIView(frame: CGRectMake(0, self.frame.height - width, self.frame.width, width)) borderLine.backgroundColor = borderColor self.addSubview(borderLine) } }
а затем добавьте это в свой viewDidLoad, заменив yourTextField своей переменной UITextField и любым цветом, который вы хотите в границе
yourTextField.setBottomBorder(UIColor.blackColor())
Это в основном добавляет вид с этим цветом в нижней части текстового поля.
На Swift 3. Вы можете создать расширение и добавить его после класса представления.
extension UITextField { func setBottomBorder(borderColor: UIColor) { self.borderStyle = UITextBorderStyle.none self.backgroundColor = UIColor.clear let width = 1.0 let borderLine = UIView() borderLine.frame = CGRect(x: 0, y: Double(self.frame.height) - width, width: Double(self.frame.width), height: width) borderLine.backgroundColor = borderColor self.addSubview(borderLine) } }
Я создал расширение для UITextField и добавил свойство Designer editable. Установка этого свойства в любой цвет изменит границу (дно) на этот цвет (установка других границ в none).
поскольку для этого также требуется изменить цвет текста держателя места, я также добавил Это в расширение.
extension UITextField { @IBInspectable var placeHolderColor: UIColor? { get { return self.placeHolderColor } set { self.attributedPlaceholder = NSAttributedString(string:self.placeholder != nil ? self.placeholder! : "", attributes:[NSForegroundColorAttributeName: newValue!]) } } @IBInspectable var bottomBorderColor: UIColor? { get { return self.bottomBorderColor } set { self.borderStyle = UITextBorderStyle.None; let border = CALayer() let width = CGFloat(0.5) border.borderColor = newValue?.CGColor border.frame = CGRect(x: 0, y: self.frame.size.height - width, width: self.frame.size.width, height: self.frame.size.height) border.borderWidth = width self.layer.addSublayer(border) self.layer.masksToBounds = true } } }
вот swift3 код с @IBInspectable
создать новый файл Cocoa Touch Class Swift File
import UIKit extension UIView { @IBInspectable var cornerRadius: CGFloat { get { return layer.cornerRadius } set { layer.cornerRadius = newValue layer.masksToBounds = newValue > 0 } } @IBInspectable var borderWidth: CGFloat { get { return layer.borderWidth } set { layer.borderWidth = newValue } } @IBInspectable var borderColor: UIColor? { get { return UIColor(cgColor: layer.borderColor!) } set { layer.borderColor = newValue?.cgColor } } @IBInspectable var leftBorderWidth: CGFloat { get { return 0.0 // Just to satisfy property } set { let line = UIView(frame: CGRect(x: 0.0, y: 0.0, width: newValue, height: bounds.height)) line.translatesAutoresizingMaskIntoConstraints = false line.backgroundColor = UIColor(cgColor: layer.borderColor!) line.tag = 110 self.addSubview(line) let views = ["line": line] let metrics = ["lineWidth": newValue] addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "|[line(==lineWidth)]", options: [], metrics: metrics, views: views)) addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[line]|", options: [], metrics: nil, views: views)) } } @IBInspectable var topBorderWidth: CGFloat { get { return 0.0 // Just to satisfy property } set { let line = UIView(frame: CGRect(x: 0.0, y: 0.0, width: bounds.width, height: newValue)) line.translatesAutoresizingMaskIntoConstraints = false line.backgroundColor = borderColor line.tag = 110 self.addSubview(line) let views = ["line": line] let metrics = ["lineWidth": newValue] addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "|[line]|", options: [], metrics: nil, views: views)) addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[line(==lineWidth)]", options: [], metrics: metrics, views: views)) } } @IBInspectable var rightBorderWidth: CGFloat { get { return 0.0 // Just to satisfy property } set { let line = UIView(frame: CGRect(x: bounds.width, y: 0.0, width: newValue, height: bounds.height)) line.translatesAutoresizingMaskIntoConstraints = false line.backgroundColor = borderColor line.tag = 110 self.addSubview(line) let views = ["line": line] let metrics = ["lineWidth": newValue] addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "[line(==lineWidth)]|", options: [], metrics: metrics, views: views)) addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[line]|", options: [], metrics: nil, views: views)) } } @IBInspectable var bottomBorderWidth: CGFloat { get { return 0.0 // Just to satisfy property } set { let line = UIView(frame: CGRect(x: 0.0, y: bounds.height, width: bounds.width, height: newValue)) line.translatesAutoresizingMaskIntoConstraints = false line.backgroundColor = borderColor line.tag = 110 self.addSubview(line) let views = ["line": line] let metrics = ["lineWidth": newValue] addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "|[line]|", options: [], metrics: nil, views: views)) addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[line(==lineWidth)]|", options: [], metrics: metrics, views: views)) } } func removeborder() { for view in self.subviews { if view.tag == 110 { view.removeFromSuperview() } } }
}
и замените файл с приведенным ниже кодом, и вы получите опцию в инспекторе атрибутов раскадровки, как это
наслаждайтесь :)
пожалуйста, взгляните на приведенный ниже пример кода;
Swift 4:
@IBDesignable class DesignableUITextField: UITextField { let border = CALayer() @IBInspectable var borderColor: UIColor? { didSet { setup() } } @IBInspectable var borderWidth: CGFloat = 0.5 { didSet { setup() } } func setup() { border.borderColor = self.borderColor?.cgColor border.borderWidth = borderWidth self.layer.addSublayer(border) self.layer.masksToBounds = true } override func layoutSubviews() { super.layoutSubviews() border.frame = CGRect(x: 0, y: self.frame.size.height - borderWidth, width: self.frame.size.width, height: self.frame.size.height) } }
* * здесь myTF-это выход для текстового поля MT**
let border = CALayer() let width = CGFloat(2.0) border.borderColor = UIColor.darkGray.cgColor border.frame = CGRect(x: 0, y: self.myTF.frame.size.height - width, width: self.myTF.frame.size.width, height: self.myTF.frame.size.height) border.borderWidth = width self.myTF.layer.addSublayer(border) self.myTF.layer.masksToBounds = true
вы можете создать одно изображение для нижней границы и установить его на фоне вашего UITextField:
yourTextField.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"yourBorderedImageName"]];
или установите borderStyle в none и поместите изображение линии точно равной длины в текстовое поле!
вы можете использовать этот организовал, а также настройка Это расширение далее:
" Реализация Одной Строки" в viewDidAppear(Так что размер кадра будет правильно):
// Add layer in your textfield yourTextField.addLayer(.bottom).addPadding(.left) // Extension extension UITextField { enum Position { case up, bottom, right, left } // MARK: - Add Single Line Layer func addLayer(_ position: Position) -> UITextField { // bottom layer let bottomLayer = CALayer() // set width let height = CGFloat(1.0) bottomLayer.borderWidth = height // set color bottomLayer.borderColor = UIColor.white.cgColor // set frame // y position changes according to the position let yOrigin = position == .up ? 0.0 : frame.size.height - height bottomLayer.frame = CGRect.init(x: 0, y: yOrigin, width: frame.size.width, height: height) layer.addSublayer(bottomLayer) layer.masksToBounds = true return self } // Add right/left padding view in textfield func addPadding(_ position: Position, withImage image: UIImage? = nil) { let paddingHeight = frame.size.height let paddingViewFrame = CGRect.init(x: 0.0, y: 0.0, width: paddingHeight * 0.6, height: paddingHeight) let paddingImageView = UIImageView.init(frame: paddingViewFrame) paddingImageView.contentMode = .scaleAspectFit if let paddingImage = image { paddingImageView.image = paddingImage } // Add Left/Right view mode switch position { case .left: leftView = paddingImageView leftViewMode = .always case .right: rightView = paddingImageView rightViewMode = .always default: break } } }
import UIkit extension UITextField { func underlinedLogin() { let border = CALayer() let width = CGFloat(1.0) border.borderColor = UIColor.black.cgColor border.frame = CGRect(x: 0, y: self.frame.size.height - width, width: self.frame.size.width, height: self.frame.size.height) border.borderWidth = width self.layer.addSublayer(border) self.layer.masksToBounds = true }
}
вызов метода на viewdidload
mobileNumberTextField.underlinedLogin()
passwordTextField.underlinedLogin()
/ / выберите как текстовое поле на mainstoryboard