UIViewController 包含像 Google+ 这样的动画

2023-12-22

理解我想要解释的内容的最好方法是打开Google+应用程序并点击主帖子流中显示的帖子背景中的任意位置。

当您点击它时,整个帖子会以漂亮的动画自动移动到屏幕中央,并在其下方加载帖子的评论。

我认为这是一个常见的UIViewController遏制场景,其中一个UIViewController在另一个里面。但是帖子如何能够动画地移动它并在容器视图控制器内“转移”自身呢?

我已经尝试创建一个简单的按钮并显示UIViewController作为彼此的弹出窗口,但不知道如何执行 Google+ 应用程序(和其他应用程序)的操作。

UPDATE

这是屏幕截图。

正如您所看到的,当您点击帖子时,帖子会向上滑动并成为新的包含内容UIViewController.


正如已经指出的,有很多方法可以实现此 UI,但一种方法是从 tableview 单元格中获取视图,将其移动到某个新背景上,然后更改其框架。当你把它放回去时,只需颠倒这个过程即可。

更详细一点可能如下:

  1. 在单元格中,我有一个容器视图,它是一个滚动视图(其用户交互通常被禁用)。

  2. 当用户点击它时,

    • 创建一个新的透明背景视图,占据整个屏幕;

    • 为该背景提供一个点击手势识别器,该识别器可以在稍后逆转该过程;

    • 将单元格的容器视图从单元格移动到这个新的背景视图(使用convertRect所以它还没有移动);

    • 通过变换对容器的轻微收缩进行动画处理(一种微妙的效果,为您提供在视图上“下推”的效果);

    • 在该动画的完成块中,启动一个新动画:

      • 恢复身份的转变;

      • 将背景色设置为很大程度上不透明(但不完全如此)的颜色;

      • 对容器视图的大小进行动画处理以占据更多屏​​幕

      • 继续并在该容器视图上启用用户交互,以便您可以滚动;

  3. 在我们的背景上设置一个点击手势的处理程序来逆转该过程。

Thus:

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:NO];

    PostCell *cell = (id)[tableView cellForRowAtIndexPath:indexPath];

    // create subview to obscure the table view behind us

    UIView *backdropView = [[UIView alloc] initWithFrame:self.view.bounds];
    backdropView.backgroundColor = [UIColor clearColor];
    [self.view addSubview:backdropView];
    self.backdropView = backdropView;

    // add a tap gesture so we can reverse the process

    [backdropView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self
                                                                              action:@selector(handleTapGesture:)]];

    // move the cell's container view to the backdrop view, preserving its location on the screen
    // (so it doesn't look like it moved)

    self.viewToMove = cell.containerView;
    self.viewToMoveOriginalCell = cell;
    self.viewToMoveOriginalFrame = cell.containerView.frame;

    // figure out where this goes on the backdrop

    CGRect frame = [self.viewToMoveOriginalCell convertRect:self.viewToMoveOriginalFrame
                                                     toView:self.backdropView];

    // move it there (though it won't appear to move yet, we're just changing its superview)

    [self.backdropView addSubview:self.viewToMove];
    self.viewToMove.frame = frame;

    // now do the animation

    [UIView animateWithDuration:0.25
                          delay:0.0
                        options:0.0
                     animations:^{

                         // first shrinking it a bit

                         self.viewToMove.transform = CGAffineTransformMakeScale(0.95, 0.95);
                     }
                     completion:^(BOOL finished) {

                         // finally restoring the size and making it bigger
                         // (and reveal the backdrop that obscures the tableview)

                         [UIView animateWithDuration:0.5 animations:^{
                             CGFloat horizontalMargin = (self.view.bounds.size.width - frame.size.width) / 2.0;
                             backdropView.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8];
                             self.viewToMove.transform = CGAffineTransformIdentity;
                             self.viewToMove.frame = CGRectMake(horizontalMargin, kVerticalMargin, self.view.bounds.size.width - 2.0 * horizontalMargin, self.view.bounds.size.height - 2.0 * kVerticalMargin);
                         }];

                         self.viewToMove.userInteractionEnabled = YES;
                     }];
}

- (void)handleTapGesture:(UITapGestureRecognizer *)gesture
{
    [UIView animateWithDuration:0.5
                          delay:0.0
                        options:0
                     animations:^{

                         // in case user scrolled in content view, scroll back

                         [self.viewToMove setContentOffset:CGPointZero animated:YES];

                         // figure out where to resize view on container view so it's
                         // going to end up where it will end up in the cell

                         CGRect frame = [self.viewToMoveOriginalCell convertRect:self.viewToMoveOriginalFrame
                                                                          toView:self.backdropView];
                         self.viewToMove.frame = frame;

                         // make the back drop appear to gracefully disappear

                         self.backdropView.backgroundColor = [UIColor clearColor];

                         // shrink content view a tad in the process

                         self.viewToMove.transform = CGAffineTransformMakeScale(0.95, 0.95);
                     }
                     completion:^(BOOL finished) {

                         // when done with that animation ...

                         [UIView animateWithDuration:0.25
                                               delay:0.0
                                             options:0
                                          animations:^{

                                              // restore the size of the content view

                                              self.viewToMove.transform = CGAffineTransformIdentity;
                                          }
                                          completion:^(BOOL finished) {

                                              // when all done, put the content view back
                                              // in the cell

                                              [self.viewToMoveOriginalCell addSubview:self.viewToMove];
                                              self.viewToMove.frame = self.viewToMoveOriginalFrame;

                                              // turn off its user interaction again 

                                              self.viewToMove.userInteractionEnabled = NO;

                                              // and now safely discard the backdrop

                                              [self.backdropView removeFromSuperview];
                                          }];
                    }];
}

正如您所知,这都是标准表视图等。如果您想使用视图控制器包含(例如,如果视图有大量的用户交互),您也可以这样做。它不会影响单元容器视图的增长/收缩方面的用户体验。

此外,这一切都不是自动布局的。您可以使用自动布局来做到这一点,但恕我直言,这更麻烦,因为您可能必须删除和添加约束,但肯定可以做到。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UIViewController 包含像 Google+ 这样的动画 的相关文章

  • 如何以编程方式更改 iPhone APN(接入点名称)?

    如何以编程方式更改 iPhone APN 接入点名称 或者强制 3G GPRS 连接以编程方式使用特定的 APN 无法通过 SDK 完成 第三方应用程序无法对硬件进行这种级别的控制 尤其是蜂窝调制解调器
  • `navigator.geolocation.getCurrentPosition()` 在 iOS PWA 上挂起

    我有这个片段 const getCurrentPosition gt new Promise
  • iOS、通用链接、Swift。 continueUserActivity 未调用

    我正在为我们的 iOS 应用程序实现通用链接 这是我的一小部分 AppDelegate private func application application UIApplication openURL url URL sourceApp
  • Swift SpriteKit edgeLoopF​​romRect 问题

    下面的代码可以识别底部和顶部边缘场景和球按预期弹开 但是 那左边缘和右边缘现场的情况一直被破坏 如果施加足够的力 球会离开屏幕 然后最终返回 就好像场景的边缘超出了 iPhone 模拟器窗口的边缘 import SpriteKit clas
  • 检测 iPhone 是否在运行时运行调试/分发构建

    是否可以在运行时检测正在运行的应用程序是否是通过调试或分发进行编译的 在项目信息中 对于调试配置 添加 DEBUG 预处理器宏 在 GCC 4 2 预处理部分 在代码中 如果您想要包含或不包含某些代码用于调试版本 则可以使用 ifdef 来
  • 如何保护 iOS 应用程序免受任何操作系统攻击(在越狱设备上)

    我希望保护我的应用程序数据 以防任何操作系统攻击或越狱 iOS 设备上的未经授权的访问 在这种情况下 有什么方法可以检测此类威胁并保护应用程序数据 虽然我同意 jrturton 的说法 但如果您有想要保护的关键数据免受流氓应用程序 而不是用
  • Objective-C UILabel 作为超链接

    我正在尝试做一个UILabel一个链接UIWebView 我怎样才能做一个UILabel作为超链接 您可以使用 UITapGestureRecognizer 它将实现与您想要的类似的功能 UILabel myLabel UILabel al
  • 将图像保存在相机胶卷中并获取资源 URL

    对于我正在开发的应用程序 我使用 UIImagePickerController 拍摄照片并将其存储在相机胶卷中 void imagePickerController UIImagePickerController picker didFi
  • (Kiss)XML xpath 和默认命名空间

    我正在开发一个 iPhone 项目 需要解析一些 xml xml 可能包含也可能不包含默认名称空间 我需要知道如何解析 xml 以防它使用默认命名空间 由于我需要读取和写入 xml 因此我倾向于使用 KissXML 但我愿意接受建议 这是我
  • 为什么 iOS 启动屏幕很慢?

    我的 iOS 应用程序启动屏幕大约需要 3 5 秒 我有一张将在启动屏幕后加载的地图 我的用户必须等待启动屏幕加载 然后再等待 3 秒才能加载地图 有没有办法最大限度地减少启动屏幕时间 基本上这种延迟意味着you在启动过程中做了一些非常错误
  • 如何使用 iPhone 将照片上传到服务器?

    我正在编写一个 iPhone 应用程序 它可以拍摄照片然后将其上传到服务器 如何使用 Cocoa 将照片上传到服务器 我想我在某处使用 NSUrl Thanks Header interface EPUploader NSObject NS
  • 使用未解析的标识符“FlurryAdInterstitial”

    我正在尝试整合Flurry Interstitial Ads使用cocoapods in Swift and Xcode 7 1 1 我正在关注开发人员雅虎网站上的此文档 https developer yahoo com flurry d
  • 在 iPhone 3GS 与 iPhone 4 上为 Mobile Safari 嵌入 HTML5 视频

    我在服务器上的 mp4 文件中有 H 264 AAC 编码的视频 mime 类型的视频 mp4 添加到 Web 服务器 IIS 7 并且我有一个带有视频标签的页面
  • 从命令行添加 Xcode 开发者帐户

    我正在尝试使用xcodebuild allowProvisioningUpdates在我只能通过命令行访问的计算机 Azure Devops macOS 托管计算机 上 不幸的是 根据man xcodebuild为了使用 allowProv
  • 在实例化对象之前是否可以检查故事板中是否存在标识符?

    在我的代码中我有这一行 但我想知道是否有办法检查是否 一些控制器 在我将它与 一起使用之前就存在实例化ViewControllerWithIdentifier 方法 如果标识符不存在 则应用程序崩溃 如果没有好的方法 这并不是一个大问题 我
  • 如何解决 Xcode 5 中的红色(已移动)文件?

    在 Xcode 4 中 当您要移动文件时 可以通过单击右侧菜单中的按钮并通过 Finder 选择新位置来解析文件的新位置 在 Xcode 5 中 右侧菜单中没有按钮 我还没有找到任何方法通过右键单击文件或顶部菜单栏选项来指定文件的新位置 在
  • 从应用程序启动 iPhone 设置屏幕?

    我正在开发一个应用程序 我希望按下按钮时 iPhone 设置屏幕应该打开 苹果有访问限制吗 到底能不能 如果能的话怎么办 不 你不能那样做 但是 作为替代方案 您可以使用这个框架 http www inappsettingskit com
  • 如何在 UICollectionView 中将行居中?

    我有一个UICollectionView与随机细胞 有什么方法可以让我将行居中吗 默认情况下它是这样的 x x x x x x x x x x x x x x 这是所需的布局 x x x x x x x x x x x x 我必须做这样的事
  • 模态转场需要点击 2 次而不是 1 次

    我的 UITableView 需要点击 2 次才能显示所选单元格的详细信息页面 一次用于选择 另一次用于显示详细信息视图 我希望有一个 CLI 直接显示所单击单元格的详细视图 我在 UITableViewManager m 中使用此方法的模
  • 像 TraceGL 一样分析 Objective C 中的代码路径?

    TraceGL 是一个非常简洁的项目 它允许 JS 程序员跟踪 Javascript 中的代码路径 它看起来像这样 我想为 Objective C 构建类似的东西 我知道运行时使跟踪方法调用变得相当容易 但是我如何跟踪控制流 例如 在上面的

随机推荐

  • C++ 根据模板参数值更改成员函数定义

    是否可以根据模板参数的值有条件地编译函数中的语句 例如 template
  • 如何通过 Javascript 动态创建表单

    我的网站 Aweber 注册表收到大量垃圾邮件 我被告知要在页面呈现后通过 JavaScript 或通过单击按钮动态创建表单 我如何通过 javascript 创建和呈现表单 一些事情如下 在 body 标签之后添加此内容 这是一个粗略的草
  • Azure Devops 管道 yml 在各个阶段循环

    我如何循环遍历数组或对象来创建阶段 下面是一个有效的 yml 文件 您可以看到构建阶段在作业的参数环境上循环 在发布阶段是否有可能实现同样的目标 发布阶段需要手动批准 必须按顺序运行并且只有在前一阶段成功完成后才能运行 parameters
  • Camera.set 预览{@override onPreviewFrame() } 不起作用

    我想要录制视频并分析当前位图在服务中 所以我注册surfaceHolder addCallback in onStartCommand功能 And set mCamera setPreviewCallback in surfaceCreat
  • ListView 抖动中的问题开关值

    我在 ListView 中为每个元素创建一个 Switch 小部件 当我单击开关时 所有元素的值都会更改 我检查了 flutter 文档 dart 文档 我想 我没有恢复 onChanged 方法中的元素位置 但怎么办呢 当我单击时 我的值
  • 带有 URL 编码数据的 Spring RestTemplate POST 请求

    我是 Spring 新手 正在尝试使用 RestTemplate 执行休息请求 Java 代码应执行与以下curl 命令相同的操作 curl data name feature color 5843AD header PRIVATE TOK
  • android中每个列表项都有viewpager的listview

    在将数据设置为列表视图中的列表项时 我需要您的帮助 在我的列表视图中 每个项目都有一个 ViewPager 每个 viewpager 应该有不同的数据 我不知道如何为每个视图页面设置不同的数据 实际上 基于列表项索引 我需要设置数据视图页面
  • 使用ip route add为多台设备添加组播路由

    TLDR 有没有办法使用 ip Route 为多个网卡添加多播路由 我们有软件将两个绑定到不同 NICS 上不同 IP 地址的套接字连接到两个单独的多播组 例如套接字 1 绑定到 192 168 0 2 并加入多播组 233 255 10
  • 当没有输出时 Process.StandardOutput.Readline() 挂起

    Note 我正在尝试跑步packer exe作为解决特定问题的后台进程azure arm构建器 我需要观察输出 我没有使用Start Process因为我不想使用中间文件来使用输出 我设置了以下代码packer exe在后台运行 以便我可以
  • 白色背景上带有浮动标签的 TextInputLayout Android 中的可见性问题

    我正在创建具有 textinputlayout 浮动标签的简单登录屏幕 下面给出了 java 文件和 xml protected void onCreate Bundle savedInstanceState super onCreate
  • Control.ClientRectangle 与 Control.DisplayRectangle

    我了解有关表单 控件的客户端矩形的概念 但我不明白之间有什么区别 Control ClientRectangle and Control DisplayRectangle 在阅读了这两个属性的 MSDN 页面后 并不清楚其中一个何时会返回与
  • 为什么我们需要 Hadoop 无密码 ssh?

    AFAIK 需要无密码 ssh 以便主节点可以在每个从节点上启动守护进程 除此之外 无密码ssh对于Hadoop的操作有什么用处吗 用户代码 jar 和数据块如何跨从节点传输 我想知道所使用的机制和协议 无密码 SSH 应该只配置为主从对
  • 在 PHP 中如何检查数组中的所有键是否都有空值? [复制]

    这个问题在这里已经有答案了 我有一个数组 array array key1 gt null key2 gt null key3 gt null key4 gt null 我想确定是否所有数组键都有空值 如果是 则返回 false 上面的示例
  • Swift 4:将字典添加到 Plist

    所以 我有一个空的 plist 我试图在 plist 中创建这些值 使用此代码 let dictionary String String key1 value1 key2 value2 key3 value3 let documentDir
  • 将 iOS 键盘布局更改为表情符号?

    当 UITextField 成为第一响应者时 是否可以将键盘布局更改为表情符号 或根据用户操作 例如点击 UIButton 我知道我可以将键盘布局更改为以下之一 typedef enum UIKeyboardTypeDefault Defa
  • 我应该使用 OpenId 的哪个 Erlang 实现(如果有)?

    我需要 OpenId 协议的 Erlang 实现 我发现了以下内容 但这似乎是一个处于早期阶段的项目 http code google com p erlopenid http code google com p erlopenid 关于我
  • python 中的 next() 真的那么快吗?

    通过这里的一篇文章 我读到使用 next 搜索和检索列表中元素的第一次出现可能会很快 然而 我惊讶地发现传统的 for if break 语法在相当长一段时间内表现得更好 如果我的分析有错误 请纠正我 这是我尝试过的一个片段 gt gt g
  • 错误:HTTP 错误:400,项目“my_project”不是启用 Firestore 的项目

    当我运行命令时firebase deploy我收到此错误 错误 HTTP 错误 400 项目 my project 不是启用 Firestore 的项目 您是否正在尝试使用 Cloud Firestore 如果是这样 请访问控制台的数据库部
  • 我们如何在 ionic 应用程序中隐藏启动屏幕?

    无论如何 在离子应用程序中隐藏或不显示启动屏幕 并且电容器中的启动屏幕时间较少或在科尔多瓦中较少 以及如何减少离子应用程序中的启动屏幕时间 谢谢 这是禁用启动画面的调整 在 config xml 文件中
  • UIViewController 包含像 Google+ 这样的动画

    理解我想要解释的内容的最好方法是打开Google 应用程序并点击主帖子流中显示的帖子背景中的任意位置 当您点击它时 整个帖子会以漂亮的动画自动移动到屏幕中央 并在其下方加载帖子的评论 我认为这是一个常见的UIViewController遏制