• 自定义scrollview右侧的滑动条


      在做这个功能之前我其实是拒绝的,为什么这么说呢,因为我怕麻烦啊!(开玩笑的,怕麻烦就不做程序员了)

      很久没有写博客,这次刚好项目中有个有趣的东西,想拿出来分享一下,希望能帮到某些小伙伴。

      首先说说需求,是这样的:

      在tableview滑动的过程中,右侧的滑动条中间放一个label随着滑动条一起滑动,并且它的centerY与滑动条的centerY相等。当然,在滑到顶部或者尾部的时候label不能超出tableview的范围。

    然后label上面显示与之对应的cell的内容。

      刚开始想用系统提供的滑动条,scrollIndicator,没啥用啊。就提供了一个方法,没办法完成这种效果,只能自定义一个。下面有几个变量,我先设置一下,height:tableview的高度,allHeight:tableview内容的高度,y:tableview的contentoffset.y,currentHeight:滑动条的高度。

      1.猜想,currentHeight/height=height/allHeight,然后去证实这一猜想,结果是有几个像素的偏差,不过并不影响。

      2.确定滑动块的位置,要判断画框在画布的上半部分还是下半部分,在上面用top,在下面用bottom(没看明白继续往下看,有完整的代码):

    if (y+height/2.0<=allHeight/2.0)
        {
            myScrollViewIndirect.top = 66+y*height/allHeight;
            if (myScrollViewIndirect.top < 66)
            {
                myScrollViewIndirect.top = 66;
            }
        }
        else
        {
            CGFloat y1 = (allHeight-height-y);
            myScrollViewIndirect.bottom = 62+height-y1*height/allHeight;
            if (myScrollViewIndirect.bottom>62+height)
            {
                myScrollViewIndirect.bottom = 62+height;
            }
        }

      3.滑块的位置的高度确定了,相当于已经完成了一半,接下来是确定label的位置,这就简单了,将滑动条的centerY给label的centerY就可以了。不过滑到最顶部,而且继续往下拉,滑动到最底部继续往上拉的时候需要判断一下label的位置。很简单的条件语句,后面有。

      4.最核心的功能,label显示其所在位置的cell内容。通过遍历tableview里面cell的位置来判断对应的是哪一个cell,获取其下标,然后在数据源中得到内容。不过由于是遍历,我实在没脸单独把这个算法拿出来,想想以后还是学学高级一点的算法吧。

      最后附上代码,不然就要被喷了。

      1 #define SUBCOUNT 0.2
      2 #import "ALDayPictureWallViewController.h"
      3 #import "ALGoalPictureWallViewController.h"
      4 
      5 @interface ALDayPictureWallViewController ()<UITableViewDelegate,UITableViewDataSource>
      6 {
      7     NSTimer *timer;
      8     CGFloat subCount;
      9     CGFloat y;
     10     //自定义滑动块
     11     UIView *myScrollViewIndirect;
     12     UILabel *myLabel;
     13     NSInteger cellCount;
     14 }
     15 @property (nonatomic, strong) UITableView *tableView;
     16 @property (nonatomic, strong) NSMutableArray *dataArray;
     17 
     18 @end
     19 
     20 @implementation ALDayPictureWallViewController
     21 
     22 - (void)viewDidLoad {
     23     [super viewDidLoad];
     24     // Do any additional setup after loading the view.
     25     self.view.backgroundColor = [UIColor whiteColor];
     26     subCount = SUBCOUNT;
     27     [self createNavi];
     28     [self createUI];
     29     
     30     myScrollViewIndirect = [LMFUITools createView:CGRectMake(0, 64, 3, 0) andBackgroundColor:[UIColor grayColor]];
     31     myScrollViewIndirect.layer.cornerRadius = myScrollViewIndirect.width/2.0;
     32     myScrollViewIndirect.right = SCREEN_WIDTH-3;
     33     [self.view addSubview:myScrollViewIndirect];
     34     
     35     myLabel = [LMFUITools createLabelWithFrame:CGRectMake(0, 0, 100, 0) andBackgroundColor:[UIColor cyanColor] andTextAlignment:NSTextAlignmentCenter andFont:[UIFont systemFontOfSize:17] andText:@"" andTextColor:[UIColor blackColor]];
     36     myLabel.right = myScrollViewIndirect.left-2;
     37     [self.view addSubview:myLabel];
     38     
     39     [self loadData];
     40 
     41 }
     42 
     43 - (void)loadData
     44 {
     45     for (int i=0; i<40; i++)
     46     {
     47         NSString *str = [NSString stringWithFormat:@"第%i行", i];
     48         [self.dataArray addObject:str];
     49     }
     50     [self.tableView reloadData];
     51 }
     52 
     53 - (NSMutableArray *)dataArray
     54 {
     55     if (_dataArray == nil)
     56     {
     57         _dataArray = [NSMutableArray array];
     58     }
     59     return _dataArray;
     60 }
     61 
     62 - (void)createNavi
     63 {
     64     float height = 20;
     65     float width = height * 16 / 28;
     66     UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(6, 20, 60, 44)];
     67     [self.view addSubview:leftView];
     68     UIImageView *image = [LMFUITools createImageView:CGRectMake(10, (44-height)/2, width, height) andBackgroundImage:@"naviBlack_image"];
     69     [leftView addSubview:image];
     70     UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(goBackView:)];
     71     [leftView addGestureRecognizer:tap];
     72     
     73     UILabel *titleLable = [LMFUITools createLabelWithFrame:CGRectMake(0, 20, SCREEN_WIDTH/2.0, 44) andBackgroundColor:nil andTextAlignment:NSTextAlignmentCenter andFont:[UIFont systemFontOfSize:17] andText:@"照片墙" andTextColor:[UIColor blackColor]];
     74     titleLable.centerX = SCREEN_WIDTH * 0.5;
     75     [self.view addSubview:titleLable];
     76     
     77     //平铺
     78     UIView *rightView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 120, 44)];
     79     rightView.right = SCREEN_WIDTH;
     80     rightView.top = 20;
     81     [self.view addSubview:rightView];
     82     
     83     UIImageView *rightImage = [LMFUITools createImageView:CGRectMake(0, 0, 44, 44) andBackgroundImage:@""];
     84     [rightView addSubview:rightImage];
     85     UILabel *label = [LMFUITools createLabelWithFrame:CGRectMake(0, 0, 44, 44) andBackgroundColor:nil andTextAlignment:NSTextAlignmentLeft andFont:[UIFont systemFontOfSize:15] andText:@"平铺" andTextColor:[UIColor colorWithHexString:@"#999999"]];
     86     label.left = rightImage.right;
     87     [rightView addSubview:label];
     88     
     89     UITapGestureRecognizer *goalPictureTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(startTimer)];
     90     [rightView addGestureRecognizer:goalPictureTap];
     91 }
     92 
     93 - (void)startTimer
     94 {
     95     if (timer == nil)
     96     {
     97         timer = [NSTimer scheduledTimerWithTimeInterval:0.002 target:self selector:@selector(startScrollTableView) userInfo:nil repeats:YES];
     98         self.tableView.userInteractionEnabled = NO;
     99         [timer fire];
    100     }
    101     else
    102     {
    103         [timer setFireDate:[NSDate distantFuture]];
    104         timer = nil;
    105         [timer invalidate];
    106         self.tableView.userInteractionEnabled = YES;
    107     }
    108 }
    109 
    110 - (void)createUI
    111 {
    112     self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, SCREEN_WIDTH, SCREEN_HEIGHT-64) style:UITableViewStylePlain];
    113     self.tableView.backgroundColor = [UIColor colorWithHexString:@"#f5f5f5"];
    114 //    self.tableView.showsVerticalScrollIndicator = NO;
    115 //    self.tableView.showsHorizontalScrollIndicator = NO;
    116 //    self.tableView.separatorInset = UIEdgeInsetsZero;
    117 //    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    118     self.tableView.delegate = self;
    119     self.tableView.dataSource = self;
    120     [self.view addSubview:self.tableView];
    121     [self.tableView setContentOffset:CGPointMake(0, 0)];
    122 }
    123 
    124 #pragma mark --tableview delegate
    125 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    126 {
    127     return 44;
    128 }
    129 
    130 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    131 {
    132     return [self.dataArray count];
    133 }
    134 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    135 {
    136     return 1;
    137 }
    138 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    139 {
    140     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
    141     if (cell == nil)
    142     {
    143         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"UITableViewCell"];
    144     }
    145     if ([self.dataArray count])
    146     {
    147         cell.textLabel.text = [self.dataArray objectAtIndex:indexPath.row];
    148     }
    149     
    150     cell.selectionStyle = 0;
    151     return cell;
    152 }
    153 
    154 - (void)goalPicture:(UITapGestureRecognizer *)gesture
    155 {
    156     ALGoalPictureWallViewController *goalPictureView = [[ALGoalPictureWallViewController alloc] init];
    157     self.hidesBottomBarWhenPushed = YES;
    158     [self.navigationController pushViewController:goalPictureView animated:YES];
    159 }
    160 
    161 #pragma mark --开始滑动
    162 - (void)startScrollTableView
    163 {
    164     y+=subCount;
    165     NSInteger count = 40;
    166     CGFloat height = count*44.0;
    167     if (y>height-self.tableView.height)
    168     {
    169         subCount = -SUBCOUNT;
    170     }
    171     else if (y<0)
    172     {
    173         subCount = SUBCOUNT;
    174     }
    175     [self.tableView setContentOffset:CGPointMake(0, y)];
    176 }
    177 
    178 - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    179 {
    180     NSLog(@"contentOffset.y      %f", scrollView.contentOffset.y);
    181     y = scrollView.contentOffset.y;
    182     
    183     //需要tableview的contentoffset.y,tableview的高度,tableview画布的高度
    184     CGFloat height = scrollView.height;
    185     CGFloat allHeight = scrollView.contentSize.height;
    186     
    187     //计算自定义滑块的高度
    188     myScrollViewIndirect.height = height*height/allHeight;
    189     //控件的高度不能设为负数,它会自动转化为正数,阿西吧
    190     float currentHeight = myScrollViewIndirect.height;
    191     //计算滑块
    192     //如果tableview的中心在画框的上部,通过top确定滑块的位置
    193     
    194     if (y<0)
    195     {
    196         currentHeight += y;
    197     }
    198     if (y+height>allHeight)
    199     {
    200         CGFloat h = fabs(y+height-allHeight);
    201         currentHeight -= h;
    202     }
    203     
    204     if (currentHeight<8)
    205     {
    206         myScrollViewIndirect.height = 8;
    207     }
    208     else
    209     {
    210         myScrollViewIndirect.height = currentHeight;
    211     }
    212     
    213     if (y+height/2.0<=allHeight/2.0)
    214     {
    215         myScrollViewIndirect.top = 66+y*height/allHeight;
    216         if (myScrollViewIndirect.top < 66)
    217         {
    218             myScrollViewIndirect.top = 66;
    219         }
    220     }
    221     else
    222     {
    223         CGFloat y1 = (allHeight-height-y);
    224         myScrollViewIndirect.bottom = 62+height-y1*height/allHeight;
    225         if (myScrollViewIndirect.bottom>62+height)
    226         {
    227             myScrollViewIndirect.bottom = 62+height;
    228         }
    229     }
    230     myLabel.height = 20;
    231     myLabel.centerY = myScrollViewIndirect.centerY;
    232     if (myLabel.top < 66)
    233     {
    234         myLabel.top = 66;
    235     }
    236     if (myLabel.bottom>62+height)
    237     {
    238         myLabel.bottom = 62+height;
    239     }
    240     CGFloat centerY = myLabel.centerY+y-64;
    241     for (NSInteger i=0; i<[self.dataArray count]; i++)
    242     {
    243         NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
    244         CGRect rectInTableView = [self.tableView rectForRowAtIndexPath:indexPath];
    245 //        CGRect rect = [self.tableView convertRect:rectInTableView toView:[self.tableView superview]];
    246         if (rectInTableView.origin.y<=centerY && centerY<=rectInTableView.origin.y+rectInTableView.size.height)
    247         {
    248             NSLog(@"cell.y=%f  cellHeight=%f", rectInTableView.origin.y, rectInTableView.size.height);
    249             myLabel.text = [self.dataArray objectAtIndex:i];
    250             return;
    251         }
    252         if (rectInTableView.origin.y > centerY)
    253         {
    254             NSLog(@"cell.y=%f  cellHeight=%f", rectInTableView.origin.y, rectInTableView.size.height);
    255             return;
    256         }
    257     }
    258 }
    259 
    260 - (void)goBackView:(UITapGestureRecognizer *)gesture
    261 {
    262     [self.navigationController popViewControllerAnimated:YES];
    263 }
    264 
    265 - (void)viewWillAppear:(BOOL)animated
    266 {
    267     [super viewWillAppear:animated];
    268     self.navigationController.navigationBar.hidden = YES;
    269 }
    270 
    271 - (void)viewWillDisappear:(BOOL)animated
    272 {
    273     [super viewWillDisappear:animated];
    274     [timer setFireDate:[NSDate distantFuture]];
    275     timer = nil;
    276     [timer invalidate];
    277     self.navigationController.navigationBar.hidden = NO;
    278 }
    279 
    280 - (void)didReceiveMemoryWarning {
    281     [super didReceiveMemoryWarning];
    282     // Dispose of any resources that can be recreated.
    283 }
    284 
    285 @end

      

  • 相关阅读:
    Java第七次作业
    JAVA第六次作业
    JAVA第五次作业
    JAVA第四次作业
    JAVA第三次作业
    JAVA第二次作业
    Java第一次作业
    2017《Java》预备作业02 计科1501刘喆
    2017《JAVA》预备作业 计科1501刘喆
    Java第十次作业--多线程
  • 原文地址:https://www.cnblogs.com/lmfboke/p/6208698.html
Copyright © 2020-2023  润新知