Objective c 使用可选返回值访问UIDynamicEmbehavior中的项
我想用Swift重写这个Objective-C方法。 我正在努力找到最好的方法Objective c 使用可选返回值访问UIDynamicEmbehavior中的项,objective-c,swift,Objective C,Swift,我想用Swift重写这个Objective-C方法。 我正在努力找到最好的方法 - (UIDynamicItemBehavior*) itemBehaviourForView:(UIView*)view { for (UIDynamicItemBehavior* behaviour in _animator.behaviors) { if (behaviour.class == [UIDynamicItemBehavior class] && [b
- (UIDynamicItemBehavior*) itemBehaviourForView:(UIView*)view
{
for (UIDynamicItemBehavior* behaviour in _animator.behaviors)
{
if (behaviour.class == [UIDynamicItemBehavior class] && [behaviour.items firstObject] == view)
{
return behaviour;
}
}
return nil;
}
我写了这样的东西:
func itemBehaviorForView(view :UIView)->UIDynamicItemBehavior
{
for dynamicItemBehavior in animator.behaviors
{
if dynamicItemBehavior is UIDynamicItemBehavior && dynamicItemBehavior.items.firstObject == view
{
return dynamicItemBehavior as UIDynamicItemBehavior
}
}
return nil
}
我看到两个问题:
dynamictembehavior.items.firstObject
不是Array
,因此没有firstObject
方法nil
我应该怎么做?如果函数有可能返回
nil
,那么函数的返回类型需要是可选的。在您的情况下,将函数声明为:
func itemBehaviorForView (view:UIView) -> UIDynamicItemBehavior?
uidynamictembehavior
的文档将items
声明为一个数组,其中包含:
var items: [AnyObject]! { get }
因此,您将使用数组下标表示法引用第一个对象,如下所示:
dynamicItemBehavior.items[0]
当然,项
可能是空的。要以惯用的Swift方式处理此问题,请执行以下操作:
if dynamicItemBehavior is UIDynamicItemBehavior {
if let firstView = dynamicItemBehavior.items?[0] {
if firstView == view {
return dynamicItemBehavior as UIDynamicItemBehavior
}
}
}
如果使用
if let
将绑定
iff…项的结果?
不是nil
转换后更实用的方法:
let r = (animator.behaviors.filter { $0 is UIDynamicItemBehavior } as [UIDynamicItemBehavior])
.filter({ $0.items?[0] === view })
return r.count > 0 ? r[0] : nil
如果我们bridgeToObjectiveC()
结果利用firstObject
属性,我们甚至可以将其压缩为一行返回:
return (animator.behaviors.filter { $0 is UIDynamicItemBehavior } as [UIDynamicItemBehavior])
.filter({ $0.items?[0] === view }).bridgeToObjectiveC().firstObject as? UIDynamicItemBehavior
备注:
目标-C==
比较Swift中的参考资料与==
中的参考资料
我知道最初的Objective-C算法非常急切,一旦找到匹配项就返回。展示功能性方法的表现力。我认为基恩勒使用功能性风格是正确的。但这不是
过滤器的作业
,而是查找的作业。它将在遇到第一场比赛时提前停止。不幸的是,Swift目前没有为我们实现find
(不同于filter
),但我们可以添加扩展
与这里的其他答案不同,我不知道动画师或行为的类型。我将假设行为是一种不安全的行为,如果这种假设是错误的,请让我知道
extension NSArray {
func find(predicate: (AnyObject) -> Bool) -> AnyObject? {
for element: AnyObject in self {
if predicate(element) {
return element
}
}
return nil
}
}
现在我们只需要更新你的函数就可以使用它
func itemBehaviorForView(view: UIView) -> UIDynamicItemBehavior?
{
func predicate(object: AnyObject) -> Bool {
if let dynamicItemBehavior = object as? UIDynamicItemBehavior {
return view === dynamicItemBehavior.items?[0]
}
return false
}
return animator.behaviors.find(predicate) as? UIDynamicItemBehavior
}
我承认,最终回报声明的演员阵容有点难看。如果animator.behaviors只包含可接受返回类型的对象,我们可以避免这种情况,但由于obj-c代码的原因,您可能会被卡住。感谢您的回复,我无法在dIB上声明项目的类型。它属于UIDynamicEmbehavior类的项。因此,以前的代码不是编译的,实际上现在的问题是如何迭代未在uidynamictembehavior
is的文档中定义的项集合,将items
显示为[AnyObject]代码>。我已经更新了答案。@GoZoner,代码无法编译。引发错误:类型“AnyObject”不能隐式向下转换为“NSObject”…哪一行?尝试使用==
以任何对象查看,不会出现错误。因为我们只是将引用/指针与类实例进行比较,这对任何类型都没有问题;建议更改为“访问UIDynamicEmbehavior中的项目w/Optional Return”行为是一个数组,如果将NSArray的扩展名更改为数组,则会出现错误:类型注释与上下文类型“T”不匹配。另外,我在“返回行为.查找(谓词)为”之前添加了一行“let behaviors:Array=animator.behavies as Array”?UIDynamicEmbehavior’。谢谢