Creați un Player de muzică iOS Controale Player

Această serie de tutori din trei părți vă va învăța cum să construiți un player de muzică personalizat cu SDK-ul iOS. Citește mai departe!


Seria Format:

  • Setarea aplicației
  • Controale pentru music player
  • UI Theming

Bine ați venit în a doua parte a acestei serii de tutorial despre construirea unui player muzical personalizat cu SDK-ul iOS. În această parte, vom continua cu secțiunea de albume pe care am început-o în prima tranșă și vom învăța cum să jucăm piese individuale.


Pasul 1: Actualizarea Storyboard

Deschideți tabloul de bord și trageți un controler de vizualizare a tabelului din Biblioteca de obiecte pe pânză. Vom folosi acest controler de tabelă pentru a afișa un singur album. Trageți CTRL din celula din Controller de vizualizare a tabelului de albume la noul controler de vizualizare de tabel, pe care tocmai l-am adăugat și selectați "push" în secțiunea "Selection Segue" din meniul pop-up.

    

Acum vom crea celulele noastre. Prima celulă din vizualizarea tabelului va conține câteva informații despre album, cum ar fi opera de artă, artistul albumului, durata albumului și numărul de cântece din album. Cealaltă celulă va conține melodiile din album. Selectați celula și deschideți Inspectorul atributelor. Setați identificatorul la "celulă" și schimbați stilul de la "personalizat" la "subtitrare".

    

Acum, când am creat celula pentru melodii, trageți o nouă celulă de vizualizare a tabelei din Biblioteca de obiecte din partea de sus a celulei pe care tocmai l-am editat. Modificați stilul de selecție de la "Albastru" la "Niciuna" și setați identificatorul la "InfoCell". După aceea, deschideți Inspectorul de mărime și modificați Înălțimea rândului la 120.

În această celulă, vom avea nevoie de o vizualizare a imaginii pentru opera de artă și două etichete pentru informații. Deci, mai întâi trageți o imagine în celulă și modificați dimensiunea acesteia la 100x100. Modificați, de asemenea, proprietățile X și Y la 10. După aceea, glisați cele două etichete din celulă și aliniați-le ca în imaginea de mai jos:

    

Selectați prima etichetă, deschideți Inspectorul atributelor și apoi schimbați fontul la "System Bold 17.0". Apoi, ștergeți textul din ambele etichete și modificați eticheta de la prima etichetă la 101 și eticheta de la a doua etichetă la 102. În cele din urmă, selectați vizualizarea imaginii și modificați eticheta acesteia la 100. Vom folosi aceste etichete pentru a regla etichetele și vizualizarea imaginilor în tableView: cellForRowAtIndexPath: metodă.


Pasul 2: Afișați un album selectat

Accesați "Fișier"> "Nou"> "Fișier ..." pentru a crea un fișier nou. Selectați "Class-Objective-C" și apoi faceți clic pe "Next". Introduceți "AlbumViewController" pentru clasă și asigurați-vă că este o subclasă de UITableViewController și că ambele casete de selectare nu sunt selectate. Dați clic din nou pe "Următorul" și apoi faceți clic pe "Creați".

Deschideți AlbumViewController.h și modificați codul pentru a citi după cum urmează:

 #import  #import  @ interfață AlbumViewController: UITableViewController NSString * albumTitle;  @property NSString * albumTitle; @Sfârșit

Aici, în principiu, doar adăugăm cadrul MediaPlayer la controlerul nostru de vizualizare a tabelului și vom crea un NSString care va conține titlul albumului. Vom actualiza acest șir atunci când utilizatorul selectează un album.

Acum deschideți AlbumsViewController.m și adăugați următoarea linie sub #import "AlbumsViewController.h":

 #import "AlbumViewController.h"

După aceasta, adăugați următoarea metodă:

 - (void) prepareForSegue: (UIStoryboardSegue *) expeditor segue: (id) expeditor AlbumViewController * detailViewController = [segue destinationViewController]; MPMediaQuery * albumsQuery = [MPMediaQuery albumsQuery]; NSArray * albums = [albumsQuery collections]; int selectIndex = [[auto.tableView indexPathForSelectedRow] rând]; MPMediaItem * selectItem = [[albums objectAtIndex: selectedIndex] representativeItem]; NSString * albumTitle = [selectată valoare pentruFerProperty: MPMediaItemPropertyAlbumTitle]; [detailViewController setAlbumTitle: albumTitle]; 

Aici trecem titlul albumului selectat la detailViewController, care este albumulViewController. Tabloul de bord va numi această metodă în timpul rulării când declanșezi o segmente în scena curentă (adică atunci când utilizatorul selectează un album).

Deschideți acum AlbumViewController.m și adăugați următoarea linie sub @implementation:

 @synthesize albumTitle;

După aceea, mergeți la viewDidLoad și modificați-l astfel:

 - (vid) viewDidLoad [super viewDidLoad]; self.title = albumTitle; 

Aici, setăm pur și simplu titlul barei de navigare la titlul albumului selectat.

Acum, că am creat un nou ecran pentru albumul selectat, cred că este o idee bună să testați aplicația. Faceți clic pe Construiți și executați pentru a testa aplicația. Dacă accesați fila albume și selectați un album, veți merge la un nou ecran cu o vizualizare tabelă goală, dar titlul barei de navigare ar trebui să fie același cu albumul selectat.


Pasul 3: Afișați melodiile și informațiile din album

Mergeți la numberOfSectionsInTableView: si tableView: numberOfRowsInSection: în AlbumViewController.m și modificați-le astfel:

 - (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView retur 1;  - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) secțiunea MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicați]; NSArray * albumTracks = [articole de albumeQuery]; retur [numărul albumelorTrack] +1; 

Aceste metode ar trebui să fie familiare până acum, dar după cum puteți vedea, noi am făcut ceva nou în a doua metodă. Am folosit un MPMediaPropertyPredicte. Cu un obiect MPMediaPropertyPredicte, puteți filtra o interogare. Am folosit titlul albumului pentru albumul selectat pentru valoarea filtrului și am folosit MPMediaPropertyAlbumTitle ca proprietate, astfel că interogarea noastră va conține doar albumul cu titlul albumului pe care l-a selectat utilizatorul.

Aveți posibilitatea să utilizați o mulțime de proprietăți diferite pentru un MPMediaPropertyPredicate. Puteți să le vizualizați pe toate în documentele Library Library Developer.

Vom returna numărul de melodii, plus 1. Celula suplimentară va fi pentru celula cu informații despre album.

Deoarece avem două tipuri diferite de celule, cu două înălțimi diferite, trebuie să le spunem tabelului nostru ce înălțime să utilizeze pentru ce celulă. Pentru aceasta, adăugați următoarea metodă în secțiunea numberOfRowsInSection: metodă:

 - (CGFloat) tableView: (UITableView *) tableVizualizare înălțimeForRowAtIndexPath: (NSIndexPath *) indexPath if ([indexPath row] == 0) return 120;  altceva return 44; 

Aici afirmăm tabelul nostru că prima noastră celulă cu informații despre album are o înălțime de 120 de pixeli și toate celelalte celule cu cântecele albumului au o înălțime de 44 de pixeli.

Acum vom crea patru metode diferite pentru a obține informații despre album. În prima metodă, vom obține albumul de artă al albumului selectat. În cea de-a doua metodă, vom primi artistul albumului. În a treia metodă, vom obține durata albumului și numărul de cântece din album. Și în ultima metodă, vom verifica dacă artiștii melodiilor din album sunt aceiași. Uneori melodiile dintr-un album au aceiași artiști, dar nu întotdeauna. Dacă melodiile au artiști diferiți, le afișăm în tabel, dar dacă toți artiștii sunt aceiași, nu le vom arăta, deoarece îl puteți vedea deja în prima celulă.

Vom începe cu crearea primei metode, deci adăugați următorul cod sub viewDidLoad metodă:

 - (UIImage *) getAlbumArtworkWithSize: (CGSize) albumSize MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicați]; NSArray * albumTracks = [articole de albumeQuery]; pentru (int i = 0; i < [albumTracks count]; i++)  MPMediaItem *mediaItem = [albumTracks objectAtIndex:i]; UIImage *artworkImage; MPMediaItemArtwork *artwork = [mediaItem valueForProperty: MPMediaItemPropertyArtwork]; artworkImage = [artwork imageWithSize: CGSizeMake (1, 1)]; if (artworkImage)  artworkImage = [artwork imageWithSize:albumSize]; return artworkImage;   return [UIImage imageNamed:@"No-artwork-album.png"]; 

Această metodă va returna imaginea de artă a albumului cu o anumită dimensiune. În primul rând, verificăm fiecare cântec pentru a vedea dacă are o imagine de artă. Facem acest lucru cu o dimensiune mică, deci aplicația noastră va fi rapidă. Imediat ce găsim o imagine de artă, obținem imaginea din nou cu dimensiunea corectă și returnează imaginea. După aceasta, metodele se opresc, astfel încât, dacă prima melodie conține o imagine de artă, ea returnează acea imagine și se oprește odată cu metoda. Am adăugat această metodă, deoarece uneori nu toate melodiile dintr-un album conțin o imagine de artă. Dacă metoda nu a găsit o imagine de artă, vom returna o imagine de artă implicită.

Nu am adăugat încă acea imagine de artă implicită, așa că haideți să facem acest lucru mai întâi. Descărcați codul sursă atașat la acest proiect și trageți [email protected] și Nu-opera de arta-album.png imaginile în proiect. Asigurați-vă că este bifată opțiunea "Copiați articolele în dosarul grupului de destinație (dacă este necesar)" și faceți clic pe "Terminare".

Acum adăugați următorul cod pentru a doua metodă:

 - (NSString *) getAlbumArtist MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicați]; NSArray * albumTracks = [articole de albumeQuery]; pentru (int i = 0; i < [albumTracks count]; i++)  NSString *albumArtist = [[[albumTracks objectAtIndex:0] representativeItem] valueForProperty:MPMediaItemPropertyAlbumArtist]; if (albumArtist)  return albumArtist;   return @"Unknown artist"; 

Aici procedăm la fel ca în metoda precedentă, dar de data aceasta pentru artistul albumului. Verificăm dacă fiecare melodie are deja un artist de album. Dacă are una, o vom întoarce și metoda se va opri. Dacă metoda nu găsește un artist de album, returnează șirul "Artist necunoscut".

Acum adăugați următorul cod pentru a treia metodă:

 - (NSString *) getAlbumInfo MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicați]; NSArray * albumTracks = [articole de albumeQuery]; NSString * trackCount; dacă ([albumTracks Count]> 1) trackCount = [NSString stringWithFormat: @ "% i Songs", [albumTracks Count]];  altceva trackCount = [NSString stringWithFormat: @ "1 Song"];  redare Durată = 0; pentru (MPMediaItem * piesă în albumTracks) playbackDuration + = [[track valueForProperty: MPMediaItemPropertyPlaybackDuration] longValue];  int albumMimute = (redareDurație / 60); NSString * albumDuration; dacă (albumMimute> 1) albumDuration = [NSString stringWithFormat: @ "% i Mins.", albumMimute];  altceva albumDuration = [NSString stringWithFormat: @ "1 Min."];  returnați [NSString stringWithFormat: @ "% @,% @", trackCount, albumDuration]; 

În această metodă, creăm un șir cu informații despre numărul de cântece din albumul selectat și despre durata albumului. Mai întâi, creăm interogarea noastră și adăugăm filtrul pentru titlul albumului. Apoi vom crea o matrice cu elementele din interogare. Apoi, verificăm dacă albumul are unul sau mai multe melodii. Dacă are un cântec, setăm șirul de trackCount la "1 Song" sau altfel setăm acel șir la numărul de cântece. După aceea, vom crea o variabilă pe durata albumului. Obținem durata în câteva secunde, dar pentru că vrem să le arătăm în câteva minute împărțim variabila de redareDurație cu 60. După ce am terminat, verificăm dacă albumul este mai lung de 1 minut. Dacă este adevărat, setăm șirul de durată a albumului la numărul de minute sau altfel spunem că este egal cu 1 minut. În final, vom returna un șir cu numărul de melodii și durata albumului.

Acum, că am creat primele noastre trei metode, adăugați următorul cod pentru ultima metodă:

 - (BOOL) sameArtiștii MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicați]; NSArray * albumTracks = [articole de albumeQuery]; pentru (int i = 0; i < [albumTracks count]; i++)  if ([[[[albumTracks objectAtIndex:0] representativeItem] valueForProperty:MPMediaItemPropertyArtist] isEqualToString:[[[albumTracks objectAtIndex:i] representativeItem] valueForProperty:MPMediaItemPropertyArtist]])   else  return NO;   return YES; 

În această metodă, verificăm dacă artistul pieselor este același sau nu. Utilizează o buclă pentru a verifica dacă artistul primei melodii este același cu artistul din numărul bucla curentă. Dacă valorile artistului nu sunt egale, metoda returnează NO-ul boolean, dar dacă este terminat cu bucla și nici unul dintre artiști nu este același, metodele returnează booleanul DA.

A fost o mulțime de cod, dar va oferi aplicației noastre o experiență mai bună, deci merită. Pentru a afișa informațiile despre album și melodii, trebuie să le modificăm tableview: cellForRowAtIndexPath: metodă. Mergeți la acea metodă și modificați codul după cum urmează:

 - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath dacă ([indexPath row] == 0) static NSString * CellIdentifier = @ "InfoCell"; UITableViewCell * celula = [tableView dequeueReusableCellWithIdentifier: CellIdentifier pentruIndexPath: indexPath]; UIImageView * albumArtworkImageView = (UIImageView *) [vizualizare celularăWithTag: 100]; albumArtworkImageView.image = [auto getAlbumArtworkWithSize: albumArtworkImageView.frame.size]; UILabel * albumArtistLabel = (UILabel *) [vizualizare celularăWithTag: 101]; albumulArtistLabel.text = [auto getAlbumArtist]; UILabel * albumInfoLabel = (UILabel *) [vizualizare celularăWithTag: 102]; albumInfoLabel.text = [auto getAlbumInfo]; celule retur;  altceva static NSString * CellIdentifier = @ "Cell"; UITableViewCell * celula = [tableView dequeueReusableCellWithIdentifier: CellIdentifier pentruIndexPath: indexPath]; MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicați]; NSArray * albumTracks = [articole de albumeQuery]; NSUInteger trackNumber = [[[albumTracks obiectAtIndex: (indexPath.row-1)] valueForProperty: MPMediaItemPropertyAlbumTrackNumber] unsignedIntegerValue]; dacă (trackNumber) cell.textLabel.text = [NSString șirWithFormat: @ "% i.% @", trackNumber, [[[albumTracks objectAtIndex: (indexPath.row-1)] valueItemPropertyTitle];  altceva cell.textLabel.text = [[[albumTracks objectAtIndex: (indexPath.row-1)] representativeItem] valueForProperty: MPMediaItemPropertyTitle];  dacă ([same sameArtists]) cell.detailTextLabel.text = @ "";  altceva if ([[[albumTracks objectAtIndex: (indexPath.row-1)] representativeItem] valueForProperty: MPMediaItemPropertyArtist]) cellDetailTextLabel.text = [[[albumTracks objectAtIndex: : MPMediaItemPropertyArtist];  altceva cell.detailTextLabel.text = @ "";  retur; 

Aceasta este o metodă foarte mare, dar codul nu este cu adevărat dificil. Să începem de la început.

Începeți prin a verifica ce rând pe care îl folosim. Dacă folosim primul rând, vrem să arătăm prima celulă pe care am creat-o în storyboard-ul nostru. După cum puteți vedea, folosim același CellIdentifier pe care l-am folosit pentru celula din storyboard-ul nostru. Am creat UIImageView și l-am atribuit imaginii în celula cu eticheta 100, care este, desigur, aceeași cu cea pe care am folosit-o mai devreme. După aceea, sunăm getAlbumArtworkWithSize: metoda pe care am creat-o mai devreme pentru a obține ilustrația albumului și pentru a actualiza vizualizarea imaginii pentru acea lucrare. Am folosit dimensiunea imaginii imaginii pentru dimensiunea operelor noastre de artă. După aceea, facem același lucru și pentru cele două etichete. Pentru textul primei etichete, numim getAlbumArtist și pentru a doua etichetă pe care o numim getAlbumInfo metodă.

Când nu folosim primul rând, dar altul, dorim să arătăm cântecele albumului. Aici vom crea mai întâi o interogare și vom adăuga un filtru la acea interogare și apoi vom stoca elementele acelei interogări într-un matrice. După aceasta, obținem numărul piesei din album și verificăm dacă există unul. Dacă există un număr de melodie disponibil, adăugăm că în fața titlului melodiei sau altceva vom arăta titlul piesei. După cum puteți vedea, am folosit (Indexpath.row-1) pentru indexul pieselor. Facem acest lucru, deoarece prima informație din tabel este utilizată pentru informațiile despre album.

După aceea, verificăm dacă melodiile au aceiași artiști prin apelarea sameArtists metoda pe care am creat-o mai devreme. Dacă artiștii sunt la fel, ștergem textul detaliului detaliat al celuleiTextLabel, dar dacă artiștii sunt diferiți și piesa conține un artist, setăm textul detaliatăTextLabel la artistul piesei respective.

În cele din urmă, trebuie să actualizăm clasa controlerului de vizualizare a tabelului, deschideți astfel tabloul de bord, selectați controlerul de vizualizare de tabel pe care l-am creat în acest tutorial, deschideți Inspectorul de identitate și modificați clasa la "AlbumViewController".

Acum, când ne-am umplut celulele cu informații și cântece, cred că este un moment bun pentru a testa aplicația noastră. Clic Construiți și executați pentru a testa aplicația. Dacă accesați fila albume și selectați un album, ar trebui să vedeți un tabel cu o imagine a albumului, câteva informații despre album și, bineînțeles, melodiile care se află în acel album.


Pasul 4: Redați o anumită muzică

Acum, că am creat o aplicație interesantă care arată melodiile și albumele noastre, ar fi bine dacă muzicianul nostru ar putea reda aceste melodii și albume. Deschideți tabloul de bord și glisați un controler de vizualizare din biblioteca de obiecte pe pânză. Vom folosi acest controler de vizualizare în tutorialul următor pentru a arăta piesa care se joacă acum, dar avem deja nevoie de melodii pentru a reda piesele. Trageți CTRL din cea de-a doua celulă din controlerul de vizualizare de tabelă pe care am creat-o în acest tutorial și selectați "push" în secțiunea "Selection Segue" din meniul pop-up. Acum faceți același lucru pentru celula din Controller de vizualizare a tabelului de melodii.

Deschideți SongsViewController.m și adăugați următoarea metodă:

 - (void) prepareForSegue: (UIStoryboardSegue *) expeditor segue: (id) expeditor MPMediaQuery * songsQuery = [MPMediaQuery songsQuery]; NSArray * melodii = [elemente de cânteceQuery]; int selectIndex = [[auto.tableView indexPathForSelectedRow] rând]; MPMediaItem * selectItem = [[melodii objectAtIndex: selectedIndex] representativeItem]; MPMusicPlayerController * muzicăPlayer = [MPMusicPlayerController iPodMusicPlayer]; [musicPlayer setQueueWithItemCollection: [colecția MPMediaItemCollectionWithItems: [melodiiQuery elemente]]]; [musicPlayer setNowPlayingItem: selectItem]; [play musicplayer]; 

Am folosit această metodă înainte în acest tutorial, dar de această dată îl folosim pentru a reda o piesă selectată. Mai intai creem o interogare pentru piesele noastre si punem elementele intr-un matrice. Apoi vom obține un MPMediaItem din matricea pe care am creat-o. Am folosit același index ca rândul pe care l-am selectat, astfel încât să putem folosi acest MPMediaItem mai târziu în această metodă pentru a actualiza elementul care se joacă acum. După aceea, vom crea un obiect MPMusicPlayerController și îl vom seta pe un iPodMusicPlayer. Aceasta înseamnă că aplicația noastră împărtășește starea iPod-ului și, dacă părăsim aplicația noastră, muzica va continua să fie redată. Apoi, actualizăm coada playerului muzical la elementele interogării și setăm articolul acum redat la MPMediaItem pe care l-am creat mai devreme în această metodă. În sfârșit, începem să jucăm muzica.

Acum deschideți AlbumViewController.m și adăugați următoarea metodă:

 - (void) prepareForSegue: (UIStoryboardSegue *) expeditor segue: (id) expeditor MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicați]; NSArray * albumTracks = [articole de albumeQuery]; int selectIndex = [[auto.tableView indexPathForSelectedRow] rând]; MPMediaItem * selectItem = [[albumTracks objectAtIndex: selectedIndex-1] representativeItem]; MPMusicPlayerController * muzicăPlayer = [MPMusicPlayerController iPodMusicPlayer]; [musicPlayer setQueueWithItemCollection: [colecția MPMediaItemCollectionWithItems: [albumQuery items]]; [musicPlayer setNowPlayingItem: selectItem]; [play musicplayer]; 

Aici procedăm la fel ca în metoda pe care am creat-o în SongsViewController.m, dar am stabilit coada muzicii pentru albumul selectat.

Acum, aplicația noastră poate reda melodiile, dați clic pe Build & Run pentru a testa această aplicație!


Concluzie

În această a doua parte a seriei despre construirea unui player de muzică, am abordat cum să creăm o celulă personalizată pentru o vizualizare de tabelă cu un storyboard, cum să utilizați un MPMediaPropertyPredicate și cum să redați melodiile și albumele pe care le afișăm în aplicația noastră. În următoarea și ultima parte a seriei, vom crea ecranul de redare și vom crea un design personalizat pentru interfața noastră.

Cod