将UIRefreshControl置于滚动UICollectionView上方的正确方法是什么?

时间:2018-02-15 20:13:59

标签: ios objective-c uicollectionview uirefreshcontrol

场景:刷新包含图像视图的控件。

我确定已经遇到过这个问题:

  1. 在UICollectionView上创建UIRefreshControl。
  2. 执行水平滚动以注意UIRefreshControl是否倾斜。
  3. enter image description here

    这是设置代码:

    - (void)setupRefreshControl {
        self.refreshControl = [UIRefreshControl new];
        self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:@"Refresh Data"];
        self.refreshControl.tintColor = UIColor.redColor;
        self.refreshControl.backgroundColor = UIColor.whiteColor;
        UIImage *hook = [UIImage imageNamed:@"Hook"];
        UIImageView *hookImageView = [[UIImageView alloc] initWithImage:hook];
        UIImage *fish = [UIImage imageNamed:@"Fish"];
        UIImageView *fishImageView = [[UIImageView alloc] initWithImage:fish];
    
        UIStackView *stackView = [[UIStackView alloc] initWithArrangedSubviews:@[hookImageView ,fishImageView]];
        stackView.axis = UILayoutConstraintAxisVertical;
        stackView.spacing = 10.0;
        [self.refreshControl addSubview:stackView];
    
        [stackView setTranslatesAutoresizingMaskIntoConstraints:NO];
        UILayoutGuide *container = [_refreshControl layoutMarginsGuide];
        [stackView.topAnchor constraintEqualToAnchor:container.topAnchor].active = YES;
        CGFloat width = self.refreshControl.bounds.size.width;
        [stackView.leftAnchor constraintEqualToAnchor:container.leftAnchor constant:width/2].active = YES;
        [self.refreshControl addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];
        self.collectionView.refreshControl = self.refreshControl;
    }
    

    如您所见,UIRefreshControl偏离水平滚动。我是否需要始终计算新的中心?

    必须有一种标准的方法来做到这一点。

2 个答案:

答案 0 :(得分:0)

最简单的方法应该是使用自动布局将堆栈视图居中,我不会将堆栈视图嵌入到刷新控件中。以下约束(除了您应该根据需要调整的20.0)应该将堆栈视图放在正确的位置:

stackView.backgroundColor = [UIColor clearColor];
[stackView.centeredXAnchor constraintEqualToAnchor:container.centeredXAnchor constant:0.0].active = YES; 
[stackView.bottomAnchor constraintEqualToAnchor:container.topAnchor constant:20.0].active = YES;

您还应该在堆栈视图中添加活动视图(或为鱼图标设置动画)和标签,您必须自己处理弹跳。

答案 1 :(得分:0)

简单的疏忽:
我只需要一个额外的锚点来居中UIRefreshControl:

- (void)setupRefreshControl {
    // Refresh Control:
    self.refreshControl = [UIRefreshControl new];
    self.collectionView.refreshControl = self.refreshControl;

    [_refreshControl setTranslatesAutoresizingMaskIntoConstraints:NO];
    UILayoutGuide *refreshControlContainer = [_collectionView layoutMarginsGuide];
    [_refreshControl.topAnchor constraintEqualToAnchor:refreshControlContainer.topAnchor constant: 1.0].active = YES;
    [_refreshControl.leftAnchor constraintEqualToAnchor:refreshControlContainer.leftAnchor constant: 1.0].active = YES;
    [_refreshControl.heightAnchor constraintEqualToConstant:300.0].active = YES;

    self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:@"Refresh Data"];
    self.refreshControl.tintColor = UIColor.redColor;
    self.refreshControl.backgroundColor = UIColor.whiteColor;

     // StackView members:
    UIImage *hook = [UIImage imageNamed:@"Hook"];
    UIImageView *hookImageView = [[UIImageView alloc] initWithImage:hook];
    UIImage *fish = [UIImage imageNamed:@"Fish"];
    UIImageView *fishImageView = [[UIImageView alloc] initWithImage:fish];

    UIStackView *stackView = [[UIStackView alloc] initWithArrangedSubviews:@[hookImageView ,fishImageView]];
    stackView.axis = UILayoutConstraintAxisVertical;
    stackView.spacing = 10.0;
    [self.refreshControl addSubview:stackView];

    // StackView:
    [stackView setTranslatesAutoresizingMaskIntoConstraints:NO];
    UILayoutGuide *stackViewContainer = [_refreshControl layoutMarginsGuide];
    [stackView.topAnchor constraintEqualToAnchor:stackViewContainer.topAnchor].active = YES;
    CGFloat width = self.refreshControl.bounds.size.width;
    [stackView.leftAnchor constraintEqualToAnchor:stackViewContainer.leftAnchor constant:width/2].active = YES;

    [self.refreshControl addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];

}