how to move one direction in UIScrollView when scrolling

前端 未结 2 1467
感情败类
感情败类 2021-01-21 00:50

I\'m new in objective-c. I create UIScrollView object and add in my view with this code:

height = self.view.frame.size.height;
width = self.view.fra         


        
相关标签:
2条回答
  • 2021-01-21 00:55

    If i understood you right, you want to disable scrolling in the direction that has been dragged less by the user. If so, UIScrollView already offers an option to do so:

    scrollView.directionalLockEnabled = YES;
    

    When this option is set to true UIScrollView will handle the correct direction lock by itself.

    For more information look at the documentation: link

    0 讨论(0)
  • 2021-01-21 00:59

    You can achieve the result you want adding some code to your delegate. This is my ViewController.m file. -viewDidLoad, #import statements and the other methods are omitted.

    @interface ViewController () {
        CGPoint initialOffset;
        NSInteger direction; // 0 undefined, 1 horizontal, 2 vertical
    }
    @end
    
    @implementation ViewController
    
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        // retrieve current offset
        CGPoint currentOffset = scrollView.contentOffset;
    
        // do we know which is the predominant direction?
        if (direction == 0) {
    
            // no.
    
            CGFloat dx = currentOffset.x - initialOffset.x;
            CGFloat dy = currentOffset.y - initialOffset.y;
    
            // we need to decide in which direction we are moving
    
            if (fabs(dx) >= fabs(dy)) {
                direction = 1; // horizontal
            } else if (fabs(dy) > fabs(dx)) {
                direction = 2;
            }
    
        }
    
        // ok now we have the direction. update the offset if necessary
        if (direction == 1 && currentOffset.y != initialOffset.y) {
    
            // remove y offset
            currentOffset.y  = initialOffset.y;
            // update
            [scrollView setContentOffset:currentOffset];
    
        } else if (direction == 2 && currentOffset.x != initialOffset.x) {
    
            currentOffset.x = initialOffset.x;
            [scrollView setContentOffset:currentOffset];
    
        }
    }
    
    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
        // store the current offset
        initialOffset = scrollView.contentOffset;
    
        // reset flag
        direction = 0; // AKA undefined
    }
    
    @end
    

    When you start dragging, the delegate will reset the flag direction to "unknown" state, and store the current content offset. After every dragging move, your -scrollViewDidScroll: will be called. There, you decide which is the predominant direction (if this hasn't been done yet) and correct the current scrolling offset accordingly, by removing the x (or y) offset.

    I tested this with the same settings you provided, only I used a UIImageView inside UIScrollView and I set up everything via InterfaceBuilder, but it should work fine. Theoretically, with this method you could replace directionLock, but remember that -scrollViewDidScroll is called many times during an action, and every time it rewrites the content offset (if the scrolling is happening in both directions). So if you leave directionLock enabled, you save many of the calls to setContentOffset: that the delegate performs.

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