国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

IOS 類似抖音下拉刷新與自定義上拉加載

這篇具有很好參考價值的文章主要介紹了IOS 類似抖音下拉刷新與自定義上拉加載。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

IOS 類似抖音下拉刷新與自定義上拉加載

最近UICollectionView中使用了pageEnabled,MJRresh直接使用時出現(xiàn)偏移。這里就暫時考慮簡單的做法。

首先考慮在UICollection與拖動手勢之間的問題。

解決UICollectionView上添加手勢不能觸發(fā)。

這里使用了子類繼承UICollectionView

#import "INMyCollectionView.h"

@implementation INMyCollectionView

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [[self nextResponder] touchesBegan:touches withEvent:event];
    [super touchesBegan:touches withEvent:event];
}


-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    [[self nextResponder] touchesMoved:touches withEvent:event];
    [super touchesMoved:touches withEvent:event];
}


- (void)touchesEnded:(NSSet *)touches
           withEvent:(UIEvent *)event {
    [[self nextResponder] touchesEnded:touches withEvent:event];
    [super touchesEnded:touches withEvent:event];
}

@end

在View上添加拖動手勢

self.startPoint = CGPointZero;
self.isInLoading = NO;

UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGestureHandle:)];
panGesture.minimumNumberOfTouches = 1;
panGesture.maximumNumberOfTouches = 1;
panGesture.delegate = self;
[self addGestureRecognizer:panGesture];

處理手勢判斷

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

// 給加的手勢設(shè)置代理, 并實現(xiàn)此協(xié)議方法

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
        
        UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer;
        CGPoint pos = [pan velocityInView:pan.view];
        if (pos.y > 0) {
            return YES;
        }
    }
    
    return NO;
}

在處理拖動手勢

 (void)panGestureHandle:(UIPanGestureRecognizer *)pan{
    if (self.collectionView.contentOffset.y > 0) {
        return;
    }
    
    DebugLog(@"panGestureHandle");
    if (self.isInLoading) {
        return;
    }
    
    if (pan.state == UIGestureRecognizerStateBegan) {
        DebugLog(@"UIGestureRecognizerStateBegan");
        self.startPoint = [pan translationInView:self];
        self.collectionView.scrollEnabled = NO;
    } if (pan.state == UIGestureRecognizerStateChanged) {
        DebugLog(@"UIGestureRecognizerStateChanged");
        CGPoint point = [pan translationInView:self];
        CGFloat distance = point.y - self.startPoint.y;
        if (distance > 0) {
            self.refreshStateLabel.text = @"下拉刷新";
            CGFloat scale = distance/KMaxScrollRefreshHeight;
            if (scale > 1.0) {
                scale = 1.0;
            }
            
            self.refreshStateLabel.alpha = scale;
            self.navbarView.alpha = (1-scale);
            self.refreshStateLabel.frame = CGRectMake(0.0, scale*(kStatusBarHeight + [BaseView baseSafeAreaEdgeInsets].top) + 5.0, CGRectGetWidth(self.bounds), 44.0);
            if (distance > KMaxScrollRefreshHeight) {
                DebugLog(@"可以下拉刷新");
            }
        } else {
            DebugLog(@"上拉操作");
            self.refreshStateLabel.alpha = 0.0;
        }
        
    } else if (pan.state == UIGestureRecognizerStateEnded || pan.state == UIGestureRecognizerStateCancelled || pan.state == UIGestureRecognizerStateFailed) {
        DebugLog(@"UIGestureRecognizerStateEnded");
        self.collectionView.scrollEnabled = YES;
        CGPoint point = [pan translationInView:self];
        CGFloat distance = point.y - self.startPoint.y;
        self.refreshStateLabel.text = @"";
        if (distance > 0) {
            if (distance > KMaxScrollRefreshHeight) {
                DebugLog(@"加載中...");
                self.refreshStateLabel.text = @"加載中...";
                self.refreshStateLabel.alpha = 1.0;
                self.isInLoading = YES;
                if (self.actionDelegate && [self.actionDelegate respondsToSelector:@selector(refreshLoadingData)]) {
                    [self.actionDelegate refreshLoadingData];
                }
            }
        }
    }
}

當(dāng)然,類似抖音的下拉,在ScrollDidScoll處理了下
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView.contentOffset.y < 0) {
        [scrollView setContentOffset:CGPointMake(0.0, 0.0)];
    } else {
        // 向上拖動,向上拖動的指定位置后加載更多數(shù)據(jù)
        DebugLog(@"向上拖動,向上拖動的指定位置后加載更多數(shù)據(jù)");
    }
}

第二部分

自己處理上拉加載更多,這里代碼如下
INUpwardRefreshView.h

@protocol INUpwardRefreshViewDelegate;

@interface INUpwardRefreshView : BaseView

@property (nonatomic, weak) id<INUpwardRefreshViewDelegate>delegate;
@property (nonatomic, strong) UIScrollView *scrollView;

- (instancetype)initWithTarget:(UIScrollView *)scrollView;

- (void)endRefreshing;

@end

@protocol INUpwardRefreshViewDelegate <NSObject>

- (void)pullUpwardRefreshDidFinish;

@end

INUpwardRefreshView.m

//
//  INUpwardRefreshView.m
//  Views
//
//  Created by ABC on 2019/7/26.
//

#import "INUpwardRefreshView.h"
#import "Color.h"
#import "NSString+size.h"

NSString *const RefreshUpKeyPathContentOffset = @"contentOffset";
NSString *const RefreshUpKeyPathContentSize = @"contentSize";

CGFloat const FooterUpHeight = 80;

@interface INUpwardRefreshView ()

@property (nonatomic, strong) UIActivityIndicatorView *activityView;
@property (nonatomic, strong) UIImageView *arrowView;
@property (nonatomic, strong) UILabel *stateLable;
@property (nonatomic, assign) BOOL isRefresh;
@property (nonatomic, assign) CGFloat lastOffSet;

@end

@implementation INUpwardRefreshView

- (instancetype)initWithTarget:(UIScrollView *)scrollView {
    self = [super init];
    if (self) {
        self.backgroundColor = [UIColor clearColor];
        
        _scrollView = scrollView;
        
        self.frame = CGRectMake(0, 0, 0, FooterUpHeight);
        [_scrollView addSubview:self];
        
        [self addObserver];
    }
    return self;
    
}

- (void)layoutSubviews{
    [super layoutSubviews];
    
    CGSize statelabelSize = [self.stateLable.text sizeWithFont:self.stateLable.font forMaxSize:CGSizeMake(MAXFLOAT, 40)];
    
    self.stateLable.frame = CGRectMake((CGRectGetWidth(self.bounds) - statelabelSize.width)/2 + 10.0, 0.0, statelabelSize.width, 40);
    
    self.arrowView.frame = CGRectMake(CGRectGetMinX(self.stateLable.frame) - CGRectGetWidth(self.arrowView.frame) - 10.0, 0.0, CGRectGetWidth(self.arrowView.frame), 40);
    
    self.activityView.frame = CGRectMake(CGRectGetMinX(self.stateLable.frame) - CGRectGetWidth(self.arrowView.frame) - 10.0, (40.0 - 20.0)/2, 20, 20);
}

- (void)setCurrentFrame {
    [self setFrame:CGRectMake(0, MAX(self.scrollView.contentSize.height, CGRectGetHeight(self.scrollView.frame)), self.scrollView.size.width, FooterUpHeight)];
    [self setNeedsLayout];
}

- (void)setFrameHeight:(CGFloat)height {
    [self setFrame:CGRectMake(0, MAX(self.scrollView.contentSize.height, CGRectGetHeight(self.scrollView.frame)), self.scrollView.size.width, height)];
    DebugLog(@"frameHeight:%f",height);
}

#pragma mark setter
- (UIActivityIndicatorView *)activityView{
    if (!_activityView) {
        _activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
        _activityView.hidesWhenStopped = YES;
        [self addSubview:_activityView];
    }
    return _activityView;
}

- (UIImageView *)arrowView{
    if (!_arrowView) {
        _arrowView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 15, 40)];
        _arrowView.image = [UIImage imageNamed:@"refresh_up_arrow"];
        //[self addSubview:_arrowView];
    }
    return _arrowView;
}

- (UILabel *)stateLable{
    if (!_stateLable) {
        _stateLable = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 90, 40)];
        _stateLable.backgroundColor = [UIColor clearColor];
        _stateLable.font = [UIFont systemFontOfSize:12];
        _stateLable.textAlignment = NSTextAlignmentLeft;
        _stateLable.textColor = [UIColor whiteColor];
        [self addSubview:_stateLable];
    }
    return _stateLable;
}

#pragma mark private
- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change{
    _stateLable.hidden = NO;
    CGFloat yOffSet = _scrollView.contentOffset.y;
    DebugLog(@"yOffSet:%f",yOffSet);
    CGFloat contentSizeHeight = _scrollView.contentSize.height;
    CGFloat frameHeight = CGRectGetHeight(_scrollView.frame);
    if (contentSizeHeight > 0 && contentSizeHeight < frameHeight) {
        CGFloat insetTop = frameHeight - contentSizeHeight;
        if (yOffSet+insetTop > 0.0) {
            //正在拖拽中
            if (self.scrollView.isDragging) {
                
                [UIView animateWithDuration:0.3 animations:^{
                    self.arrowView.hidden = NO;
                    if (yOffSet+insetTop > 100.0) {
                        self.arrowView.transform =  CGAffineTransformMakeRotation(M_PI);
                        self.stateLable.text = @"松開夾子";
                    }else{
                        self.arrowView.transform =  CGAffineTransformMakeRotation(M_PI*2);
                        self.stateLable.text = @"繼續(xù)滑動";
                    }
                }];
                
                [self setFrameHeight:(yOffSet+insetTop)];
            } else {
                if (yOffSet+insetTop > 100.0) {
                    [self beginRefreshing];
                }
            }
        }
        
    } else {
        //正在拖拽中
        CGFloat aYBottom = yOffSet - (contentSizeHeight - frameHeight);
        if (self.scrollView.isDragging) {
            
            [UIView animateWithDuration:0.3 animations:^{
                self.arrowView.hidden = NO;
                if (aYBottom > 100.0) {
                    self.arrowView.transform =  CGAffineTransformMakeRotation(M_PI);
                    self.stateLable.text = @"松開加載";
                }else{
                    self.arrowView.transform =  CGAffineTransformMakeRotation(M_PI*2);
                    self.stateLable.text = @"繼續(xù)滑動";
                }
            }];
            
            [self setFrameHeight:yOffSet];
        } else {
            if (contentSizeHeight > 0 && aYBottom > 100.0) {
                [self beginRefreshing];
            }
        }
    }
}

#pragma mark publick
- (void)beginRefreshing{
    [self setFrameHeight:FooterUpHeight];
    
    if (!_isRefresh) {
        
        _isRefresh = YES;
        CGFloat insetTop = _scrollView.contentInset.top;
        //設(shè)置偏移量,銜接加載的更多數(shù)據(jù)
         [UIView animateWithDuration:0.35 animations:^{
             //[self.scrollView setContentInset:UIEdgeInsetsMake(insetTop, 0, FooterUpHeight, 0)];
             [self.activityView startAnimating];
             self.arrowView.hidden = YES;
             self.stateLable.text = @"加載中";
         } completion:^(BOOL finished) {
             [self startBeginRefresh];
         }];
    }
}

- (void)startBeginRefresh {
    // Refresh action!
    if ([self.delegate respondsToSelector:@selector(pullUpwardRefreshDidFinish)]) {
        [self.delegate performSelector:@selector(pullUpwardRefreshDidFinish) withObject:nil];
    }
}

- (void)endRefreshing {
    _isRefresh = NO;
    
    [UIView animateWithDuration:0.3 animations:^{
        [self.activityView stopAnimating];
        self.arrowView.hidden = YES;
        self.arrowView.transform =  CGAffineTransformMakeRotation(M_PI*2);
    }];
}

#pragma mark KVO
- (void)addObserver{
    NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
    [_scrollView addObserver:self forKeyPath:RefreshUpKeyPathContentOffset options:options context:nil];
    
    [_scrollView addObserver:self forKeyPath:RefreshUpKeyPathContentSize options:options context:nil];
}

- (void)removeObserver{
    [_scrollView removeObserver:self forKeyPath:RefreshUpKeyPathContentOffset];
    [_scrollView removeObserver:self forKeyPath:RefreshUpKeyPathContentSize];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    if ([keyPath isEqualToString:RefreshUpKeyPathContentOffset]) {
        [self scrollViewContentOffsetDidChange:change];
    } else if ([keyPath isEqualToString:RefreshUpKeyPathContentSize]) {
        [self setCurrentFrame];
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

- (void)dealloc{
    [self removeObserver];
}

@end

使用上拉加載的shih
在collection創(chuàng)建的時候,設(shè)置下即可

_upwardRefreshView = [[INUpwardRefreshView alloc] initWithTarget:_collectionView];
 _upwardRefreshView.delegate = self;

源碼地址:

https://github.com/goodbruce/DouyinRefresh文章來源地址http://www.zghlxwxcb.cn/news/detail-488539.html

到了這里,關(guān)于IOS 類似抖音下拉刷新與自定義上拉加載的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 微信小程序-上拉加載更多和下拉刷新

    微信小程序-上拉加載更多和下拉刷新

    頁面配置文件中配置 \\\"enablePullDownRefresh\\\": true 開啟下拉刷新 設(shè)置 onPullDownRefresh 方法 在用戶下拉時會調(diào)用 onPullDownRefresh 方法 在完成后需要調(diào)用 wx.stopPullDownRefresh() 關(guān)閉刷新狀態(tài) 可以在頁面配置文件中配置 \\\"onReachBottomDistance\\\":50 來設(shè)置觸發(fā)上拉加載的距離,單位為 px 。 默認(rèn):

    2024年02月15日
    瀏覽(16)
  • Android 實現(xiàn) RecyclerView下拉刷新,SwipeRefreshLayout上拉加載

    Android 實現(xiàn) RecyclerView下拉刷新,SwipeRefreshLayout上拉加載

    上拉、下拉的效果圖如下: 使用步驟 1、在清單文件中添加依賴 implementation ‘com.android.support:recyclerview-v7:27.1.1’ implementation “androidx.swiperefreshlayout:swiperefreshlayout:1.0.0” 2、main布局 item.xml footview.xml(底部提示) 2、MyAdapter 3、MainActivity實現(xiàn)

    2024年02月13日
    瀏覽(20)
  • H5如何做頁面下拉刷新和上拉加載

    這里以vant為例 結(jié)構(gòu) 處理方法

    2024年02月10日
    瀏覽(20)
  • flutter開發(fā)實戰(zhàn)-下拉刷新與上拉加載更多實現(xiàn)

    flutter開發(fā)實戰(zhàn)-下拉刷新與上拉加載更多實現(xiàn)

    flutter開發(fā)實戰(zhàn)-下拉刷新與上拉加載更多實現(xiàn) 在開發(fā)中經(jīng)常遇到列表需要下拉刷新與上拉加載更多,這里使用EasyRefresh,版本是3.3.2+1 EasyRefresh可以在Flutter應(yīng)用程序上輕松實現(xiàn)下拉刷新和上拉加載。它幾乎支持所有Flutter Scrollable小部件。它的功能與安卓的SmartRefreshLayout非常相似

    2024年02月07日
    瀏覽(25)
  • Flutter 庫:強大的下拉刷新上拉加載框架——EasyRefresh

    EasyRefresh 是一個用于 Flutter 應(yīng)用程序的簡單易用的 下拉刷新 和 上拉加載 框架。它支持幾乎所有的 Flutter 可滾動小部件。它的功能與Android 的 SmartRefreshLayout 非常相似,并吸收了許多第三方庫的優(yōu)點。EasyRefresh 集成了各種樣式的頁眉和頁腳,但沒有任何限制,您可以輕松自定

    2024年01月19日
    瀏覽(24)
  • 微信小程序 下拉分頁 z-paging下拉刷新、上拉加載

    微信小程序 下拉分頁 z-paging下拉刷新、上拉加載

    【z-paging下拉刷新、上拉加載】高性能,全平臺兼容。支持虛擬列表,支持nvue、vue3 - DCloud 插件市場 ?z-paging,使用非常簡單,按部就班就行了 1,首先將其導(dǎo)入自己的小程序項目中 ?導(dǎo)入后的效果 2,具體如何使用:https://z-paging.zxlee.cn? ? 選項式api寫法(vue2/vue3) 組合式api寫法

    2024年02月11日
    瀏覽(24)
  • uniapp使用自帶【刷新方法】與使用【scroll-view】實現(xiàn)下拉刷新上拉加載

    uniapp使用自帶【刷新方法】與使用【scroll-view】實現(xiàn)下拉刷新上拉加載

    前言:uniapp自帶下拉刷新,上拉加載功能基本可以滿足刷新需求,但是頂部有狀態(tài)欄的頁面就得進行特殊處理,使用scroll-view解決,狀態(tài)欄會連帶被下拉問題 ? 1、uniapp自帶下拉刷新、上拉加載 在page.json中對應(yīng)頁面路由設(shè)置【enablePullDownRefresh】值為true(開啟下拉刷新) 代碼:

    2024年02月11日
    瀏覽(21)
  • 學(xué)習(xí)微信小程序的下拉刷新和上拉加載更多

    好的,下面我將為你詳細(xì)介紹微信小程序中的下拉刷新和上拉加載更多功能,并提供代碼案例。 下拉刷新功能 下拉刷新是指當(dāng)用戶在小程序頁面下拉時,頁面可以重新加載最新的數(shù)據(jù)。為了實現(xiàn)下拉刷新功能,我們需要使用小程序提供的 onPullDownRefresh 生命周期函數(shù)。 以一個

    2024年04月14日
    瀏覽(18)
  • 微信小程序 - scroll-view組件之上拉加載下拉刷新(解決上拉加載不觸發(fā))

    微信小程序 - scroll-view組件之上拉加載下拉刷新(解決上拉加載不觸發(fā))

    最近在做微信小程序項目中,有一個功能就是做一個商品列表分頁限流然后實現(xiàn)上拉加載下拉刷新功能,遇到了一個使用scroll-viwe組件下拉刷新事件始終不觸發(fā)問題,網(wǎng)上很多說給scroll-view設(shè)置一個高度啥的就可以解決,有些人設(shè)置了高度也不觸發(fā),所以在下就研究了一波這個

    2024年02月14日
    瀏覽(90)
  • 小白學(xué)習(xí)微信小程序的下拉刷新和上拉加載更多

    微信小程序是一種基于微信生態(tài)的輕量級應(yīng)用程序,與傳統(tǒng)的Web應(yīng)用程序相比,微信小程序具有更低的開發(fā)成本、更高的運行速度和更好的用戶體驗。在微信小程序開發(fā)中,下拉刷新和上拉加載更多是非常常用的功能,并且在實現(xiàn)上也比較簡單。在本篇文章中,我們將詳細(xì)介

    2024年02月05日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包