UIKit 좌표 계 를 통 해 iOS 의 UIScrollView 구성 요 소 를 전면적으로 파악 합 니 다.

11442 단어 iOSUIScrollView
UIKit 의 좌표 시스템 특성 에 감 사 드 립 니 다.30 여 줄 의 코드 를 사용 하면 UIScrollView 의 정 수 를 재현 할 수 있 습 니 다.물론 진정한 UIScrollView 는 우리 가 하 는 것 보다 훨씬 복잡 합 니 다.반등 효과,운동량 스크롤,확대 시도,그리고 대리 방법 도 있 습 니 다.이런 특성 들 은 우리 가 여기 서 언급 하지 않 았 습 니 다.
우선 UIKit 의 좌표계 가 어떻게 작 동 하 는 지 알 아 보 겠 습 니 다.스크롤 시도 코드 구현 에 만 관심 이 있다 면 다음 소절 을 안심 하고 뛰 어 넘 을 수 있 습 니 다.UIKit 좌 표 는 모든 View 가 자신의 좌표 시스템 을 정의 합 니 다.아래 그림 에서 보 듯 이 x 축 은 오른쪽 을 가리 키 고 y 축 은 아래 를 가리킨다.
201652092612128.png (1400×1400)
이 논리 좌표 계 는 View 에 포 함 된 너비 와 높이 에 관심 이 없습니다.전체 좌 표 는 경계 없 이 사방 으로 무한 연장 되 어 있 습 니 다.우 리 는 좌표계 에 네 개의 키 View 를 설치 합 니 다.모든 색상 블록 은 하나의 View 를 대표 합 니 다.
201652092648762.png (1368×1952)
View 코드 를 추가 하면 다음 과 같 습 니 다.

UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 100, 100)];
redView.backgroundColor = [UIColor colorWithRed:0.815 green:0.007
    blue:0.105 alpha:1];
 
UIView *greenView = [[UIView alloc] initWithFrame:CGRectMake(150, 160, 150, 200)];
greenView.backgroundColor = [UIColor colorWithRed:0.494 green:0.827
    blue:0.129 alpha:1];
 
UIView *blueView = [[UIView alloc] initWithFrame:CGRectMake(40, 400, 200, 150)];
blueView.backgroundColor = [UIColor colorWithRed:0.29 green:0.564
    blue:0.886 alpha:1];
 
UIView *yellowView = [[UIView alloc] initWithFrame:CGRectMake(100, 600, 180, 150)];
yellowView.backgroundColor = [UIColor colorWithRed:0.972 green:0.905
    blue:0.109 alpha:1];
 
[mainView addSubview:redView];
[mainView addSubview:greenView];
[mainView addSubview:blueView];
[mainView addSubview:yellowView];
bounds
Apple 의 UIView 문서 에 서 는 bounds 속성 을 이렇게 설명 합 니 다.
bounds 사각형...이 보기 가 자신의 좌표계 에 있 는 위치 와 크기 를 설명 합 니 다.
하나의 View 는 좌표계 평면 에 정 의 된 창문 이나 사각형 의 시각 영역 으로 볼 수 있다.View 의 경 계 는 이 사각형 시각 영역의 위치 와 크기 를 나 타 냅 니 다.
우리 의 View 너비 320 픽 셀,높이 480 픽 셀,원점 이(0,0)이 라 고 가정 합 니 다.그러면 이 View 는 전체 좌표계 평면의 관찰 구가 되 었 고 전체 평면의 일부분 만 보 여 주 었 다.이 View 경계 밖 에 있 는 지역 은 여전히 존재 하 며 숨겨 져 있 을 뿐이다.
201652092752308.png (1368×1952)
하나의 View 는 평면 에 있 는 관찰 구 를 제공 했다.View 의 bounds 사각형 은 이 구역 의 위치 와 크기 를 설명 합 니 다.
Frame
다음은 bounds 의 원점 좌 표를 수정 해 보 겠 습 니 다.

CGRect bounds = mainView.bounds;
bounds.origin = CGPointMake(0, 100);
mainView.bounds = bounds;

우리 가 bound 원점 을(0,100)으로 설정 하면 전체 화면 이 이렇게 보 입 니 다.
201652092853910.png (1368×1952)
bounds 의 원점 을 수정 하 는 것 은 평면 적 으로 이 시각 영역 을 이동 하 는 것 과 같다.
보아하니 이 View 가 100 픽 셀 을 아래로 이동 한 것 같다.이 View 자신의 좌표계 에서 이것 은 확실히 맞다.그러나 이 View 는 실제 화면 에 있 는 위치(더 정확히 말 하면 아버지 View 의 위치)는 변 하지 않 았 습 니 다.이것 은 View 의 frame 속성 에 의 해 결정 되 기 때문에 변 하지 않 았 습 니 다.
frame 사각형...이 View 가 아버지 View 좌표계 에서 의 위치 와 크기 를 정의 합 니 다.
View 의 위 치 는 상대 적 으로 고정 되 어 있 기 때문에 전체 좌표 평면 을 우리 가 상하 로 끌 수 있 는 투명 한 막 으로 상상 하고 이 View 를 우리 가 좌표 평면 을 관찰 하 는 창 으로 상상 할 수 있다.View 의 Bounds 속성 을 조정 하 는 것 은 이 막 을 드래그 하 는 것 과 같 습 니 다.그러면 아래 의 내용 은 우리 View 에서 관찰 할 수 있 습 니 다.
201652092922466.gif (1368×1952)
bounds 의 원점 좌 표를 수정 하 는 것 도 전체 좌 표를 위로 끌 어 올 리 는 것 과 같 습 니 다.View 의 frame 은 변 하지 않 았 기 때문에 부모 View 의 위치 에 비해 변 하지 않 았 습 니 다.
사실 이것 이 바로 UIScrollView 가 미 끄 러 질 때 발생 하 는 일이 다.한 사용자 의 측면 에서 볼 때 그 는 이 View 의 하위 View 가 이동 하고 있다 고 생각 했 는데 사실은 그들의 좌표계 에서 위치(그들의 frame)는 변화 가 없 었 다.
UIScrollView 만 들 기
스크롤 뷰 는 중성자 뷰 의 좌 표를 필요 로 하지 않 습 니 다.유일 하 게 해 야 할 일 은 그의 bounds 속성 을 바 꾸 는 것 이다.이 점 을 알 게 되면 간단 한 scroll view 를 실현 하 는 데 어려움 이 없다.저 희 는 gesture recognizer 로 사용자 의 드래그 동작 을 식별 하고 사용자 가 드래그 하 는 오프셋 에 따라 bounds 의 원점 을 바 꿉 니 다.

// CustomScrollView.h
@import UIKit;
 
@interface CustomScrollView : UIView
 
@property (nonatomic) CGSize contentSize;
 
@end
  
// CustomScrollView.m
#import "CustomScrollView.h"
 
@implementation CustomScrollView
 
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self == nil) {
        return nil;
    }
    UIPanGestureRecognizer *gestureRecognizer = [[UIPanGestureRecognizer alloc]
        initWithTarget:self action:@selector(handlePanGesture:)];
    [self addGestureRecognizer:gestureRecognizer];
    return self;
}
 
- (void)handlePanGesture:(UIPanGestureRecognizer *)gestureRecognizer
{
    CGPoint translation = [gestureRecognizer translationInView:self];
    CGRect bounds = self.bounds;
 
    // Translate the view's bounds, but do not permit values that would violate contentSize
    CGFloat newBoundsOriginX = bounds.origin.x - translation.x;
    CGFloat minBoundsOriginX = 0.0;
    CGFloat maxBoundsOriginX = self.contentSize.width - bounds.size.width;
    bounds.origin.x = fmax(minBoundsOriginX, fmin(newBoundsOriginX, maxBoundsOriginX));
 
    CGFloat newBoundsOriginY = bounds.origin.y - translation.y;
    CGFloat minBoundsOriginY = 0.0;
    CGFloat maxBoundsOriginY = self.contentSize.height - bounds.size.height;
    bounds.origin.y = fmax(minBoundsOriginY, fmin(newBoundsOriginY, maxBoundsOriginY));
 
    self.bounds = bounds;
    [gestureRecognizer setTranslation:CGPointZero inView:self];
}
 
@end
실제 UIScrollView 와 마찬가지 로 우리 클래스 에 도 contentSize 속성 이 있 습 니 다.이 값 을 외부 에서 설정 해서 스크롤 할 수 있 는 영역 을 지정 해 야 합 니 다.bounds 의 큰 시간 을 바 꾸 면 설정 값 이 올 바른 지 확인 해 야 합 니 다.
결과:
201652092955135.gif (520×974)
UIScrollView 상용 조작 방법 정리
201652093020313.jpg (600×319)

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    // 
    self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 64, 320, 568-64)];
    // 
    self.scrollView.delegate = self;
    self.scrollView.backgroundColor = [UIColor redColor];
    [self.view addSubview:_scrollView];
    /**
     *  CGPoint contentOffSet                      
     *  CGSize contentSize                          ( )
     *  UIEdgeInsets contentInset                   scrollView
     *  BOOL directionalLockEnabled                   
     *  BOOL bounces                               
     *  BOOL alwaysBounceVertical                   
     *  BOOL alwaysBounceHorizontal                   
     *  BOOL pagingEnabled                           
     *  BOOL scrollEnabled                           
     *  BOOL showsHorizontalScrollIndicator           
     *  BOOL showsVerticalScrollIndicator           
     *  UIEdgeInsets scrollIndicatorInsets            scrollerView
     *  UIScrollViewIndicatorStyle indicatorStyle   
     *  float decelerationRate                        scrollerView
     *  BOOL tracking                               
     *  BOOL dragging                               
     *  BOOL decelerating                           
     *  BOOL delaysContentTouches                   
     *  BOOL canCancelContentTouches                touch
     *  float minimumZoomScale                       
     *  float maximumZoomScale                       
     *  float zoomScale                               
     *  BOOL bouncesZoom                           
     *  BOOL zooming                               
     *  BOOL zoomBouncing                           
     *  BOOL scrollsToTop                           
     */

    //  , ,
    [self.scrollView flashScrollIndicators];
    // 
    [self.scrollView setContentOffset:CGPointMake(320, 0) animated:YES];

}

#pragma mark UIScrollViewDelegate
// 
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
{


}

// 
// , 。 ( , , , ), 。
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;
{

}

// , , 。 , 。
// decelerate, , , ( ), ,decelerate=YES
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
{

}

// 
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView;
{

}

// , , 。 , 。
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
{

}

//  , , setContentOffset
// , , ,
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView;
{

}

//  , uiscrollview subview , UIView 。
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView;
{

    return nil;
}

// , 。 , 。
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
{
    NSLog(@"scrollViewWillBeginZooming");
}

// , minimumZoomScale maximumZoomScale ( ), 。
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(double)scale;
{

}

//  , , , , NO
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView;
{

    return YES;
}

// 
- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView;
{

}

좋은 웹페이지 즐겨찾기