Below I have a line of code that scrolls to a certain point in a UIScrollView. However once it has scrolled there it does not allow me to scroll back up.
[scroller setContentOffset:CGPointMake(0,500) animated:NO];
Any help will be appreciated, thank you.
did you try using UIScrollView method scrollRectToVisible:
Here is an example
- (void)goToPage:(int)page animated:(BOOL)animated
{
CGRect frame;
frame.origin.x = self.scroller.frame.size.width * page;
frame.origin.y = 0;
frame.size = self.scroller.frame.size;
[self.scroller scrollRectToVisible:frame animated:animated];
// update the scroll view to the appropriate page
}
I use this. The button calls this method. Should work well.
- (void)downExecute:(id)sender {
NSLog(#"scroll down");
CGFloat currentOffset = _scrollView.contentOffset.y;
CGFloat newOffset;
newOffset = currentOffset + self.view.bounds.size.height;
[UIScrollView animateWithDuration:0.3 animations:^(void) {
[_scrollView setContentOffset:CGPointMake(0.0, newOffset)];
} completion:^(BOOL finished) {
}];
}
I had this kind of problem because I called this method from viewDidLayoutSubviews(). Check where are you calling it from. When I moved the logic to viewDidAppear() everything worked as expected. Hope it helps, cheers.
Related
fields in my view, i want to move my text-view up when keyboard appears when i started entering text in 6th, 7th, 8th. text-Fields only.
I tried solution for you question and I simply got.
#define kOFFSET_FOR_KEYBOARD 80.0
#interface ViewController ()
{
NSInteger tagTF;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)setMovedUp:(BOOL)movedUP
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
CGRect rect = self.view.frame;
if(movedUP)
{
rect.origin.y -= kOFFSET_FOR_KEYBOARD;
rect.size.height += kOFFSET_FOR_KEYBOARD;
}
else{
rect.origin.y += kOFFSET_FOR_KEYBOARD;
rect.size.height -= kOFFSET_FOR_KEYBOARD;
}
self.view.frame = rect;
[UIView commitAnimations];
}
#pragma mark - UITextFieldDelegate Methods
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
tagTF = textField.tag;
if(textField.tag>=6)
{
if(self.view.frame.origin.y >= 0)
{
[self setMovedUp:YES];
}
}
return YES;
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
if(textField.tag>=6)
{
[self setMovedUp:NO];
}
[textField resignFirstResponder];
return YES;
}
From my above answer I set the textField tag from 1 to 8.It works perfectly what you want.Please set the delegate for textField.
I have an extensive blog post explaining how to do this:
Shifting views to make room for the keyboard
The gist of it is that you add notification handlers for the keyboard will show and keyboard will hide notifications. In those handlers, you get the height of the keyboard, then do some math to figure out how much you need to move the field up so the keyboard doesn't cover it. You then move your view controller's view up just enough to keep the field exposed.
It gets more complicated than that, but that's all covered in the blog post (which is part of a larger blog post on animating random shapes that includes a working example of the keyboard technique.)
here is the official documentation by Apple regarding handling the keyboard.
There are lots of options for that.
I was using TPKeyboardAvoidingScrollView for a long time. Right now, i am using IQKeyboardManager much more simple and easy to integrate.
IQKeyboardManager
- (BOOL) textFieldShouldBeginEditing:(UITextField *)textField {
CGRect frame = self.view.frame;
Float y = frame.origin.y - 70;
frame.origin.y = y;
self.view.frame = frame;
return YES;
}
- (void) textFieldDidEndEditing:(UITextField *)textField{
CGRect frame = self.view.frame;
Float y = frame.origin.y + 70;
frame.origin.y = y;
self.view.frame = frame;
}
if you have change y value(like 70, 80, ...)in textFieldShouldBeginEditing method, and add same value to y in textFieldDidEndEditing method.
try this code.
I have a UITableView that is at the bottom of my main UIViewController, it currently only shows the top two rows. To show the rest I don't want it to scroll, I want the user to be able to "pull" the view up to reveal the additional 4 rows (can then swipe down on it to "push" it back into its original place), and I want the "pull" to be similar to how control center works in iOS. The spring that it has is really great.
Looks like I can add a UIPanGestureRecognizer to do the pull:
UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(pan:)];
pan.maximumNumberOfTouches = pan.minimumNumberOfTouches = 1;
[self addGestureRecognizer:pan];
- (void)pan:(UIPanGestureRecognizer *)aPan; {
CGPoint currentPoint = [aPan locationInView:self];
[UIView animateWithDuration:0.01f
animations:^{
CGRect oldFrame = _viewToChange.frame;
_viewToChange.frame = CGRectMake(oldFrame.origin.x, currentPoint.y, oldFrame.size.width, ([UIScreen mainScreen].bounds.size.height - currentPoint.y));
}];
}
Ref this question.
Doing this does sort of work, but my UITableView flashes as you pull it up and it eventually disappears.
There is also no spring, and no way to set a "max" so that you can't pull up the view past a certain point.
Does anyone have ideas on how this can be achieved?
this is how i write the pan:. t is tableView(initially user interaction is disabled). 40 in code is for more realistic look in pan. 200 is max value i used and 60 is min value. i directly add t to tableview with height 60 and increased the height with animation.
- (void)pan:(UIPanGestureRecognizer *)aPan; {
CGPoint currentPoint = [aPan locationInView:self.view];
CGRect fr = t.frame;
if ((currentPoint.y - fr.origin.y) < 40 && (fr.size.height <= 200) )
{
float nh = (currentPoint.y >= self.view.frame.size.height - 200) ? self.view.frame.size.height-currentPoint.y : 200;
if (nh < 60) {
nh = 60;
}
[UIView animateWithDuration:0.01f animations:^{
[t setFrame:CGRectMake(0, self.view.frame.size.height-nh, t.frame.size.width, nh)];
}];
if (nh == 200) {
[t setUserInteractionEnabled:YES];
}
else
{
[t setUserInteractionEnabled:NO];
}
}
}
or without pan; with using tableview's scrollview delegate methods, when tableview begin dragging in closed state, opening the large mode and when tableview scroll to top sliding down
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
NSLog(#"scroll");
if (scrollView.contentOffset.y == 0) {
[UIView animateWithDuration:0.2f animations:^{
[scrollView setFrame:CGRectMake(0, self.view.frame.size.height-200, t.frame.size.width, 200)];
}];
}
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView.contentOffset.y == 0) {
[UIView animateWithDuration:0.2f animations:^{
[scrollView setFrame:CGRectMake(0, self.view.frame.size.height-60, t.frame.size.width, 60)];
}];
}
}
I have a question for you!
I have a method:
- (void)pushNewTableViewController:(NewTableViewController *)newTableViewController
{
[self addChildViewController:newTableViewController];
[self.scrollView addSubview:newTableViewController.view];
[UIView animateWithDuration:0.5f animations:^
{
CGRect frame = CGRectZero;
frame.origin.x = COLUMN_WIDTH * self.navigationStack.count;
frame.origin.y = 0.0f;
frame.size.width = COLUMN_WIDTH;
frame.size.height = self.view.frame.size.height;
newTableViewController.view.frame = frame;
}
completion:^(BOOL finished)
{
[self.navigationStack addObject:newTableViewController];
self.scrollView.contentSize = [self sizeForContent];
[self.scrollView scrollRectToVisible:newTableViewController.view.frame animated:YES];
}];
}
Basically, this method works fine, except the line [self.scrollView scrollRectToVisible:newTableViewController.view.frame animated:YES];.
The idea of this method is to scroll the scroll view to the right to make newTableViewController.view.frame to be fully visible. But instead of this, scroll view doesn't scroll anywhere...
Maybe any one of you, guys, know why it doesn't work as I expect?
Whenever I click on an image, I want the image to display as a larger image with the ability to zoom. So far when I click on the image, it displays as I want it to inside a scrollview. However, I have to get lucky to be able to zoom in properly. Most of the time when I attempt to zoom, the image just moves down and to the right and does not zoom at all. Here is my code:
-(void) pictureButtonAction
{
self.scrollImageView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
self.scrollImageView.contentSize = self.fullImageView.image.size;
self.scrollImageView.delegate = self;
self.scrollImageView.clipsToBounds = YES;
self.scrollImageView.scrollEnabled = YES;
[self.scrollImageView setMaximumZoomScale:4.0f];
[self.scrollImageView setMinimumZoomScale:1.0f];
[self.view addSubview:self.scrollImageView];
[self.scrollImageView addSubview:fullImageView];
}
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.fullImageView;
}
ImageViews frame got changed while zooming , so that it moves down. So, You have to centralize the image view each time you zoom .
your scrollviews contentsize should be greater than or equal to your image size , if your fullImageView.image.size is less than your scrollviews bounds ,then set your scrollviews contentSize atleast double the scrollviews bounds .
call the below function in scrollViewDidZoom delegate method
-(void) centerScrollViewContents
{
CGSize boundsSize = self.scrollView.bounds.size;
CGRect contentsFrame = self.imageView.frame;
if (contentsFrame.size.width < boundsSize.width) {
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0f;
} else {
contentsFrame.origin.x = 0.0f;
}
if (contentsFrame.size.height < boundsSize.height) {
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0f;
} else {
contentsFrame.origin.y = 0.0f;
}
self.imageView.frame = contentsFrame;
}
Try this , hope it will help you ; happy coding ! :)
#Maria's answer works but when zooming you'll experience unwanted bounces, instead of using it under scrollViewDidZoom, use scrollViewDidEndZooming: delegate to prevent that..
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
[self centerScrollViewContents];
}
and with a little enhancement from her code:
[UIView animateWithDuration:0 animations:^{
self.previewImageView.frame = contentsFrame;
}];
a bit late for an answer but i hope this will be useful to some..
I want to create a screen to pull up from down and need to pull down.like iOS notifications screen (but in reverse direction).Please share if any example is there.Thanks in advance.
The full-on way to do this in iOS 7 is with an interactive custom transition. You will use a UIScreenEdgePanGestureRecognizer and respond to the drag gesture from the edge of the screen by performing part of the transition animation to match the distance the user's finger has travelled. Look into the UIPercentDrivenInteractiveTransition class to help you do that.
Here's a complete example you can download and run: it happens that I'm doing it from the left or right, not the top or bottom, but it is the same basic idea.
https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch06p296customAnimation2/ch19p620customAnimation1/AppDelegate.m
But beware: if you try to do it from the top or the bottom you will get interference from the notification center (top) and the control center (bottom). It can be tricky to prevent that interference.
Hi you can use it.
- (void)showShareView {
[self.view bringSubviewToFront:self.view_Email];
[UIView beginAnimations:#"Show"
context:nil];
[UIView setAnimationDuration:0.3F];
CGRect frame = self.view_Email.frame;
if (IS_IPHONE5) {
if(txtFieldActiveFlag==1){
frame.origin.y = 568-420;
}else{
frame.origin.y = 568-220;
}
} else {
frame.origin.y = 480 - 275 - 88;
}
self.view_Email.frame = frame;
[UIView commitAnimations];
}
- (void)hideShareView {
[UIView beginAnimations:#"Show"
context:nil];
[UIView setAnimationDuration:0.3F];
CGRect frame = self.view_Email.frame;
if (IS_IPHONE5) {
if(txtFieldActiveFlag==2){
frame.origin.y = 568-220;
}else{
frame.origin.y = 568;
}
} else {
frame.origin.y = 480;
}
self.view_Email.frame = frame;
[UIView commitAnimations];
}
//call method from any button action.
[self showShareView]; //show the view up
[self hideShareView]; //show the view down
Thanks