Vertically centering a UITextField's attributedPlaceholder - ios

I am currently unable to vertically align an attributedPlaceholder inside a UITextField and I've no idea why.
Here's what I am doing:
self.addressBar = [[UITextField alloc] initWithFrame: CGRectMake(...)];
self.addressBar.backgroundColor = [UIColor whiteColor];
self.addressBar.attributedPlaceholder = [[NSAttributedString alloc] initWithString:#"Placeholder text"
attributes:#{
NSForegroundColorAttributeName: [UIColor colorWithRed:79/255.0f green:79/255.0f blue:79/255.0f alpha:0.5f],
NSFontAttributeName : [UIFont fontWithName:#"Gotham-BookItalic" size:14.0],
}
];
self.addressBar.delegate = self;
self.addressBar.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
[self.view addSubview:self.addressBar];
And here's what happening:
It's quite clear that this happens due to the fact that the UITextFieldLabel's height is 10px smaller than the UItextField itself, but I can't seem change that.
This only happens using an attributedPlaceholder though; the default placeholder property works just fine.
Any ideas?

Use NSParagraphStyle to increase minimum line height:
NSMutableParagraphStyle *style = [self.addressBar.defaultTextAttributes[NSParagraphStyleAttributeName] mutableCopy];
style.minimumLineHeight = self.addressBar.font.lineHeight - (self.addressBar.font.lineHeight - [UIFont fontWithName:#"Gotham-BookItalic" size:14.0].lineHeight) / 2.0;
self.addressBar.attributedPlaceholder = [[NSAttributedString alloc] initWithString:#"Placeholder text"
attributes:#{
NSForegroundColorAttributeName: [UIColor colorWithRed:79/255.0f green:79/255.0f blue:79/255.0f alpha:0.5f],
NSFontAttributeName : [UIFont fontWithName:#"Gotham-BookItalic" size:14.0],
NSParagraphStyleAttributeName : style
}
];
You could also override a - (CGRect)placeholderRectForBounds:(CGRect)bounds; method in UITextField subclass.
It's messy, but it works :)

Placeholder will not be aligned if your textfield's text font is different than that of textfield's placeholder's font. Make sure both the font are same if you want to align properly or else you can follow kean's answer.
textField.font = [UIFont fontWithName:#"HelveticaNeue" size:12];
textField.attributedPlaceholder =
[[NSAttributedString alloc] initWithString:#"Enter fruit/vegetable name"
attributes:#{
NSFontAttributeName : [UIFont fontWithName:#"HelveticaNeue" size:12.0]
}
];

If you are using attributedPlaceholder, make sure to set the font of the textField to be the same font you use in the attributedString.

As #Kean answered. And you should do it like this in Swift 4:
let defaultParagraphValue = self.textField.defaultTextAttributes[NSAttributedStringKey.paragraphStyle.rawValue]
if let lineHeight = self.textField.font?.lineHeight,
let style = defaultParagraphValue as? NSParagraphStyle,
let mutableStyle = style.mutableCopy() as? NSMutableParagraphStyle {
mutableStyle.minimumLineHeight = lineHeight - (lineHeight - UIFont.systemFont(ofSize: 16).lineHeight) / 2.0
let placeholderAttribute = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 16),
NSAttributedStringKey.paragraphStyle: mutableStyle]
let attributeHolder = NSAttributedString(string: "Placeholder String",
attributes: placeholderAttribute)
self.textField.attributedPlaceholder = attributeHolder
}
This works in iOS 10, iOS 11 fix this issue.

Related

IOS align text placeholder to be in the center and left alignment

I'm creating an IOS form that submits feed back.
I want to have placeholder text to be in the center vertically and left alignment horizontal in the text field
I have tried this
- (void)drawPlaceholderInRect:(CGRect)rect {
[RGB(36, 84, 157) setFill];
UIFont *font = [UIFont SingPostLightItalicFontOfSize:_placeholderFontSize fontKey:kSingPostFontOpenSans];
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
paragraphStyle.alignment = NSTextAlignmentLeft;
NSDictionary *attributes = #{ NSFontAttributeName: font,
NSParagraphStyleAttributeName: paragraphStyle,
NSForegroundColorAttributeName: [UIColor blackColor]};
[[self placeholder] drawInRect:rect withAttributes:attributes];
}
But the place holder text is on top vertical. How can we achieve the gold. Thanks a lot
The following code will solve your problem. I tried it myself. It's just one additional line to your code.
- (void)drawPlaceholderInRect:(CGRect)rect {
CGFloat fontSize = 18;
UIFont *font = [UIFont systemFontOfSize:fontSize];
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
paragraphStyle.alignment = NSTextAlignmentLeft;
NSDictionary *attributes = #{ NSFontAttributeName: font,
NSParagraphStyleAttributeName: paragraphStyle,
NSForegroundColorAttributeName: [UIColor blackColor]};
CGRect newRect = CGRectInset(rect, 0, rect.size.height/2 - fontSize/2);
[[super placeholder] drawInRect:newRect withAttributes:attributes];
}
You can put placeholder's "y" position means your "rect" value as a textfield height/2 .One more solution if you use default property of textfield for placeholder that would be horizontally aligned .
like as :
var tt : UITextField
tt.placeholder = ""

UITextView: Background Color while keeping Left/Right Paragraph Indent

In my UITextView, I want certain NSRanges to be indented left and right equally and be highlighted in a specific color. I am achieving this by modifying NSMutableAttributedStrings and setting the textView.attributedText. To get the left/right indentation, I'm using NSMutableParagraphStyle - however, this is removing the highlighting (NSBackgroundColor). How can I get it such that the highlighting starts from the beginning, even with the headIndent.
// padding
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.headIndent = 5.0;
paragraphStyle.firstLineHeadIndent = 5.0;
paragraphStyle.tailIndent = -5.0;
NSDictionary *referenceAttributes = #{NSForegroundColorAttributeName: [UIColor lightGrayColor], NSBackgroundColorAttributeName: [UIColor brownColor], NSFontAttributeName: [UIFont fontWithName:#"HelveticaNeue-Bold" size: 14], NSParagraphStyleAttributeName: paragraphStyle};
Use following code to give padding in UITextView
self.textView.textContainer.lineFragmentPadding = 0;

AttributedString in UINavigationBar not showing both lines of text

I am trying to set a two line label in my UINavigationBar. When I do the following, it only shows one line (the part before the line break).
NSString *title = #"First line of title is bigger\nSecond line of title is smaller";
NSDictionary *attribute1 = #{NSForegroundColorAttributeName: [UIColor colorWithRed:148/255.0f green:147/255.0f blue:147/255.0f alpha:1],
NSFontAttributeName: [UIFont boldSystemFontOfSize: 14.0f]};
NSDictionary *attribute2 = #{NSForegroundColorAttributeName: [UIColor colorWithRed:148/255.0f green:147/255.0f blue:147/255.0f alpha:1],
NSFontAttributeName: [UIFont boldSystemFontOfSize: 10.0f]};
const NSRange line1Range = {0, 29};
const NSRange line2Range = {31, 30};
NSMutableAttributedString *attributedText =[[NSMutableAttributedString alloc] initWithString:title];
[attributedText setAttributes: attribute1 range:line1Range];
[attributedText setAttributes: attribute2 range:line2Range];
UILabel *label = [[UILabel alloc] init];
label.attributedText=attributedText;
self.navigationItem.titleView = label;
[self.navigationItem.titleView sizeToFit];
For comparison, the following shows both line. The following is for comparison only. The top version is what I need.
UILabel *label = [[UILabel alloc] init];
label.backgroundColor = [UIColor clearColor];
label.numberOfLines = 2;
label.font = [UIFont boldSystemFontOfSize: 14.0f];
label.textColor = [UIColor colorWithRed:148/255.0f green:147/255.0f blue:147/255.0f alpha:1];
label.text = #"First line of title is bigger\nSecond line of title is smaller";
self.navigationItem.titleView = label;
[self.navigationItem.titleView sizeToFit];
Any help getting the top version to work correctly?
It appears that calling label.sizeToFit() before self.navigationItem.titleView = label displays the NSAttributedString title correctly.
(Swift, iOS8.1, XCode 6.1.1)
Easy problem, easy solution. Even if you are using attributedText instead of text, you still need to:
label.numberOfLines = 0;

attributedPlaceholder font change

I am trying to change the font of my placeholder but although the placeholder text appears, the font is the standard. Im using the following method to set up my UITextField:
UITextField *name = [[UITextField alloc] initWithFrame:CGRectMake(25, 0, frame.size.width - 50, 50)];
name.borderStyle = UITextBorderStyleNone;
name.background = [UIImage imageNamed:#"UITextField_orange.png"];
name.attributedPlaceholder = [[NSAttributedString alloc] initWithString:#"Name" attributes:#{NSFontAttributeName:#"Champagne&Limousines"}];;
[self addSubview:name];
The value that goes with the NSFontAttributeName key should be a UIFont object:
name.attributedPlaceholder = [[NSAttributedString alloc] initWithString:#"Name" attributes: #{
NSFontAttributeName: [UIFont fontWithName:#"Champagne&Limousines" size:12]
}];

Letterpress effect for UILabel in iOS 7 SDK

In the WWDC 2013 videos they show that a developer can use a letterpress effect on text.
Does anyone have any example code of how to do this/how to do this with a UILabel?
They've made it pretty simple now.
//Use any font you want or skip defining it
UIFont* font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
//Use any color you want or skip defining it
UIColor* textColor = [UIColor blueColor];
NSDictionary *attrs = #{ NSForegroundColorAttributeName : textColor,
NSFontAttributeName : font,
NSTextEffectAttributeName : NSTextEffectLetterpressStyle};
NSAttributedString* attrString = [[NSAttributedString alloc]
initWithString:note.title
attributes:attrs];
myTextLabel.attributedText = attrString;
It's part of NSAttributedString UIKitAdditions

Resources