亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

iOS自定義可展示、交互的scrollView滾動(dòng)條

 更新時(shí)間:2019年04月28日 10:19:52   作者:hero_wqb  
這篇文章主要為大家詳細(xì)介紹了iOS自定義可展示、交互的scrollView滾動(dòng)條,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

上一篇簡(jiǎn)述了封裝上拉、下拉刷新控件,本篇在此基礎(chǔ)上添加了一個(gè)自定義的scrollView滾動(dòng)條,可展示、交互,首先看一下效果圖:

簡(jiǎn)單闡述一下實(shí)現(xiàn)邏輯:自定義滾動(dòng)條視圖繼承UIView,添加滾動(dòng)條滑動(dòng)事件、其他區(qū)域點(diǎn)擊事件,通過代理方法與列表關(guān)聯(lián)。在列表刷新完成及scrollView代理方法中更新滾動(dòng)條。

簡(jiǎn)單說一下計(jì)算邏輯,如上圖(原諒博主的圖)所示,其中b、c、d是已知的。首先計(jì)算滾動(dòng)條的高度a,理想情況下它與整個(gè)滾動(dòng)區(qū)域b的比值應(yīng)該等于scrollView的展示區(qū)域b與scrollView的內(nèi)容高度d的比值,就是 a/b = b/d,即 a = b*b/d,也是就代碼中的“_scrollBar.barHeight = pow(tableView.bounds.size.height,2) / tableView.contentSize.height;”這句話。

既然是理想情況,就有特殊情況,首先如果內(nèi)容高度d小于展示區(qū)域b,就是說不需要滑動(dòng)時(shí),這里可以有兩種處理,第一種是隱藏滾動(dòng)條,第二種是將滾動(dòng)條高度設(shè)為與滾動(dòng)區(qū)域一致,方便觀察,這里使用后一種。還有一種特殊情況就是,如果內(nèi)容區(qū)域d無限增大,則滾動(dòng)條高度a無限減小,所以需要給定一個(gè)最小高度限制。

好了,上面計(jì)算出滾動(dòng)條高度a,然后計(jì)算滾動(dòng)條Y向位置x,很容易看出來 x/b = c/d,正常情況下這是沒有問題的,但是當(dāng)滾動(dòng)條高度非常小,小于我們?cè)O(shè)定的最小高度時(shí)就會(huì)有誤差,那么換另一種寫法 x/(b-a) = c/(d-b),即 x = (b-a)*c/(d-b),代碼中“_scrollBar.yPosition = (_scrollBar.bounds.size.height - _scrollBar.barHeight) *_tableView.contentOffset.y / (_tableView.contentSize.height -_scrollBar.bounds.size.height);”這句話。那么在scrollView代理方法中更新這兩項(xiàng)就實(shí)現(xiàn)了滾動(dòng)條高度根據(jù)scrollView內(nèi)容增減,并根據(jù)scrollView滑動(dòng)而移動(dòng)。

最后在我們自定義滾動(dòng)條的代理方法中設(shè)置scrollView的contentOffset,即可實(shí)現(xiàn)scrollView隨著滾動(dòng)條的點(diǎn)擊滑動(dòng)而移動(dòng)。計(jì)算方法與上面一致 x/(b-a) = c/(d-b),區(qū)別是這次動(dòng)條Y向位置x是已知的,scrollView的Y向偏移量c是未知的,即 c = (d-b)*x/(b-a),代碼中“[_tableViewsetContentOffset:CGPointMake(0, (_tableView.contentSize.height -_scrollBar.bounds.size.height) * scrollBar.yPosition / (_scrollBar.bounds.size.height - _scrollBar.barHeight))];”這句話。

下面貼上相關(guān)代碼:

控制器ViewController:

#import <UIKit/UIKit.h>
 
@interface ViewController : UIViewController
 
@end
 
/*** ---------------分割線--------------- ***/
 
#import "ViewController.h"
#import "HWRefresh.h"
#import "HWScrollBar.h"
 
@interface ViewController ()<UITableViewDataSource, UITableViewDelegate, HWScrollBarDelegate>
 
@property (nonatomic, strong) NSMutableArray *array;
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, weak) HWScrollBar *scrollBar;
@property (nonatomic, weak) HWScrollBar *tableBar;
@property (nonatomic, assign) NSInteger page;
 
@end
 
@implementation ViewController
 
- (NSMutableArray *)array
{
 if (!_array) {
 _array = [NSMutableArray array];
 }
 
 return _array;
}
 
- (void)viewDidLoad {
 [super viewDidLoad];
 
 self.view.backgroundColor = [UIColor blackColor];
 self.page = 1;
 
 //模擬獲取信息
 [self getInfo];
 
 //創(chuàng)建控件
 [self creatControl];
 
 //添加頭部刷新
 [self addHeaderRefresh];
 
 //添加尾部刷新
 [self addFooterRefresh];
}
 
- (void)getInfo
{
 NSArray *array = @[@"iOS HERO博客", @"iOS HERO博客", @"iOS HERO博客", @"iOS HERO博客", @"http://blog.csdn.net/hero_wqb", @"iOS HERO博客", @"iOS HERO博客", @"iOS HERO博客", @"iOS HERO博客", @"http://blog.csdn.net/hero_wqb"];
 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
 if (self.page == 1) {
 self.array = [NSMutableArray arrayWithArray:array];
 }else{
 [self.array addObjectsFromArray:array];
 }
 [_tableView reloadData];
 [_tableView headerEndRefreshing];
 [_tableView footerEndRefreshing];
 NSLog(@"已經(jīng)刷新好了");
 });
}
 
- (void)creatControl
{
 //列表視圖
 _tableView = [[UITableView alloc] initWithFrame:CGRectMake(20, 64, [[UIScreen mainScreen] bounds].size.width - 100, [[UIScreen mainScreen] bounds].size.height - 164) style:UITableViewStylePlain];
 _tableView.dataSource = self;
 _tableView.delegate = self;
 [self.view addSubview:_tableView];
 
 //滾動(dòng)展示條
 HWScrollBar *tableBar = [[HWScrollBar alloc] initWithFrame:CGRectMake(CGRectGetMaxX(_tableView.frame), CGRectGetMinY(_tableView.frame), 5, _tableView.bounds.size.height)];
 tableBar.foreColor = [UIColor greenColor];
 tableBar.backColor = [UIColor grayColor];
 tableBar.userInteractionEnabled = NO;
 [self.view addSubview:tableBar];
 _tableBar = tableBar;
 
 //滾動(dòng)條
 HWScrollBar *scrollBar = [[HWScrollBar alloc] initWithFrame:CGRectMake(CGRectGetMaxX(_tableView.frame) + 20, CGRectGetMinY(_tableView.frame), 40, _tableView.bounds.size.height)];
 scrollBar.delegate = self;
 scrollBar.minBarHeight = 80;
 [self.view addSubview:scrollBar];
 _scrollBar = scrollBar;
}
 
- (void)addHeaderRefresh
{
 __weak typeof(self) weakSelf = self;
 [_tableView addHeaderRefreshWithCallback:^{
 __strong typeof(weakSelf) strongSelf = weakSelf;
 strongSelf.page = 1;
 [strongSelf getInfo];
 }];
}
 
- (void)addFooterRefresh
{
 __weak typeof(self) weakSelf = self;
 [_tableView addFooterRefreshWithCallback:^{
 __strong typeof(weakSelf) strongSelf = weakSelf;
 strongSelf.page ++;
 [strongSelf getInfo];
 }];
}
 
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
 return self.array.count;
}
 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
 static NSString *identifier = @"refreshTest";
 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
 if (!cell) {
 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
 }
 cell.textLabel.text = [_array[indexPath.row] stringByAppendingString:[NSString stringWithFormat:@"_%ld", indexPath.row]];
 
 return cell;
}
 
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
 //更新滾動(dòng)條高度
 if (tableView.contentSize.height <= tableView.bounds.size.height) {
 _scrollBar.barHeight = tableView.bounds.size.height;
 _tableBar.barHeight = tableView.bounds.size.height;
 }else {
 _scrollBar.barHeight = pow(tableView.bounds.size.height, 2) / tableView.contentSize.height;
 _tableBar.barHeight = pow(tableView.bounds.size.height, 2) / tableView.contentSize.height;
 }
 
 //更新滾動(dòng)條Y向位置
 _scrollBar.yPosition = (_scrollBar.bounds.size.height - _scrollBar.barHeight) * _tableView.contentOffset.y / (_tableView.contentSize.height - _scrollBar.bounds.size.height);
 _tableBar.yPosition = (_tableBar.bounds.size.height - _tableBar.barHeight) * _tableView.contentOffset.y / (_tableView.contentSize.height - _tableBar.bounds.size.height);
 });
}
 
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
 //滑動(dòng)到底部自動(dòng)刷新
 if (_tableView.contentSize.height > _tableView.frame.size.height && _tableView.contentOffset.y + _tableView.frame.size.height > _tableView.contentSize.height - 40 && _page < 50) {
 [_tableView footerBeginRefreshing];
 }
 
 //更新滾動(dòng)條位置
 _scrollBar.yPosition = (_scrollBar.bounds.size.height - _scrollBar.barHeight) * scrollView.contentOffset.y / (scrollView.contentSize.height - _scrollBar.bounds.size.height);
 _tableBar.yPosition = (_tableBar.bounds.size.height - _tableBar.barHeight) * scrollView.contentOffset.y / (scrollView.contentSize.height - _tableBar.bounds.size.height);
}
 
#pragma mark - SXScrollBarDelegate
- (void)scrollBarDidScroll:(HWScrollBar *)scrollBar
{
 [_tableView setContentOffset:CGPointMake(0, (_tableView.contentSize.height - _scrollBar.bounds.size.height) * scrollBar.yPosition / (_scrollBar.bounds.size.height - _scrollBar.barHeight))];
}
 
- (void)scrollBarTouchAction:(HWScrollBar *)scrollBar
{
 [UIView animateWithDuration:scrollBar.barMoveDuration animations:^{
 [_tableView setContentOffset:CGPointMake(0, (_tableView.contentSize.height - _scrollBar.bounds.size.height) * scrollBar.yPosition / (_scrollBar.bounds.size.height - _scrollBar.barHeight))];
 }];
}
 
@end

自定義滾動(dòng)條HWScrollBar:

#import <UIKit/UIKit.h>
 
@class HWScrollBar;
 
@protocol HWScrollBarDelegate <NSObject>
 
//滾動(dòng)條滑動(dòng)代理事件
- (void)scrollBarDidScroll:(HWScrollBar *)scrollBar;
 
//滾動(dòng)條點(diǎn)擊代理事件
- (void)scrollBarTouchAction:(HWScrollBar *)scrollBar;
 
@end
 
@interface HWScrollBar : UIView
 
//背景色
@property (nonatomic, strong) UIColor *backColor;
 
//前景色
@property (nonatomic, strong) UIColor *foreColor;
 
//滾動(dòng)動(dòng)畫時(shí)長(zhǎng)
@property (nonatomic, assign) CGFloat barMoveDuration;
 
//限制滾動(dòng)條最小高度
@property (nonatomic, assign) CGFloat minBarHeight;
 
//滾動(dòng)條實(shí)際高度
@property (nonatomic, assign) CGFloat barHeight;
 
//滾動(dòng)條Y向位置
@property (nonatomic, assign) CGFloat yPosition;
 
//代理
@property (nonatomic, weak) id<HWScrollBarDelegate> delegate;
 
@end
 
/*** ---------------分割線--------------- ***/
 
#import "HWScrollBar.h"
#import "UIColor+HW.h"
 
@interface HWScrollBar ()
 
@property (nonatomic, weak) UIView *scrollBar;
@property (nonatomic, weak) UIView *backView;
 
@end
 
@implementation HWScrollBar
 
- (instancetype)initWithFrame:(CGRect)frame
{
 if (self = [super initWithFrame:frame]) {
 //初始化設(shè)置
 [self initInfo];
 
 //創(chuàng)建控件
 [self creatControl];
 
 //添加手勢(shì)
 [self addSwipeGesture];
 }
 
 return self;
}
 
- (void)initInfo
{
 _minBarHeight = 40.0f;
 _barMoveDuration = 0.25f;
 _foreColor = [UIColor colorWithHexString:@"#2f9cd4"];
 _backColor = [UIColor colorWithHexString:@"#e6e6e6"];
 
 self.layer.cornerRadius = self.bounds.size.width * 0.5;
 self.layer.masksToBounds = YES;
 self.backgroundColor = _backColor;
}
 
- (void)creatControl
{
 //背景視圖
 UIView *backView = [[UIView alloc] initWithFrame:self.bounds];
 [self addSubview:backView];
 _backView = backView;
 
 //滾動(dòng)條
 UIView *scrollBar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height)];
 scrollBar.backgroundColor = _foreColor;
 scrollBar.layer.cornerRadius = self.bounds.size.width * 0.5;
 scrollBar.layer.masksToBounds = YES;
 [self addSubview:scrollBar];
 _scrollBar = scrollBar;
}
 
- (void)addSwipeGesture
{
 //添加點(diǎn)擊手勢(shì)
 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
 [_backView addGestureRecognizer:tap];
 
 //添加滾動(dòng)條滑動(dòng)手勢(shì)
 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
 [_scrollBar addGestureRecognizer:pan];
}
 
- (void)setForeColor:(UIColor *)foreColor
{
 _foreColor = foreColor;
 
 _scrollBar.backgroundColor = _foreColor;
}
 
- (void)setBackColor:(UIColor *)backColor
{
 _backColor = backColor;
 
 self.backgroundColor = backColor;
}
 
- (void)setBarHeight:(CGFloat)barHeight
{
 _barHeight = barHeight > _minBarHeight ? barHeight : _minBarHeight;
 
 CGRect temFrame = _scrollBar.frame;
 temFrame.size.height = _barHeight;
 _scrollBar.frame = temFrame;
}
 
- (void)setYPosition:(CGFloat)yPosition
{
 _yPosition = yPosition;
 
 CGRect temFrame = _scrollBar.frame;
 temFrame.origin.y = yPosition;
 _scrollBar.frame = temFrame;
}
 
- (void)handlePan:(UIPanGestureRecognizer *)sender
{
 //獲取偏移量
 CGFloat moveY = [sender translationInView:self].y;
 
 //重置偏移量,避免下次獲取到的是原基礎(chǔ)的增量
 [sender setTranslation:CGPointMake(0, 0) inView:self];
 
 //在頂部上滑或底部下滑直接返回
 if ((_yPosition <= 0 && moveY <= 0) || (_yPosition >= self.bounds.size.height - _barHeight && moveY >= 0)) return;
 
 //賦值
 self.yPosition += moveY;
 
 //防止瞬間大偏移量滑動(dòng)影響顯示效果
 if (_yPosition < 0) self.yPosition = 0;
 if (_yPosition > self.bounds.size.height - _barHeight && moveY >= 0) self.yPosition = self.bounds.size.height - _barHeight;
 
 //代理
 if (_delegate && [_delegate respondsToSelector:@selector(scrollBarDidScroll:)]) {
 [_delegate scrollBarDidScroll:self];
 }
}
 
- (void)handleTap:(UITapGestureRecognizer *)sender
{
 //點(diǎn)擊滾動(dòng)條返回
 if (sender.view == _scrollBar) return;
 
 //獲取點(diǎn)擊的位置
 CGFloat positionY = [sender locationInView:self].y;
 
 //賦值
 [UIView animateWithDuration:_barMoveDuration animations:^{
 self.yPosition = positionY > _yPosition ? positionY - _barHeight : positionY;
 }];
 
 //代理
 if (_delegate && [_delegate respondsToSelector:@selector(scrollBarTouchAction:)]) {
 [_delegate scrollBarTouchAction:self];
 }
}
 
@end

Demo 下載鏈接

猜你喜歡:自定義水平滾動(dòng)條、進(jìn)度條。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • iOS設(shè)置圓角陰影 避免離屏渲染

    iOS設(shè)置圓角陰影 避免離屏渲染

    這篇文章主要為大家詳細(xì)介紹了iOS設(shè)置圓角陰影,避免離屏渲染,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • iOS中詳解Block作為property屬性實(shí)現(xiàn)頁面之間傳值

    iOS中詳解Block作為property屬性實(shí)現(xiàn)頁面之間傳值

    這篇文章主要介紹了iOS中Block作為property屬性實(shí)現(xiàn)頁面之間傳值的相關(guān)知識(shí)點(diǎn),以及代碼分享,一起學(xué)習(xí)下吧。
    2018-02-02
  • 實(shí)例講解iOS音樂播放器DOUAudioStreamer用法

    實(shí)例講解iOS音樂播放器DOUAudioStreamer用法

    本篇文章給大家通過實(shí)例講解了iOS音樂播放器DOUAudioStreamer用法以及分享了實(shí)例代碼,一起學(xué)習(xí)參考下吧。
    2017-12-12
  • IOS 基礎(chǔ)之nil,NULL,NSNULL區(qū)別詳解

    IOS 基礎(chǔ)之nil,NULL,NSNULL區(qū)別詳解

    這篇文章主要介紹了IOS 基礎(chǔ)之nil,NULL,NSNULL區(qū)別詳解的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • 詳解MacOs免密登錄CentOs操作步驟

    詳解MacOs免密登錄CentOs操作步驟

    這篇文章主要介紹了詳解MacOs免密登錄CentOs操作步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • iOS、Mac OS X系統(tǒng)中編程實(shí)現(xiàn)漢字轉(zhuǎn)拼音的方法(超級(jí)簡(jiǎn)單)

    iOS、Mac OS X系統(tǒng)中編程實(shí)現(xiàn)漢字轉(zhuǎn)拼音的方法(超級(jí)簡(jiǎn)單)

    這篇文章主要介紹了iOS、Mac OS X系統(tǒng)中編程實(shí)現(xiàn)漢字轉(zhuǎn)拼音的方法(超級(jí)簡(jiǎn)單),本文講解的方法不僅支持中文,還支持日文、韓文等,需要的朋友可以參考下
    2015-04-04
  • 詳解iOS設(shè)計(jì)中的UIWindow使用

    詳解iOS設(shè)計(jì)中的UIWindow使用

    這篇文章主要介紹了iOS設(shè)計(jì)中的UIWindow使用,包括UIWindowLevel和KeyWindow兩個(gè)大的方面的講解,需要的朋友可以參考下
    2015-09-09
  • 詳解適配iOS10 的相關(guān)權(quán)限設(shè)置

    詳解適配iOS10 的相關(guān)權(quán)限設(shè)置

    在最新版本的iOS10系統(tǒng)中,如果你的項(xiàng)目中訪問了隱私數(shù)據(jù),比如:相機(jī)、相冊(cè)、錄音、定位、聯(lián)系人等等。涉及到權(quán)限問題,本篇文章主要介紹了適配iOS10 的相關(guān)權(quán)限設(shè)置,有興趣的可以了解一下。
    2016-12-12
  • 分析IOS RunLoop的事件循環(huán)機(jī)制

    分析IOS RunLoop的事件循環(huán)機(jī)制

    RunLoop是與線程相關(guān)的基礎(chǔ)架構(gòu)中的一部分,它是一個(gè)處理事件的循環(huán)(線程進(jìn)入這個(gè)循環(huán),運(yùn)行事件處理程序來響應(yīng)傳入的事件),RunLoop的目的是當(dāng)有事件需要處理時(shí),線程是活躍的、忙碌的,當(dāng)沒有事件后,線程進(jìn)入休眠。
    2021-06-06
  • 99%?iOS開發(fā)都不知道的KVO崩潰分析詳解

    99%?iOS開發(fā)都不知道的KVO崩潰分析詳解

    這篇文章主要為大家介紹了99%?iOS開發(fā)都不知道的KVO崩潰分析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01

最新評(píng)論