将 UIRefreshControl 置于滚动 UICollectionView 上方的正确方法是啥?
Posted
技术标签:
【中文标题】将 UIRefreshControl 置于滚动 UICollectionView 上方的正确方法是啥?【英文标题】:What's the proper way to center the UIRefreshControl above a scrolling UICollectionView?将 UIRefreshControl 置于滚动 UICollectionView 上方的正确方法是什么? 【发布时间】:2018-02-15 20:13:59 【问题描述】:场景:包含图像视图的刷新控件。
我确定遇到过这个问题:
-
在 UICollectionView 上创建 UIRefreshControl。
水平滚动以注意 UIRefreshControl 是倾斜的。
这是设置代码:
- (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
在水平滚动条上偏离中心。我是否需要始终计算新中心?
必须有一个标准的方法来做到这一点。
【问题讨论】:
【参考方案1】:最简单的方法应该是使用自动布局使堆栈视图居中,我不会将堆栈视图嵌入到刷新控件中。以下约束(您应该适应您的需要的 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;
您还应该向堆栈视图添加一个活动视图(或动画鱼图标)和一个标签,并且您必须自己处理弹跳。
【讨论】:
我无法让您的建议对我有用。但是,我确实设法通过上面发布的解决方案将 UIRefreshControl 居中。我错过了几个锚。 ....尽管我喜欢它的行为有点奇怪。 我的建议是取消控制。 这是一个需要使用控件的编码挑战。但我同意删除控件会让生活更轻松。 @FrederickC.Lee:太糟糕了,我没有中奖。 ;-)【参考方案2】:简单的监督: 我只需要一个额外的锚来使 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];
【讨论】:
以上是关于将 UIRefreshControl 置于滚动 UICollectionView 上方的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
UIRefreshControl 在启用 preferLargeTitles 的情况下向下滚动时出现奇怪的跳转
当 UIRefreshControl 处于活动状态时,字母滚动条会向下移动?
类似于 UIRefreshControl 将隐藏的 UIView 添加到 UITableView