Bygg en iOS Music Player Spiller kontroller

Denne tredelte opplæringsserien vil lære deg å bygge en tilpasset musikkspiller med iOS SDK. Les videre!


Serieformat:

  • Programoppsett
  • Music Player Controls
  • UI Theming

Velkommen til den andre delen av denne opplæringsserien om å bygge en tilpasset musikkspiller med iOS SDK. I denne delen fortsetter vi med albumavsnittet vi startet i første del, og vi lærer hvordan du spiller de enkelte sporene.


Trinn 1: Oppdaterer Storyboard

Åpne storyboardet og dra en tabellvisningskontroller fra Objektbiblioteket til lerretet. Vi bruker denne tabellvisningskontrollen til å vise et enkelt album. CTRL-dra fra cellen i Albums Table View Controller til den nye Table View Controller vi nettopp lagt til og velg "push" under "Selection Segue" -delen fra popup-menyen.

    

Nå skal vi lage våre celler. Den første cellen i tabellvisningen vil inneholde litt informasjon om albumet, for eksempel kunstverket, albumartisten, varigheten av albummet og antall sanger på albumet. Den andre cellen inneholder sangene fra albumet. Velg cellen og åpne Egenskaper inspektøren. Sett Identifier til "Cell" og endre stilen fra "Custom" til "Subtitle".

    

Nå som vi har opprettet cellen til sangene, drar du en ny tabellvisningscelle fra Objektbiblioteket på toppen av cellen vi nettopp har redigert. Endre det utvelgingsstilen fra "Blå" til "Ingen" og sett Identifier til "InfoCell". Deretter åpner du størrelsesinspektøren og endrer radens høyde til 120.

I denne cellen trenger vi en bildevisning for kunstverket og to etiketter for informasjonen. Så, først, dra en bildevisning i cellen og endre størrelsen til 100x100. Endre også X- og Y-egenskapene til 10. Etter det, dra de to etikettene i cellen og juster dem som bildet nedenfor:

    

Velg den første etiketten, åpne Egenskaper Inspektør, og endre deretter Fonten til "System Fet 17.0". Deretter sletter du teksten fra begge etikettene og endrer taggen fra den første etiketten til 101 og taggen fra den andre etiketten til 102. Endelig velger du bildevisningen og endrer etiketten til 100. Vi vil bruke disse kodene for å justere etikettene og bildevisningen i Tableview: cellForRowAtIndexPath: metode.


Trinn 2: Vis et valgt album

Gå til "File"> "New"> "File ..." for å opprette en ny fil. Velg "Objective-C class" og klikk deretter "Next". Skriv inn "AlbumViewController" for klassen, og kontroller at det er en underklasse av UITableViewController, og at begge avmerkingsboksene ikke er valgt. Klikk på "Neste" igjen og klikk på "Opprett".

Åpne AlbumViewController.h og endre koden for å lese som følger:

 #importere  #importere  @interface AlbumViewController: UITableViewController NSString * albumTitle;  @property NSString * albumTitle; @slutt

Her legger vi i utgangspunktet bare MediaPlayer-rammen til kontrollen til tabellvisningen, og vi lager en NSString som inneholder albumtittelen. Vi oppdaterer denne strengen når brukeren velger et album.

Åpne nå AlbumsViewController.m og legg til følgende linje under #import "AlbumsViewController.h":

 #import "AlbumViewController.h"

Deretter legger du til følgende metode:

 - (void) prepareForSegue: (UIStoryboardSegue *) segue sender: (id) sender AlbumViewController * detailViewController = [segue destinationViewController]; MPMediaQuery * albumsQuery = [MPMediaQuery albumsQuery]; NSArray * albums = [albumsQuery collections]; int selectedIndex = [[self.tableView indexPathForSelectedRow] rad]; MPMediaItem * selectedItem = [[album objectAtIndex: selectedIndex] representativeItem]; NSString * albumTitle = [selectedItem valueForProperty: MPMediaItemPropertyAlbumTitle]; [detailViewController setAlbumTitle: albumTitle]; 

Her passerer vi tittelen på det valgte albumet til detailViewController, som er AlbumViewController. Fortellingsbrettet kaller denne metoden ved kjøretid når du utløser en segue i den aktuelle scenen (dvs. når brukeren velger et album).

Åpne nå AlbumViewController.m og legg til følgende linje under @implementation:

 @synthesize albumTitle;

Deretter går du til viewDidLoad metode og endre den for å lese som følger:

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

Her setter vi bare tittelen på navigeringslinjen til den valgte albumtittelen.

Nå som vi har opprettet en ny skjerm for det valgte albumet, synes jeg det er en god idé å teste appen. Klikk på Bygg og kjør for å teste appen. Hvis du går til albumfanen og velger et album, går du til en ny skjerm med en tom tabellvisning, men tittelen på navigeringslinjen skal være den samme som det valgte albumet.


Trinn 3: Vis album sangene og info

Gå til numberOfSectionsInTableView: og Tableview: numberOfRowsInSection: metoder i AlbumViewController.m og endre dem til å lese som følger:

 - (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return 1;  - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) seksjon MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicate]; NSArray * albumTracks = [albumQuery-elementer]; returnere [albumtracks telling] +1; 

Disse metodene bør være kjent nå, men som du kan se gjorde vi noe nytt i den andre metoden. Vi brukte en MPMediaPropertyPredicte. Med et MPMediaPropertyPredicte-objekt kan du filtrere en forespørsel. Vi brukte albumtittelen til det valgte albumet for filterverdien, og vi brukte MPMediaPropertyAlbumTitle som egenskapen, så vår forespørsel inneholder bare albumet med tittelen på albumet brukeren valgte.

Du kan bruke mange forskjellige egenskaper for en MPMediaPropertyPredicate. Du kan se dem alle i IOS Developer Library-dokumentene.

Vi returnerer antall sanger, pluss 1. Den ekstra cellen vil være for cellen med albuminformasjonen.

Fordi vi har to forskjellige typer celler, med to forskjellige høyder, må vi fortelle tabelloversikten hvilken høyde som skal brukes til hvilken celle. For å gjøre det, legg til følgende metode under numberOfRowsInSection: metode:

 - (CGFloat) tableView: (UITableView *) tableView heightForRowAtIndexPath: (NSIndexPath *) indexPath if ([indexPath row] == 0) return 120;  ellers return 44; 

Her forteller vi vår tabellvisning at vår første celle med albuminformasjonen har en høyde på 120 piksler og alle de andre cellene med sangene i albumet har en høyde på 44 piksler.

Nå skal vi lage fire forskjellige metoder for å få litt informasjon om albumet. I den første metoden får vi albumet til det valgte albumet. I den andre metoden får vi albumartisten. I den tredje metoden får vi varigheten av albumet og antall sanger i albumet. Og i den siste metoden, vil vi sjekke om artister av sangene i albummet er de samme. Noen ganger har sangene i et album de samme artistene, men ikke alltid. Hvis sangene har forskjellige artister, viser vi dem i tabellvisningen, men hvis alle artister er de samme, vil vi ikke vise dem fordi du allerede kan se den i den første cellen.

Vi starter med å lage den første metoden, så legg til følgende kode under viewDidLoad metode:

 - (UIImage *) getAlbumArtworkWithSize: (CGSize) albumSize MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicate]; NSArray * albumTracks = [albumQuery-elementer]; for (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"]; 

Denne metoden vil returnere bildebildet til albumet med en bestemt størrelse. Først sjekker vi hver sang for å se om den har et kunstverkbilde. Vi gjør dette med en liten størrelse, så vår app blir rask. Så snart vi finner et illustrasjonsbilde, får vi det bildet igjen med riktig størrelse og returnerer bildet. Etter det stopper metodene, så hvis den første sangen inneholder et kunstverkbilde, returnerer det bildet og stopper med metoden. Vi har lagt til denne metoden, fordi noen ganger ikke alle sangene i et album inneholder et illustrasjonsbilde. Hvis metoden ikke fant et illustrasjonsbilde, returnerer vi et standard illustrasjonsbilde.

Vi har ikke lagt til det standardbildet for kunst, enda, så la oss gjøre dette først. Last ned kildekoden knyttet til dette prosjektet og dra [email protected] og No-kunstverk-album.png bilder i prosjektet. Pass på at "Kopier elementer i destinasjonsgruppens mappe (om nødvendig)" er merket og klikk "Fullfør".

Legg nå følgende kode for den andre metoden:

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

Her gjør vi det samme som i forrige metode, men denne gangen for albumartisten. Vi ser etter at hver sang allerede har en albumartist. Hvis den har en, returnerer vi den og metoden stopper. Hvis metoden ikke finner en albumartner, returnerer den strengen "Ukjent artist".

Legg nå følgende kode for vår tredje metode:

 - (NSString *) getAlbumInfo MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicate]; NSArray * albumTracks = [albumQuery-elementer]; NSString * trackCount; hvis ([albumtracks teller]> 1) trackCount = [NSString stringWithFormat: @ "% i Songs", [albumTracks count]];  else trackCount = [NSString stringWithFormat: @ "1 Song"];  lang avspillingDuration = 0; for (MPMediaItem * Spor i albumTracks) playbackDuration + = [[spor valueForProperty: MPMediaItemPropertyPlaybackDuration] longValue];  int albumMimutes = (playbackDuration / 60); NSString * albumDuration; hvis (albumMimutes> 1) albumDuration = [NSString stringWithFormat: @ "% jeg Mins.", albumMimutes];  else albumDuration = [NSString stringWithFormat: @ "1 Min."];  returnere [NSString stringWithFormat: @ "% @,% @", trackCount, albumDuration]; 

I denne metoden lager vi en streng med informasjon om antall sanger i det valgte albumet og om varigheten av albumet. Først oppretter vi spørringen og legger til filteret for albumtittelen. Deretter lager vi en matrise med elementene fra spørringen. Deretter sjekker vi om albumet har en eller flere sanger. Hvis den har en sang, setter vi trackCount-strengen til "1 Song" eller ellers setter vi den aktuelle strengen til antall sanger. Deretter lager vi en variabel for varigheten av albumet. Vi får varigheten i sekunder, men fordi vi vil vise dem i løpet av minutter, deler vi variabelen playbackDuration med 60. Når det er gjort, kontrollerer vi om albumet er lengre enn 1 minutt. Hvis det er sant, setter vi lengden på albumets varighet til antall minutter, ellers sier vi at det er lik 1 minutt. Til slutt returnerer vi en streng med sportallet og albumets varighet.

Nå som vi har opprettet våre tre første metoder, legger du til følgende kode for den siste metoden:

 - (BOOL) sameArtists MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicate]; NSArray * albumTracks = [albumQuery-elementer]; for (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; 

I denne metoden kontrollerer vi om artistene til sangene er like eller ikke. Den bruker en for sløyfe for å sjekke om kunstneren til den første sangen er den samme som kunstneren fra det nåværende sløyfenummeret. Hvis artistverdiene ikke er like, returnerer metoden det boolske NO, men hvis det er ferdig med sløyfen og ingen av artistene er de samme, returnerer metodene den boolske JA.

Det var mye kode, men det vil gi vår app en bedre opplevelse, så det er verdt. For å faktisk vise albuminformasjon og sanger må vi endre tableView: cellForRowAtIndexPath: metode. Gå til den metoden og endre koden for å lese som følger:

 - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath if ([indexPath row] == 0) statisk NSString * CellIdentifier = @ "InfoCell"; UITableViewCell * celle = [tableView dequeueReusableCellWithIdentifier: CellIdentifier forIndexPath: indexPath]; UIImageView * albumArtworkImageView = (UIImageView *) [cellevisningWithTag: 100]; albumArtworkImageView.image = [self getAlbumArtworkWithSize: albumArtworkImageView.frame.size]; UILabel * albumArtistLabel = (UILabel *) [cellevisningWithTag: 101]; albumArtistLabel.text = [self getAlbumArtist]; UILabel * albumInfoLabel = (UILabel *) [cellevisningWithTag: 102]; albumInfoLabel.text = [self getAlbumInfo]; returcelle;  ellers statisk NSString * CellIdentifier = @ "Cell"; UITableViewCell * celle = [tableView dequeueReusableCellWithIdentifier: CellIdentifier forIndexPath: indexPath]; MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicate]; NSArray * albumTracks = [albumQuery-elementer]; NSUInteger trackNumber = [[[AlbumTracks objectAtIndex: (indexPath.row-1)] valueForProperty: MPMediaItemPropertyAlbumTrackNumber] unsignedIntegerValue]; if (trackNumber) cell.textLabel.text = [NSString stringWithFormat: @ "% i.% @", trackNumber, [[[albumTracks objectAtIndex: (indexPath.row-1)] representativeItem] valueForProperty: MPMediaItemPropertyTitle]];  else cell.textLabel.text = [[[albumTracks objectAtIndex: (indexPath.row-1)] representativeItem] valueForProperty: MPMediaItemPropertyTitle];  hvis ([self sameArtists]) cell.detailTextLabel.text = @ "";  else if ([[[AlbumTracks objectAtIndex: (indexPath.row-1)] representativeItem] valueForProperty: MPMediaItemPropertyArtist]) cell.detailTextLabel.text = [[[AlbumTracks objectAtIndex: (indexPath.row-1)] representativeItem] valueForProperty : MPMediaItemPropertyArtist];  ellers cell.detailTextLabel.text = @ "";  returcelle; 

Dette er en veldig stor metode, men koden er ikke veldig vanskelig. La oss starte fra begynnelsen.

Begynn med å sjekke hvilken rad vi bruker. Hvis vi bruker den første raden, vil vi vise den første cellen vi opprettet i vår storyboard. Som du kan se, bruker vi samme CellIdentifier som vi brukte for cellen i vår storyboard. Vi opprettet UIImageView og tilordnet den til bildevisningen i cellen med merket 100, som selvfølgelig er det samme som tidligere brukt. Etter det kaller vi getAlbumArtworkWithSize: Metode vi opprettet tidligere for å få albumet, og oppdatere bildevisningen for det aktuelle bildet. Vi brukte størrelsen på bildevisningen for størrelsen på vårt kunstverk. Etter det gjør vi det samme for de to etikettene. For teksten til den første etiketten, kaller vi getAlbumArtist metode og for den andre etiketten vi kaller getAlbumInfo metode.

Når vi ikke bruker den første raden, men en annen, vil vi vise sangene i albumet. Her oppretter vi først en forespørsel og legger til et filter på det spørringen, og vi lagrer deretter elementene i det spørringen i en matrise. Etter det får vi spornummeret i albumet og sjekker om det er en. Hvis det finnes et spornummer, legger vi til det foran sangtittelen eller ellers viser vi bare tittelen på sangen. Som du kan se brukte vi (Indexpath.row-1) for indeksen av sporene. Vi gjør dette fordi den første cellen i tabellvisningen er brukt til albuminformasjonen.

Deretter sjekker vi om sangene har de samme artister ved å ringe sameArtists metode vi opprettet tidligere. Hvis artister er de samme, sletter vi teksten til cellens detaljTextLabel, men hvis artistene er forskjellige og sporet inneholder en artist, setter vi teksten til detaljTextLabel til artisten av det sporet.

Endelig trenger vi å oppdatere klassen av våre bordvisningskontroller, så åpne storyboardet, velg tabellvisningskontrollen vi opprettet i denne opplæringen, åpne identitetsinspektøren og endre klassen til "AlbumViewController".

Nå som vi har fylt cellene våre med informasjonen og sangene, synes jeg det er et godt tidspunkt å teste appen vår. Klikk Bygg og kjøre for å teste appen. Hvis du går til albumfanen og velger et album, bør du se en tabellvisning med et albumbilde, litt informasjon om albumet og selvfølgelig sangene som er i det albumet.


Trinn 4: Spill litt musikk

Nå som vi har opprettet en kul app som viser våre sanger og album, ville det være fint om vår musikkspiller faktisk kunne spille av disse sangene og albumene. Åpne storyboardet og dra en View Controller fra objektbiblioteket til lerretet. Vi skal bruke denne View Controller i neste opplæring for å vise den nåværende sangen, men vi trenger allerede segiene til å spille sporene. CTRL-dra fra den andre cellen i Table View Controller vi opprettet i denne opplæringen, og velg "push" under "Selection Segue" -delen fra popup-menyen. Gjør det samme for cellen i Song Table View Controller.

Åpne SongsViewController.m og legg til følgende metode:

 - (void) prepareForSegue: (UIStoryboardSegue *) segue sender: (id) avsender MPMediaQuery * songsQuery = [MPMediaQuery songsQuery]; NSArray * songs = [songsQuery items]; int selectedIndex = [[self.tableView indexPathForSelectedRow] rad]; MPMediaItem * selectedItem = [[sanger objectAtIndex: selectedIndex] representativeItem]; MPMusicPlayerController * musicPlayer = [MPMusicPlayerController iPodMusicPlayer]; [musicPlayer setQueueWithItemCollection: [MPMediaItemCollection collectionWithItems: [songsQuery items]]]; [musicPlayer setNowPlayingItem: selectedItem]; [musicPlayer play]; 

Vi brukte denne metoden før i denne opplæringen, men denne gangen bruker vi den til å spille et valgt spor. Først oppretter vi en forespørsel for sangene våre og legger elementene i en matrise. Da får vi en MPMediaItem fra gruppen vi opprettet. Vi brukte den samme indeksen som raden vi valgte, så vi kan bruke denne MPMediaItem senere i denne metoden for å oppdatere nåspillingen. Deretter oppretter vi et MPMusicPlayerController-objekt og setter det til en iPodMusicPlayer. Dette betyr at vår app deler iPod-tilstanden, og hvis vi avslutter vår app, fortsetter musikken. Deretter oppdaterer vi køen til musikkspilleren til elementene i spørringen, og angir spillet som nå spilles til MPMediaItem vi opprettet tidligere i denne metoden. Til slutt begynner vi å spille musikken.

Nå åpner du AlbumViewController.m og legger til følgende metode:

 - (void) prepareForSegue: (UIStoryboardSegue *) segue sender: (id) avsender MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicate]; NSArray * albumTracks = [albumQuery-elementer]; int selectedIndex = [[self.tableView indexPathForSelectedRow] rad]; MPMediaItem * selectedItem = [[albumTracks objectAtIndex: selectedIndex-1] representativeItem]; MPMusicPlayerController * musicPlayer = [MPMusicPlayerController iPodMusicPlayer]; [musicPlayer setQueueWithItemCollection: [MPMediaItemCollection collectionWithItems: [albumQuery items]]]; [musicPlayer setNowPlayingItem: selectedItem]; [musicPlayer play]; 

Her gjør vi faktisk det samme som i metoden vi opprettet i SongsViewController.m, men vi satte køen til musikkspilleren til det valgte albumet.

Nå kan vår app spille av sangene, klikk på Build & Run for å teste denne appen!


Konklusjon

I denne andre delen av serien om å bygge en musikkspiller dekket vi hvordan du lager en egendefinert celle for en tabellvisning med et storyboard, hvordan du bruker en MPMediaPropertyPredicate og hvordan du spiller sanger og album som vi viser i vår app. I neste og siste del av serien, vil vi lage skuespillet nå og lage et tilpasset grensesnittdesign for vår app.