UITextView not positioned correctly - iphone

Hi I have UITextView that I want it to make its height right above the keyboard. I am making a notes app and I need to bring the UITextView up so it scroll easily.Here is the code:
CGRect keyboardBounds = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect frame = self.notesTextView.frame;
CGFloat height = self.notesTextView.frame.size.height;
height = frame.size.height;
frame.size.height -= keyboardBounds.size.height;
self.notesTextView.frame = frame;
However the screen turns out like this:

Here's the answer you need: https://stackoverflow.com/a/1127025/189804
Doing this right is hard but essential. Don't forget to use all the information in the info dictionary passed to the keyboard notification, You need to read the height of the emerging keyboard rather than hard-coding a value, you need to get the animation duration so you can rearrange your views with the same animation duration and you also need to respond to events while editing - imagine that a user begins editing, then decides to connect a bluetooth keyboard to make the editing task easier, or they begin editing with the keyboard connected and then the keyboard battery quits...

You need to resize the scroll view. Don't touch the textview's frame ever (unless you make a subclass).
CGRect frame = self.textView.enclosingScrollView.frame;
frame.size.height = 42;
self.textView.enclosingScrollView.frame = newFrame;

Related

how do I reconfigure loading position of a custom keypad as user scrolls down iPhone

I have a tip calculator that uses a custom made keypad for number input. I have it set up to come into the screen at the bottom of the screen based off of screen size. Code below:
-(void)PreTaxTotalShowKeyPad
{
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
// CGFloat screenWidth = screenSize.width;
CGFloat screenHeight = screenSize.height;
[UIView beginAnimations:#"animateView" context:nil];
[UIView setAnimationDuration:0.5];
CGRect keypadViewiPhone = CGRectMake(0,(screenHeight -350),320,277);
PreTaxTotaliPhoneKeypadView.frame = keypadViewiPhone;
PreTaxTotaliPhoneKeypadView.alpha = 1.0;
[UIView commitAnimations];
}
The prob I have is that if you scroll down a bit and click the textbox to bring it back up it loads mush higher then I want it and is not visually pleasing.
I now realize (not sure how i missed it) that since I use a scroller view, when the user scrolls down the screen-size of course remains the same yet the distance from the top of the scroll view changes.
I looked everywhere and cant seem to figure out how to programmically get the cord for the bottom of the screen window to the top of the scroll view.
in essence changing the code
CGRect keypadViewiPhone = CGRectMake(0,(screenHeight -350),320,277);
to
CGRect keypadViewiPhone = CGRectMake(0,( distanceFromTopOfScrollViewToBottomOfScreen - 350),320,277);
so that way it loads up in the correct position no matter where you are (and can be used to scroll with the page too)

Overlay menu in iOS like Comcast Xfinity iPad app

In the Comcast Xfinity iPad app, there is a small button called "Filter by" at the bottom of the screen.
When a user touch the button, a overlay menu will slide up (like the menu UI in Android).
Can anyone give me some hints about how to create this kind of overlay menu?
Thanks.
For this you can create a UIView in your nib and make it look like the menu you need, then in viewdidload you can set its origin to be just off the screen and when you want it to appear just use an animation to slide it up into view and then slide it back off the screen when you're done.
In viewDidLoad:
CGRect frame = [your_menu_view].frame;
frame.origin.y += frame.size.height;
[your_menu_view].frame = frame;
When you are ready to show it:
NSTimeInterval animationDuration = 0.3;//play around with the animation length here
CGRect frame = [your_menu_view].frame;
[UIView beginAnimations:#"MenuSlideIn" context:nil];
[UIView setAnimationDuration:animationDuration];
frame.origin -= frame.size.height;
[your_menu_view].frame = frame;
[UIView commitAnimations];
Then use the same to get rid of it except subtract add its height.
haven't tested it but it should work.

UIKit: UIScrollView automatically scrolling when a subview increases its width past the edge of the screen

In the context of the iPhone:
I have a UIScrollView containing a UIImage. When the user taps the screen inside the UIImage, a UITextField is added where the user touched. The user can edit this UITextField, and the text field will automatically resize itself based on whether text was added or deleted.
When the a UITextField being edited increases its width, the scrollview automatically scrolls to show the increased width.
The problem comes in because the automatic scrolling of the textfield doesn't respect the y-value of the screen
For example, say the user added a text field to the bottom of the image. When they go to edit that text field, the keyboard will show, hiding the text field. I have code in place to scroll the screen to show the text field. The problem comes in when the user enters so much text that that text field extends past the edge of the screen. When this happens, the screen scrolls horizontally to fit the wider text, but also vertically - the vertical scrolling ends up hiding the textfield, basically nullifying anything I did to show the text field.
Code to show the text field if it's hidden by the keyboard:
- (void)keyboardWasShown:(NSNotification*)notification
{
NSDictionary* info = [notification userInfo];
CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
self.offset = self.contentOffset;
CGRect frame = self.frame;
// self.activeField is the name of the field that is the current first responder - this just adds a little bit of padding
frame.size.height -= keyboardSize.height + (self.activeField.frame.size.height * 2);
if (!CGRectContainsPoint(frame, self.activeField.frame.origin)) {
CGPoint scrollPoint = CGPointMake(self.offset.x, self.activeField.frame.origin.y - keyboardSize.height + (activeField.frame.size.height * 2));
[self setContentOffset:scrollPoint animated:YES];
}
}
Here is the code to increase the size of the text field:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
CGSize stringSize = [string sizeWithFont:textField.font];
CGSize newSize = [newString sizeWithFont:textField.font];
// Make textField wider if we're close to running up against it
if (newSize.width > (textField.frame.size.width - self.widthOffset)) {
CGRect textFieldFrame = textField.frame;
if (stringSize.width > self.widthOffset) {
textFieldFrame.size.width += stringSize.width;
}
textFieldFrame.size.width += self.widthOffset;
textField.frame = textFieldFrame;
}
// Shrink the textField if there is too much wasted space
if ((textField.frame.size.width - newSize.width) > self.widthOffset) {
CGRect textFieldFrame = textField.frame;
textFieldFrame.size.width = newSize.width + self.widthOffset;
textField.frame = textFieldFrame;
}
return YES;
}
The question is: How do I get the UIScrollView to respect the y-value of itself when automatically scrolling?
Basically setFrame of UIScrollView will readjust the scrollview offset, done by _adjustContentOffsetIfNecessary. As that method is private and not documented, there is very little we can guess on how the adjustment will happen.
There are two ways to stop the unnecessary scrolling or wrong offset being set:
1) reset the UIScrollView offset after applying setFrame. This you can do, if you are modifying the frame of UIScrollView intentionally based on some calculations.
CGPoint oldOffset = [scrollView contentOffset];
scrollView.frame = CGRectMake(newFrame);
[scrollView setContentOffset:oldOffset];
2) apply offset changes without animation. In your keyboardWasShown , change
[self setContentOffset:scrollPoint animated:YES]; to
[self setContentOffset:scrollPoint animated:NO];
Reason: when more than one offset is applied with animation on, the result offset is ambiguous. Here the internal method(_adjustContentOffsetIfNecessary) applies an offset change and the other one is done by your code. You can notice this if you try to log all the offsets being applied in the UIScrollView delegate method:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
NSLog(#" offset: %#", NSStringFromCGPoint(scrollView.conentOffset))
}
Let me know if this helps.
One possible workaround could be to respond to the scrollViewDidScroll delegate method check to see if the UITextField is hidden again, then re-scroll if necessary. Seems like a bit of a hack, but it sounds like the UIScrollView auto scrolling behavior is what's getting in your way, and if there's no way to directly affect it, the only option is to work around it. There is also the disadvantage, however, that if you do this then it appears to scroll twice.
If the auto-scrolling behavior happens only when the UITextField expands beyond the edge of the screen, you could also move the field to stay completely visible if it looks like it's going to expand beyond the edge of the screen.
Instead of changing the content offset, change the scroll view's display frame.
- (void)keyboardWill:(NSNotification*)notification
{
CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
// Update the scroll view's frame to the region not covered by the keyboard.
self.frame = CGRectMake(self.fullSizedFrame.origin.x,
self.fullSizedFrame.origin.y,
self.fullSizedFrame.size.width,
self.fullSizedFrame.size.height - keyboardSize.height);
}
- (void)keyboardWillHide:(NSNotification*)notification
{
// Set the frame back to the original frame before the keyboard was shown.
self.frame = self.fullSizedFrame;
}
If you don't allow the user to change screen orientation, then fullSizedFrame could be set to the original frame of the view when it is first displayed. If changes in orientation are allowed, you'll need to calculate the appropriate value for fullSizedFrame based on the orientation.

UITextView change height instead of scroll

By default, the UITextView's contentView becomes scrollable when there is too much text to fit into the textview based on it's height.
I'd like to disable this and instead, update the height of the UITextView to fit in the text. The reason I'm doing this is because I'm adding the UITextView as a subview of a UIScrollView which should handle the scrolling, much like in the native Mail app (when you enter text, the whole view scrolls up, not just the textview.
Anyone got some ideas / has run into the same problem before?
It is very simply done like this:
CGRect frame = textView.frame;
frame.size = textView.contentSize;
textView.frame = frame;
This should set the height of the textview to appropriately fit all of its content.
Few little changes:
-(void)textViewDidChange:(UITextView *)textView {
CGFloat fontHeight = (textView.font.ascender - textView.font.descender) + 1;
CGRect newTextFrame = textView.frame;
newTextFrame.size = textView.contentSize;
newTextFrame.size.height = newTextFrame.size.height + fontHeight;
textView.frame = newTextFrame;
}
Adding the font height gives room for the autocorrection box when you spell something incorrectly.
The UITextView should also be set to not scroll:
[aTextView setScrollEnabled:NO];

UIScrollView contentOffset jumps after animation - in 3.0 beta 5

I have a UIScrollView with a few UITextFields on it. When the user edits a text field it scrolls so that the UITextField is centered. The problem I am running into is that the UIScrollView is scrolling to the correct spot but at the last frame of the animation it is jumps to 300,300. It works fine in 2.2.1 but not in 3.0 beta 5. It always jumps to exactly 300,300 too. The strange thing is that when I call the returnScrollAfterEdit method that moves the scroll view the same way it works just fine. Any ideas what could cause this?
- (void)scrollViewToCenterOfScreen:(UIView *)field withKeyboard:(bool)withKeyboard {
CGFloat viewCenterY = field.center.y;
CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
CGFloat availableHeight = applicationFrame.size.height - 215;
CGFloat y = viewCenterY - availableHeight / 2.0;
NSLog([NSString stringWithFormat:#"w:%f h%f availH:%f y:%f x:%f", applicationFrame.size.width, applicationFrame.size.height, availableHeight, y, self.contentOffset.x]);
if (y
I'm not sure if this is exactly what you are looking for but I had some crazy issues with UITextView as well. It would scroll to the bottom of the frame if I had selected any text in the view. I fixed this by turning off the scrollEnabled before adding the text to the UITextView.
So the code would look something like this:
[textarea setText:#""]; //blank out the text to scroll back to the top
[textarea setScrollEnabled:NO]; //disable to avoid scrolling
[textarea setText:#"new text here"];
[textarea setScrollEnabled:YES];
[textarea resignFirstResponder]; //to drop annoying blue
I hope this helps.
Fixed with the release version of 3.0