我想在Swift中重写这个Objective-C方法。 我试图找到最佳方法。
- (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
}
我看到两个问题:
dynamicItemBehavior.items.firstObject
不是Array
,因此没有firstObject
方法
我无法退回nil
我该怎么办?
答案 0 :(得分:1)
如果函数有可能返回nil
,则函数的返回类型必须是可选。在您的情况下,将函数声明为:
func itemBehaviorForView (view:UIView) -> UIDynamicItemBehavior?
UIDynamicItemBehavior
的文档将items
声明为数组:
var items: [AnyObject]! { get }
因此您将使用数组下标表示法引用第一个对象:
dynamicItemBehavior.items[0]
当然,items
可能是空的。要在惯用的Swift中使用:
if dynamicItemBehavior is UIDynamicItemBehavior {
if let firstView = dynamicItemBehavior.items?[0] {
if firstView == view {
return dynamicItemBehavior as UIDynamicItemBehavior
}
}
}
如果if let <var>
的结果不是<var>
,...items?
的使用将绑定nil
。
答案 1 :(得分:0)
转换后的更多功能方法:
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
<强>说明:强>
Objective-C ==
将Swift中的引用与===
进行比较。
我知道最初的Objective-C算法非常渴望并且在找到匹配后立即返回。展示功能方法的表现力。
答案 2 :(得分:0)
我认为Keenle使用功能风格走在正确的轨道上。但这不是filter
的工作,这是find
的工作。它会在遇到的第一场比赛中提早停止。不幸的是,Swift目前没有为我们实现find
(与filter
不同),但我们可以添加扩展名!
与此处的其他答案不同,我不知道动画师或行为的类型。我假设行为是NSArray,如果这个假设不正确,请告诉我。
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代码,你很可能会坚持使用它。