2014-09-23 51 views
1

我创建了UIView的扩展,在UIKeyboard上为UITextField/UITextView添加UIToolbar。Swift:将对象转换为其他对象

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: 我试过将其转换为可选

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。

有什么建议吗?

+1

一个TextView没有文本框和任何对象有没有方法inputAccessoryView - SWIFT强制类型安全 – 2014-09-23 21:13:56

+0

是的,我知道,但我应该如何克服上述问题。我将我的开源库转换为swift https://github.com/hackiftekhar/IQKeyboardManager/blob/master/IQKeyBoardManager/IQUIView%2BIQKeyboardToolbar.m见175行 – 2014-09-23 21:17:57

回答

4

1一个TextView没有文本框
至2任何物体都有inputAccessoryView
没有方法 - >> SWIFT强制类型安全

所以你不能只投对象的东西,他们不

从文档


“的UIResponder类声明了两个属性输入视图和输入附件的观点:
@property(只读,保留)UIView * inputView;
@property(只读,保留)的UIView * inputAccessoryView;”

但它是只读的,有


所以检查类

var xy:AnyObject!; 

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

是的,但是UIResponder声明它们是只读的。我无法克服这个问题。我在UIView上创建了扩展,因为它包含在UITextField和UITextView类层次结构中。对于UIView,这些属性仍然是只读的。 – 2014-09-24 13:06:33

+0

编辑一个简短的如果基于类切换[未经测试,但应] – 2014-09-24 13:19:54

+0

它工作,但如何检查我的实例是否响应'setInputAccessoryView:'然后调用'setInputAccessoryView:'这种方法? – 2014-09-24 15:47:33

2

在斯威夫特,你可以使用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,使用NSObject类的isKindOfClass方法斯威夫特因为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 ") 
}