Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 使用可选返回值访问UIDynamicEmbehavior中的项_Objective C_Swift - Fatal编程技术网

Objective c 使用可选返回值访问UIDynamicEmbehavior中的项

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

我想用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
}
我看到两个问题:

  • 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’。谢谢