iOS拖动UIView,布料效果

时间:2013-12-10 21:02:44

标签: ios swift user-interface uiview drag

自从我看到this menu drag concept以来,我真的很想知道如何实现它。 所以我想知道如何在UIView中使用布料效果进行拖动?

我知道如何拖动物品,但是你如何给它们起涟漪效果呢?

(更好的形象:http://dribbble.com/shots/899177-Slide-Concept/attachments/98219enter image description here

2 个答案:

答案 0 :(得分:9)

简而言之:真的,真的很难。旧的Classics应用程序使用一系列预渲染的光滑纸张图像在其视图内容的简单转换下实现了这些线条,但正如您可以从这些屏幕截图中看到的(以及下面的那个 - 请注意文本在底部仍然是一条直线,因为它正在进行基本的透视变换),效果相当有限。

screenshot of Classics app showing page-turn effect

Dribbble设计中显示的效果要复杂得多,因为它实际上正在对视图的内容进行一次碾压,而不仅仅是像经典那样扭曲它;目前我能想到的唯一方法是对iOS进行确切的效果,就是放入OpenGL并用网格扭曲内容。

一个更简单的选择是使用UIPageViewController,至少你会得到漂亮的iBooks风格的卷曲纸效果 - 它不是面料,但它比GL选项容易得多。

答案 1 :(得分:2)

已经有一个开源重新实现。

此博文:Mesh Transforms涵盖私人CAMeshTransform。它不是将CALayer视为一个简单的四边形,而是将CALayers变成一个连接面网格。本课程是Apple如何实现页面卷曲和iBooks翻页效果的方法

但是,API根本不能容忍格式错误的输入,Apple已将其保留为私有API。

如果你继续阅读那篇博文,虽然你会在关于它是私有API之后来到这一部分。

  

本着CAMeshTransform的精神,我创建了一个BCMeshTransform,它几乎复制了原始类的每个特征。
  ...
  如果没有对Core Animation渲染服务器的直接公共访问,我被迫使用OpenGL进行实现。这不是一个完美的解决方案,因为它引入了原始类没有的一些缺点,但它似乎是目前唯一可用的选项。

实际上,他将内容视图渲染为OpenGL纹理,然后显示它。这让他可以随心所欲地使用它。

包括这样......

  

我建议您查看我为BCMeshTransformView制作的演示应用。它包含了一些关于如何使用网格变换来丰富交互的想法,就像我对that famous Dribbble非常简单但功能性的看法一样。

什么着名的Dribbble?这一个:

以下是示例:

开源项目: https://github.com/Ciechan/BCMeshTransformView
幕布效果的示例: BCCurtainDemoViewController.m

它是如何运作的?

它使BCMeshTransformView设置了一些照明和视角。

// From: https://github.com/Ciechan/BCMeshTransformView/blob/master/Demo/BCMeshTransformViewDemo/BCCurtainDemoViewController.m#L59
self.transformView.diffuseLightFactor = 0.5;

CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = -1.0/2000.0;
self.transformView.supplementaryTransform = perspective;

然后使用UIPanGestureRecognizer跟踪触摸,并在每次用户手指移动时使用此方法构建新的网格变换。

// From: https://github.com/Ciechan/BCMeshTransformView/blob/master/Demo/BCMeshTransformViewDemo/BCCurtainDemoViewController.m#L91
self.transformView.meshTransform = [BCMutableMeshTransform curtainMeshTransformAtPoint:CGPointMake(point.x + self.surplus, point.y) boundsSize:self.transformView.bounds.size];

// From: https://github.com/Ciechan/BCMeshTransformView/blob/master/Demo/BCMeshTransformViewDemo/BCMeshTransform%2BDemoTransforms.m#L14
+ (instancetype)curtainMeshTransformAtPoint:(CGPoint)point boundsSize:(CGSize)boundsSize
{
    const float Frills = 3;

    point.x = MIN(point.x, boundsSize.width);

    BCMutableMeshTransform *transform = [BCMutableMeshTransform identityMeshTransformWithNumberOfRows:20 numberOfColumns:50];

    CGPoint np = CGPointMake(point.x/boundsSize.width, point.y/boundsSize.height);

    [transform mapVerticesUsingBlock:^BCMeshVertex(BCMeshVertex vertex, NSUInteger vertexIndex) {
        float dy = vertex.to.y - np.y;
        float bend = 0.25f * (1.0f - expf(-dy * dy * 10.0f));

        float x = vertex.to.x;

        vertex.to.z = 0.1 + 0.1f * sin(-1.4f * cos(x * x * Frills * 2.0 * M_PI)) * (1.0 - np.x);
        vertex.to.x = (vertex.to.x) * np.x + vertex.to.x * bend * (1.0 - np.x);

        return vertex;
    }];

    return transform;
}