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

后端 未结 3 1085
迷失自我
迷失自我 2021-02-13 13:09

In the context of the iPhone:

I have a UIScrollView containing a UIImage. When the user taps the screen inside the UIImage, a

相关标签:
3条回答
  • 2021-02-13 13:36

    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.

    0 讨论(0)
  • 2021-02-13 13:39

    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.

    0 讨论(0)
  • 2021-02-13 14:01

    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.

    0 讨论(0)
提交回复
热议问题