How to Add a Bottom Line on Textfield (Swiftui)

How can I add a bottom line on TextField (SwiftUI)

The solution of kontiki does not work with Beta 6, though.
So I created a solution where I embed a TextField and a drawn bottom line in a new view. You can just copy the code and use it by writing TextFieldWithBottomLine(placeholder: "My placeholder") Used in a view it looks like:

Usage of TextView with bottom line

The first thing I create is a horizontal line:

import SwiftUI

struct HorizontalLineShape: Shape {

func path(in rect: CGRect) -> Path {

let fill = CGRect(x: 0, y: 0, width: rect.size.width, height: rect.size.height)
var path = Path()
path.addRoundedRect(in: fill, cornerSize: CGSize(width: 2, height: 2))

return path
}
}

struct HorizontalLine: View {
private var color: Color? = nil
private var height: CGFloat = 1.0

init(color: Color, height: CGFloat = 1.0) {
self.color = color
self.height = height
}

var body: some View {
HorizontalLineShape().fill(self.color!).frame(minWidth: 0, maxWidth: .infinity, minHeight: height, maxHeight: height)
}
}

struct HorizontalLine_Previews: PreviewProvider {
static var previews: some View {
HorizontalLine(color: .black)
}
}

Next I create a view that contains a TextField and the HorizontalLine below:

import SwiftUI

struct TextFieldWithBottomLine: View {
@State var text: String = ""
private var placeholder = ""
private let lineThickness = CGFloat(2.0)

init(placeholder: String) {
self.placeholder = placeholder
}

var body: some View {
VStack {
TextField(placeholder, text: $text)
HorizontalLine(color: .black)
}.padding(.bottom, lineThickness)
}
}

struct TextFieldWithBottomLine_Previews: PreviewProvider {
static var previews: some View {
TextFieldWithBottomLine(placeholder: "My placeholder")
}
}

To see it in action I created a sample view:

import SwiftUI

struct SampleView: View {
@State var text: String = ""
@ObservedObject var model: LoginModel

init() {
self.model = LoginModel()
}

init(model: LoginModel) {
self.model = model
}

var body: some View {
TextFieldWithBottomLine(placeholder: "My placeholder").padding(24)
}

func initialActions() {

}

func reactOnButtonClick() {

}
}

struct SampleView_Previews: PreviewProvider {
static var previews: some View {
SampleView()
}
}

Add bottom border line to UI TextField view in SwiftUI / Swift / Objective-C / Xamarin

I am creating custom textField to make it reusable component for SwiftUI

SwiftUI

struct CustomTextField: View {
var placeHolder: String
@Binding var value: String

var lineColor: Color
var width: CGFloat

var body: some View {
VStack {
TextField(self.placeHolder, text: $value)
.padding()
.font(.title)

Rectangle().frame(height: self.width)
.padding(.horizontal, 20).foregroundColor(self.lineColor)
}
}
}

Usage:

@Binding var userName: String
@Binding var password: String

var body: some View {
VStack(alignment: .center) {
CustomTextField(placeHolder: "Username", value: $userName, lineColor: .white, width: 2)
CustomTextField(placeHolder: "Password", value: $password, lineColor: .white, width: 2)
}
}



Swift 5.0

I am using Visual Formatting Language (VFL) here, This will allow adding a line to any UIControl.

You can create a UIView extension class like UIView+Extention.swift

import UIKit

enum LinePosition {
case top
case bottom
}

extension UIView {
func addLine(position: LinePosition, color: UIColor, width: Double) {
let lineView = UIView()
lineView.backgroundColor = color
lineView.translatesAutoresizingMaskIntoConstraints = false // This is important!
self.addSubview(lineView)

let metrics = ["width" : NSNumber(value: width)]
let views = ["lineView" : lineView]
self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[lineView]|", options:NSLayoutConstraint.FormatOptions(rawValue: 0), metrics:metrics, views:views))

switch position {
case .top:
self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[lineView(width)]", options:NSLayoutConstraint.FormatOptions(rawValue: 0), metrics:metrics, views:views))
break
case .bottom:
self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[lineView(width)]|", options:NSLayoutConstraint.FormatOptions(rawValue: 0), metrics:metrics, views:views))
break
}
}
}

Usage:

textField.addLine(position: .LINE_POSITION_BOTTOM, color: .darkGray, width: 0.5)

Objective C:

You can add this helper method to your global helper class(I used global class method) or in the same view controller(using an instance method).

typedef enum : NSUInteger {
LINE_POSITION_TOP,
LINE_POSITION_BOTTOM
} LINE_POSITION;

- (void) addLine:(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;
}
}

Usage:

[self addLine:self.textField atPosition:LINE_POSITION_TOP withColor:[UIColor darkGrayColor] lineWitdh:0.5];

Xamarin code:

 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;

TextField stroke border text with SwiftUI

Here is a solution using .trim on two RoundedRectangles based on the length of the label text, which should give you the result you want:

struct CustomTextField: View {
let placeholder: String
@Binding var text: String

@State private var width = CGFloat.zero
@State private var labelWidth = CGFloat.zero

var body: some View {
TextField(placeholder, text: $text)
.foregroundColor(.gray)
.font(.system(size: 20))
.padding(EdgeInsets(top: 15, leading: 10, bottom: 15, trailing: 10))
.background {
ZStack {
RoundedRectangle(cornerRadius: 5)
.trim(from: 0, to: 0.55)
.stroke(.gray, lineWidth: 1)
RoundedRectangle(cornerRadius: 5)
.trim(from: 0.565 + (0.44 * (labelWidth / width)), to: 1)
.stroke(.gray, lineWidth: 1)
Text(placeholder)
.foregroundColor(.gray)
.overlay( GeometryReader { geo in Color.clear.onAppear { labelWidth = geo.size.width }})
.padding(2)
.font(.caption)
.frame(maxWidth: .infinity,
maxHeight: .infinity,
alignment: .topLeading)
.offset(x: 20, y: -10)

}
}
.overlay( GeometryReader { geo in Color.clear.onAppear { width = geo.size.width }})
.onChange(of: width) { _ in
print("Width: ", width)
}
.onChange(of: labelWidth) { _ in
print("labelWidth: ", labelWidth)
}


}
}

Sample Image

how to add % symbol at the end textField in swiftUI

for this i made a function and on right side put a image as percentage that fixed my issue

    func makeUIView(context: Context) -> UITextField {
let textField = UITextField(frame: .zero)
textField.delegate = context.coordinator
textField.tintColor = UIColor.clear
textField.rightView = makeImageForTextField()
textField.rightViewMode = .always
textField.keyboardType = .decimalPad
let toolBar = UIToolbar(
frame: CGRect(
x: 0, y: 0,
width: textField.frame.size.width,
height: 44
)
)
let doneButton = UIBarButtonItem(
title: "Done",
style: .done,
target: self,
action: #selector(textField.doneButtonTapped(button:))
)

toolBar.items = [doneButton]
toolBar.setItems([doneButton], animated: true)
textField.inputAccessoryView = toolBar
return textField
}

private func makeImageForTextField() -> UIButton {
let button = UIButton()
button.setImage(UIImage(systemName: "percent"), for: .normal)
button.tintColor = .black
button.isUserInteractionEnabled = false
return button
}

Creating a textfield with only bottom Line in Ios

Yes it is possible. Here is how to do it:

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;

Hope this helps!!

How to only show bottom border of UITextField in Swift

Try to do by this way, with Swift 5.1:

var bottomLine = CALayer()
bottomLine.frame = CGRect(x: 0.0, y: myTextField.frame.height - 1, width: myTextField.frame.width, height: 1.0)
bottomLine.backgroundColor = UIColor.white.cgColor
myTextField.borderStyle = UITextField.BorderStyle.none
myTextField.layer.addSublayer(bottomLine)

You have to set the borderStyle property to None

If you are using the autolayout then set perfect constraint else bottomline will not appear.

Hope it helps.

Xcode: Swift - How to make bottom line border color that appears/disappear when the text field is edited?

Go with below steps:

@IBOutlet var nameTextField: UITextField    
@IBOutlet var surnameTextField: UITextField

override func viewDidLoad() {
super.viewDidLoad()
nameTextField.delegate = self
}

func textFieldDidBeginEditing(textField: UITextField!) { //didBegin method(when you start editing in textfield)
//To addBorder for specific Textfield just make a if else condition like:
if textField == nameTextField {
addBottomBorder()
}

}

func textFieldShouldEndEditing(textField: UITextField!) -> Bool { //EndEiditing method(when you end editing in textfield)
//To removeBorder for specific Textfield just make a if else condition like:
if textField == nameTextField {
removeBottomBorder()
}

}


Related Topics



Leave a reply



Submit