测试已测试 | ✓ |
Lang语言 | Obj-CObjective C |
许可证 | Apache 2 |
发布最后发布 | 2017年2月 |
由 Jeff Verkoeyen 维护。
Material Motion Runtime 是一个用于声明式描述运动的工具。
这个库本身没有做太多。然而,它所做的事情是使运动作为离散的数据单元被表达,这些数据可以进行检查、组合,并通过网络发送。
这个库鼓励您以数据的形式描述运动,我们称之为 计划。计划被提交到一个 运行时。运行时负责协调 表演者(performers)的创建,它们是负责将计划转换为具体执行的对象。
导入 Material Motion Runtime 框架
@import MaterialMotionRuntime;
您现在将能够访问所有 API。
运行以下命令,检查本地的仓库副本以访问 Catalog 应用程序
git clone https://github.com/material-motion/material-motion-runtime-objc.git
cd material-motion-runtime-objc
pod install
open MaterialMotionRuntime.xcworkspace
Material Motion Runtime 由两组 API 组成:一组是运行时/事务对象,另一组是由计划和执行者类型松散组成的协议集合。
Runtime 对象是一个协调实体,其主要责任是通过创建执行者来履行计划。您可以在应用程序生命周期中的任何时候创建多个运行时。一个好规则是每个交互或过渡都使用一个运行时。
计划和执行协议分别为Material Motion Runtime定义了被视为计划或执行者所需的最小特性。
计划和执行者之间存在着共生关系。计划由它定义的执行者执行。执行者行为由提供的计划实例配置。
通过阅读Starmap了解Material Motion Runtime的更多信息。
以下步骤提供了可复制粘贴的代码片段。
创建新的计划类型时需要问自己的问题
一般规则如下
代码片段
在Objective-C中
@interface <#Plan#> : NSObject
@end
@implementation <#Plan#>
@end
在Swift中
class <#Plan#>: NSObject {
}
执行者负责执行计划。实现方式有多种
有关每种执行类型的详细信息,请参阅相关链接。
注意:每个目标类型仅创建一个执行者实例。这允许您将多个计划注册到同一目标,以便配置执行者。有关更多信息,请参阅如何使用计划配置执行者。
代码片段
在Objective-C中
@interface <#Performer#> : NSObject <MDMPerforming>
@end
@implementation <#Performer#> {
UIView *_target;
}
- (instancetype)initWithTarget:(id)target {
self = [super init];
if (self) {
assert([target isKindOfClass:[UIView class]]);
_target = target;
}
return self;
}
- (void)addPlan:(id<MDMPlan>)plan {
<#Plan#>* <#casted plan instance#> = plan;
// Do something with the plan.
}
@end
在Swift中
class <#Performer#>: NSObject, Performing {
let target: UIView
required init(target: Any) {
self.target = target as! UIView
super.init()
}
func addPlan(_ plan: Plan) {
let <#casted plan instance#> = plan as! <#Plan#>
// Do something with the plan.
}
}
遵守计划要求
代码片段
在Objective-C中
@interface <#Plan#> : NSObject <MDMPlan>
@end
@implementation <#Plan#>
- (Class)performerClass {
return [<#Plan#> class];
}
- (id)copyWithZone:(NSZone *)zone {
return [[[self class] allocWithZone:zone] init];
}
@end
在Swift中
class <#Plan#>: NSObject, Plan {
func performerClass() -> AnyClass {
return <#Performer#>.self
}
func copy(with zone: NSZone? = nil) -> Any {
return <#Plan#>()
}
}
代码片段
在Objective-C中
@interface MyClass ()
@property(nonatomic, strong) MDMRuntime* runtime;
@end
- (instancetype)init... {
...
self.runtime = [MDMRuntime new];
...
}
在Swift中
class MyClass {
let runtime = Runtime()
}
代码片段
在Objective-C中
[runtime addPlan:<#Plan instance#> to:<#View instance#>];
在Swift中
runtime.addPlan(<#Plan instance#>, to:<#View instance#>)
代码片段
在Objective-C中
@interface MyClass ()
@property(nonatomic, strong) MDMRuntime* runtime;
@end
- (instancetype)init... {
...
self.runtime = [MDMRuntime new];
...
}
在Swift中
class MyClass {
let runtime = Runtime()
}
代码片段
在Objective-C中
[runtime addPlan:<#Plan instance#> named:<#name#> to:<#View instance#>];
在Swift中
runtime.addPlan(<#Plan instance#>, named:<#name#>, to:<#View instance#>)
利用Swift的类型化switch/case语句处理多种计划类型。
func addPlan(_ plan: Plan) {
switch plan {
case let <#plan instance 1#> as <#Plan type 1#>:
()
case let <#plan instance 2#> as <#Plan type 2#>:
()
case is <#Plan type 3#>:
()
default:
assert(false)
}
}
代码片段
在Objective-C中
@interface <#Performer#> (NamedPlanPerforming) <MDMNamedPlanPerforming>
@end
@implementation <#Performer#> (NamedPlanPerforming)
- (void)addPlan:(id<MDMNamedPlan>)plan named:(NSString *)name {
<#Plan#>* <#casted plan instance#> = plan;
// Do something with the plan.
}
- (void)removePlanNamed:(NSString *)name {
// Remove any configuration associated with the given name.
}
@end
在Swift中
extension <#Performer#>: NamedPlanPerforming {
func addPlan(_ plan: NamedPlan, named name: String) {
let <#casted plan instance#> = plan as! <#Plan#>
// Do something with the plan.
}
func removePlan(named name: String) {
// Remove any configuration associated with the given name.
}
}
组合执行者能够通过计划发射器发射新的计划。这一功能使得计划的复用和高级抽象的创建成为可能。
代码片段
在Objective-C中
@interface <#Performer#> ()
@property(nonatomic, strong) id<MDMPlanEmitting> planEmitter;
@end
@interface <#Performer#> (Composition) <MDMComposablePerforming>
@end
@implementation <#Performer#> (Composition)
- (void)setPlanEmitter:(id<MDMPlanEmitting>)planEmitter {
self.planEmitter = planEmitter;
}
@end
在Swift中
// Store the emitter in your class' definition.
class <#Performer#>: ... {
...
var emitter: PlanEmitting!
...
}
extension <#Performer#>: ComposablePerforming {
var emitter: PlanEmitting!
func setPlanEmitter(_ planEmitter: PlanEmitting) {
emitter = planEmitter
}
}
执行者只能为其关联的目标发射计划。
代码片段
在Objective-C中
[self.planEmitter emitPlan:<#(nonnull id<MDMPlan>)#>];
在Swift中
emitter.emitPlan<#T##Plan#>)
执行者可能会在一段时间内或在交互活动期间执行动作。这类执行者被称为持续执行者。
持续执行者能够通过生成is-active令牌来影响运行时的活动状态。只要存在is-active令牌且未被终止,运行时就被认为处于活动状态。当与对应工作完成的令牌预期终止时,持续执行者应当终止令牌。
例如,注册平台动画的执行者可能在动画开始时生成令牌。当动画完成后,令牌会被终止。
代码片段
在Objective-C中
@interface <#Performer#> ()
@property(nonatomic, strong) id<MDMIsActiveTokenGenerating> tokenGenerator;
@end
@interface <#Performer#> (Composition) <MDMComposablePerforming>
@end
@implementation <#Performer#> (Composition)
- (void)setIsActiveTokenGenerator:(id<MDMIsActiveTokenGenerating>)isActiveTokenGenerator {
self.tokenGenerator = isActiveTokenGenerator;
}
@end
在Swift中
// Store the emitter in your class' definition.
class <#Performer#>: ... {
...
var tokenGenerator: IsActiveTokenGenerating!
...
}
extension <#Performer#>: ContinuousPerforming {
func set(isActiveTokenGenerator: IsActiveTokenGenerating) {
tokenGenerator = isActiveTokenGenerator
}
}
你可能会需要存储令牌,以便稍后引用。
代码片段
在Objective-C中
id<MDMIsActiveTokenable> token = [self.tokenGenerator generate];
tokenMap[animation] = token;
在Swift中
let token = tokenGenerator.generate()!
tokenMap[animation] = token
代码片段
在Objective-C中
[token terminate];
在Swift中
token.terminate()
跟踪允许您观察运行时内部发生的事件。这些信息可用于以下目的:
不支持其他目的的使用。
代码片段
在Objective-C中
@interface <#Custom tracer#> : NSObject <MDMTracing>
@end
@implementation <#Custom tracer#>
@end
在Swift中
class <#Custom tracer#>: NSObject, Tracing {
}
跟踪协议的文档列举了可用的方法。
代码片段
在Objective-C中
@implementation <#Custom tracer#>
- (void)didAddPlan:(id<MDMPlan>)plan to:(id)target {
}
@end
在Swift中
class <#Custom tracer#>: NSObject, Tracing {
func didAddPlan(_ plan: Plan, to target: Any) {
}
}
代码片段
在Objective-C中
[runtime addTracer:[MDMConsoleLoggingTracer new]];
在Swift中
runtime.addTracer(ConsoleLoggingTracer())
代码片段
在Objective-C中
@interface <#SomeClass#> () <MDMTimelineObserving>
@end
@implementation <#SomeClass#>
- (void)timeline:(MDMTimeline *)timeline didAttachScrubber:(MDMTimelineScrubber *)scrubber {
}
- (void)timeline:(MDMTimeline *)timeline didDetachScrubber:(MDMTimelineScrubber *)scrubber {
}
- (void)timeline:(MDMTimeline *)timeline scrubberDidScrub:(NSTimeInterval)timeOffset {
}
@end
在Swift中
extension <#SomeClass#>: TimelineObserving {
func timeline(_ timeline: Timeline, didAttach scrubber: TimelineScrubber) {
}
func timeline(_ timeline: Timeline, didDetach scrubber: TimelineScrubber) {
}
func timeline(_ timeline: Timeline, scrubberDidScrub timeOffset: TimeInterval) {
}
}
代码片段
在Objective-C中
[timeline addTimelineObserver:<#(nonnull id<MDMTimelineObserving>)#>];
在Swift中
timeline.addObserver(<#T##observer: TimelineObserving##TimelineObserving#>)
我们欢迎贡献!
查看我们的即将到来的里程碑。
根据Apache 2.0许可证授权。请参阅LICENSE获取详细信息。