Meine Anwendung verwendet ein UITextView
. Jetzt möchte ich die UITextView
einen Platzhalter zu haben, der dem Platzhalter ähnelt, den Sie für eine UITextField
.
Wie kann man das tun?
Meine Anwendung verwendet ein UITextView
. Jetzt möchte ich die UITextView
einen Platzhalter zu haben, der dem Platzhalter ähnelt, den Sie für eine UITextField
.
Wie kann man das tun?
Einfach erstellen @IBDesignable
Unterklasse Ihrer UITextView
:
@IBDesignable class AttributedTextView: UITextView {
private let placeholderLabel = UILabel()
@IBInspectable var placeholder: String = "" {
didSet {
setupPlaceholderLabelIfNeeded()
textViewDidChange()
}
}
override var text: String! {
didSet {
textViewDidChange()
}
}
//MARK: - Initialization
override func awakeFromNib() {
super.awakeFromNib()
setupPlaceholderLabelIfNeeded()
NotificationCenter.default.addObserver(self, selector: #selector(textViewDidChange), name: .UITextViewTextDidChange, object: nil)
}
//MARK: - Deinitialization
deinit {
NotificationCenter.default.removeObserver(self)
}
//MARK: - Internal
func textViewDidChange() {
placeholderLabel.isHidden = !text.isEmpty
layoutIfNeeded()
}
//MARK: - Private
private func setupPlaceholderLabelIfNeeded() {
placeholderLabel.removeFromSuperview()
placeholderLabel.frame = CGRect(x: 0, y: 8, width: frame.size.width, height: 0)
placeholderLabel.textColor = UIColor.lightGray
placeholderLabel.text = placeholder
placeholderLabel.sizeToFit()
insertSubview(placeholderLabel, at: 0)
}
}
und richten Sie dann einfach Ihren Platzhalter in Identitätskontrolleur :
Nachdem ich die meisten der vorgeschlagenen Lösungen für diese scheinbar offensichtliche - aber fehlende - Funktion von UITextView durchgesehen (und ausprobiert) habe, war die "beste" Lösung, die ich gefunden habe, die von BobDickinson. Aber ich mochte es nicht, auf eine ganz neue Unterklasse zurückgreifen zu müssen [ich bevorzuge Drop-in-Kategorien für solch einfache funktionale Ergänzungen], und auch nicht, dass sie UITextViewDelegate-Methoden abfängt, was wahrscheinlich Ihren bestehenden UITextView-Verarbeitungscode durcheinanderbringen wird. Hier ist also mein Vorschlag für eine Drop-in-Kategorie, die mit jeder bestehenden UITextView-Instanz funktionieren wird...
#import <objc/runtime.h>
// Private subclass needed to override placeholderRectForBounds: to correctly position placeholder
@interface _TextField : UITextField
@property UIEdgeInsets insets;
@end
@implementation _TextField
- (CGRect)placeholderRectForBounds:(CGRect)bounds
{
CGRect rect = [super placeholderRectForBounds:bounds];
return UIEdgeInsetsInsetRect(rect, _insets);
}
@end
@implementation UITextView (Placeholder)
static const void *KEY;
- (void)setPlaceholder:(NSString *)placeholder
{
_TextField *textField = objc_getAssociatedObject(self, &KEY);
if (!textField) {
textField = [_TextField.alloc initWithFrame:self.bounds];
textField.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
textField.userInteractionEnabled = NO;
textField.font = self.font;
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
textField.insets = UIEdgeInsetsMake(self.textContainerInset.top,
self.textContainerInset.left + self.textContainer.lineFragmentPadding,
self.textContainerInset.bottom,
self.textContainerInset.right);
[self addSubview:textField];
[self sendSubviewToBack:textField];
objc_setAssociatedObject(self, &KEY, textField, OBJC_ASSOCIATION_RETAIN);
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(updatePlaceholder:) name:UITextViewTextDidChangeNotification object:nil];
}
textField.placeholder = placeholder;
}
- (NSString*)placeholder
{
UITextField *textField = objc_getAssociatedObject(self, &KEY);
return textField.placeholder;
}
- (void)updatePlaceholder:(NSNotification *)notification
{
UITextField *textField = objc_getAssociatedObject(self, &KEY);
textField.font = self.font;
[textField setAlpha:self.text.length? 0 : 1];
}
@end
Es ist einfach zu bedienen, nur das Offensichtliche
UITextView *myTextView = UITextView.new;
...
myTextView.placeholder = @"enter text here";
Es funktioniert durch Hinzufügen eines UITextField - an der richtigen Stelle - hinter Ihrer UITextView, und nutzen Sie Es ist Platzhalter statt (daher müssen Sie sich nicht um die richtige Farbe usw. kümmern), dann hören für Benachrichtigungen, wann immer Ihr UITextView geändert wird, um dieses UITextField anzuzeigen/auszublenden (und daher stört es nicht mit Ihren bestehenden UITextViewDelegate-Aufrufen). Und es sind keine magischen Zahlen involviert... :-)
Mit objc_setAssociatedObject()/objc_getAssociatedObject() soll vermieden werden, dass die Unterklasse UITextView verwendet werden muss. [Um das UITextField korrekt zu positionieren, war es leider notwendig, eine "private" Unterklasse einzuführen, um placeholderRectForBounds zu überschreiben:]
Angepasst von BobDickinsons Swift-Antwort.
Ich habe gerade festgestellt, dass ab dem iOS 10
können Sie jetzt tatsächlich eine UITextView
zu einer Methode als UITextField
und setzen Sie innerhalb der Methode den Platzhalter. Gerade versucht und es funktioniert ohne Unterklasse UITextView
.
Dies ist ein Beispiel dafür, was bei mir funktioniert hat:
-(void)customizeTextField:(UITextField *)textField placeholder:(NSString *)pText withColor:(UIColor *)pTextColor{
textField.attributedPlaceholder = [[NSAttributedString alloc]
initWithString:pText
attributes:@{NSForegroundColorAttributeName:pTextColor}];
}
Und um es für eine UITextView
müssen Sie es einfach mit einem Cast wie diesem an die Methode übergeben:
[self customizeTextField:(UITextField*)_myTextView placeholder:@"Placeholder" withColor:[UIColor blackColor]];
N.B: Nach einem Test habe ich herausgefunden, dass die Lösung auch unter folgenden Bedingungen gut funktioniert iOS9.x
verursacht aber einen Absturz bei iOS8.x
Einfacher und immer noch unter Berücksichtigung des vom Benutzer eingegebenen Textes
BOOL placeHolderTextVisible;
bei viewDidLoad auf YES setzen (oder DidMoveToSuperview, oder awakeFromNib)
dann, bei - (BOOL) textView:(UITextView*)textView shouldBeginEditing
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView;
{
if (placeHolderTextVisible) {
placeHolderTextVisible = NO;
textView.text = @"";
}
return YES;
}
Sie können einfach eine Beschriftung für die Textansicht festlegen.
MyUITextView.h
@interface MyUITextView : UITextView {
UILabel* _placeholderLabel;
}
@property(nonatomic, assign)NSString *placeholder;
MyUITextView.m
@implementation MyUITextView
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Create placeholder
viewFrame = CGRectMake(0, 0, frame.size.width, 15);
_placeholderLabel = [[UILabel alloc] initWithFrame:viewFrame];
_placeholderLabel.textColor = [UIColor lightGrayColor];
[self addSubview:_placeholderLabel];
// Add text changed notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil];
}
return self;
}
- (void)setPlaceholder:(NSString *)placeholder {
_placeholderLabel.text = placeholder;
}
- (NSString*)placeholder {
return _placeholderLabel.text;
}
#pragma mark UITextViewTextDidChangeNotification
- (void)textChanged:(NSNotification *)notification {
_placeholderLabel.hidden = ([self.text lenght] == 0);
}
@end
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
0 Stimmen
Der TTTextEditor von Three20 (der seinerseits UITextField verwendet) unterstützt sowohl Platzhaltertext als auch das Wachsen nach Höhe (er wird zu einem UITextView).
0 Stimmen
Hier ist eine kleine und geniale Lösung für dieses Problem
24 Stimmen
Wie wäre es mit der Kategorie UITextView+Placeholder? github.com/devxoul/UITextView-Platzhalter
2 Stimmen
Ich bevorzuge die Lösung von @devxoul, da sie Kategorie und nicht Unterklasse verwendet. Außerdem erzeugt sie ein Feld für "Platzhalter"-Optionen (Platzhaltertext und Textfarbe) in IBs Inspektor. Sie verwendet einige Bindungstechniken. Was für ein toller Code
0 Stimmen
Wenn Sie Folgendes verwenden
UITextView
wird die Lösung ganz anders aussehen. Hier sind ein paar Lösungen. Schwebender Platzhalter y Gefälschte Native Platzhalter0 Stimmen
Versuchen Sie diese Antwort :) [_textView setTextColor:[UIColor lightGrayColor]];
0 Stimmen
@ICoffeeConsumer Interessant ist, dass die native iOS-Kalender-App mehrzeiligen editierbaren Text hat - mit einem Platzhalter (Hinzufügen von "Notizen" zu einem Ereignis). Es gibt also einen direkten Beweis dafür, dass Apple selbst die Notwendigkeit/Nutzung dafür erkennt.