Delegatii sunt un instrument util in comunicarea intre obiecte. În acest tutorial vom crea și implementa un delegat personalizat pentru a permite trei UISliders
pentru a ajusta culoarea de fundal a a ViewController
.
Mesajele din Obiectiv-C sunt o stradă cu sens unic. O clasă părinte poate trimite un mesaj copilului său, dar copilul nu poate trimite singur un mesaj părintelui său. Cu toate acestea, cu ajutorul unui delegat, se poate realiza o comunicare bidirecțională. UIScrollView
și UITableView
utilizați delegați de rutină pentru a comunica între model, vizualizare și controler. Există multe motive pentru care modelul delegat este util. Un delegat ar putea fi folosit pentru a face un obiect reutilizabil, pentru a oferi un mod flexibil de a trimite mesaje sau de a implementa personalizarea.
Lansați Xcode și faceți clic pe File> New> Project. Selectați o aplicație de vizualizare unică iOS și faceți clic pe "Next". Denumiți produsul "Delegați" și introduceți un nume pentru identificatorul companiei dvs., cum ar fi "com.companyName.delegates". Alegeți familia de dispozitive iPhone și faceți clic pe "Next". Alegeți o locație pentru stocarea proiectului și faceți clic pe "Creați".
UISlider
Faceți clic pe File> New> File și alegeți o clasă Cocoa Touch Objective-C. Denumiți clasa "MTSlider" și alegeți UISlider
din meniul derulant "Subclasa". Faceți clic pe "Următorul", apoi pe "Creați".
În primul rând trebuie să declare metodele pentru delegat. Faceți clic pe "MTSlider.h". Introduceți următorul cod deasupra interfeței.
@ class MTSlider; @protocol MTSliderDelegate@optional - (void) MTSliderDidChange: (MTSlider *) Valoarea MTSlider withValue: (CGFloat); @ cerută - (CGFloat) startPositionForMTSlider: (MTSlider *) MTSlider; @Sfârșit
Observați linia @ class MTSlider
. Prin plasarea acestui cod peste orice altceva, compilatorul este informat că la un moment dat în jos, MTSlider
vor fi declarate. Fără această directivă compilator, compilatorul vă va avertiza, deoarece se așteaptă să găsească interfața pentru MTSlider
imediat.
Metodele delegatului sunt declarate începând cu @protocol
. Protocolul MTSliderDelegate
este în conformitate cu NSObject
protocol pentru un anumit motiv. NSObject
protocol conține o metodă, respondsToSelector:
, care poate fi folosită pentru a asigura că obiectul delegat implementează o metodă opțională înainte de apelarea metodei. Apelarea unei metode care nu este implementată de obiectul delegat va determina o cerere să se prăbușească.
În mod simplu, o metodă opțională este o metodă care nu trebuie implementată de obiectul delegat; în acest caz, obiectul delegat va fi ViewController
, totuși ar putea fi orice obiect. Metoda opțională MTSliderDidChange: withValue:
este trimis în obiectul delegate atunci când valoarea cursorului se modifică.
Pe de altă parte, o metodă necesară este o metodă care trebuie implementată de către obiectul delegat sau altfel veți primi un avertisment de compilator. Metoda cerută startPositionForMTSlider:
întreabă obiectul delegatului unde ar trebui să înceapă glisoarele și își obține valoarea poziției inițiale în schimbul delegatului.
În continuare în "MTSlider.h", tastați următorul cod direct de mai jos @interface
să declare o variabilă instanță, sau ivar, pentru delegat.
idsliderDelegate;
daca tu folosesc ARC, introduceți în schimb codul următor:
__weak idsliderDelegate;
Ivarul este de tip id
astfel încât este flexibil și poate accepta orice tip de obiect. Următoarea parte, MTSliderDelegate
spune că orice obiect a ajuns să fie atribuit sliderDelegate
vor conține metodele de protocol MTSliderDelegate
ca parte a implementării proprii.
Terminați prin sintetizarea metodei setter și getter. Tastați următorul cod chiar sub variabila de închidere a variabilei de instanță.
@property (nonatomic, atribuie) idsliderDelegate;
daca tu folosesc ARC, introduceți în schimb codul următor:
@property (nonatomic, slab) idsliderDelegate;
Faceți clic pe "MTSlider.m" și introduceți următorul cod de mai jos @implementation
pentru a finaliza proprietatea.
@synthesize sliderDelegate;
Faceți clic pe fișierul "ViewController.h". Tastați codul următor pentru a vă conforma cu MTSliderDelegate
protocol și import "MTSlider.h".
#import "MTSlider.h" @interface ViewController: UIViewController
Faceți clic pe fișierul "ViewController.m" și introduceți următorul cod pentru a implementa MTSliderDelegate
metode de protocol.
- (CGFloat) startPositionForMTSlider: (MTSlider *) MTSlider - (void) MTSliderDidChange: (MTSlider *) Valoarea MTSlider withValue: (CGFloat)
Crearea unui inițializator personalizat este cheia pentru obținerea poziției de început pentru glisiere. În "MTSlider.h", adăugați următorul cod pentru a declara noul inițializator.
- (id) initWithFrame: Cadrul (CGRect) șiDelegați: (id) DelegateObject;
Faceți clic pe "MTSlider.m" și căutați initWithFrame:
metodă. Ștergeți metoda existentă și o înlocuiți cu următorul cod.
- (id) initWithFrame: Cadrul (CGRect) șiDelegați: (id) delegateObject auto = [super initWithFrame: cadru]; dacă (self) self.sliderDelegate = delegateObject; auto.value = [sliderDelegare startPositionForMTSlider: auto]; întoarce-te;
Setarea delegatului în timpul inițializării permite imediat apelarea metodei delegate. Metoda startPositionForMTSlider:
devine locația de pornire pentru glisiere. Deoarece se numește în inițializator, pozițiile glisierelor sunt setate înainte de a fi desenate pe ecran.
UISlider
Metodă UISlider
metodă SetValue: animat:
se numește automat de fiecare dată când se mișcă un clichet al culisantului. Încă în fișierul "MTSlider.m", adăugați următoarea metodă.
- (void) setValue: (float) valoare animată: (BOOL) animată [super setValue: valoare animată: animată]; dacă (sliderDelegate! = nil && [sliderDelegate răspundeToSelector: @selector (MTSliderDidChange: withValue:)]) [[auto sliderDelegate] MTSliderDidChange: self withValue: value];
Prin suprimare SetValue: animat:
de fiecare dată când se deplasează un clichet al unui glisor, este trimis un mesaj către obiectul delegat. Observați apelul la super, super setValue: animat:
. Este important să nu greșești în mod accidental ceva pe care metoda îl face în spatele scenei atunci când elimină o metodă existentă.
Metoda delegatului MTSliderDidChange: withValue:
este metoda protocolului opțional declarat mai devreme. Obiectul delegat este trimis de fiecare dată când cursorul se schimbă. Rețineți că apelarea unei metode care nu a fost implementată va cauza ca aplicația să se prăbușească. apel respondsToSelector:
pe obiectul delegat verifică că este bine să mergeți mai departe și să trimiteți mesajul metodei opționale delegate.
Faceți clic pe fișierul "ViewController.m" și introduceți codul următor viewDidLoad
pentru a seta culoarea de fundal a vederii cu patru componente de culori și pentru a crea instanțe roșu, verde și albastru MTSlider
obiecte. daca tu folosesc ARC, asigurați-vă că eliminați liniile [redSlider release];
, [eliberarea verdeSlider];
, și [release blueSlider];
deoarece aceste apeluri nu sunt necesare.
CGFloat sliderColorPosition = 0.3f; self.view.backgroundColor = [Culoarea UICcolorWithRed: sliderColorPosition verde: sliderColorPosition albastru: sliderColorPosition alpha: 1.0f]; CGRectul redSliderFrame = CGRectMake (20.0f, 20.0f, 280.0f, 28.0f); MTSlider * redSlider = [[MTSlider alin] initWithFrame: redSliderFrame șiDelegate: self]; redSlider.tag = 1; [self.view addSubview: redSlider]; [redSlider release]; CGRect verdeSliderFrame = CGRectMake (20.0f, 70.0f, 280.0f, 28.0f); MTSlider * greenSlider = [[MTSlider aliniere] initWithFrame: greenSliderFrame șiDelegate: self]; greenSlider.tag = 2; [self.view addSubview: greenSlider]; [eliberarea verdeSlider]; CGRectul blueSliderFrame = CGRectMake (20.0f, 120.0f, 280.0f, 28.0f); MTSlider * blueSlider = [[MTSlider alocare] initWithFrame: blueSliderFrame șiDelegate: self]; blueSlider.tag = 3; [self.view addSubview: blueSlider]; [release blueSlider];
Utilizând personalizarea MTSlider
initializare, initWithFrame: andDelegate:
, delegatul este setat și ViewController
obiect devine obiectul delegate al fiecărui cursor. În mod normal, s-ar putea să așteptați să vedeți un set de delegați folosind următorul cod: redSlider.sliderDelegate = sine;
. Cu toate acestea, în acest caz, atribuirea delegatului este transmisă în timpul inițializării.
Observați că proprietățile etichetei fiecărui glisor au fost setate. Inițial, culoarea de fundal a ViewController
este setat la gri închis. Pe măsură ce fiecare glisor este reglat, culoarea de fundal se va schimba în consecință, deoarece eticheta identifică ce glisor este activ.
Găsiți punerea în aplicare a startPositionForMTSlider:
, și introduceți următorul cod în interiorul brațelor pentru a seta valoarea inițială a glisoarelor la 0.3.
CGFloat sliderStartPosition = 0.3f; întoarcere sliderStartPosition;
Găsiți punerea în aplicare a MTSliderDidChange: withValue:
, și adăugați următorul cod pentru a ajusta culoarea de fundal.
dacă (MTSlider.tag == 1) // Red Slider CGColorRef bgColor = auto.view.backgroundColor.CGColor; const CGFloat * culoriPointer = CGColorGetComponents (bgColor); CGFloat currentGreen = culoriPointer [1]; CGFloat currentBlue = culoriPointer [2]; auto.view.backgroundColor = [Culoare UICcolorWithRed: valoare verde: curent albastruGreen: currentBlue alpha: 1.0f]; dacă (MTSlider.tag == 2) // Ecranul verde CGColorRef bgColor = auto.view.backgroundColor.CGColor; const CGFloat * culoriPointer = CGColorGetComponents (bgColor); CGFloat currentRed = culoriPointer [0]; CGFloat currentBlue = culoriPointer [2]; self.view.backgroundColor = [Culoarea UICcolorWithRed: curentaRed verde: valoarea albastra: currentBlue alpha: 1.0f]; dacă (MTSlider.tag == 3) // Slider albastru CGColorRef bgColor = auto.view.backgroundColor.CGColor; const CGFloat * culoriPointer = CGColorGetComponents (bgColor); CGFloat currentRed = culoriPointer [0]; CGFloat currentGreen = culoriPointer [1]; auto.view.backgroundColor = [Culoare UICcolorWithRed: curenteRed verde: curent albastruGreen: valoare alfa: 1.0f];
De fiecare dată când cursorul se schimbă, se trimite un mesaj la metoda delegatului. Mesajul conține mesajul curent MTSlider
și valoarea sa. Proprietatea tag-ului curent al cursorului este accesată pentru a determina ce glisor a trimis mesajul, iar culoarea de fundal este actualizată în consecință.
Faceți clic pe Produs> Executare sau faceți clic pe săgeata "Rulare" în colțul din stânga sus pentru a vedea glisoarele în acțiune. Reglați glisoarele pentru a vedea cum elementele copilului pot controla culoarea de fond a elementului părinte.
Există multe alte modalități de a controla culoarea de fundal a unui UIViewController
, inclusiv obiectivele sau notificările. Apple a proiectat UISlider
să utilizați un model țintă pentru a transmite date. Cu toate acestea, dacă doriți să adăugați mai multe funcționalități, cea mai bună modalitate de a comunica de la un copil la părinte este crearea unui delegat personalizat.