UITextView text vertical Alignment - iphone

I have created Custom UITextView class ,where textView grows dynamically as user types characters and textview frame resized dynamically.I want to align the text vertically center in the frame,it always coming to bottom by default.I added UIEdgeInsets to make or look a like it into center but it creates more issues for me.If i try to set content offset then the textView center also shifts.Is the content offset and textView center effect each other ?.I want textview center where ever it is but the text inside the textView stays vertically center.
Initially i am setting UITextView font 23.0 with a rectangular border(textview frame layer border).When i start typing in that box the text is coming on bottom of the border.Then i am using
[textView setContentInset:UIEdgeInsetsMake(5,0,10,0)];
to make text in center. Then i have to send this text for printing which is placed on an UIImageView.Here i am using the mentioned code by Paras to match printer dpi and resizing it.But the text as looks on UIImageview doesn't match the exact placement of print because i have added UIEdgeInset to adjust vertical alignment

I have two types to set dynamic height to the UITextView see both are bellow...
UPDATE:
First Create UITextView programmatically like bellow...
-(IBAction)btnAddTextView:(id)sender
{
UIView *viewTxt = [[UIView alloc]initWithFrame:CGRectMake(imgBackBoard.center.x - 100,20, 220, 84)];
[viewTxt setBackgroundColor:[UIColor clearColor]];
viewTxt.userInteractionEnabled = YES;
UITextView *txtAddNote=[[UITextView alloc]initWithFrame:CGRectMake(20,20, 180, 44)];
[txtAddNote setBackgroundColor:[UIColor scrollViewTexturedBackgroundColor]];
[txtAddNote setFont:[UIFont fontWithName:#"Helvetica-Bold" size:15]];
txtAddNote.layer.borderWidth = 2.0;
txtAddNote.layer.borderColor= [UIColor redColor].CGColor;
viewTxt.tag = 111;
txtAddNote.tag = 111;
txtAddNote.userInteractionEnabled= YES;
txtAddNote.delegate = self;
txtAddNote.textColor = [UIColor whiteColor];
[viewTxt addSubview:txtAddNote];
[viewBoard addSubview:viewTxt];
[txtAddNote release];
}
First
1. This bellow Method is Delegate Method of UITextViewDelegate.
in .h class add this UITextViewDelegate and then give your textView.delegate to self like bellow..
yourTextView.delegate = self;
and use paste this bellow method...
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
textView.frame = CGRectMake(textView.frame.origin.x, textView.frame.origin.y, textView.frame.size.width, textView.contentSize.height);
return YES;
}
here when your UITextView editing at a time with its text, the content size of textView is change.
2. Use my bellow custom Method for set Dynamic Height of UILable,UITextField and also UITextView
-(float) calculateHeightOfTextFromWidth:(NSString*) text: (UIFont*)withFont: (float)width :(UILineBreakMode)lineBreakMode
{
[text retain];
[withFont retain];
CGSize suggestedSize = [text sizeWithFont:withFont constrainedToSize:CGSizeMake(width, FLT_MAX) lineBreakMode:lineBreakMode];
[text release];
[withFont release];
return suggestedSize.height;
}
use this method like bellow...
CGSize sizeToMakeLabel = [yourTextView.text sizeWithFont:yourTextView.font];
yourTextView.frame = CGRectMake(yourTextView.frame.origin.x, yourTextView.frame.origin.y,
sizeToMakeLabel.width, sizeToMakeLabel.height);

Related

How to set the number of lines in uitextfield dynamically?

Actually i am trying to set the text in the textfield in next line when it becomes larger in the first line ad default. Can you please help me. my uitextfield is taken through the IB. and i am trying to write it and wants to post something like comment.
[viewFeedback setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"background_Feedback.png"]]];
CGSize size = [txtFeedback.text sizeWithFont:txtFeedback.font];
CGRect f = txtFeedback.frame;
f.size.height = ceil(size.width/f.size.width)*size.height;
txtFeedback.frame = f;
txtFeedback is the textfield name here..
Well this would be a Increasing the height of the UITextfield dynamically. Please follow this or add your custom frame
In your UITextViewDelegate implementation of textViewDidChange: you need to calculate the size of the text for the specific width and adjust accordingly.
-(void)textViewDidChange:(UITextView *)textView
{
NSString *text = [textView text];
NSFont *font = [textView font];
CGFloat width = [textView frame].size.width;
CGSize size = [text sizeWithFont:font constrainedToSize:CGSizeMake(width, 9999) lineBreakMode:UILineBreakModeWordWrap];
/* Adjust text view width with "size.height" */
}

UITextView background image does not fit in frame size of UITextView frame

I am developing an app where I need to put a UITextView for the large text. I have a background image of size 180X89(same as UITextView frame size). When put the image behind the UITextView, everything appears good however, when the user hits the text area and keyboard appears, the cursor appears just outside the edge of the image.
I want the cursor to be appeared in textbox.
Code for getting UITextview
CGRect textViewFrame = CGRectMake(125.0f, 155.0f, 180.0f, 90.0f);
UITextView *textView = [[UITextView alloc] initWithFrame:textViewFrame];
textView.returnKeyType = UIReturnKeyDone;
textView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed: #"textbox.png"]];
textView.delegate = self;
[self.view addSubview:textView];
Try this:
UIImage *bgImage = [UIImage imageNamed:#"textbox.png"];
UIImageView *bgImageView = [[UIImageView alloc] initWithImage:bgImage];
CGRect textViewFrame = CGRectMake(125.0f, 155.0f, 180.0f, 90.0f);
bgImageView.frame = textViewFrame;
UITextView *textView = [[UITextView alloc] initWithFrame:textViewFrame];
textView.returnKeyType = UIReturnKeyDone;
textView.delegate = self;
[self.view addSubview:bgImageView];
[self.view addSubview:textView];
Or something like it.
There is very simple approach. Just use UIImageView behind the TextView and set UITextView Background color as clear color.
What you can do in such situations is to make the size of the UITextView a bit smaller so that it just comes in ur background image and also give the UITextView a corner radius using the framework <QuartzCore> like textview.layer.cornerRadius = 10; (import the header for the framework). This approach would also give the UITextView edges a bit of roundness to make it look like the image u provided above.
So, in short add the UIImageView then add the UITextView above it and make the background of the textview as clearcolor . Hope this helps !!! :)
Add UIImageView on your view, Then add UITextView on UIImageView with inner frame of
CGPointMake(10,10) as Origin
and CGSizeMake(imageView.frame.size.width - 20.0, imageView.frame.size.hieght - 20.0) as Size of textView.

How to add View below other view in ViewController in iOS?

In my app i am creating view controller with mixed of UILabel and UITextview which want to be scrollable because the text are dynamic and also exceeds vertical screen size.
I am currently having Scrollview which has subviews as below. Views are created in Xcode 4.3 Storyboard.
UILabel1(Say Heading)
UITextView1(Dynamic text which can be any size)
UILabel2(Second Heading)
UITextView2(Dynamic text which can be any size)
and so on.
The problem is
When the UITextView1 has more content then it overlaps with UILabel2 which i don't want.
I would like to have UILabel1 on top of scrollView and UITextView1 below the UILabel1. UILabel2 below UITextView1 and so on.
What i have to do to achieve this?
EDIT
In Storyboard
![enter image description here][1]
In Simulator
![enter image description here][2]
Thanks for your help guys. Much appreciated.
Code
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[scrollView setScrollEnabled:YES];
[self.view addSubview:cockTailNameLabel];
[self.view insertSubview:txtIngredients belowSubview:cockTailNameLabel];
[self.view insertSubview:scrollView belowSubview:cockTailNameLabel];
//[scrollView]
[self.cockTailNameLabel setText:self.passcockTailName];
[_txtUse setText:self.passUse];
[_txtUse setEditable:NO];
[_txtUse setUserInteractionEnabled:NO];
CGRect useFrame = _txtUse.frame;
useFrame.size.height = _txtUse.contentSize.height;
_txtUse.frame = useFrame;
[txtIngredients setText:self.passIngredients];
[txtIngredients setEditable:NO];
[txtIngredients setUserInteractionEnabled:NO];
CGRect ingredientFrame = txtIngredients.frame;
ingredientFrame.size.height = txtIngredients.contentSize.height;
txtIngredients.frame = ingredientFrame;
[txtRecipe setText:self.passReceipe];
[txtRecipe setEditable:NO];
[txtRecipe setUserInteractionEnabled:NO];
CGRect recipeFrame = txtIngredients.frame;
recipeFrame.size.height = txtRecipe.contentSize.height;
txtRecipe.frame = recipeFrame;
[scrollView insertSubview:_txtUse belowSubview:cockTailNameLabel];
[scrollView insertSubview:titleIngredients belowSubview:_txtUse];
[scrollView insertSubview:txtIngredients belowSubview:titleIngredients];
[scrollView insertSubview:btnReceipe belowSubview:txtIngredients];
[scrollView insertSubview:btnHome belowSubview:txtIngredients];
[scrollView insertSubview:txtRecipe belowSubview:btnHome];
[scrollView insertSubview:btnfacebookShare belowSubview:txtRecipe];
[scrollView insertSubview:btnTwitterShare belowSubview:txtRecipe];
/*[scrollView addSubview:_txtUse];
[scrollView addSubview:titleIngredients];
[scrollView addSubview:txtIngredients];
[scrollView addSubview:btnReceipe];
[scrollView addSubview:btnHome];
[scrollView addSubview:txtRecipe];
[scrollView addSubview:btnfacebookShare];
[scrollView addSubview:btnTwitterShare];*/
[scrollView setContentSize:CGSizeMake(320, 1000)];
NSLog(#"RecipeName :%# ",passcockTailName);
}
In Storyboard or IB you can rearrange them freely.
In code you do - (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview.
In code (in viewDidLoad):
UIScrollView *scroll =[[UIScrollView alloc] initWithFrame:CGrectMake(0,0 320, 480)];
[self.view addSubview:scroll];
// code to init your UI object
UILabel *uilabel1 = [[UIlabel alloc] initWithFrame:CGrectMake(10,10, 100, 40)]; // example
uilabel1.font = [UIFont systemFontOfSize:10];
uilabel1.text = #"UILabel1";
uilabel1.backgroundColor = [UIColor clearColor];
//
//
UILabel *uilabel2 = [[UIlabel alloc] initWithFrame:CGrectMake(10, 10 + 10 + uilabel1.frame.origin.y, 100, 40)]; // example
uilabel2.font = [UIFont systemFontOfSize:10];
uilabel2.text = #"UILabel2";
uilabel2.backgroundColor = [UIColor clearColor];
//
//
[scroll addSubview:uilabel1];
[uilabel1 releale];
[scroll addSubview:uilabel2];
[uilabel2 releale];
//
//
// in end
float offset = 10.0 * 2; // offset between uiobjects, N - number of objects
scroll.contentSize = CGSizeMake (0, 0, uilabel1.frame.size.height + uilabel2.frame.size.height + offset, 320);
Note that you may set frame (and other properties) of yours uiobjects and adds it in order to descend.
You can tell next view to start from the end of the first view like so:
startYOfNextView = firstView.frame.origin.y position + firstView.frame.size.height;
Do the same for the rest of the other view. If your view has variable text length, you may need to precaculate the height of the string based on a specific font e.g.:
CGSize maxSize = CGSizeMake(widthOfView, 9999999);
CGSize expectedSize = CGSizeMake(stringVar sizeWithFont:[UIFont fontWithName:#"Arial"] withMaxSize:maxSize lineBreakMode:UILineBreakModeWordWrap);
then tell your dynamic view to use the height of expectedSize variable like so:
myDynamicView = [[UILabel alloc] initWithFrame:CGRectMake(..., expectedSize.height)];
Your issue is labels are coming on top of the textview (Overlapped), right?
In This case, you are modifying the height of the textview dynamically. If its just for display purpose you can set the text to a UILabel with numberOfLines = 0 instead of UITextview; As its added to scrollview adding a label will be fine.
Also you need to modify the origin.y of the remaining views so that it will be properly aligned. ie, secondView.origin.y = firstView.origin.y + firstView.size.height + offset. Likewise modify the origin of the remaining views wrt the just above view. So that its origin will lie outside the previous view frame.
In my case I had to project it over the parent view, so remember there is also something,
- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview
I think adding a transparent UI button is the fastest solution. You could add it once and then show / hide whenever you need to disable all views below the current one (assuming the "current" view, say a popup, was added last to your superview).
Declare an instance variable UIButton* _parentDisablingOverlay; in your popup view, then add this in its init or layoutSubviews method:
_parentDisablingOverlay = [[UIButton alloc] initWithFrame:CGRectMake(0,0, self.superview.frame.size.width, self.superview.frame.size.height)];
[self.superview insertSubview:_parentDisablingOverlay belowSubview:self];
_parentDisablingOverlay.hidden = true;
Later on, when you want to show the popup and disable everything below:
- (void) open {
self.hidden = false;
_parentDisablingOverlay.hidden = false;
}
Similarly to close and re-enable everything:
- (void) close {
self.hidden = true;
_parentDisablingOverlay.hidden = true;
}

Setting the position of setImage and setTitle of UIButton

I want to have a large button the spans the length of my table cells that contains a setImage icon on the right and a setTitle on the left. However, what happens by default is that everything is aligned to the left.
Is there a way to change the position of the UIButton image and title views? I want everything to be in one button so that if someone clicks the title the icon will change its state as well.
Make your image the same size as the button (i.e. pad it out with transparency) so things go where you want them to be. Say you have an image that 40 x 40, but you want it on the right side of a button 300 x 40. Just increase the size of the image with transparency to have 260 pixels of nothing on the left. For your text, you can use the alignment icons in Interface builder to put the title where you want it.
What I did was subclass UIButton and set [self titleLabel] and [self imageView] in the layoutSubview method.
#import "CustomDetailTableButton.h"
#implementation CustomDetailTableButton
- (void)layoutSubviews
{
[super layoutSubviews];
UILabel *titleLabel = [self titleLabel];
CGRect fr = [titleLabel frame];
fr.origin.x = 10.0;
fr.origin.y = 5.0;
[[self titleLabel] setFrame:fr];
UIImageView *imageView = [self imageView];
CGRect iFrame = [imageView frame];
iFrame.origin.x = 300.0;
iFrame.origin.y = 7.0;
[[self imageView] setFrame:iFrame];
}
#end

Placeholder text not centered for UITextField created programmatically

I am creating a UITextField programmatically and placing it inside a UIView. The font size is set to 15.0f (system font). But the placeholder that appears is not centered in the text view. Any one know how to resolve this?
I found some references on SO for blurred text etc and tried setting the frame of the textfield with integer values, but it doesn't make a difference.
UITextField *txtField = [[UITextField alloc] initWithFrame:CGRectMake(5.0f, 6.0f, 278.0f, 32.0f)];
[txtField setPlaceholder:#"My placeholder"];
[txtField setFont:[UIFont systemFontOfSize:15.0]];
[txtField setBorderStyle:UITextBorderStyleRoundedRect];
[txtField setAutocorrectionType:UITextAutocorrectionTypeNo];
[txtField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
[txtField setKeyboardType:UIKeyboardTypeEmailAddress];
[txtField setReturnKeyType:UIReturnKeyDone];
[txtField setClearButtonMode:UITextFieldViewModeWhileEditing];
Thank you for any help
Note: I mean that the text is not centered vertically in the textfield (it is a bit towards the top). So setting the text alignment is not the solution.
Adding an image of the issue for clarification - as seen in the image, the placeholder text is more towards the top and not in the center vertically.
You need to add:
txtField.textAlignment = NSTextAlignmentCenter; // Pre-iOS6 SDK: UITextAlignmentCenter
Keep in mind, this adjusts both the alignment of the placeholder text as well as the text the user will enter in.
How to center vertically
Since the original question was updated to request how to vertically align the placeholder text and that answer is buried in the comments, here is how to do that:
txtField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
This does not work as expected on iOS7. On iOS7 you will have to override TextField class and
- (void) drawPlaceholderInRect:(CGRect)rect
method.
Like this:
- (void) drawPlaceholderInRect:(CGRect)rect
{
[[UIColor blueColor] setFill];
CGRect placeholderRect = CGRectMake(rect.origin.x, (rect.size.height- self.font.pointSize)/2, rect.size.width, self.font.pointSize);
[[self placeholder] drawInRect:placeholderRect withFont:self.font lineBreakMode:NSLineBreakByWordWrapping alignment:self.textAlignment];
}
Works for both iOS7 and earlier versions.
I was using just the color, but we need to set the font as well.
This one worked for me:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:
#{
NSForegroundColorAttributeName:[UIColor whiteColor],
NSFontAttributeName: [UIFont systemFontOfSize:12]
}];
Changing the minimum line height using NSParagraphStyle was the only solution that worked for me:
NSMutableParagraphStyle *style = [self.addressBar.defaultTextAttributes[NSParagraphStyleAttributeName] mutableCopy];
style.minimumLineHeight = self.addressBar.font.lineHeight - (self.addressBar.font.lineHeight - placeholderFont.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 : placeholderFont,
NSParagraphStyleAttributeName : style
}];