• 可自定义整个菜单的宽度,可自定义菜单按钮,自定义下拉展示的cell,可自定义数据模型。按钮显示内容可与下拉列表不一致(因为有时候按钮需要显示缩写)。选中某列某行后会有相应回调,传回位置及数据模型。
  • ios自定义下拉列表

    2016-03-04 12:43:28
    下拉列表的实现方法有许多种,笔者在此只介绍实际上目中切实使用的,最简单(并不是最优)的一种方法。实现思路: 1、自定义一个UIView,添加到相应ViewController的指定位置。默认透明度为0。 2、给对应的调出...

    下拉列表的实现方法有许多种,笔者在此只介绍实际上目中切实使用的,最简单(并不是最优)的一种方法。

    实现思路:
    1、自定义一个UIView,添加到相应ViewController的指定位置。默认透明度为0。
    2、给对应的调出控件添加相应方法,在相应方法中将下拉列表的透明度设为1。
    3、为了达到下拉列表调出的时候,其他控件不响应,在下拉列表下添加一个UIView,添加到同样的ViewController 上,默认透明度也为0。在下拉列表调出的时候,同时设置其透明度为0.3(根据需要调整)。
    4、再次点击调出控件的时候或者是点击下拉列表中的控件时,设置下拉列表,及其遮挡视图的透明度为0。(点击调出控件的响应方法中可以设置一个全局的Bool值,每次点击都变为 !Bool 值)

    下面是实现代码。
    (1)、自定义的下拉列表的UIView

    #import "BView.h"
    
    @interface testView : BView
    
    @property (nonatomic, copy) void(^searchTypeVCBlock)(NSInteger);
    
    @end
    
    #import "testView.h"
    #import "Masonry.h"
    
    @implementation testView
    
    -(id)initWithFrame:(CGRect)frame
    {
        if (self = [super initWithFrame:frame]) {
    
            NSArray * arr = @[@"全部",@"商品",@"方案"];
    
            for (int i=0; i<arr.count; i++) {
                UIButton * button = [[UIButton alloc] init];
                [button setTitle:arr[i] forState:UIControlStateNormal];
                [button setTitleColor:UIColorFromRGBOne(0x73) forState:UIControlStateNormal];
                button.titleLabel.font = GetFont(BFONT_15);
                button.tag = 100+i;
                [button addTarget:self action:@selector(clickbutton:) forControlEvents:UIControlEventTouchUpInside];
                [self addSubview:button];
    
                button.frame = CGRectMake(0, i*35, SCREEN_WIDTH, 35);
            }
    
            for (int j=0; j<2; j++) {
                UIImageView * testImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 35+j*35, SCREEN_WIDTH, 1)];
                testImageView.backgroundColor = UIColorFromRGBOne(0x99);
                [self addSubview:testImageView];
            }
        }
        return self;
    }
    
    -(void)clickbutton:(UIButton *)button{
    
        if (button.tag == 100) {
            if (self.searchTypeVCBlock){
                self.searchTypeVCBlock(0);
            }
        }else if (button.tag == 101){
            if (self.searchTypeVCBlock){
                self.searchTypeVCBlock(1);
            }
        }else if (button.tag == 102){
            if (self.searchTypeVCBlock){
                self.searchTypeVCBlock(2);
            }
        }
    //    NSInteger typeTag = button.tag-100;
    //    self.searchTypeVCBlock(typeTag);
    }
    
    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    - (void)drawRect:(CGRect)rect {
        // Drawing code
    }
    */
    
    @end
    

    (2)、在对应的ViewController中添加UIVIew

     _KeepOutView = [[UIView alloc]initWithFrame:self.view.frame];
        _KeepOutView.backgroundColor = [UIColor grayColor];
        _KeepOutView.alpha = 0;
        [self.view addSubview:_KeepOutView];
    
    //下拉列表
        _dropDownMenuView = [[testView alloc] init];
        _dropDownMenuView.userInteractionEnabled = YES;
        _dropDownMenuView.backgroundColor = [UIColor whiteColor];
        [self.view addSubview:_dropDownMenuView];
        _dropDownMenuView.frame = CGRectMake(0, 0, SCREEN_WIDTH, 105);
        _dropDownMenuView.alpha = 0;
        _dropDown = NO;
    
        __weak typeof(self) weakSelf = self;
        _dropDownMenuView.searchTypeVCBlock = ^(NSInteger searchInteger){
            _typeInteger = searchInteger;
    
            weakSelf.dropDownMenuView.alpha = 0;
            weakSelf.KeepOutView.alpha = 0;
    
            [weakSelf loadData];
            [weakSelf createUI];
            [weakSelf doaction];
        };
    

    (3)、调用下拉列表

    //搜索类型选择
        _typeLabel = [[UILabel alloc] init];
        _typeLabel.text = _typeArray[_typeInteger];
        _typeLabel.font = GetFont(BFONT_12);
        _typeLabel.textAlignment = 1;
        _typeLabel.layer.borderWidth = 1;
        _typeLabel.layer.borderColor = UIColorFromRGBOne(0x99).CGColor;
        _typeLabel.textColor = UIColorFromRGBOne(0x73);
        [searchView addSubview:_typeLabel];
        [_typeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.size.mas_equalTo(CGSizeMake(32, 26));
            make.leftMargin.equalTo(searchView).with.offset(-1);
            make.topMargin.equalTo(searchView).with.offset(-1);
        }];
    
        UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickLabel)];
        _typeLabel.userInteractionEnabled = YES;
        [_typeLabel addGestureRecognizer:tapGesture];

    (4)、响应方法,设施知否显示下拉列表

    #pragma mark - 分类选择商品
    -(void)clickLabel{
        _dropDown = !_dropDown;
        if (_dropDown) {
            _dropDownMenuView.alpha = 1;
            _KeepOutView.alpha = 0.3;
        }else{
            _dropDownMenuView.alpha = 0;
            _KeepOutView.alpha = 0;
        }
    }
    

    点击其他方法取消下拉列表的方法就很简单就不在这里具体说了。需要注意的是,下拉列表的View,和遮挡视图的View添加顺序,先添加遮挡视图。
    希望对你能有帮助

    展开全文
  • 首先自定义一个UIRefreshControl名字叫做NewRefreshControl,在UITableViewController中将它的refreshControl设置成自定义的refreshControl,并且为refreshControl添加监听事件.- (void)viewDidLoad { [super ...

    首先自定义一个UIRefreshControl名字叫做NewRefreshControl,在UITableViewController中将它的refreshControl设置成自定义的refreshControl,并且为refreshControl添加监听事件.

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.refreshControl = [[NewRefreshControl alloc]init];
        [self.refreshControl addTarget:self action:@selector(reloadData) forControlEvents:UIControlEventValueChanged];
    }

    然后自定义一个视图名字叫做NewRefreshView
    这里写图片描述
    将NewRefreshView添加到NewRefreshControl中并且设置好约束

        [self addSubview:self.refreshView];
    //设置约束
    self.refreshView.translatesAutoresizingMaskIntoConstraints = NO;
            NSLayoutConstraint *centerX = [NSLayoutConstraint constraintWithItem:self.refreshView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0];
            NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:self.refreshView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:160];
            NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:self.refreshView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:60];
            [self addConstraint:centerX];
            [self.refreshView addConstraint:width];
            [self.refreshView addConstraint:height];

    隐藏refreshControl自带的刷新视图,并且使用KVO监听refreshControl的frame

            //隐藏菊花
            self.tintColor = [UIColor clearColor];
            //KVO 监听refreshControl的frame
            [self addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];

    在KVO的回调方法中,当下拉的时候也就是refreshControl的frame改变的时候让箭头翻转.当刷新数据的时候隐藏下拉刷新视图并且显示正在加载的视图

    //记录是否翻转
    @property(nonatomic,assign)BOOL isTurn;
    //记录是否正在加载数据
    @property(nonatomic,assign)BOOL isLoading;
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
        //当刷新数据的时候隐藏下拉加载视图并且显示正在加载的视图
        if (self.isRefreshing && !self.isLoading) {
            self.refreshView.pullView.hidden = YES;
            //数据加载的动画
            [self.refreshView loadingImageViewAnimation];
            self.isLoading = YES;
        }
        //当下拉的时候让箭头翻转(这里自定义的refreshView的高度是60)
        if (self.frame.origin.y < -60 && !self.isTurn) {
            NSLog(@"翻");
            //箭头翻转动画
            [self.refreshView pullImageViewAnimation];
            self.isTurn = YES;
        }else if(self.frame.origin.y > -60 && self.isTurn){
            NSLog(@"翻回来");
            [self.refreshView pullImageViewAnimation];
            self.isTurn = NO;
        }
    }
    
    - (void)dealloc{
        [self removeObserver:self forKeyPath:@"frame"];
    }

    在自定义的refreshView中实现箭头翻转动画和视图加载动画

    #import "NewRefreshView.h"
    @implementation NewRefreshView
    //箭头翻转动画
    - (void)pullImageViewAnimation{
        [UIView animateWithDuration:1 animations:^{
            self.pullImageView.transform = CGAffineTransformRotate(self.pullImageView.transform, M_PI);
        }];
    }
    //数据加载动画
    - (void)loadingImageViewAnimation{
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
        animation.toValue = @(2 * M_PI);
        animation.duration = 2;
        animation.removedOnCompletion = NO;
        animation.repeatCount = MAXFLOAT;
        [self.loadingImageView.layer addAnimation:animation forKey:nil];
    }
    @end

    最后重写自定义refreshControl的endRefreshing方法

    - (void)endRefreshing{
        [super endRefreshing];
        self.refreshView.pullView.hidden = NO;
        [self.refreshView.loadingImageView.layer removeAllAnimations];
        self.isLoading = NO;
    }

    并且在refreshControl的监听方法中调用

    - (void)reloadData{
        //在这里调用加载数据的方法
        NSLog(@"刷新数据");
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            //结束刷新
            [self.refreshControl endRefreshing];
        });
    }

    默认是箭头向下,往下拉的时候箭头翻转到上面,在往下的时候下拉刷新的视图隐藏替换成正在加载的视图,刷新结束恢复到原来的状态.
    最终效果

    展开全文
  • iOS 自定义下拉搜索选项框。

    之前两篇简述了UISearchbar的属性、方法,以及UISearchbar的简单使用。本篇在此基础上简单封装了一个下拉选项框。

    先看一下效果图:



    封装的HWOptionButton属性:

    @property (nonatomic,strong)NSArray *array; //需要显示的选项数组

    @property (nonatomic,copy,readonly)NSString *title; //选择的标题

    @property (nonatomic,assign,readonly)NSInteger row; //选择的行数

    @property (nonatomic,assign)BOOL showPlaceholder;  //是否显示提示文字,默认为显示

    @property (nonatomic,assign)BOOL showSearchBar;  //是否显示搜索条,默认为不显示


    下面贴上代码:

    ViewController:

    #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController
    
    @end
    
    /*** ---------------分割线--------------- ***/
    
    #import "ViewController.h"
    #import "HWOptionButton.h"
    
    @interface ViewController ()<HWOptionButtonDelegate>
    
    @property (nonatomic, weak) HWOptionButton *optionButton;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.view.backgroundColor = [UIColor blackColor];
        
        [self creatControl];
    }
    
    - (void)creatControl
    {
        HWOptionButton *optionBtn = [[HWOptionButton alloc] initWithFrame:CGRectMake(50, 100, 200, 44)];
        optionBtn.array = @[@"mac", @"kobe", @"tracy", @"allen", @"ios", @"android", @"swift", @"object", @"activity"];
        optionBtn.delegate = self;
        optionBtn.showSearchBar = YES;
    //    optionBtn.showPlaceholder = NO;
        [self.view addSubview:optionBtn];
        self.optionButton = optionBtn;
        
        UIButton *sureBtn = [[UIButton alloc] initWithFrame:CGRectMake(50, 450, 200, 44)];
        [sureBtn setTitle:@"确认" forState:UIControlStateNormal];
        sureBtn.backgroundColor = [UIColor orangeColor];
        [sureBtn addTarget:self action:@selector(sureBtnOnClick) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:sureBtn];
    }
    
    - (void)sureBtnOnClick
    {
        if ([_optionButton.title isEqualToString:@"-请选择-"]) {
            NSLog(@"未选择");
            return;
        }
        
        NSLog(@"选择了第%ld行,标题为%@", _optionButton.row, _optionButton.title);
    }
    
    #pragma mark - HWOptionButtonDelegate
    - (void)didSelectOptionInHWOptionButton:(HWOptionButton *)optionButton
    {
        //do something...
    }
    
    @end


    HWOptionButton:

    #import <UIKit/UIKit.h>
    
    @class HWOptionButton;
    
    @protocol HWOptionButtonDelegate <NSObject>
    
    //确认选项后,如有其它特殊操作,用此代理事件
    - (void)didSelectOptionInHWOptionButton:(HWOptionButton *)optionButton;
    
    @end
    
    @interface HWOptionButton : UIView
    
    @property (nonatomic, strong) NSArray *array;
    @property (nonatomic, copy, readonly) NSString *title;
    @property (nonatomic, assign, readonly) NSInteger row;
    @property (nonatomic, assign) BOOL showPlaceholder; //default is YES.
    @property (nonatomic, assign) BOOL showSearchBar; //default is NO.
    @property (nonatomic, weak) id<HWOptionButtonDelegate> delegate;
    
    @end
    
    /*** ---------------分割线--------------- ***/
    
    #import "HWOptionButton.h"
    
    #define KMainW [UIScreen mainScreen].bounds.size.width
    #define KMainH [UIScreen mainScreen].bounds.size.height
    #define KMarginYWhenMoving 20.0f
    #define KRowHeight 44.0f
    #define KMaxShowLine 6
    #define KFont [UIFont systemFontOfSize:15.0f]
    #define KBackColor [UIColor whiteColor]
    
    @interface HWOptionButton ()<UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate>
    
    @property (nonatomic, strong) NSArray *searchArray;
    @property (nonatomic, strong) UIWindow *cover;
    @property (nonatomic, strong) UITableView *tableView;
    @property (nonatomic, strong) UISearchBar *searchBar;
    @property (nonatomic, weak) UIView *view;
    @property (nonatomic, weak) UIButton *button;
    @property (nonatomic, copy, readwrite) NSString *title;
    @property (nonatomic, assign, readwrite) NSInteger row;
    
    @end
    
    @implementation HWOptionButton
    
    static NSString *KOptionButtonCell = @"KOptionButtonCell";
    
    - (instancetype)initWithFrame:(CGRect)frame
    {
        if (self = [super initWithFrame:frame]) {
            [self setup];
        }
        
        return self;
    }
    
    - (instancetype)initWithCoder:(NSCoder *)coder
    {
        if (self = [super initWithCoder:coder]) {
            [self setup];
        }
        
        return self;
    }
    
    - (void)setup {
        self.title = @"-请选择-";
        
        UIButton *button = [[UIButton alloc] initWithFrame:self.bounds];
        [button setTitleColor:[UIColor colorWithRed:180/255.0 green:180/255.0 blue:180/255.0 alpha:1.0f] forState:UIControlStateNormal];
        [button setTitleColor:[UIColor blackColor] forState:UIControlStateSelected];
        [button setTitle:_title forState:UIControlStateNormal];
        button.titleLabel.font = KFont;
        [button setBackgroundImage:[UIImage imageNamed:@"optionBtn_nor"] forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:button];
        self.button = button;
        
        //搜索框
        _searchBar = [[UISearchBar alloc] init];
        _searchBar.barTintColor = KBackColor;
        _searchBar.layer.borderWidth = 1.0f;
        _searchBar.layer.borderColor = [[UIColor blackColor] CGColor];
        _searchBar.delegate = self;
        _searchBar.keyboardType = UIKeyboardTypeASCIICapable;
        
        //选项视图
        _tableView = [[UITableView alloc] init];
        _tableView.rowHeight = KRowHeight;
        _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        _tableView.layer.borderWidth = 1.0f;
        _tableView.layer.borderColor = [[UIColor blackColor] CGColor];
        _tableView.dataSource = self;
        _tableView.delegate = self;
        
        self.showPlaceholder = YES;
        self.showSearchBar = NO;
    }
    
    - (void)buttonAction:(UIButton *)button
    {
        [self creatControl];
        
        [self endEditing];
    }
    
    - (void)creatControl
    {
        //遮盖window
        _cover = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        _cover.windowLevel = UIWindowLevelAlert;
        _cover.hidden = NO;
        
        //window视图
        UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        [_cover addSubview:view];
        self.view = view;
        
        //遮盖视图
        UIView *backview = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        backview.backgroundColor = [UIColor colorWithRed:(0)/255.0 green:(0)/255.0 blue:(0)/255.0 alpha:0.0f];
        [backview addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(Tap:)]];
        [self.view addSubview:backview];
        
        //坐标转换
        CGRect frame = [self.superview convertRect:self.frame toView:self.view];
        
        //显示选项按钮
        UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(frame.origin.x, frame.origin.y, self.frame.size.width, self.frame.size.height)];
        button.titleLabel.font = KFont;
        [button setTitle:_button.titleLabel.text forState:UIControlStateNormal];
        [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [button addTarget:self action:@selector(btnOnClick) forControlEvents:UIControlEventTouchUpInside];
        [button setBackgroundImage:[UIImage imageNamed:@"optionBtn_sel"] forState:UIControlStateNormal];
        [self.view addSubview:button];
        
        //搜索框
        if (_showSearchBar) {
            _searchBar.frame = CGRectMake(frame.origin.x, CGRectGetMaxY(frame), frame.size.width, KRowHeight);
            [self.view addSubview:_searchBar];
        }
        
        //设置tableviewFrame
        NSInteger rowCount = _showSearchBar ? KMaxShowLine - 1 : KMaxShowLine;
        CGFloat tabelViewY = _showSearchBar ? CGRectGetMaxY(_searchBar.frame) : CGRectGetMaxY(frame);
        if (_array.count <= rowCount) {
            _tableView.frame = CGRectMake(frame.origin.x, tabelViewY, frame.size.width, _array.count * KRowHeight);
        }else {
            _tableView.frame = CGRectMake(frame.origin.x, tabelViewY, frame.size.width, rowCount * KRowHeight);
        }
        
        [self.view addSubview:_tableView];
    }
    
    - (void)endEditing
    {
        [[[self findViewController] view] endEditing:YES];
    }
    
    - (UIViewController *)findViewController
    {
        id target = self;
        while (target) {
            target = ((UIResponder *)target).nextResponder;
            if ([target isKindOfClass:[UIViewController class]]) {
                break;
            }
        }
        return target;
    }
    
    - (void)setArray:(NSArray *)array
    {
        _array = array;
        
        self.searchArray = [_array copy];
        
        [self setInfo];
    }
    
    - (void)setShowPlaceholder:(BOOL)showPlaceholder
    {
        _showPlaceholder = showPlaceholder;
        
        [self setInfo];
    }
    
    - (void)setInfo
    {
        if (!_showPlaceholder && _array.count > 0) {
            [_button setSelected:YES];
            _title = _array[0];
            [_button setTitle:_title forState:UIControlStateNormal];
        }
        
        [_tableView reloadData];
    }
    
    - (void)btnOnClick
    {
        [self dismissOptionAlert];
    }
    
    - (void)Tap:(UITapGestureRecognizer *)recognizer
    {
        [self dismissOptionAlert];
    }
    
    - (void)dismissOptionAlert
    {
        [_searchBar resignFirstResponder];
        
        if (self.view.frame.origin.y == 0) {
            [self removeCover];
        }else {
            [self searchBarTextDidEndEditing:_searchBar];
        }
    }
    
    - (void)removeCover
    {
        [_searchBar resignFirstResponder];
        _cover.hidden = YES;
        _cover = nil;
    }
    
    #pragma mark - UISearchBarDelegate
    - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
    {
        if (searchText.length > 0) {
            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[c] %@", searchText];
            _searchArray = [[_array filteredArrayUsingPredicate:predicate] copy];
        }else {
            _searchArray = [_array copy];
        }
        
        [_tableView reloadData];
    }
    
    - (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
    {
        UIView *view = self.superview;
        while (view.superview) {
            view = view.superview;
        }
        
        CGFloat Y = KMarginYWhenMoving - [self.superview convertRect:self.frame toView:self.view].origin.y;
        [UIView animateWithDuration:0.22f animations:^{
            view.frame = CGRectMake(0, Y, KMainW, KMainH);
            self.view.frame = CGRectMake(0, Y, KMainW, KMainH);
        }];
        
        return YES;
    }
    
    - (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
    {
        UIView *view = self.superview;
        while (view.superview) {
            view = view.superview;
        }
        
        [UIView animateWithDuration:0.22f animations:^{
            view.frame = CGRectMake(0, 0, KMainW, KMainH);
            self.view.frame = CGRectMake(0, 0, KMainW, KMainH);
        }completion:^(BOOL finished) {
            [self removeCover];
        }];
    }
    
    #pragma mark - tableViewDelegate
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return _searchArray.count;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:KOptionButtonCell];
        if (!cell) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:KOptionButtonCell];
        }
        cell.textLabel.text = _searchArray[indexPath.row];
        cell.backgroundColor = [UIColor whiteColor];
        cell.textLabel.font = KFont;
        
        return cell;
    }
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        _row = indexPath.row;
        [_button setSelected:YES];
        self.title = _searchArray[_row];
        [self.button setTitle:self.title forState:UIControlStateNormal];
        [self dismissOptionAlert];
        
        if (_delegate && [_delegate respondsToSelector:@selector(didSelectOptionInHWOptionButton:)]) {
            [_delegate didSelectOptionInHWOptionButton:self];
        }
    }
    
    @end

    写博客是希望大家共同交流成长,博主水平有限难免有偏颇不足之处,欢迎批评指正。



    展开全文
  • 自定义下拉刷新动画
  • iOS 自定义下拉刷新控件 —— 解决图片拉伸与数据刷新冲突点击文字即可跳转
    展开全文
  • 微信小程序手把手教你实现自定义下拉刷新前言思路分析实现尾巴 前言 在上一篇文章:微信小程序手把手教你实现类似Android中ViewPager控件效果,通过这篇文章我们实现了跟android开发中ViewPager+Fragment类似的效果...

    微信小程序自定义下拉刷新

    前言

    在上一篇文章:微信小程序手把手教你实现类似Android中ViewPager控件效果,通过这篇文章我们实现了跟android开发中ViewPager+Fragment类似的效果。可是在实际开发中,我们往往在页面上需要加上下拉刷新功能,通过小程序自带的页面下拉刷新在单个页面支持很好,可是在我们上一篇文章写的页面中使用效果却不是很理想。所以,今天我们来实现在scorll-view中自定义下拉刷新功能,效果图如下:
    在这里插入图片描述

    思路分析

    相信很多小伙伴在做android和ios开发的时候,也做过自定义下拉刷新功能,其实我们这里也是借鉴类似的思路。本文实现的思路是:

    • 在页面顶部放置一个view,这个view主要用来展示刷新状态提示用户,view初始高度为0
    • 监听用户手指touch事件,根据用户移动的距离来动态改变顶部刷新状态view的高度
    • 设置一个高度阈值,当下拉距离大于等于这个阈值,松开手指触发刷新操作

    实现

    首先是布局文件:

    // wxml布局文件
    <scroll-view style='height:100%' scroll-y='{{!isindrag}}' bindscroll='scorll'>
      //监听布局touch事件
      <view class='column' bindtouchstart='start' bindtouchend='end' bindtouchmove='move'>
        //刷新状态view
        <view style='height:{{hei}}px;background:gray' class='refresh'>{{desc}}</view>
        <view class='item' wx:for='{{data}}'>
          <view class='title'>{{item}}</view>
          <view class='bottom'>
            <view>新华网</view>
            <view class='comment'>2344</view>
          </view>
        </view>
      </view>
    </scroll-view>
    

    主要逻辑其实是js中,下面我会贴出代码,并写好详细注释:

    // js文件
    var sy;//记录手指的y坐标
    Component({
      /**
       * 组件的属性列表
       */
      properties: {
        
      },
    
      /**
       * 组件的初始数据
       */
      data: {
        data: ['狗狗是人类最好的朋友', '90%长痘的人都不知道,药店里不起眼的东西,睡前抹一抹,祛痘很快', '保时捷Cayenne,即刻驾驭梦想','沙漠极限挑战:三台空调挑战70度极限高温,谁先宕机?','德牧带大的二哈,二哈现在离不开她了,一刻不见就想德牧','为什么说达到第四宇宙速度就可以逃出银河系?','许久没去草坪的边牧,来到公园,开心的像个孩子'],
        desc: '下拉刷新',//刷新提示语
        hei: 0,//刷新view高度阈值
        scrolltop: 0,//scorll-view滑动离顶部的距离
        isindrag: false//是否在下拉状态(必须要滑动到顶部才能触发)
      },
    
      /**
       * 组件的方法列表
       */
      methods: {
        start(e) {
          //记录手指触摸是的y坐标
          sy = e.touches[0].clientY   
          console.log('开始触摸 sy : ' + sy + ' scrolltop : ' + this.data.scrolltop)
        },
        move(e) {
          //计算手指滑动的距离
          var delta = e.touches[0].clientY - sy
          console.log('delta : ' + delta)
          //scorll-view滑动到顶部且继续向上滑动时,走scorll-view滑动流程
          if(this.data.hei <= 0 && delta <= 0){
            return
          }
          //scorll-view已经滑动到顶部,继续下拉进入下拉状态
          if (this.data.scrolltop <= 0){
            if (this.data.isindrag == false){
              this.setData({
                isindrag: true
              })
            }
            var tempdelta = 0
            console.log('hei : ' + this.data.hei)
            if(delta > 0){//手指向下滑动
              if (this.data.hei > 50) {//触发阈值,更改状态
                this.setData({
                  desc: '松开刷新'
                })
                tempdelta = this.data.hei + delta / (this.data.hei - 50)//增大下拉阻尼感
              } else {
                this.setData({
                  desc: '下拉刷新'
                })
                //手指移动未到阈值,按正常滑动增加高度
                tempdelta = this.data.hei + delta
              }
            } else {//手指向上滑动
              tempdelta = this.data.hei + delta
              //刷新状态view最小为0
              if(tempdelta <= 0){
                tempdelta = 0
              }
              this.setData({
                desc: '下拉刷新'
              })
            }
            //滑动完成设置刷新view高度
            this.setData({
              hei: tempdelta
            })
          }
          //每次滑动事件后记录y坐标
          sy = e.touches[0].clientY
        },
        end(e) {
          console.log('手指离开')
          //手指离开时,如果阈值大于等于50,则触发刷新
          if(this.data.hei >= 50){
            this.setData({
              desc: '正在刷新...'
            })
            this.setData({
              hei: 50
            })
            //模拟耗时操作,2秒后恢复正常状态
            setTimeout(function () {
              sy = 0
              that.setData({
                desc: '下拉刷新',
                hei: 0,
                isindrag: false,
                scrolltop: 0
              })
            }, 2000)
          }else{//未下拉到阈值,松开时则收起刷新view
            sy = 0
            that.setData({
              desc: '下拉刷新',
              hei: 0,
              isindrag: false,
              scrolltop: 0
            })
          }
        },
        scorll(e) {
          //未进入下拉状态时,记录scorll-view滑动距离顶部的距离
          var st = e.detail.scrollTop
          console.log('滚动 st : '+st)
          if (this.data.isindrag == false){
            this.setData({
              scrolltop: st
            })
          }
        }
      }
    })
    

    尾巴

    本来是想展开写的更详细点的,但是写着发现其实核心代码也不复杂,对照着注释和思路来看一目了然,所以就偷个小懒了,直接上了代码。文中的刷新view比较简单,就一行提示文字,如果你愿意,可以换成更加复杂的view来展示你的刷新状态。
    好了,今天的文章就到这里了,如果文章中有错误的地方,欢迎大家留言指正。如果你喜欢我的文章,也欢迎给我点赞,评论,谢谢!

    展开全文
  • iOS-自定义下拉刷新上拉加载(可根据自己的需求改) 欢迎关注 http://blog.csdn.net/u014220518/article/details/54407135
  • 自己做了个下拉加载组件 发现在ios弹性情况下不会出现预期的效果,在网上找了很久,自己也思考了很久总结了三个方法,来实现ios的兼容。 首先思考:ios为什么会出现情况? 发现:在ios弹性触发的情况下 微信的监听...
  • Flutter之自定义下拉列表组件 一.实现思路 通过自定义路由继承自PopupRoute,并结合Navigator.push使弹出的下拉列表能够覆盖在当前页面显示 使用CustomSingleChildLayout组件,自定义SingleChildLayoutDelegate并结合...
  • 最终实现后的效果(这里提示有个不同点就是,自定义了导航条,并且下拉的时候,自定义导航条必须固定) 小程序实现下拉加载2种方式: 1. 简单粗暴,直接开启enablePullDownRefresh,开启全局下拉...
  • 本文主要介绍iOS 利用MJRefresh实现自定义动画的上拉刷新下拉加载效果,一般的类型(包括更新时间与loading图案)这里不做介绍. 要想实现此功能,首先得有一套load的图片数组. 接下来就是实现过程: 引入头文件: #...
  • 导航条自定义下拉菜单
  • 如果你需要自定义下拉刷新,那么使用page级别的下拉刷新是无法定制样式的,微信提供了scroll-view来支持用户自定义下拉刷新,先看文档:... 用uni-app开发,可以封装成vue组件,比较方便: <template>...
  • 自定义下拉刷新,上拉加载,详情看简书:http://www.jianshu.com/p/21837c99100e demo下载地址:https://github.com/bobtaocool/TBRefreshDemo
  • 在考虑实现自定义下拉刷新组件的时候,首先要明确,这个算是一种hack方案。并不是说自定义的有多么好,反而自定义下拉刷新在android下会有细微的卡顿(我这种实现方式)。所以尽量还是用小程序自带的吧。 这个...
  • 自定义下拉刷新 简单实现 美团下拉刷新 android
1 2 3 4 5 ... 20
收藏数 12,933
精华内容 5,173