Swift:类型转换为其他对象的对象

时间:2014-09-23 21:02:53

标签: ios swift

我创建了UIView的扩展,在UIKeyboard上为UITextField / UITextView添加UIToolbar。

extension UIView {

    public func addDoneOnKeyboardWithTarget (target : AnyObject, action : Selector) {

        //Creating UIToolbar
        var toolbar = UIToolbar()

        //Configuring toolbar
        var items = NSMutableArray()
        var nilButton = IQBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
        items.addObject(nilButton)
        var doneButton = IQBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Done, target: target, action: doneAction)
        items.addObject(doneButton)
        toolbar.items = items

        //Now typecasting self to UITextField for compilation purposes because `inputAccessoryView` is readonly for UIView. it's readwrite for UITextField and UITextView both.
        var textField : UITextField = self as UITextField   //Runtime error for UITextView

        //Setting new toolbar as inputAccessoryView
        textField.inputAccessoryView = toolbar
    }
}

它适用于UITextField,但是当我在UITextView上调用上面的函数时,它会在类型转换时崩溃。


尝试1: 我试过把它转换为Optional

var textField : UITextField? = self as? UITextField
textField?.inputAccessoryView = toolbar

现在它不会在UITextView上崩溃,但也不会在其上设置任何inputAccessoryView。当我试图打印它。它在控制台上打印nil

println(textField?.inputAccessoryView)  //It prints 'nil'

尝试2: 我试过它转换为AnyObject

var textField : AnyObject = self as AnyObject
textField.inputAccessoryView = toolbar  //Compile time error

如果我将UITextField替换为UITextView,那么显然它适用于UITextView但不适用于UITextField。

有什么建议吗?

2 个答案:

答案 0 :(得分:4)

到1,textview是没有文本字段的 到2,任何对象都没有方法inputAccessoryView
- >> swift强制执行类型安全

所以你不能只是将对象转换为他们不是

的东西

<强> BUT

来自docs:
“UIResponder类为输入视图和输入附件视图声明了两个属性:
@property(readonly,retain)UIView * inputView;
@property(readonly,retain)UIView * inputAccessoryView;“

但只读它


所以检查班级

    var xy:AnyObject!;

    if(xy.isKindOfClass(UITextField)) {
        var t = xy as UITextField;
        //...
    }
    else if(xy.isKindOfClass(UITextView)) {
        var t = xy as UITextView;
        //...
    }

答案 1 :(得分:2)

在Swift 中,您可以使用type check运算符(is)来检查实例是否属于某个子类类型。如果实例属于该子类类型,则为类型检查运算符returns true,如果不是,则为false

 let aViewInstance : UIView = UITextView()

 if aViewInstance is UITextField
 {
     // here, aViewInstance must be an instance of UITextField class & can't be nil
     print(aViewInstance)
     let textField : UITextField = aViewInstance as! UITextField
     print(textField)
 }
 else if aViewInstance is UITextView
 {
     // here, aViewInstance must be an instance of UITextView class & can't be nil
     print(aViewInstance)
     let textView : UITextView = aViewInstance as! UITextView
     print(textView)
 }
 else
 {
     print(" other object ")
 }

因此,您无需使用subclass type Swift 中的isKindOfClass类方法检查NSObject,因为isKindOfClass方法仅可用在NSObject和它的子类(所有 Objective-C 类)。在 Swift 中,可以创建一个没有基类或超类的类。 例如 -

 class BaseClass { 
 //properties and methods
 }

 let anObject : AnyObject = BaseClass()

 if anObject is BaseClass {
    print(anObject) // here, must be an instance of BaseClass, you can use it
 } else {
    print(" other object ")
 }