Chciałbym, aby obramowanie w dolnej części zostało zachowane tylko w UITextField
. Ale nie wiem, jak możemy to utrzymać na dole.
Czy możesz mi doradzić?
textField
Tworzę niestandardowy, aby był komponent wielokrotnego użytku dla 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)
}
}
}
Stosowanie:
@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
Używam tutaj języka Visual Formatting Language (VFL), co pozwoli na dodanie wiersza do dowolnego pliku UIControl
.
Możesz utworzyć UIView
klasę rozszerzenia, taką jakUIView+Extention.swift
import UIKit
enum LINE_POSITION {
case LINE_POSITION_TOP
case LINE_POSITION_BOTTOM
}
extension UIView {
func addLine(position : LINE_POSITION, 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 .LINE_POSITION_TOP:
self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[lineView(width)]", options:NSLayoutConstraint.FormatOptions(rawValue: 0), metrics:metrics, views:views))
break
case .LINE_POSITION_BOTTOM:
self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[lineView(width)]|", options:NSLayoutConstraint.FormatOptions(rawValue: 0), metrics:metrics, views:views))
break
}
}
}
Stosowanie:
textField.addLine(position: .LINE_POSITION_BOTTOM, color: .darkGray, width: 0.5)
Cel C:
Możesz dodać tę metodę pomocniczą do swojej globalnej klasy pomocnika (użyłem metody klasy globalnej) lub w tym samym kontrolerze widoku (używając metody instancji).
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;
}
}
Stosowanie:
[self addLine:self.textField atPosition:LINE_POSITION_TOP withColor:[UIColor darkGrayColor] lineWitdh:0.5];
Kod 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;
Jeśli chcesz się obejść bez wcześniejszej znajomości ramek , bez podklas i bez automatycznego układu :
Swift 5 / 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
}
}
Dzwoń yourTextField.setBottomBorder()
z dowolnego miejsca, nie upewniając się, że ramki są prawidłowe.
Wynik wygląda następująco:
Swift UI
struct MyTextField: View {
var myPlaceHolder: String
@Binding var text: String
var underColor: Color
var height: CGFloat
var body: some View {
VStack {
TextField(self.myPlaceHolder, text: $text)
.padding()
.font(.title)
Rectangle().frame(height: self.height)
.padding(.horizontal, 24).foregroundColor(self.underColor)
}
}
}
viewDidLoad()
?Możesz utworzyć podklasę,
UITextField
jak pokazano poniżej:źródło
tintColor
indidBeginEditing
ididEndEditing
Żadne z tych rozwiązań nie spełniło moich oczekiwań. Chciałem podklasę TextField, ponieważ nie chcę ustawiać obramowania ręcznie przez cały czas. Chciałem też zmienić kolor obramowania np. Z powodu błędu. Oto moje rozwiązanie z
Anchors
:---- Opcjonalny ----
Aby zmienić kolor, dodaj coś w ten sposób do
CustomTextField Class
:Aby wywołać błąd, po utworzeniu wystąpienia CustomTextField
Mam nadzieję, że to komuś pomoże;)
źródło
a potem po prostu zrób to:
źródło
viewDidLoad()
, ramka byłaby niepoprawna. Mamy więc dwie możliwości:viewDidLayoutSubviews()
lubviewDidAppear()
. AleviewDidLayoutSubviews()
dzwonienie wiele razy i dzwonienie zviewDidAppear()
nie byłoby dobrym doświadczeniem.viewDidLayoutSubviews()
nie zadziała również, jeśli pole tekstowe jest zagnieżdżone wewnątrzmultiple View
. Otrzymasz wiele broderów.Możesz utworzyć to rozszerzenie poza klasą i zastąpić szerokość dowolną wartością borderWidth.
Szybki 4
Oryginalny
a następnie dodaj to do swojego viewDidLoad, zastępując yourTextField zmienną UITextField i dowolnym kolorem w obramowaniu
Zasadniczo dodaje to widok z tym kolorem u dołu pola tekstowego.
źródło
Cel C
Szybki
źródło
To, co zrobiłem, to utworzenie rozszerzenia do UITextField i dodanie edytowalnej właściwości Projektanta. Ustawienie tej właściwości na dowolny kolor spowodowałoby zmianę obramowania (na dole) na ten kolor (ustawienie innych granic na brak).
Ponieważ wymaga to również zmiany koloru tekstu zastępczego, dodałem to również do rozszerzenia.
źródło
W Swift 3. Możesz utworzyć rozszerzenie i dodać je po swojej klasie widoku.
źródło
Proszę spojrzeć na poniższy przykład kodu;
Swift 4:
źródło
Oto kod Swift3 z @IBInspectable
utwórz nowy plik Cocoa Touch Class Swift File
}
i zastąp plik poniższym kodem, a otrzymasz taką opcję w inspektorze atrybutów scenorysu
Cieszyć się :)
źródło
** W tym przypadku myTF jest gniazdem dla pola tekstowego MT **
źródło
możesz utworzyć jeden obraz dla dolnej granicy i ustawić go jako tło swojego UITextField:
lub ustaw borderStyle na none i umieść obraz linii o dokładnie takiej samej długości jak textfield!
źródło
Zaktualizowany kod:
Swift 5.0
Teraz wywołaj tę funkcję w viewDidLayoutSubviews ()
UWAGA: Ta metoda będzie działać tylko w viewDidLayoutSubviews ()
źródło
Przyjrzałem się każdemu z tych rozwiązań, które również wydają się działać z jednym problemem. Tryb ciemny i ustawienie tła
Ustawienie Tło UITextField musi być zgodne z tłem widoku nadrzędnego lub żadna linia nie jest wyświetlana
Więc to zadziała w trybie jasnym Aby dostać się do pracy w trybie ciemnym zmień kolor tła na czarny i to działa Wykluczyć kolor z tyłu a linia się nie pojawia
To okazało się dla mnie najlepszym rozwiązaniem
źródło
Instruktaż
źródło
SwiftUI
w SwiftUI, jest
View
nazywanyDivider
, który jest idealnie dopasowany do tego. Możesz dodać go poniżej dowolnego widoku, osadzając je w prostymVStack
:źródło
Możesz użyć tego ZORGANIZOWANEGO i dodatkowo DOSTOSOWAĆ to rozszerzenie:
źródło
}
wywołanie metody na viewdidload
mobileNumberTextField.underlinedLogin()
passwordTextField.underlinedLogin()
// wybierz jak pole tekstowe na płycie głównej
źródło
Do widoku: (Najbardziej zalecane)
Działa dla wszystkich typów
UIView
podklas (widok, plik tekstowy, etykieta itp.) Przy użyciuUIView extension
Jest to prostsze i wygodniejsze. Ale jedynym warunkiem jest to, że
view
musi zawierać układ automatyczny.Jak używać?
i
źródło