【问题标题】:Annotation error in Swift for loop with array and UIView带有数组和 UIView 的 Swift for 循环中的注释错误
【发布时间】:2014-06-06 22:10:51
【问题描述】:

我认为将一个小的 Obj-C 库转换为 Swift 会是一个很棒的学习实验。因为我最终想在应用程序中使用这个库,所以我在这里找到了 Path 应用程序菜单示例:https://github.com/yourabi/PathMenuExample

我认为我在转换和搜索答案方面做得很好,因为我刚刚开始使用 Obj-C 和 Swift。但是现在我遇到了一个我找不到解决方案的错误。

ExpandableNavigation.swift

import Foundation
import UIKit;

class ExpandableNavigation: NSObject {

    var mainButton: UIButton;
    var menuItems: NSArray;
    var radius: CGFloat;
    var speed: CGFloat;
    var bounce: CGFloat;
    var bounceSpeed: CGFloat;
    var expanded: Bool;
    var transition: Bool;


    init(menuItems: NSArray, mainButton: UIButton, radius: CGFloat) {
            self.menuItems = menuItems;
            self.mainButton = mainButton;
            self.radius = radius;
            self.speed = 0.15;
            self.bounce = 0.225;
            self.bounceSpeed = 0.1;
            expanded = false;
            transition = false;

            super.init()

            if self.mainButton != nil {
                for view: UIView in self.menuItems {
                    view.center = self.mainButton.center;
                }

                self.mainButton.addTarget(self, action:"press", forControlEvents: UIControlEvents.TouchUpInside);
            }
    }

    func expand() -> Void {
        transition = true;

        UIView.animateWithDuration(0.15, animations: {
            self.mainButton.transform = CGAffineTransformMakeRotation(45.0 * M_PI/180)
        })

        for view: UIView in self.menuItems {
            var index: Int? = findIndex(self.menuItems, valueToFind: view);
            var oneOverCount: Float;
            if self.menuItems.count <= 1 {
                oneOverCount = 1.0;
            } else {
                oneOverCount = (1.0 / Float(self.menuItems.count - 1));
            }
            var indexOverCount: CGFloat = CGFloat(index!) * CGFloat(oneOverCount);
            var rad: CGFloat = (1.0 - CGFloat(indexOverCount)) * 90.0 * CGFloat(M_PI) / 180.0;
            var rotation: CGAffineTransform = CGAffineTransformMakeRotation(rad);
            var x: CGFloat = (self.radius + self.bounce * self.radius) * rotation.a;
            var y: CGFloat = (self.radius + self.bounce * self.radius) * rotation.c;
            var center: CGPoint = CGPointMake(view.center.x + x, view.center.y + y);
            UIView.animateWithDuration(self.speed,
                delay: self.speed * indexOverCount,
                options: UIViewAnimationOptions.CurveEaseIn,
                animations: {
                    view.center = center;
                },
                completion: {(finished: Bool) in
                    UIView.animateWithDuration(self.bounceSpeed,
                        animations: {
                            var x: CGFloat = self.bounce * self.radius * rotation.a;
                            var y: CGFloat = self.bounce * self.radius * rotation.c;
                            var center: CGPoint = CGPointMake(view.center.x + x, view.center.y + y);
                            view.center = center;
                        });
                    if view == (self.menuItems.endIndex - 1) {
                        self.expanded = true;
                        self.transition = false;
                    }
                })

        }
    }

    func collapse() -> Void {
        transition = true;

    }

    @IBAction func press(sender: AnyObject) {
        if !self.transition {
            if !self.expanded {
                self.expand();
            } else {
                self.collapse();
            }
        }
    }

    func findIndex<T: Equatable>(array: T[], valueToFind: T) -> Int? {
        for (index, value) in enumerate(array) {
            if value == valueToFind {
                return index
            }
        }
        return nil
    }
}

ExpandableNavigation.swift 出错

Error: Type annotation does not match contextual type 'AnyObject'

这个错误发生在它所说的 init() 和 expand() 方法中 for view: UIView in self.menuItems { 我尝试制作数组 UIView[] 但这会导致其他地方出现错误。

ViewController.swift - 供参考

class ViewController: UIViewController {
@IBOutlet var expandNavMainButton: UIButton;
@IBOutlet var expandNavCheckInButton: UIButton;
@IBOutlet var expandNavReviewButton: UIButton;
@IBOutlet var expandNavPhotoButton: UIButton;
@IBOutlet var expandNavStatusButton: UIButton;
var expandableNavigation: ExpandableNavigation;

init(coder aDecoder: NSCoder!) {
    var buttons: NSArray = [expandNavCheckInButton, expandNavReviewButton, expandNavPhotoButton, expandNavStatusButton];
    var myRadius: CGFloat = 120.0
    self.expandableNavigation = ExpandableNavigation(menuItems: buttons, mainButton: self.expandNavMainButton, radius: myRadius);
    super.init(coder: aDecoder)
}

【问题讨论】:

    标签: nsarray swift


    【解决方案1】:

    为了安全起见,Swift 不会为您进行任何隐式转换。它不会在没有显式转换的情况下将 AnyObject(这是 NSArray 存储的类型)转换为 UIView。您应该执行以下操作:

    for obj : AnyObject in menuItems {
        if let view = obj as? UIView {
            view.center = self.mainButton.center;
        }
    }
    

    这会循环遍历带有 AnyObject 的菜单项数组,并在将其转换为视图之前检查 obj 是否为视图。

    【讨论】:

    • 有没有更短的方法来写这个?例如,当迭代所有成员都属于给定类型的 NSSet 时。
    • 编译器似乎批准了for X in Y.allObjects as Type[],这样就解决了我的问题。
    • @bouke 请注意,即使集合中的一个对象不是“类型”类型,整个应用程序也会崩溃
    猜你喜欢
    • 2016-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多