/ / Sottoclasse più tipi UIVIew con metodi comuni: obiettivo-c, rapido

Sottoclassi più tipi UIVIew con metodi comuni - obiettivo-c, rapido

In Objective-C / Swift, come sottoclassare più elementiUIVview con metodi comuni? Ad esempio, la sottoclasse di UILabel e UITextView in cui il metodo setText è comune. Non voglio duplicare il codice per due classi separate che ereditano rispettivamente da UILabel e UITextView. Voglio una singola classe che usa il metodo setText in modo indipendente se "self" è un UILabel o UITextView. Inoltre vorrei essere in grado di impostare questa classe in Storyboard per UILabels e UITextViews.

Grazie,

risposte:

0 per risposta № 1

Non puoi, almeno non facilmente. In Swift, puoi dichiarare un protocollo che ha un setText() metodo e quindi sottoclasse UILabel e UITextView con versioni che implementano quel protocollo. Ma perché entrambi sono UIView sottoclassi, e quindi compatibile con Objective-C, è probabilmente una migliore idea usare il metodo Objective-C [NSObject respondsToSelector:] e passare @selector(setText:) per determinare se gli oggetti sono conformi a quel metodo e, in tal caso, chiamare setText: su di essi.


0 per risposta № 2

In goal-c puoi definire un protocollo che dichiara il sottoinsieme comune di metodi o proprietà esistenti

@protocol TextViewType <NSObject>
@property(nonatomic, strong) NSString *text;
@end

Ora puoi dichiarare la conformità a questo protocollo per le classi esistenti usando categorie vuote su quelle classi

@interface UILabel (Text) <TextViewType>
@end

@interface UITextView (Text)<TextViewType>
@end

@interface UITextField (Text)<TextViewType>
@end

Questo è tutto. Ora puoi usarlo come

@property (weak, nonatomic) IBOutlet id<TextViewType> label;
@property (weak, nonatomic) IBOutlet id<TextViewType> textView;

e

[self.label setText:@"Title"];
[self.textView setText:@"Lorem Ipsum"];

In Swift questo può essere fatto in modo simile:

import UIKit

protocol TextViewType {
var text: String? { set get }
}

extension UILabel: TextViewType {}
extension UITextField : TextViewType {}

Ma non funzionerà

extension UITextView : TextViewType {}

Ciò è dovuto a diversi optional:

UILabel e UITextField possedere questa proprietà:

var text: String?

mentre UITextView possiede questo:

var text: String!

Qui puoi usare l'ereditarietà del protocollo e le estensioni del protocollo:

protocol TextViewType {
var theText: String? { set get }
}

Questo definisce l'interfaccia che vogliamo usare in seguito

protocol OptionalTextViewType: TextViewType {
var text: String? { set get }
}

Questa specializzazione di TextViewType definisce la variabile di supporto var text: String?

protocol ImplicitUnwrappedOptionalTextViewType: TextViewType {
var text: String! { set get }
}

Questa specializzazione di TextViewType definisce la variabile di supporto var text: String!

Ora possiamo aggiungere estensioni di protocollo alle specializzazioni:

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 ?? ""
}
}
}

Ora dobbiamo definire la conformità ai protocolli più specifici:

extension UILabel: OptionalTextViewType { }
extension UITextField: OptionalTextViewType {}
extension UITextView : ImplicitUnwrappedOptionalTextViewType {}

e possiamo usarlo come:

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"

come label, textView e textField sono digitati come TextViewType, solo var theText: String? è esposto.