/ / Подклас на множество типове UIVIew с общи методи - цел-c, бърза

Подклас на няколко UIVIew типа с общи методи - цел-c, бърз

В Objective-C / Swift, как да подклас множествоUIViews с общи методи? Например, подкласиране на UILabel и UITextView, където често е използван методът setText. Не искам да дублирам кода за два отделни класа, наследяващи съответно от UILabel и UITextView.Искам един клас, който използва метода setText независимо дали "self" е UILabel или UITextView.Бих искал също така да задам този клас в Storyboard за UILabels и UITextViews.

Благодаря,

Отговори:

0 за отговор № 1

Не можете, поне не лесно. В Swift можете да декларирате протокол, който има a setText() метод и след това подклас UILabel и UITextView с версии, които изпълняват този протокол. Но тъй като и двете са UIView подкласове и по този начин съвместими с Цел-С, вероятно е по-добра идея да използвате метода на Целка-С [NSObject respondsToSelector:] и влизай @selector(setText:) за да определите дали предметите съответстват на този метод и ако е така, обадете се setText: на тях.


0 за отговор № 2

В цел-в можете да определите протокол, който декларира общата подмножество на съществуващите методи или свойства

@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? е изложена.