自定义容器和自定义转换

     2023-03-13     136

关键词:

【中文标题】自定义容器和自定义转换【英文标题】:Custom Containers and Custom Transitions 【发布时间】:2013-11-16 21:13:25 【问题描述】:

自定义转场很容易与标准容器配合使用,同时呈现模态视图控制器。但是在完全自定义的容器中使用自定义转换呢?

我想将UIViewControllerContextTransitioning 协议与我的自定义容器一起使用,并利用过渡和交互式过渡。

UIViewControllerContextTransitioning头文件的注释中我读到:

// The UIViewControllerContextTransitioning protocol can be adopted by custom
// container controllers.  It is purposely general to cover more complex
// transitions than the system currently supports. 

但我不明白如何创建上下文过渡并启动所有自定义过渡过程。

【问题讨论】:

您是否尝试在自定义容器类的推送视图控制器方法中同时调用 presentViewController:animated:completion: 和 addChildViewController:?除了 presentViewController 之外,我找不到任何会导致调用转换委托的方法。 那么您认为仅presentViewController 就可以解决问题吗?我认为这个功能与模态视图控制器相关......但可能你是对的。 如果您有时间尝试一下,请告诉它是否有效,我最近太忙了,无法尝试。 我会在接下来的几天里确定...请看一下这个问题并最终用您的评论填写答案,以便我接受它:) 非常抱歉,伙计 :( 我尝试了所有我能想到的方法,但没有用。最后,我查看了那个头文件,我读到“现在……”部分,然后我放弃了。但是感谢您提出的好问题,我在尝试找到解决方案时学到了很多东西。 【参考方案1】:

这很有可能!

看看这个SO Answer。

您只需创建一个符合 UIViewControllerContextTransitioning 协议的 viewController 并使用 ViewController Containment API(addChildViewController:、willMoveToParentViewController: 等)。

当您想启动自定义过渡时,只需调用您的 transitionController 上的 [animateTransition] 方法。从那时起,它与 Apple 提供的 API 相同。

使您的自定义容器适合 Transitioning API。

实际上,iOS7 中引入的所有新协议(UIViewControllerContextTransitioning 等)并不是真正需要实现您自己的完全自定义的 containerViewController。它只是提供了一个整洁的类关系和方法池。但是您可以自己编写所有内容,而无需使用任何私有 API。 ViewController Containment(在 iOS5 中引入)是您完成这项工作所需要的。

我刚刚尝试过,它甚至可以使用交互式过渡。

如果您需要一些示例代码,请告诉我,我会提供一些:)

编辑

顺便说一句,这就是 iOS 版 Facebook 和 Instagram 创建导航概念的方式。您可以在这些应用程序中滚开 NavigationBar,当“推送”新的 ViewController 时,NavigationBar 似乎在推送期间已被重置。

具有讽刺意味的是,一个月前我在 *** 上问了完全相同的问题:D

My Question

我才意识到我自己回答了:)

祝你有美好的一天!

【讨论】:

我接受了你的回答!这是正确的:) 谢谢!有一些代码示例会很棒。目前,按照您的建议,我能够在两个控制器之间执行动画,但在animateTransition 我必须手动添加每个子视图......这是正确的方法吗?使用带有标准模态控制器的自定义转换,“to-view”会自动添加到上下文视图中......所以我想知道我的代码是否正确。 我很高兴能帮助你:) 当你实现你自己的容器时,你还负责确保 childViewControllers 的视图被正确地添加和删除。通常,一次只有 1 个 childController 的视图可见,但这不是必须的。因此,当您当前添加和删除每个 childViewController 的视图时,您的代码可能是正确的;) 系统转换(如 NavigationController、Modal 等)在使用自定义转换时为您处理“fromVC”的删除。我会尽快为您整理一些示例代码:) 谢谢卡布斯!真的很难找到关于这个主题的好例子(我的意思是自定义容器 + 自定义转换:))。 @Cabus 我只想跳进去说我也很想看看这个例子! 好吧,我终于有时间为你建立一个例子。它有据可查,所以我想它会自我解释 :) 见github.com/ImJCabus/iOS7-Custom-ContainerViewController【参考方案2】:

事实上,它是这么说的,但你是不完整的:

UIViewControllerContextTransitioning 协议可以通过 自定义容器控制器。特意笼统地涵盖 比系统当前支持的更复杂的转换。为了 现在,导航推送/弹出和 UIViewController 存在/关闭 可以自定义转换。

这意味着您可以通过调用presentViewController:animated:completion: 方法来触发您的VC 的transitioningDelegate,或者您可以在您的UINavigationControllerDelegate 类中实现navigationController:animationControllerForOperation:fromViewController:toViewController: 并返回一个符合UIViewControllerAnimatedTransitioning 协议的对象。

综上所述,提供自定义转场的方式只有两种。在我们添加子视图以创建自定义容器视图控制器时,两者都需要呈现/推送 VC。

未来,Apple 可能会按照他们在头文件中声明的第一行所说的去做,但现在你想做的似乎是不可能的。

【讨论】:

我很高兴地说你错了 :) 检查 Cabus 答案。 我想给应得的人+50,但我不能,当我想开始赏金时,它只允许我给+100。有什么帮助吗? 我真的不知道最大限制是100还是更多...我也可以开始超过100分的赏金。【参考方案3】:

来自docsUIViewControllerContextTransitioning

不要在你自己的课程中采用这个协议,你也不应该 直接创建采用该协议的对象。

【讨论】:

【参考方案4】:

请看MPFoldTransition,它对我有用。

您也可以使用以下类别,您可以使用它创建自己的过渡。

#import <UIKit/UIKit.h>

@interface UIView (Animation)

- (void) moveTo:(CGPoint)destination duration:(float)secs option:(UIViewAnimationOptions)option;
- (void) downUnder:(float)secs option:(UIViewAnimationOptions)option;
- (void) addSubviewWithZoomInAnimation:(UIView*)view duration:(float)secs option:(UIViewAnimationOptions)option;
- (void) removeWithZoomOutAnimation:(float)secs option:(UIViewAnimationOptions)option;
- (void) addSubviewWithFadeAnimation:(UIView*)view duration:(float)secs option:(UIViewAnimationOptions)option;
- (void) removeWithSinkAnimation:(int)steps;
- (void) removeWithSinkAnimationRotateTimer:(NSTimer*) timer;

@end

实施:

#import "UIView+Animation.h"

@implementation UIView (Animation)

- (void) moveTo:(CGPoint)destination duration:(float)secs option:(UIViewAnimationOptions)option

    [UIView animateWithDuration:secs delay:0.0 options:option
                     animations:^
                         self.frame = CGRectMake(destination.x,destination.y, self.frame.size.width, self.frame.size.height);
                     
                     completion:nil];


- (void) downUnder:(float)secs option:(UIViewAnimationOptions)option

    [UIView animateWithDuration:secs delay:0.0 options:option
         animations:^
             self.transform = CGAffineTransformRotate(self.transform, M_PI);
             self.alpha = self.alpha - 0.5;
         
         completion:nil];


- (void) addSubviewWithZoomInAnimation:(UIView*)view duration:(float)secs option:(UIViewAnimationOptions)option

    // first reduce the view to 1/100th of its original dimension
    CGAffineTransform trans = CGAffineTransformScale(view.transform, 0.01, 0.01);
    view.transform = trans; // do it instantly, no animation
    [self addSubview:view];
    // now return the view to normal dimension, animating this tranformation
    [UIView animateWithDuration:secs delay:0.0 options:option
        animations:^
            view.transform = CGAffineTransformScale(view.transform, 100.0, 100.0);
        
        completion:nil];    


- (void) removeWithZoomOutAnimation:(float)secs option:(UIViewAnimationOptions)option

    [UIView animateWithDuration:secs delay:0.0 options:option
    animations:^
        self.transform = CGAffineTransformScale(self.transform, 0.1, 0.1);
    
    completion:^(BOOL finished)  
        [self removeFromSuperview]; 
    ];


// add with a fade-in effect
- (void) addSubviewWithFadeAnimation:(UIView*)view duration:(float)secs option:(UIViewAnimationOptions)option

    view.alpha = 0.0;   // make the view transparent
    [self addSubview:view]; // add it
    [UIView animateWithDuration:secs delay:0.0 options:option
                     animations:^view.alpha = 1.0;
                     completion:nil];   // animate the return to visible 


// remove self making it "drain" from the sink!
- (void) removeWithSinkAnimation:(int)steps

    //NSTimer *timer;
    if (steps > 0 && steps < 100)   // just to avoid too much steps
        self.tag = steps;
    else
        self.tag = 50;
    [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(removeWithSinkAnimationRotateTimer:) userInfo:nil repeats:YES];

- (void) removeWithSinkAnimationRotateTimer:(NSTimer*) timer

    CGAffineTransform trans = CGAffineTransformRotate(CGAffineTransformScale(self.transform, 0.9, 0.9),0.314);
    self.transform = trans;
    self.alpha = self.alpha * 0.98;
    self.tag = self.tag - 1;
    if (self.tag <= 0)
    
        [timer invalidate];
        [self removeFromSuperview];
    


@end

希望它能解决您的问题。享受。:)

【讨论】:

你没有理解我的问题。我的问题是“如何将 CUSTOM CONTAINER 与 CUSTOM TRANSITIONS 一起使用”。

Sagemaker 无服务器推理和自定义容器:模型归档子流程失败

】Sagemaker无服务器推理和自定义容器:模型归档子流程失败【英文标题】:SagemakerServerlessInference&customcontainer:Modelarchiversubprocessfails【发布时间】:2022-01-1622:45:58【问题描述】:我想使用新的ServerlessInference在Sagemaker上托管一个... 查看详情

使用堆栈和自定义选项构建docker容器(代码片段)

stackguide的“Docker”部分中有关于如何使用stack构建Docker容器的说明。但是,我需要在容器中提供其他选项,即:RUNmkdir-p/codeVOLUME/codeWORKDIR/codeRUNuseraddapp--uid9000USERapp#Resetfpco/stack-run'sdumbENTRYPOINTENTRYPOINT[]CMD["/usr/bin/engine"]可以在stack.y... 查看详情

map的默认排序和自定义排序

...map的值做特殊的排序(不经其他容器的辅助),这就需要在定义map变量时做些特 查看详情

docker提供的几种原生网络和自定义网络(11)

Docker网络从覆盖范围可分为单个host上的容器网络和跨多个host的网络,本章重点讨论前一种Docker安装时会自动在host上创建三个网络,我们可用 dockernetworkls 命令查看:下面我们分别讨论它们。none网络故名思议,none网络就... 查看详情

让断点与 jest、Visual Studio 代码和自定义 typescript 转换器一起工作

】让断点与jest、VisualStudio代码和自定义typescript转换器一起工作【英文标题】:Gettingbreakpointstoworkwithjest,Visualstudiocodeandacustomtypescripttransformer【发布时间】:2017-10-1720:13:07【问题描述】:我无法使用ts-jest作为自定义预处理器在VSCo... 查看详情

iCloud 容器默认 vs 自定义

】iCloud容器默认vs自定义【英文标题】:iCloudcontainerdefaultvscustom【发布时间】:2015-03-0202:13:56【问题描述】:我正在将iCloudCoreData同步添加到已发布的应用程序中。我对默认容器和自定义容器之间的区别感到困惑。我从测试中学... 查看详情

django中的日期处理注意事项和自定义时间格式转换(代码片段)

...注意;另外,如果不习惯Django的默认时间格式,也可以自定义的修改。DateTimeField、DateField和TimeField,其值分别对应着Python里的dateti 查看详情

Wordpress 自定义帖子类型和自定义分类

】Wordpress自定义帖子类型和自定义分类【英文标题】:WordpressCustomPostTypeandCustomTaxonomy【发布时间】:2013-08-0314:50:08【问题描述】:我在自定义帖子类型和自定义分类方面遇到问题。我创建了一个名为“gallery”的自定义帖子类型... 查看详情

xaml和自定义类

XAML和自定义类可扩展应用程序标记语言(XAML)支持使用任何公共语言运行库(CLR)语言定义自定义类或结构,然后使用XAML标记(包括在同一标记文件中混合使用WindowsPresentationFoundation(WPF)定义的XAML和自定义类的XAML标记)... 查看详情

spring标准事件和自定义事件-观察者模式(代码片段)

Spring标准事件和自定义事件-观察者模式spring事件系统事件自定义事件声明事件发布事件监听事件实现`ApplicationListener`接口`@EventListener`注解。异步消息监听:顺序监听:通用消息声明通用消息事件监听通用消息事件spr... 查看详情

spring标准事件和自定义事件-观察者模式(代码片段)

Spring标准事件和自定义事件-观察者模式spring事件系统事件自定义事件声明事件发布事件监听事件实现`ApplicationListener`接口`@EventListener`注解。异步消息监听:顺序监听:通用消息声明通用消息事件监听通用消息事件spr... 查看详情

spring标准事件和自定义事件-观察者模式(代码片段)

Spring标准事件和自定义事件-观察者模式spring事件系统事件自定义事件声明事件发布事件监听事件实现`ApplicationListener`接口`@EventListener`注解。异步消息监听:顺序监听:通用消息声明通用消息事件监听通用消息事件spr... 查看详情

带有自定义控件和自定义 StringProperty 的 Proguard

】带有自定义控件和自定义StringProperty的Proguard【英文标题】:ProguardwithcustomcontrolandcustomStringProperty【发布时间】:2021-12-2706:56:59【问题描述】:我想将proguard与带有一些自定义控件的javafx应用程序一起使用。我有一个包含属性的... 查看详情

自定义 UIViewController 和自定义 UIView

】自定义UIViewController和自定义UIView【英文标题】:CustomUIViewControllerandcustomUIView【发布时间】:2011-04-1014:34:32【问题描述】:我有三个观点,它们有几个相似之处。例如位置30,30的UIImageView和同一位置的三个UILabel。在不复制和粘... 查看详情

使用自定义列名称和自定义值保存 JSON

】使用自定义列名称和自定义值保存JSON【英文标题】:SaveJSONwithCustomColumnnameandcustomvalue【发布时间】:2021-12-0902:37:04【问题描述】:我有这个代码foreach(vartableindoc.DocumentNode.SelectNodes("//table[@id=\'formTbl\']"))foreach(varrowintable.SelectNode... 查看详情

Botpress:自定义内容类型和自定义渲染

】Botpress:自定义内容类型和自定义渲染【英文标题】:Botpress:CustomContentTypeandCustomRendering【发布时间】:2019-04-2001:36:28【问题描述】:我是Botpress的新手。我刚刚安装了Botpress的最新版本“botpress-ce-v11_0_1-win-x64”。我浏览了文档... 查看详情

未找到具有自定义分页 404 的自定义分类和自定义帖子类型

】未找到具有自定义分页404的自定义分类和自定义帖子类型【英文标题】:Customtaxonomyandcustomposttypewithcustompagination404notfound【发布时间】:2014-10-2601:33:55【问题描述】:当来自General->Reading的帖子小于我的自定义分类cities(自定... 查看详情

具有自定义事件和自定义变量的 Universal Analytics 代码

】具有自定义事件和自定义变量的UniversalAnalytics代码【英文标题】:UniversalAnalyticstagwithcustomeventandcustomvariables【发布时间】:2016-06-2712:22:03【问题描述】:我想在Google跟踪代码管理器中创建一个UniversalAnalytics代码(启用增强型电... 查看详情