gpt4 book ai didi

iphone - 垂直 UIScrollView?

转载 作者:行者123 更新时间:2023-11-28 17:59:18 25 4
gpt4 key购买 nike

我正在努力进行一些 iOS 开发,我希望有人能够帮助我提出建议。我想实现一堆看起来像一副纸牌的 UIView。用户应该能够通过触摸刷出“卡片”。我想到了带有 pagingEnabled 的 UIScrollViews 给人一种卡片是分开的印象。但是,UIScrollView 可以从左侧或右侧出现的内容水平滑动。我希望我的牌组位于屏幕中间,这样用户就可以从牌组中刷卡而不会看到卡片出现在左侧或右侧。此外,我正在考虑使用触摸方法(touchesBegan、touchesMoved 等)来移动 View 。它可以工作......但我担心我无法重现卡的正确机制(摩擦,滑动时的弹跳效果等......)。

有人可以指点我正确的技术或建议一些教程吗?我已经做了一些研究,但找不到任何有用的东西。

这是我想要达到的效果的图像。

enter image description here

我想要实现的是将牌从牌堆中刷出来。

非常感谢!

最佳答案

我猜你想要轻扫以取出牌堆顶部的牌并将其“洗牌”到牌堆底部,露出牌堆中的第二张牌,如下所示:

card moving from top to bottom of deck

动画在现实生活中要流畅得多。我不得不使用低帧率来使动画 GIF 变小。

一种方法是创建 UIView 的子类来管理卡片 View 堆栈。我们将管理器 View 称为 BoardView。我们将为其提供两种公共(public)方法:一种用于将顶牌洗到底层,一种用于将底牌洗牌至顶层。

@interface BoardView : UIView

- (IBAction)goToNextCard;
- (IBAction)goToPriorCard;

@end

@implementation BoardView {
BOOL _isRestacking;
}

我们将使用 _isRestacking 变量来跟踪棋盘 View 是否正在为卡片移动到一边制作动画。

BoardView 将其所有 subview 视为卡片 View 。它负责将它们堆叠起来,顶部卡片居中。在您的屏幕截图中,您将较低的卡片偏移了稍微随机的数量。我们可以通过随机旋转下面的卡片让它看起来更性感一点。此方法对 View 应用小的随机旋转:

- (void)jostleSubview:(UIView *)subview {
subview.transform = CGAffineTransformMakeRotation((((double)arc4random() / UINT32_MAX) - .5) * .2);
}

我们希望将它应用于每个添加的 subview :

- (void)didAddSubview:(UIView *)subview {
[self jostleSubview:subview];
}

每当 View 的大小发生变化,或者当 View 被赋予新的 subview 时,系统都会发送 layoutSubviews。我们将利用这一点将所有卡片放在棋盘 View 边界中间的堆栈中。但是,如果 View 当前正在为卡片设置动画,我们不想进行布局,因为它会终止动画。

- (void)layoutSubviews {
if (_isRestacking)
return;
CGRect bounds = self.bounds;
CGPoint center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
UIView *topView = self.subviews.lastObject;
CGFloat offset = 10.0f / self.subviews.count;
for (UIView *view in self.subviews.reverseObjectEnumerator) {
view.center = center;
if (view == topView) {
// Make the top card be square to the edges of the screen.
view.transform = CGAffineTransformIdentity;
}
center.x -= offset;
center.y -= offset;
}
}

现在我们准备好处理改组了。要“转到下一张卡片”,我们需要将最上面的卡片移动到一边,然后将其移动到 subview 堆叠顺序的底部,然后将其动画化回中间。我们还需要微调所有其他卡片的位置,因为它们都更靠近堆栈的顶部。

- (void)goToNextCard {
if (self.subviews.count < 2)
return;

首先,我们将最上面的卡片移动到一边。为了让它看起来更性感,我们在移动时旋转卡片。

    UIView *movingView = self.subviews.lastObject;
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationCurveEaseInOut animations:^{
_isRestacking = YES;
CGPoint center = movingView.center;
center.x = -hypotf(movingView.frame.size.width / 2, movingView.frame.size.height / 2);
movingView.center = center;
movingView.transform = CGAffineTransformMakeRotation(-M_PI_4);
}

在完成 block 中,我们将卡片移到堆栈底部。

    completion:^(BOOL finished) {
_isRestacking = NO;
[self sendSubviewToBack:movingView];

为了将现在位于底部的卡片移回堆栈,并插入所有其他卡片,我们只需调用 layoutSubviews。但我们不应该直接调用 layoutSubviews,因此我们使用适当的 API:setNeedsLayout 后跟 layoutIfNeeded。我们在动画 block 中调用 layoutIfNeeded,这样卡片就会动画到它们的新位置。

        [self setNeedsLayout];
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction animations:^{
[self jostleSubview:movingView];
[self layoutIfNeeded];
} completion:nil];
}];
}

goToNextCard 到此结束。我们可以类似地执行 goToPriorCard:

- (void)goToPriorCard {
if (self.subviews.count < 2)
return;
UIView *movingView = [self.subviews objectAtIndex:0];
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
_isRestacking = YES;
CGPoint center = movingView.center;
center.x = -movingView.frame.size.height / 2;
movingView.center = center;
movingView.transform = CGAffineTransformMakeRotation(-M_PI_4);
} completion:^(BOOL finished) {
_isRestacking = NO;
UIView *priorTopView = self.subviews.lastObject;
[self bringSubviewToFront:movingView];
[self setNeedsLayout];
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction animations:^{
[self jostleSubview:priorTopView];
[self layoutIfNeeded];
} completion:nil];
}];
}

一旦有了 BoardView,您只需附加一个向它发送 goToNextCard 消息的滑动手势识别器,以及另一个向它发送 的滑动手势识别器goToPriorCard 消息。并且你需要添加一些 subview 来充当卡片。

另一个细节:为了让卡片的边缘在推挤时看起来平滑,您需要在 Info 中将 UIViewEdgeAntialiasing 设置为 YES。 plist.

你可以在这里找到我的测试项目:http://dl.dropbox.com/u/26919672/cardstack.zip

关于iphone - 垂直 UIScrollView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9369034/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com