在Objective-C / Swift中,如何使用常用方法子类化多个UIViews? 例如,子类化UILabel和UITextView,其中setText方法很常见。我不想复制分别继承自UILabel和UITextView的两个单独类的代码。如果“self”是UILabel或UITextView,我想要一个单独使用setText方法的类。此外,我希望能够在故事板中为UILabels和UITextViews设置此类。
谢谢,
答案 0 :(得分:0)
你不能,至少不容易。在Swift中,您可以声明一个具有setText()
方法的协议,然后使用实现该协议的版本将UILabel
和UITextView
子类化。但由于这两者都是UIView
子类,因而与Objective-C兼容,因此使用Objective-C方法[NSObject respondsToSelector:]
并传入@selector(setText:)
来确定对象是否更好一点符合该方法,如果是,请在其上调用setText:
。
答案 1 :(得分:0)
在objective-c中,您可以定义一个声明现有方法或属性的公共子集的协议
@protocol TextViewType <NSObject>
@property(nonatomic, strong) NSString *text;
@end
现在,您可以通过在这些类上使用空类别来声明现有类的此协议的一致性
@interface UILabel (Text) <TextViewType>
@end
@interface UITextView (Text)<TextViewType>
@end
@interface UITextField (Text)<TextViewType>
@end
那就是它。现在你可以像
一样使用它@property (weak, nonatomic) IBOutlet id<TextViewType> label;
@property (weak, nonatomic) IBOutlet id<TextViewType> textView;
和
[self.label setText:@"Title"];
[self.textView setText:@"Lorem Ipsum"];
在Swift中可以这样做:
import UIKit
protocol TextViewType {
var text: String? { set get }
}
extension UILabel: TextViewType {}
extension UITextField : TextViewType {}
但它不适用于
extension UITextView : TextViewType {}
这是因为不同的选项:
UILabel
和UITextField
拥有此属性:
var text: String?
而UITextView
拥有这个:
var text: String!
您可以在这里使用协议继承和协议扩展:
protocol TextViewType {
var theText: String? { set get }
}
这定义了我们稍后要使用的界面
protocol OptionalTextViewType: TextViewType {
var text: String? { set get }
}
TextViewType
的这种专业化定义了支持变量var text: String?
protocol ImplicitUnwrappedOptionalTextViewType: TextViewType {
var text: String! { set get }
}
TextViewType
的这种专业化定义了支持变量var text: String!
现在我们可以为专业化添加协议扩展:
extension OptionalTextViewType {
var theText: String? {
set {
self.text = newValue
}
get {
return self.text
}
}
}
extension ImplicitUnwrappedOptionalTextViewType {
var theText: String? {
set {
self.text = newValue ?? ""
}
get {
return self.text ?? ""
}
}
}
现在我们需要定义与更具体协议的一致性:
extension UILabel: OptionalTextViewType { }
extension UITextField: OptionalTextViewType {}
extension UITextView : ImplicitUnwrappedOptionalTextViewType {}
我们可以像以下一样使用它:
var label: TextViewType = UILabel(frame: CGRect(x: 0, y: 0, width: 120, height: 20))
label.theText = "Label"
var textView: TextViewType = UITextView(frame: CGRect(x: 0, y: 0, width: 120, height: 20))
textView.theText = "TextView"
var textField: TextViewType = UITextField(frame: CGRect(x: 0, y: 0, width: 120, height: 20))
textField.theText = "TextField"
label
,textView
和textField
的输入为TextViewType
,只有var theText: String?
被曝光。