最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

通過(guò)UIKit坐標(biāo)系來(lái)全面掌握iOS中的UIScrollView組件

 更新時(shí)間:2016年05月20日 09:34:36   作者:Ole Begemann  
iOS開(kāi)發(fā)套件中的UIScrollView組件十分強(qiáng)大,不僅是滾動(dòng),縮放操作也能夠控制自如,其核心當(dāng)然是坐標(biāo)軸上的控制,下面就通過(guò)UIKit坐標(biāo)系來(lái)全面掌握iOS中的UIScrollView組件

感謝UIKit的坐標(biāo)系統(tǒng)特性,使我們之花了30幾行代碼就能重現(xiàn)UIScrollView的精華,當(dāng)然真正的UIScrollView要比我們所做的復(fù)雜的多,反彈效果,動(dòng)量滾動(dòng),放大試圖,還有代理方法,這些特性我們沒(méi)有在這里涉及到。
首先,讓我們先來(lái)了解一下UIKit中的坐標(biāo)系是怎么工作的。如果你只對(duì)滾動(dòng)試圖的代碼實(shí)現(xiàn)感興趣可以放心跳過(guò)下一小節(jié)。UIKit坐標(biāo)系每一個(gè)View都定義了他自己的坐標(biāo)系統(tǒng)。如下圖所示,x軸指向右方,y軸指向下方:

201652092612128.png (1400×1400)

注意這個(gè)邏輯坐標(biāo)系并不關(guān)注包含在其中View的寬度和高度。整個(gè)坐標(biāo)系沒(méi)有邊界向四周無(wú)限延伸.我們?cè)谧鴺?biāo)系中放置四個(gè)子View。每一次色塊代表一個(gè)View:

201652092648762.png (1368×1952)

添加View的代碼實(shí)現(xiàn)如下:

復(fù)制代碼 代碼如下:

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關(guān)于UIView的文檔中是這樣描述bounds屬性的:

bounds矩形…描述了該視圖在其自身坐標(biāo)系中的位置和大小。

一個(gè)View可以被看作是定義在其所在坐標(biāo)系平面上的一扇窗戶或者說(shuō)是一個(gè)矩形的可視區(qū)域。View的邊界表明了這個(gè)矩形可視區(qū)域的位置和大小。

假設(shè)我們的View寬320像素,高480像素,原點(diǎn)在(0,0)。那么這個(gè)View就變成了整個(gè)坐標(biāo)系平面的觀察口,它展示的只是整個(gè)平面的一小部分。位于該View邊界外的區(qū)域依然存在,只是被隱藏起來(lái)了。

201652092752308.png (1368×1952)

一個(gè)View提供了其所在平面的一個(gè)觀察口。View的bounds矩形描述了這個(gè)可是區(qū)域的位置和大小。

Frame
接下來(lái)我們來(lái)試著修改bounds的原點(diǎn)坐標(biāo):

復(fù)制代碼 代碼如下:

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


當(dāng)我們把bound原點(diǎn)設(shè)為(0,100)后,整個(gè)畫面看起來(lái)就像這樣:

201652092853910.png (1368×1952)

修改bounds的原點(diǎn)就相當(dāng)與在平面上移動(dòng)這個(gè)可視區(qū)域。

看起來(lái)好像是這個(gè)View向下移動(dòng)了100像素,在這個(gè)View自己的坐標(biāo)系中這確實(shí)沒(méi)錯(cuò)。不過(guò)這個(gè)View真正位于屏幕上的位置(更準(zhǔn)確的說(shuō)在其父View上的位置)其實(shí)沒(méi)有改變,因?yàn)檫@是由View的frame屬性決定的,它并沒(méi)有改變:

frame矩形…定義了這個(gè)View在其父View坐標(biāo)系中的位置和大小。

由于View的位置是相對(duì)固定的,你可以把整個(gè)坐標(biāo)平面想象成我們可以上下拖動(dòng)的透明幕布,把這個(gè)View想象成我們觀察坐標(biāo)平面的窗口。調(diào)整View的Bounds屬性就相當(dāng)于拖動(dòng)這個(gè)幕布,那么下方的內(nèi)容就能在我們View中被觀察到:

201652092922466.gif (1368×1952)

修改bounds的原點(diǎn)坐標(biāo)也相當(dāng)于把整個(gè)坐標(biāo)系向上拖動(dòng),因?yàn)閂iew的frame沒(méi)由變過(guò),所以它相對(duì)于父View的位置沒(méi)有變化過(guò)。

其實(shí)這就是UIScrollView滑動(dòng)時(shí)所發(fā)生的事情。注意從一個(gè)用戶的角度來(lái)看,他以為時(shí)這個(gè)View中的子View在移動(dòng),其實(shí)他們的在坐標(biāo)系中位置(他們的frame)沒(méi)有發(fā)生過(guò)變化。

打造你的UIScrollView
一個(gè)scroll view并不需要其中子View的坐標(biāo)來(lái)使他們滾動(dòng)。唯一要做的就是改變他的bounds屬性。知道了這一點(diǎn),實(shí)現(xiàn)一個(gè)簡(jiǎn)單的scroll view就沒(méi)什么困難了。我們用一個(gè)gesture recognizer來(lái)識(shí)別用戶的拖動(dòng)操作,根據(jù)用戶拖動(dòng)的偏移量來(lái)改變bounds的原點(diǎn):

復(fù)制代碼 代碼如下:

// CustomScrollView.h
@import UIKit;
 
@interface CustomScrollView : UIView
 
@property (nonatomic) CGSize contentSize;
 
@end

復(fù)制代碼 代碼如下:
 
// 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一樣,我們的類也有一個(gè)contentSize屬性,你必須從外部來(lái)設(shè)置這個(gè)值來(lái)指定可以滾動(dòng)的區(qū)域,當(dāng)我們改變bounds的大小時(shí)我們要確保設(shè)置的值是有效的。

結(jié)果:

201652092955135.gif (520×974)

UIScrollView常用操作方法整理

201652093020313.jpg (600×319)

復(fù)制代碼 代碼如下:

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

    //  創(chuàng)建一個(gè)滾動(dòng)視圖
    self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 64, 320, 568-64)];
    //  設(shè)置代理
    self.scrollView.delegate = self;
    self.scrollView.backgroundColor = [UIColor redColor];
    [self.view addSubview:_scrollView];
    /**
     *  CGPoint contentOffSet                       監(jiān)控目前滾動(dòng)的位置
     *  CGSize contentSize                          滾動(dòng)范圍大小(主屬性)
     *  UIEdgeInsets contentInset                   視圖在scrollView中的位置
     *  BOOL directionalLockEnabled                    指定控件是否只能在一個(gè)方向上滾動(dòng)
     *  BOOL bounces                                控制控件遇到邊框是否反彈
     *  BOOL alwaysBounceVertical                    控制垂直方向遇到邊框是否反彈
     *  BOOL alwaysBounceHorizontal                    控制水平方向遇到邊框是否反彈
     *  BOOL pagingEnabled                            控制控件是否整頁(yè)翻動(dòng)
     *  BOOL scrollEnabled                            控制控件是否能滾動(dòng)
     *  BOOL showsHorizontalScrollIndicator            控制是否顯示水平方向的滾動(dòng)條
     *  BOOL showsVerticalScrollIndicator            控制是否顯示垂直方向的滾動(dòng)條
     *  UIEdgeInsets scrollIndicatorInsets            指定滾動(dòng)條在scrollerView中的位置
     *  UIScrollViewIndicatorStyle indicatorStyle    設(shè)定滾動(dòng)條的樣式
     *  float decelerationRate                        改變scrollerView的減速點(diǎn)位置
     *  BOOL tracking                                監(jiān)控當(dāng)前目標(biāo)是否正在被跟蹤
     *  BOOL dragging                                監(jiān)控當(dāng)前目標(biāo)是否正在被拖拽
     *  BOOL decelerating                            監(jiān)控當(dāng)前目標(biāo)是否正在減速
     *  BOOL delaysContentTouches                    控制視圖是否延時(shí)調(diào)用開(kāi)始滾動(dòng)的方法
     *  BOOL canCancelContentTouches                控制控件是否接觸取消touch的事件
     *  float minimumZoomScale                        縮放的最小比例
     *  float maximumZoomScale                        縮放的最大比例
     *  float zoomScale                                設(shè)置變化比例
     *  BOOL bouncesZoom                            控制縮放的時(shí)候是否會(huì)反彈
     *  BOOL zooming                                判斷控件的大小是否正在改變
     *  BOOL zoomBouncing                            判斷是否正在進(jìn)行縮放反彈
     *  BOOL scrollsToTop                            控制控件滾動(dòng)到頂部
     */

    //  提示用戶,在界面創(chuàng)建的時(shí)候,水平滾動(dòng)條或者垂直滾動(dòng)條會(huì)出現(xiàn)一次閃現(xiàn)效果
    [self.scrollView flashScrollIndicators];
    //  偏移帶動(dòng)畫效果
    [self.scrollView setContentOffset:CGPointMake(320, 0) animated:YES];

}

#pragma mark UIScrollViewDelegate
//  只要滾動(dòng)了就會(huì)觸發(fā)
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
{


}

//  開(kāi)始拖拽視圖
// 當(dāng)開(kāi)始滾動(dòng)視圖時(shí),執(zhí)行該方法。一次有效滑動(dòng)(開(kāi)始滑動(dòng),滑動(dòng)一小段距離,只要手指不松開(kāi),只算一次滑動(dòng)),只執(zhí)行一次。
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;
{

}

// 滑動(dòng)視圖,當(dāng)手指離開(kāi)屏幕那一霎那,調(diào)用該方法。一次有效滑動(dòng),只執(zhí)行一次。
// decelerate,指代,當(dāng)我們手指離開(kāi)那一瞬后,視圖是否還將繼續(xù)向前滾動(dòng)(一段距離),經(jīng)過(guò)測(cè)試,decelerate=YES
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
{

}

//  將開(kāi)始降速時(shí)
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView;
{

}

// 滾動(dòng)視圖減速完成,滾動(dòng)將停止時(shí),調(diào)用該方法。一次有效滑動(dòng),只執(zhí)行一次。
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
{

}

//  滾動(dòng)動(dòng)畫停止時(shí)執(zhí)行,代碼改變時(shí)出發(fā),也就是setContentOffset改變時(shí)
// 當(dāng)滾動(dòng)視圖動(dòng)畫完成后,調(diào)用該方法,如果沒(méi)有動(dòng)畫,那么該方法將不被調(diào)用
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView;
{

}

//  設(shè)置放大縮小的視圖,要是uiscrollview的subview , 返回將要縮放的UIView對(duì)象。要執(zhí)行多次
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView;
{

    return nil;
}

// 當(dāng)將要開(kāi)始縮放時(shí),執(zhí)行該方法。一次有效縮放,就只執(zhí)行一次。
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
{
    NSLog(@"scrollViewWillBeginZooming");
}

// 當(dāng)縮放結(jié)束后,并且縮放大小回到minimumZoomScale與maximumZoomScale之間后(我們也許會(huì)超出縮放范圍),調(diào)用該方法。
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(double)scale;
{

}

//  如果你不是完全滾動(dòng)到滾軸視圖的頂部,你可以輕點(diǎn)狀態(tài)欄,那個(gè)可視的滾軸視圖會(huì)一直滾動(dòng)到頂部,那是默認(rèn)行為,你可以通過(guò)該方法返回NO來(lái)關(guān)閉它
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView;
{

    return YES;
}

//  已經(jīng)滑動(dòng)到頂部
- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView;
{

}


相關(guān)文章

最新評(píng)論

黔江区| 大同县| 芷江| 德钦县| 咸丰县| 晋宁县| 许昌市| 灵山县| 隆安县| 长泰县| 额尔古纳市| 翁牛特旗| 建平县| 凤山市| 吉木乃县| 南城县| 保定市| 田东县| 高平市| 新野县| 天门市| 宣威市| 怀集县| 麦盖提县| 崇左市| 建宁县| 天全县| 吉木乃县| 石楼县| 保德县| 思茅市| 呈贡县| 清丰县| 灌南县| 明光市| 巴东县| 荃湾区| 开原市| 东城区| 珠海市| 武宁县|