Is is possible to change a UISearchBar placeholder's alignment? - ios

I am going to need to show the UISearchBar in different alignments because of different input languages.
I saw this answer, but I can't find where is it that you actually align the text to the right on a UISearchBar.
Any ideas?
Thanks!

This is what I've done:
for (UIView *subView in self.subviews){
if ([subView isKindOfClass:[UITextField class]]) {
UITextField *text = (UITextField*)subView;
text.textAlignment = UITextAlignmentRight;
text.rightViewMode = UITextFieldViewModeAlways;
}
}
If you also want to move the magnifying glass icon, you can do this:
text.leftView = nil;
text.rightView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"search_icon.png"]];
But you will have to provide the search_icon.png image.

Here is the solution
UITextField *searchTextField = [searchBar valueForKey:#"_searchField"];
UILabel *placeholderLabel = [searchTextField valueForKey:#"_placeholderLabel"];
[placeholderLabel setTextAlignment:NSTextAlignmentLeft];

To set attributed placeholder text to achieve left aligned placeholder, try this code...
//Step1 : Make blank attributed string
NSMutableAttributedString * attributedString = [[NSMutableAttributedString alloc] initWithString:#""];
//Step2 : Append placeholder to blank attributed string
NSString *strSearchHere = #"Search here...";
NSDictionary * attributes = [NSDictionary dictionaryWithObject:[UIColor blackColor] forKey:NSForegroundColorAttributeName];
NSAttributedString * subString = [[NSAttributedString alloc] initWithString:strSearchHere attributes:attributes];
[attributedString appendAttributedString:subString];
//Step3 : Append dummy text to blank attributed string
NSString *strLongText = #"LongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongTextLongText";
NSDictionary * attributesLong = [NSDictionary dictionaryWithObject:[UIColor clearColor] forKey:NSForegroundColorAttributeName];
NSAttributedString * subStringLong = [[NSAttributedString alloc] initWithString:strLongText attributes:attributesLong];
[attributedString appendAttributedString:subStringLong];
//Step4 : Set attributed placeholder string to searchBar textfield
UITextField *searchTextField = [searchBarr valueForKey:#"_searchField"];
searchTextField.attributedPlaceholder = attributedString;
searchTextField.leftView = nil; //To Remove Search icon
searchTextField.textAlignment = NSTextAlignmentLeft;

Related

Changing the color of a buttons text in iOS (objective-c)

I want to change the color of the text in my button to be blue on load. I also need only the first 9 letters (length of userName) of the buttons text to be blue, not all of the text. How do I do this?
Example:
This above image shows "#LisaLisa is following you". This is the buttons text. How do I make just "#LisaLisa" to be blue, with "is following you" staying black?
UIButton *someButton = [UIButton buttonWithType:UIButtonTypeSystem];
NSString *someUsername = #"#LisaLisa";
NSString *buttonText = [NSString stringWithFormat:#"%# is following you.", someUsername];
NSRange rangeToHighlight = [buttonText rangeOfString:someUsername];
NSDictionary *defaultAttributes = #{NSForegroundColorAttributeName: [UIColor blackColor]};
NSDictionary *highlightedAttributes = #{NSForegroundColorAttributeName: [UIColor blueColor]};
NSMutableAttributedString *attributedTitle = [[NSMutableAttributedString alloc] initWithString:buttonText attributes:defaultAttributes];
[attributedTitle addAttributes:highlightedAttributes range:rangeToHighlight];
[someButton setAttributedTitle:attributedTitle forState:UIControlStateNormal];
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setLineBreakMode:NSLineBreakByWordWrapping];
UIColor *color1 = [UIColor redColor];
UIColor *color2 = [UIColor blueColor];
UIFont *font1 = [UIFont fontWithName:#"HelveticaNeue" size:20.0f];
UIFont *font2 = [UIFont fontWithName:#"HelveticaNeue-Light" size:20.0f];
NSDictionary *dict1 = #{NSFontAttributeName:font1,
NSForegroundColorAttributeName:color1 }; // Added line
NSDictionary *dict2 = #{NSFontAttributeName:font2,
NSForegroundColorAttributeName:color2 }; // Added line
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] init];
[attString appendAttributedString:[[NSAttributedString alloc] initWithString:senderName attributes:dict1]];
[attString appendAttributedString:[[NSAttributedString alloc] initWithString:#"posted to" attributes:dict2]];
[cell.profileIDButton setAttributedTitle:attString forState:UIControlStateNormal];
[[cell.profileIDButton titleLabel] setNumberOfLines:0];
[[cell.profileIDButton titleLabel] setLineBreakMode:NSLineBreakByWordWrapping];
This answer worked for me. I wasnt able to test Andre's answers yet.
UILabel * myLabel = [[UILabel alloc] init];//used for whole string
myLabel.numberOfLines = 0;
NSString * myUserName = #"#LisaLisa";//used for userName
//add button on UserName
UIButton * muButton = [[UIButton alloc] init];
myLabel.text = [NSString stringWithFormat:#"%#", myUserName];
myLabel = [self setDynamicLableFrame:myLabel fontSize:fontSize Width:width];
//Here width is your Label's Width. Because we have to make sure that our, our label's width is not greater than our device's width and fontSize is label's fontSize
muButton.frame = myLabel.frame;
myLabel.text = [NSString stringWithFormat:#"%# is following you", myUserName];
myLabel = [self setDynamicLableFrame:myLabel fontSize:fontSize Width:width];//used for making dynamic height of label
//For changing color of UserName
NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithAttributedString: myLabel.attributedText];
[text addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(0, myUserName.length)];
[myLabel setAttributedText: text];
Following method is used for making label's Dynamic Height & Width. Because we have to set Button's frame only on UserName ("LisaLisa").
//for setting the dynamic height of labels
-(UILabel *)setDynamicLableFrame:(UILabel*)myLabel fontSize:(float)size Width:(float)Width
{
CGSize possibleSize = [myLabel.text sizeWithFont:[UIFont fontWithName:REGULER_FONT size:size] constrainedToSize:CGSizeMake(300, 9999) lineBreakMode:NSLineBreakByWordWrapping];
CGRect newFrame = myLabel.frame;
newFrame.size.height = possibleSize.height;
if (possibleSize.width < Width) {
newFrame.size.width = possibleSize.width;
}else{
newFrame.size.width = Width;
}
myLabel.frame = newFrame;
return myLabel;
}
Hope, This is what you're looking for. Any concern get back to me.

UILabel won't register line spacing property

For some reason this code (the bold text in particular) doesn't change the line spacing of the text at all:
UIFont* customFont = [UIFont fontWithName:#"BebasNeue" size:70];
NSString * text = #"Their \nIdeas";
**NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text];
NSMutableParagraphStyle *paragrahStyle = [[NSMutableParagraphStyle alloc] init];
paragrahStyle.lineSpacing = 30;
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragrahStyle range:NSMakeRange(0, [text length])];**
UILabel *lbl1 = [[UILabel alloc] init];
[lbl1 setFrame:CGRectMake(120, 70, viewWidth, 180)];
lbl1.backgroundColor = [UIColor clearColor];
lbl1.textColor = grayColor;
lbl1.numberOfLines = 2;
lbl1.attributedText = attributedString;
lbl1.userInteractionEnabled = NO;
lbl1.text = text;
[lbl1 setFont:customFont];
[view addSubview:lbl1];
[lbl1 setTransform:CGAffineTransformMakeRotation(0.35)];
What am I doing wrong?
The issue is with this line ,
lbl1.text = text;
You are assigning a non attributed string just after assigning the attributed string which contains all line spacing data. Remove above line then your code will work.
And if you are using a large value for line spacing, make sure your label's height is enough to display the second line.

wrapping text of a UITextView (line break mode)

A UITextView (kind of modal : it is shown when pressing on a button) appears for the user to collect what he wants to write in another UITextView which is fixed.
I resize the UITextView's height (the one which is fixed), and put in it the text that has been entered by the user in the other (modal) UITextView.
But, instead of doing the line break (as it did in the modal UITextView), the fixed UITextView does not wrap the text...
How can I make the fixed UITextView wrap the text ?
Here is my code :
textsToDisplay[index] = [enterText text];
NSInteger _stringTotalLength=[[enterText text] length];
NSMutableAttributedString *attSt=[[NSMutableAttributedString alloc] initWithString:[enterText text]];
[attSt addAttribute:NSFontAttributeName
value:[UIFont fontWithName:#"Helvetica" size:15.0]
range:NSMakeRange(0, _stringTotalLength)];
float height3 = ceil(attSt.size.height);
UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
if(UIInterfaceOrientationIsPortrait(interfaceOrientation)){
cellSizes[index] = CGSizeMake(screenWidth-6,height3+10);
}else if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
cellSizes[index] = CGSizeMake(screenHeight-25,height3+10);
}
I store the text which was entered by the user in textsToDisplay which is a table of NSString. I am using a UICollectionView whose cells contain the fixed UITextView and I set the text in the following method :
- (UICollectionViewCell*) collectionView:(UICollectionView *)collectView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
NSMutableAttributedString *attSt=[[NSMutableAttributedString alloc] initWithString:textsToDisplay[index]];
NSInteger _stringTotalLength=[textsToDisplay[index] length];
[attSt addAttribute:NSFontAttributeName
value:[UIFont fontWithName:#"Helvetica" size:15.0]
range:NSMakeRange(0, _stringTotalLength)];
cell.textView.attributedText =attSt;
I create the uitextview for entering code like this :
float width = 500.0f;
enterText = [[UITextView alloc] initWithFrame:CGRectMake(self.view.frame.size.width/2-(width)/2, self.view.frame.size.height/2-200, width, 400)];
NSMutableAttributedString *attSt=[[NSMutableAttributedString alloc] initWithString:questionCell.textView.text];
NSInteger _stringTotalLength=[questionCell.textView.text length];
[attSt addAttribute:NSFontAttributeName
value:[UIFont fontWithName:#"Helvetica" size:15.0]
range:NSMakeRange(0, _stringTotalLength)];
enterText.attributedText = attSt;
enterText.tag = 92;
enterText.backgroundColor = [UIColor whiteColor];
enterText.alpha = 1;
enterText.delegate = self;
[self.view addSubview:enterText];
and here is how I create the uitextview in a cell :
textView = [[UITextView alloc]initWithFrame:CGRectMake(50, 0, widthLabel-50, 50)];
textView.userInteractionEnabled = YES;
textView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
textView.backgroundColor = [UIColor clearColor];
and I configure it like this :
cell.textView.frame = CGRectMake(50, 0, cellSizes[index].width-50, cellSizes[index].height);
I ended up using a uilabel in each uicollectionviewcell because it is way too complex to do the line break with a uitextview.

What is the equivalent of Android's "Spannable" in Objective-C

Im on an iOS app that should able to highlight text, and make it clickable too.
I read about NSAttributedString in iOS but it still more complicated than Spannable in android.
Is there any other Objective c way to do that, if not; what should i do using NSAttributedString to highlight a paragraph word by word, and how to make my text clickable.
Update:
What exactly i want that each word should be clickable and can be
highlighted as a single word in one paragraph.
I found a perfect solution using UITextView, it will make every word in within the UITextView clickable.
Firstly, Create an UITextView and add an UITapGestureRecognizer to it as follows:
CGRect textViewFrame = CGRectMake(0, 40, 100, 100);
textView = [[UITextView alloc]initWithFrame: textViewFrame];
textView.textAlignment = NSTextAlignmentCenter;
textView.backgroundColor = [UIColor clearColor];
textView.editable = NO;
textView.selectable = NO;
[self.view addSubView:textView];
// i used to `NSMutableAttributedString` highlight the text
string = [[NSMutableAttributedString alloc]initWithString:#"Any text to detect A B $ & - +"];
[string addAttribute:NSFontAttributeName
value:[UIFont systemFontOfSize:40.0]
range:NSMakeRange(0, [string length])];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init] ;
[paragraphStyle setAlignment:NSTextAlignmentCenter];
[string addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [string length])];
[textView setAttributedText:string];
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapRecognized:)];
//modify this number to recognizer number of tap
[singleTap setNumberOfTapsRequired:1];
[textView addGestureRecognizer:singleTap];
Then add the UITapGestureRecognizer #selector:
- (void)tapRecognized:(UITapGestureRecognizer *)recognizer{
if(recognizer.state == UIGestureRecognizerStateRecognized)
{
CGPoint point = [recognizer locationInView:recognizer.view];
NSString * detectedText = [self getWordAtPosition:point inTextView: textView];
if (![detectedText isEqualToString:#""]) {
NSLog(#"detectedText == %#", detectedText);
} }
}
All this magic is related to this method, witch can detect any touch on the UITextView and get the tapped word:
-(NSString*)getWordAtPosition:(CGPoint)pos inTextView:(UITextView*)_tv
{
//eliminate scroll offset
pos.y += _tv.contentOffset.y;
//get location in text from textposition at point
UITextPosition *tapPos = [_tv closestPositionToPoint:pos];
//fetch the word at this position (or nil, if not available)
UITextRange * wr = [_tv.tokenizer rangeEnclosingPosition:tapPos withGranularity:UITextGranularityWord inDirection:UITextLayoutDirectionRight];
return [_tv textInRange:wr];
}
And for highlighting the text:
-(void)setTextHighlited :(NSString *)txt{
for (NSString *word in [textView.attributedText componentsSeparatedByString:#" "]) {
if ([word hasPrefix:txt]) {
NSRange range=[self.textLabel.text rangeOfString:word];
[string addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:range];
}}
[textView setAttributedText:string];
}
And thats it, hope this helps others.
Unfortunately the behavior that you're looking for isn't as simple in objective-c as Spannable.
However, it can be accomplished fairly easily:
Create a UILabel or UITextView.
Highlight some of the words using NSMutableAttributedString and NSRange (see below).
Apply the attributed string to the attributedText property.
Create UIButtons with clear backgrounds and no label and position over the top of the clickable words.
Add a target to each button and create a selector method.
Here's some example code for the attributed string to get you started:
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString: [NSString stringWithFormat:#"Text containing a bold word and another"];
[string addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"HelveticaNeue-Bold" size:14] range:NSMakeRange(18,4)];
[string addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"HelveticaNeue-Bold" size:14] range:NSMakeRange(32, 7)];
label.attributedText = string;

Colour of a substring in a string of text view

I have text view like:
UITextview staticTxt = [[UITextView alloc]initWithFrame:CGRectMake(10, 80, 300, 400)];
staticTxt.backgroundColor = [UIColor clearColor];
staticTxt.text = #"this is a textview";
staticTxt.textColor = [UIColor whiteColor];
[self.view addSubview:staticTxt];
Now what i want is text "textview" should be in some different colour. How can i do this?
Thanks!!
You need to create an attributed text string, as described in this answer:
Underline text in a UITextView
First of all,You have to break your string into substrings. As you said in your comment,""this is a" is in white and "textview" is in red"... Am going to suggest you a way in that reference.
staticTxt.text = #"this is a textview";
NSString *yourString = staticTxt.text;
NSString *str = [[yourString componentsSeparatedByString:#"a "] lastObject];
Now you can set color of "str" substring.
Let me tell you one thing very clearly.It is way only to change substring color of static string.. If you are going to change the text of your textview dynamically... then this method is not a good choice...
You can use different color , different font and different size text in your control(UILabel, UITextField or UItextView) by using this class method
+ (void)setMultiColorAndFontText:(NSString *)text rangeString:(NSArray *)rangeString inputView:(UITextView*) inputView font:(NSArray*) fontName color:(NSArray*) colorName
{
inputView.layer.sublayers = nil;
NSMutableAttributedString *mutableAttributedString = [[ NSMutableAttributedString alloc]initWithString:text];
for (int i =0 ; i<[rangeString count]; i++)
{
CTFontRef ctFont = CTFontCreateWithName((__bridge CFStringRef) [UIFont fontWithName:[fontName objectAtIndex:i] size:14.0].fontName, [UIFont fontWithName:[fontName objectAtIndex:i] size:14.0].pointSize, NULL);
NSRange whiteRange = [text rangeOfString:[rangeString objectAtIndex:i]];
if (whiteRange.location != NSNotFound)
{
[mutableAttributedString addAttribute:(NSString *)kCTForegroundColorAttributeName value:(id)[colorName objectAtIndex:i] range:whiteRange];
[mutableAttributedString addAttribute:(NSString*)kCTFontAttributeName
value:( __bridge id)ctFont
range:whiteRange];
}
}
CGSize expectedinputViewSize = [text sizeWithFont:[UIFont fontWithName:#"Helvetica" size:14.0f] constrainedToSize:CGSizeMake(186,100) lineBreakMode:UILineBreakModeWordWrap];
CATextLayer *textLayer = [[CATextLayer alloc]init];
textLayer.frame =CGRectMake(0,4, inputView.frame.size.width,expectedinputViewSize.height+4);
textLayer.contentsScale = [[UIScreen mainScreen] scale];
textLayer.string=mutableAttributedString;
textLayer.opacity = 1.0;
textLayer.alignmentMode = kCAAlignmentLeft;
[inputView.layer addSublayer:textLayer];
[textLayer setWrapped:TRUE];
[inputView setText:#""];
}
Here you can pass your text , its range , font and color as parameters.
Example :
[CommonFunctions setMultiColorAndFontText:#"This is a textview" rangeString:[NSArray arrayWithObjects:#"This is a",#"textview", nil] textfield:txtEmailAddress font:[NSArray arrayWithObjects:#"Arial",#"Helvetica",nil] color:[NSArray arrayWithObjects:(UIColor *)[UIColor whiteColor].CGColor,(UIColor *)[UIColor redColor].CGColor,nil]];
It will display text with different color and different font.
Note : In this method we have used UITextView . If you need UILabel or UITextField then you just need to change it in same way like:
UILabel
+ (void)setMultiColorAndFontText:(NSString *)text rangeString:(NSArray *)rangeString inputView:(UILabel*) label font:(NSArray*) fontName color:(NSArray*) colorName;
UITextField
+ (void)setMultiColorAndFontText:(NSString *)text rangeString:(NSArray *)rangeString inputView:(UITextField*) label font:(NSArray*) fontName color:(NSArray*) colorName;
UITextView
+ (void)setMultiColorAndFontText:(NSString *)text rangeString:(NSArray *)rangeString inputView:(UITextView*) label font:(NSArray*) fontName color:(NSArray*) colorName;
Hope it helps you.

Resources