澳门威利斯人_威利斯人娱乐「手机版」

来自 澳门威利斯人 2020-04-16 23:41 的文章
当前位置: 澳门威利斯人 > 澳门威利斯人 > 正文

两年iOS经验之你忽略的小知识点,自定义下拉刷

图片 1iOS11图片

#import "MJRefreshHeader.h"
@interface XSHeaderRefresh : MJRefreshHeader
@end```

- XSHeaderRefresh.m(下面代码全部为.m文件内容)
1)自定义视图用到哪些UI元素在这里声明

4 给视图增加闪的功能

先row = 0调用壹遍 cellForRow,然后三回heightForRow.然后再是row =1 ,依次类推。看打字与印刷结果

4.2 方案

首先在创制好的Xcode项目标Storyboard中拖放二个ImageView控件,在右侧栏的检查器中设置好ImageView的来得图片。将ImageView控件关联成T索罗德SnapViewController的属性boxImageView。

从指标库中拖放四个TapGestureRecognizer类型的手势到Storyboard的气象中,并将手势关联成TENCORESnapViewController的动作方法tap:。

其次在TCR-VSnapViewController中定义多个村办属性UIDynamicAnimator类型的animator和UISnapBehavior类型的snapBehavior。重写setter方法对animator属性举行最早化。

最终完成tap:方法,该措施中开创snapBehavior行为,使boxImageView闪向手指触摸的地点。

末端的法子能够自定义,也足以用系统的。

  • 率先贴上MJ在GitHub上的源码和表明 MJRefresh源码和注解地方 其实看过小编自个儿写的表明之后大致都能拿来本身用了。这里小编根本是说一下依据MJRefresh自定义的底工代谢视图。

  • 能够先下载小编的demo看一下,张开今后如下图的目录结构:

    MJDIYHeader.png

    其一DIY文件夹里面正是小编给的自定义刷新视图的实例。

  • 现今自作者DIY一个协和的下拉和上拉刷新视图。话十分少说一向上代码:自己的身教重于言教自定义刷新视图下载地址
    自定义一个类继承自MJRefreshHeader,这里笔者定义的类名位XSHeaderRefresh。
    自笔者的运营效果图:

    XSRefresh.gif

  • XSHeaderRefresh.h

4.1 问题

此案例使用UISnapBehavior给视图增多闪的效果与利益,点击显示屏某处imageView就闪向某处,如图-6所示:

图片 2

图-6

UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageWithName:@"text.png"]];

import "XSHeaderRefresh.h"

@interface XSHeaderRefresh()
@property(weak, nonatomic) UIView * headerFreshView;
@property(weak, nonatomic)UILabel * label;
@property(nonatomic, strong)UIImageView * imageView;
@end```
2卡塔尔(قطر‎这里做控件的开始化配置
@implementation XSHeaderRefresh

  • (void)prepare {
    [super prepare];
    // 设置控件的万丈
    self.mj_h = 75;
    UIView * view = [[UIView alloc] init];
    [self addSubview:view];
    self.headerFreshView = view;
    UILabel *label = [[UILabel alloc] init];
    label.textColor = [UIColor colorWithRed:1.0 green:0.5 blue:0.0 alpha:1.0];
    label.font = [UIFont boldSystemFontOfSize:12];
    label.textAlignment = NSTextAlignmentCenter;
    label.backgroundColor = [UIColor clearColor];
    [self.headerFreshView addSubview:label];
    self.label = label;
    UIImageView * imageView = [[UIImageView alloc] init];
    imageView.image = [UIImage imageNamed:@"arrow"];
    [self.headerFreshView addSubview:imageView];
    self.imageView = imageView;
    }

3卡塔尔设置子控件的职分和尺寸

  • (void)placeSubviews
    {
    [super placeSubviews];
    self.headerFreshView.bounds = CGRectMake(0, 0, 110, 20);
    self.headerFreshView.center = CGPointMake(self.mj_w*0.5, self.mj_h-20);
    self.label.frame = CGRectMake(30, 0, 80, 20);
    self.imageView.frame = CGRectMake(10, 5, 10, 10);
    }
    4State of Qatar重写父类方法
    #pragma mark 监听scrollView的contentOffset改变
  • (void)scrollViewContentOffsetDidChange:(NSDictionary *)change
    {
    [super scrollViewContentOffsetDidChange:change];
    }

    #pragma mark 监听scrollView的contentSize改变
    - (void)scrollViewContentSizeDidChange:(NSDictionary *)change
    {
        [super scrollViewContentSizeDidChange:change];   
    }
    
    #pragma mark 监听scrollView的拖拽状态改变
    - (void)scrollViewPanStateDidChange:(NSDictionary *)change
    {
        [super scrollViewPanStateDidChange:change];
    }
    
     #pragma mark 监听控件的刷新状态
     - (void)setState:(MJRefreshState)state
     {
     MJRefreshCheckState;
    
     switch (state) {
     case MJRefreshStateIdle:
             self.label.text = @"下拉刷新";
             [self endAnimation];
             break;
     case MJRefreshStatePulling:
             self.label.text = @"松开加载更多";
             [self endAnimation];
             break;
     case MJRefreshStateRefreshing:
             self.label.text = @"加载中...";
             [self startAnimation];
     break;
     default:
     break;
     }
    }
    #pragma mark 监听拖拽比例(控件被拖出来的比例)
    - (void)setPullingPercent:(CGFloat)pullingPercent
    {
        [super setPullingPercent:pullingPercent];
    
        self.label.textColor = [UIColor blackColor];
    }
    

    5State of Qatar图片旋转(自定义)

    -(void)startAnimation
    {
        CABasicAnimation *basicAni= [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
        basicAni.duration = 1;
        basicAni.repeatCount = MAXFLOAT;
        //    basicAni.repeatDuration = 3;
        basicAni.toValue = @(M_PI * 2);
        [self.imageView.layer addAnimation:basicAni forKey:nil];
    }
    - (void)endAnimation
    {
        [self.imageView.layer removeAllAnimations];
    }
    
  • 调用类的以身作则
    1)
    __unsafe_unretained UITableView *tableView = self.tableView;
    // 下拉刷新
    tableView.mj_header= [XSHeaderRefresh headerWithRefreshingBlock:^{
    // 模拟延迟加载数据,因而2秒后才调用(真实开销中,能够移除这段gcd代码)
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    // 甘休刷新
    [tableView.mj_header endRefreshing];
    });
    }];
    2)也能够那样

self.productListTabView.mj_header = [XSHeaderRefresh headerWithRefreshingTarget:self refreshingAction:@selector(refresh)];
self.productListTabView.mj_footer = [XSFooterRefresh footerWithRefreshingTarget:self refreshingAction:@selector(loadMore)];

其中refreshloadMore是你刷新和加载的格局
上拉加载代码中也可能有示范就非常的少做描述了。

1.1 问题

当给有些视图加上UIGravityBehavior引力行为以往,那么些视图就有珍视力,会就像是掉入了无底洞,不断地下坠,不断的增长速度,本案例使用UIGravityBehavior重力行为给imageView增多重力行为,如图-1所示:

图片 3

图-1

#ifdef DEBUG

#define NSLog(FORMAT, ...) fprintf(stderr,"%sn",[[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);

#else

#define NSLog

#endif

2.3 步骤

达成此案例要求依照如下步骤实行。

步骤一:拖放ImageView控件

首先在开立好的Xcode项指标Storyboard中拖放二个ImageView控件,在右侧栏的检查器中装置好ImageView的来得图片。将ImageView控件关联成TRCollisionViewController的特性boxImageView,代码如下所示:

 

  1. @interface TRCollisionViewController () <UICollisionBehaviorDelegate>
  2. @property (weak, nonatomic) IBOutlet UIImageView *boxImageView;
  3. @end

步骤二:创建TRBackgroundView类

先是创制叁个TRBackgroundView类世袭至UIView,该类有四个UIBezierPath类型的公开属性path。在Storyboard上将View关联成TRBackgroundView,如图-4所示:

图片 4

图-4

接下来在TRBackgroundView.m文件中重写initWithCoder:方法和drawRect:绘制方法,initWithCoder:方法中接受colorWithPatternImage:方法设置背景颜色,drawRect:方法中则基于path属性进行绘图,代码如下所示:

 

  1. #import "TRBackgroundView.h"
  2. @implementation TRBackgroundView
    • (id)initWithCoder:(NSCoder *)aDecoder
  3. {
  4. self = [super initWithCoder:aDecoder];
  5. if(self){
  6. self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"BackgroundTile"]];
  7. }
  8. return self;
  9. }
      • (void)drawRect:(CGRect)rect
  10. {
  11. [[UIColor redColor]setFill];
  12. [[UIColor greenColor]setStroke];
  13. [self.path stroke];
  14. [self.path fill];
  15. }
  16. @end

步骤三:加多重力行为和碰撞行为

先是在TRCollisionViewController类中定义三个UIDynamicAnimator类型的自用属性animator,代码如下所示:

 

  1. @interface TRCollisionViewController () <UICollisionBehaviorDelegate>
  2. @property (weak, nonatomic) IBOutlet UIImageView *boxImageView;
  3. @property (strong, nonatomic) UIDynamicAnimator *animator;
  4. @end

下一场在viewDidLoad方法中使boxImageView旋转45度,使boxImageView的二个角朝下,代码如下所示:

 

    • (void)viewDidLoad
  1. {
  2. [super viewDidLoad];
  3. self.boxImageView.transform = CGAffineTransformRotate(self.boxImageView.transform, M_PI_4);
  4. }

最终在viewDidAppear:方法中创制属性animator,将self.view设置为属性animator的referenceView援引视图,给属性boxImageView增多引力行为和碰撞行为,使boxImageView和制图出来的path举办冲撞,代码如下所示:

 

    • (void)viewDidAppear:(BOOL)animated
  1. {
  2. UIDynamicAnimator *animator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
  3. self.animator = animator;
  4. //创制重力行为
  5. UIGravityBehavior *gravity = [[UIGravityBehavior alloc]initWithItems:@[self.boxImageView]];
  6. //重力的强度
  7. gravity.magnitude = 0.1;
  8. //重力的可行性
  9. gravity.gravityDirection = CGVectorMake(0, 1);
  10. [animator addBehavior:gravity];
  11. //创设碰撞行为
  12. UICollisionBehavior *collision = [[UICollisionBehavior alloc]initWithItems:@[self.boxImageView]];
  13. //将援引视图的方圆翻译成可碰撞的多个边
  14. collision.translatesReferenceBoundsIntoBoundary = YES;
  15. //设置delegate
  16. collision.collisionDelegate = self;
  17. //用UIBezierPath创设二个造型并具有冲击行为
  18. UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(20, 450, 280, 30) cornerRadius:10.0];
  19. TRBackgroundView *myView = (TRBackgroundView *)self.view;
  20. myView.path = path;
  21. [myView setNeedsDisplay];
  22. [collision addBoundaryWithIdentifier:@"MyPathIdenrifier" forPath:path];
  23. [animator addBehavior:collision];
  24. }

手续四:完结协议情势

达成UICollisionBehaviorDelegate的磋商方式beganContactForItem: withBoundaryIdentifier:atPoint:,完碰撞起首时boxImageView颜色产生变动,代码如下所示:

 

    • (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier atPoint:(CGPoint)p
  1. {
  2. UIImageView *box = (UIImageView *)item;
  3. box.tintColor = [UIColor redColor];
  4. // imageWithRenderingMode:IOS7提供的新的成效,设置一个UIImage在渲染时是还是不是接受当前视图的Tint Color
  5. //UIImageRenderingModeAlwaysTemplate表示一贯根据Tint Color绘制图片,忽视图片的颜料消息。
  6. box.image = [box.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
  7. NSLog(@"%@,%@,point:(%.0f, %.0f", item, identifier, p.x, p.y);
  8. }

以此特性构建在autoLayout构造的label中,倘诺是非零,那么那几个性子用于多行Label的文字固定宽度

3.1 问题

UIAttachmentBehavior吸附行为,三个视图发生某种行为后相关联的指标也随后一齐活动,本案例使用UIAttachmentBehavior给视图增加吸附功用,是七个视图发生关联行为,如图-5所示:

图片 5

图-5

- 设置label每一行文字的最大开间

5.3 步骤

福寿齐天此案例供给依据如下步骤举办。

步骤一:搭建Storyboard界面

率先在成立好的Xcode项指标Storyboard中拖放二个ImageView控件,在右侧栏的检查器中安装好ImageView的彰显图片。将ImageView控件关联成TRPushViewController的习性boxImageView,代码如下所示:

 

  1. @interface TRPushViewController ()
  2. @property (weak, nonatomic) IBOutlet UIImageView *boxImageView;
  3. @end

从指标库中拖放一个PanGestureRecognizer类型的手势到Storyboard的风貌中,并将手势关联成TRPushViewController的动作方法panAction:。

手续二:定义属性animator和pushBehavior

在TRPushViewController中定义八个个人属性UIDynamicAnimator类型的animator和UIPushBehavior类型pushBehavior,代码如下所示:

 

  1. @interface TRPushViewController ()
  2. @property (weak, nonatomic) IBOutlet UIImageView *boxImageView;
  3. @property (strong, nonatomic) UIDynamicAnimator *animator;
  4. @property (strong, nonatomic)UIPushBehavior *pushBehavior;
  5. @end

接下来重写setter方法对animator属性进行初步化,代码如下所示:

 

    • (UIDynamicAnimator *)animator
  1. {
  2. if(!_animator)_animator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
  3. return _animator;
  4. }

质量三:创设重力展现,实现手势的动作方法

先是创设碰撞行为和push行为,由于撞击行为供给总计视图边距,供给得到self.topLayoutGuide.length的值,所以将冲击行为和push行为的代码写在viewDidAppear:方法中,代码如下所示:

 

    • (void)viewDidAppear:(BOOL)animated
  1. {
  2. [super viewDidAppear:animated];
  3. //创造碰撞行为
  4. UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc]initWithItems:@[self.boxImageView]];
  5. [collisionBehavior setTranslatesReferenceBoundsIntoBoundaryWithInsets:UIEdgeInsetsMake(self.topLayoutGuide.length, 0, self.bottomLayoutGuide.length, 0)];
  6. [self.animator addBehavior:collisionBehavior];
  7. //成立pushBehavior行为,UIPushBehaviorModeContinuous格局表示推力持续施加
  8. self.pushBehavior = [[UIPushBehavior alloc]initWithItems:@[self.boxImageView] mode:UIPushBehaviorModeContinuous];
  9. [self.animator addBehavior:self.pushBehavior];
  10. }

下一场达成tap:方法,该方法中boxImageView随初阶指滑动完毕碰撞和推进,代码如下所示:

 

    • (IBAction)panAction:(UIPanGestureRecognizer *)sender {
  1. CGPoint point = [sender locationInView:self.view];
  2. CGPoint center = self.boxImageView.center;
  3. //总括移动的矛头
  4. CGFloat angle = atan2(center.y - point.y, center.x - point.x) M_PI;
  5. self.pushBehavior.angle = angle;
  6. //总计移动的快慢
  7. CGFloat distance = sqrt(powf(point.x - center.x, 2) powf(point.y - center.y, 2));
  8. self.pushBehavior.magnitude = distance / 10;
  9. //激活
  10. self.pushBehavior.active = YES;
  11. }

末段增加dynamicItemBehavior行为,是视图在运动进程中发出摩擦和反弹,代码如下所示:

 

    • (IBAction)panAction:(UIPanGestureRecognizer *)sender {
  1. CGPoint point = [sender locationInView:self.view];
  2. CGPoint center = self.boxImageView.center;
  3. //总计移动的趋势
  4. CGFloat angle = atan2(center.y - point.y, center.x - point.x) M_PI;
  5. self.pushBehavior.angle = angle;
  6. //计算移动的快慢
  7. CGFloat distance = sqrt(powf(point.x - center.x, 2) powf(point.y - center.y, 2));
  8. self.pushBehavior.magnitude = distance / 10;
  9. //激活
  10. self.pushBehavior.active = YES;
  11. //添加UIDynamicItemBehavior
  12. UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[self.boxImageView]];
  13. //设置摩擦力大小
  14. itemBehavior.friction = 0.2;
  15. //允许旋转
  16. itemBehavior.allowsRotation = YES;
  17. //设置旋转速度
  18. [itemBehavior addAngularVelocity:M_PI_4 forItem:self.boxImageView];
  19. [self.animator addBehavior:itemBehavior];
  20. }

- awakeFormNib 是将冷冻的nib控件唤醒,即全数子控件创立完结后就能调用这一个办法,在此个地方IBOutlet连接的品质才会真的的有值,所以修改nib控件的属性值应该在这里个主意恐怕运维进程之后的不二等秘书诀。

3.3 步骤

金玉满堂此案例要求根据如下步骤举行。

步骤一:拖放ImageView控件

率先在开立好的Xcode项目标Storyboard中拖放一个ImageView控件,在左边栏的检查器中安装好ImageView的体现图片。将ImageView控件关联成TRAttachmentViewController的习性boxImageView,代码如下所示:

 

  1. @interface TRAttachmentViewController ()
  2. @property (weak, nonatomic) IBOutlet UIImageView *boxImageView;
  3. @end

本案例相像要求多少个TRBackgroundView类,直接利用上贰个案例的TRBackgroundView类就可以,在Storyboard上将View关联成TRBackgroundView。

步骤二:定义属性

在TRAttachmentViewController类中定义八个天性分别为UIDynamicAnimator类型的animator,UIGravityBehavior类型的gravityBehavior,以至UIAttachmentBehavior类型的attachmentBehavior,并且选拔重写setter的法子进行初步化,代码如下所示:

 

  1. @interface TRAttachmentViewController ()
  2. @property (weak, nonatomic) IBOutlet UIImageView *boxImageView;
  3. @property (strong, nonatomic) UIDynamicAnimator *animator;
  4. @property (strong, nonatomic) UIGravityBehavior *gravityBehavior;
  5. @property (strong, nonatomic) UIAttachmentBehavior *attachmentBehavior;
  6. @end
  7. //重写setter方法
    • (UIDynamicAnimator *)animator
  8. {
  9. if(!_animator)_animator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
  10. return _animator;
  11. }
      • (UIGravityBehavior *)gravityBehavior
  12. {
  13. if (!_gravityBehavior) {
  14. _gravityBehavior = [[UIGravityBehavior alloc]initWithItems:@[self.boxImageView]];
  15. }
  16. return _gravityBehavior;
  17. }
      • (UIAttachmentBehavior *)attachmentBehavior
  18. {
  19. CGPoint attachedToAnchor = CGPointMake(self.boxImageView.center.x, self.boxImageView.frame.origin.y - 50);
  20. if (!_attachmentBehavior) {
  21. //使用initWithItem:attachedToAnchor:方法开张开端化,使boxImageView和attachedToAnchor产生关联行为
  22. _attachmentBehavior = [[UIAttachmentBehavior alloc]initWithItem:self.boxImageView attachedToAnchor:attachedToAnchor];
  23. }
  24. return _attachmentBehavior;
  25. }

步骤三:增多手势,完成关系引力表现

率先在Storyboard中给View加多UIPanGestureRecognizer类型的手势,关联成pan:方法。

然后在TRAttachmentViewController中落到实处pan:方法,该情势中依照手势的图景在boxImageView的宗旨点和手指触摸点绘制一条直线,並且boxImageView和手指触摸点爆发关联的重力表现,代码如下所示:

 

    • (IBAction)pan:(UIPanGestureRecognizer *)sender
  1. {
  2. if (sender.state == UIGestureRecognizerStateBegan) {
  3. //手势起头增多关系行为和重力行为
  4. [self.animator addBehavior:self.gravityBehavior];
  5. self.attachmentBehavior.anchorPoint = [sender locationInView:self.view];
  6. //阻尼
  7. self.attachmentBehavior.damping = 0.1;
  8. //频率
  9. self.attachmentBehavior.frequency = 1.0;
  10. [self.animator addBehavior:self.attachmentBehavior];
  11. [self drawLine];
  12. [self.view setNeedsDisplay];
  13. }
  14. if(sender.state == UIGestureRecognizerStateChanged){
  15. CGPoint location = [sender locationInView:self.view];
  16. //手指运动进程中改造anchorPoint
  17. self.attachmentBehavior.anchorPoint = location;
  18. [self drawLine];
  19. [self.view setNeedsDisplay];
  20. }else if(sender.state == UIGestureRecognizerStateEnded){
  21. //手势结束移除关联行为和地力行为
  22. [self.animator removeBehavior:self.attachmentBehavior];
  23. [self.animator removeBehavior:self.gravityBehavior];
  24. ((TRBackgroundView *)self.view).path = nil;
  25. [self.view setNeedsDisplay];
  26. }
  27. }
    • (void)drawLine
  28. {
  29. __weak UIAttachmentBehavior *weakAttachmentBehavior = self.attachmentBehavior;
  30. __weak UIImageView *weakBoxImageView = self.boxImageView;
  31. __weak TRBackgroundView *weakMyView = (TRBackgroundView *)self.view;
  32. self.attachmentBehavior.action = ^{
  33. UIBezierPath *path = [UIBezierPath bezierPath];
  34. [path moveToPoint:weakAttachmentBehavior.anchorPoint];
  35. [path addLineToPoint:weakBoxImageView.center];
  36. path.lineWidth = 2;
  37. weakMyView.path = path;
  38. [weakMyView setNeedsDisplay];
  39. };
  40. }

先逐个调三遍heightForRow方法再逐个调贰遍cellForRow方法,在调cellForRow方法的时候并不会再调二回对应的heightForRow方法。若是大家贯彻了:【-tableView: estimatedHeightForRowAtIndexPath:】给了系统推断高度,那么上述五个主意的实行各种就能太阿倒持。并且给定推断高度对于TableView的习性方面也唤起不菲。

5.2 方案

首先在成立好的Xcode项指标Storyboard中拖放三个ImageView控件,在侧面栏的检查器中装置好ImageView的来得图片。将ImageView控件关联成TRPushViewController的性质boxImageView。

从目的库中拖放二个PanGestureRecognizer类型的手势到Storyboard的现象中,并将手势关联成TRPushViewController的动作方法panAction:。

其次在TRPushViewController中定义七个村办属性UIDynamicAnimator类型的animator和UIPushBehavior类型pushBehavior。重写setter方法对animator属性进行开首化。

然后创制碰撞行为和push行为,由于碰上行为须要总结视图边距,必要取得self.topLayoutGuide.length的值,所以将冲击行为和push行为的代码写在viewDidAppear:方法中。

最终达成tap:方法,该办法中boxImageView随开始指滑动达成碰撞和推进,并有所摩擦和反弹效果。

这么不用给定frame 系统也足以来得出带图片大小的ImageView。

1.2 方案

第一在开创好的Xcode项指标Storyboard中拖放二个ImageView控件和四个Button控件,在侧面栏的检查器中设置好ImageView的展现图片。

将ImageView控件关联成TENCOREViewController的性格imageView,四个按键关联成T中华VViewController的动作方法start和end。

其次在TTucsonViewController中定义多个个人属性UIDynamicAnimator类型的animator和UIGravityBehavior类型的gravityBehavior。

然后在viewDidLoad方法中创建属性animator和gravityBehavior,将self.view设置为属性animator的referenceView援引视图,给属性imageView增添引力行为。

终极达成start方法和end方法,点击start按键imageView起先奉行重力行为往下坠,点击end开关结束引力行为。

本文由澳门威利斯人发布于澳门威利斯人,转载请注明出处:两年iOS经验之你忽略的小知识点,自定义下拉刷

关键词: 澳门威利斯人 经验 两年 知识点 刷新