Questa serie di tutorial in tre parti ti insegnerà come creare un lettore musicale personalizzato con l'SDK di iOS. Continuare a leggere!
Benvenuti alla seconda parte di questa serie di tutorial sulla costruzione di un lettore musicale personalizzato con l'SDK di iOS. In questa parte, continueremo con la sezione degli album che abbiamo iniziato nella prima puntata e impareremo come suonare le singole tracce.
Apri lo storyboard e trascina un controller di visualizzazione tabella dalla Libreria oggetti all'area di disegno. Useremo questo Controller Vista Tavolo per mostrare un singolo album. CTRL-trascina dalla cella nella vista tabella degli album Controller al nuovo controller vista tabella che abbiamo appena aggiunto e seleziona "push" nella sezione "Segmento selezione" dal menu a comparsa.
Ora creeremo le nostre celle. La prima cella nella visualizzazione tabella conterrà alcune informazioni sull'album, ad esempio l'opera d'arte, l'artista dell'album, la durata dell'album e il numero di brani dell'album. L'altra cella conterrà le canzoni dell'album. Seleziona la cella e apri l'ispettore Attributi. Imposta l'identificatore su "Cell" e cambia lo stile da "Personalizzato" a "Sottotitolo".
Ora che abbiamo creato la cella per i brani, trascina una nuova cella di visualizzazione tabella dalla Libreria oggetti sopra la cella che abbiamo appena modificato. Cambia lo stile di selezione da "Blu" a "Nessuno" e imposta l'identificatore su "InfoCell". Successivamente, apri Impostazioni dimensione e modifica l'altezza della riga su 120.
In questa cella, avremo bisogno di una visualizzazione dell'immagine per il disegno e di due etichette per l'informazione. Quindi, per prima cosa, trascina una vista immagine nella cella e modifica le sue dimensioni su 100x100. Modificare anche le proprietà X e Y su 10. Successivamente, trascinare le due etichette nella cella e allinearle come nell'immagine seguente:
Seleziona la prima etichetta, apri l'ispettore Attributi e quindi modifica il Font in "System Bold 17.0". Successivamente, elimina il testo da entrambe le etichette e modifica il tag dalla prima etichetta a 101 e il tag dalla seconda etichetta a 102. Infine, seleziona la vista dell'immagine e modifica il suo tag a 100. Utilizzeremo questi tag per regolare le etichette e la vista dell'immagine nel tableView: cellForRowAtIndexPath:
metodo.
Vai su "File"> "Nuovo"> "File ..." per creare un nuovo file. Selezionare "Classe Objective-C" e quindi fare clic su "Avanti". Inserisci "AlbumViewController" per la classe e assicurati che sia una sottoclasse di UITableViewController e che entrambe le caselle di controllo non siano selezionate. Fai nuovamente clic su "Avanti" e poi su "Crea".
Apri AlbumViewController.h e modifica il codice da leggere come segue:
#importare#importare @interface AlbumViewController: UITableViewController NSString * albumTitle; @property NSString * albumTitle; @fine
Qui, fondamentalmente aggiungiamo il framework MediaPlayer al nostro controller di visualizzazione tabella e creiamo una NSString che conterrà il titolo dell'album. Aggiorneremo questa stringa quando l'utente seleziona un album.
Ora apri AlbumViewController.m e aggiungi la seguente riga sotto #import "AlbumsViewController.h"
:
#import "AlbumViewController.h"
Successivamente, aggiungi il seguente metodo:
- (vuoto) prepareForSegue: (UIStoryboardSegue *) segue mittente: (id) mittente AlbumViewController * detailViewController = [segue destinationViewController]; MPMediaQuery * albumsQuery = [MPMediaQuery albumsQuery]; Album NSArray * = [albumsQuery collections]; int selectedIndex = [[self.tableView indexPathForSelectedRow] row]; MPMediaItem * selectedItem = [[album objectAtIndex: selectedIndex] representativeItem]; NSString * albumTitle = [selectedItem valueForProperty: MPMediaItemPropertyAlbumTitle]; [detailViewController setAlbumTitle: albumTitle];
Qui passiamo il titolo dell'album selezionato al detailViewController
, che è l'AlbumViewController. Lo storyboard chiamerà questo metodo in fase di esecuzione quando si attiva un seguito nella scena corrente (ad esempio, quando l'utente seleziona un album).
Ora apri AlbumViewController.m e aggiungi la seguente riga sotto @implementation:
@synthesize albumTitle;
Dopodiché, vai al viewDidLoad
metodo e cambiarlo per leggere come segue:
- (void) viewDidLoad [super viewDidLoad]; self.title = albumTitle;
Qui, semplicemente impostiamo il titolo della barra di navigazione sul titolo dell'album selezionato.
Ora che abbiamo creato una nuova schermata per l'album selezionato, penso che sia una buona idea testare l'app. Fai clic su Crea ed esegui per testare l'app. Se vai alla scheda album e selezioni un album, andrai a una nuova schermata con una vista tabella vuota, ma il titolo della barra di navigazione dovrebbe essere lo stesso dell'album selezionato.
Vai al numberOfSectionsInTableView:
e il tableView: numberOfRowsInSection:
metodi in AlbumViewController.m e modificarli per leggere come segue:
- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return 1; - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) section MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicate]; NSArray * albumTracks = [albumQuery items]; return [albumTracks count] +1;
Questi metodi dovrebbero essere familiari ormai, ma come puoi vedere abbiamo fatto qualcosa di nuovo nel secondo metodo. Abbiamo usato un MPMediaPropertyPredicte. Con un oggetto MPMediaPropertyPredicte, puoi filtrare una query. Abbiamo usato il titolo dell'album selezionato per il valore del filtro e abbiamo usato MPMediaPropertyAlbumTitle come proprietà, quindi la nostra query conterrà solo l'album con il titolo dell'album selezionato dall'utente.
È possibile utilizzare molte proprietà diverse per un MPMediaPropertyPredicate. Puoi visualizzarli tutti nella documentazione della libreria per sviluppatori iOS.
Restituiamo il numero di brani, più 1. La cella in più sarà per la cella con le informazioni sull'album.
Poiché abbiamo due diversi tipi di celle, con due altezze diverse, dobbiamo indicare alla nostra tabella quale altezza utilizzare per quale cella. Per fare ciò, aggiungi il seguente metodo sotto il numberOfRowsInSection:
metodo:
- (CGFloat) tableView: (UITableView *) tableView heightForRowAtIndexPath: (NSIndexPath *) indexPath if ([indexPath row] == 0) return 120; else return 44;
Qui diciamo al nostro tableview che la nostra prima cella con le informazioni sull'album ha un'altezza di 120 pixel e tutte le altre celle con le canzoni dell'album hanno un'altezza di 44 pixel.
Ora creeremo quattro metodi diversi per ottenere alcune informazioni sull'album. Nel primo metodo, otterremo le illustrazioni dell'album dell'album selezionato. Nel secondo metodo, otterremo l'artista dell'album. Nel terzo metodo, otterremo la durata dell'album e il numero di brani nell'album. E nell'ultimo metodo, controlleremo se gli artisti delle canzoni nell'album sono gli stessi. A volte le canzoni di un album hanno gli stessi artisti, ma non sempre. Se le canzoni hanno artisti diversi, li mostriamo nella tabella, ma se tutti gli artisti sono uguali, non li mostreremo perché puoi già vederli nella prima cella.
Inizieremo con la creazione del primo metodo, quindi aggiungiamo il seguente codice sotto il viewDidLoad
metodo:
- (UIImage *) getAlbumArtworkWithSize: (CGSize) albumSize MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicate]; NSArray * albumTracks = [albumQuery items]; per (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"];
Questo metodo restituirà l'immagine grafica dell'album con una dimensione specifica. Per prima cosa, controlliamo ogni canzone per vedere se ha un'immagine grafica. Lo facciamo con una piccola dimensione, quindi la nostra app sarà veloce. Non appena troviamo un'immagine grafica, otteniamo di nuovo quell'immagine con le dimensioni corrette e restituiamo l'immagine. Dopodiché, i metodi si fermano, quindi se la prima canzone contiene un'immagine grafica, restituisce quell'immagine e si ferma con il metodo. Abbiamo aggiunto questo metodo perché a volte non tutti i brani di un album contengono un'immagine grafica. Se il metodo non ha trovato un'immagine grafica, viene restituita un'immagine grafica predefinita.
Non abbiamo ancora aggiunto quell'immagine grafica predefinita, quindi facciamolo prima. Scarica il codice sorgente allegato a questo progetto e trascina il [email protected] e No-artwork-album.png immagini nel progetto. Assicurati che "Copia gli elementi nella cartella del gruppo di destinazione (se necessario)" sia selezionato e fai clic su "Fine".
Ora aggiungi il seguente codice per il secondo metodo:
- (NSString *) getAlbumArtist MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicate]; NSArray * albumTracks = [albumQuery items]; per (int i = 0; i < [albumTracks count]; i++) NSString *albumArtist = [[[albumTracks objectAtIndex:0] representativeItem] valueForProperty:MPMediaItemPropertyAlbumArtist]; if (albumArtist) return albumArtist; return @"Unknown artist";
Qui facciamo lo stesso del metodo precedente, ma questa volta per l'artista dell'album. Controlliamo se ogni canzone ha già un artista dell'album. Se ce l'ha, lo restituiamo e il metodo si ferma. Se il metodo non trova un artista dell'album, restituisce la stringa "Artista sconosciuto".
Ora aggiungi il seguente codice per il nostro terzo metodo:
- (NSString *) getAlbumInfo MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicate]; NSArray * albumTracks = [albumQuery items]; NSString * trackCount; if ([albumTracks count]> 1) trackCount = [NSString stringWithFormat: @ "% i Songs", [count di albumTracks]]; else trackCount = [NSString stringWithFormat: @ "1 Song"]; long playbackDuration = 0; for (MPMediaItem * track in albumTracks) playbackDuration + = [[track valueForProperty: MPMediaItemPropertyPlaybackDuration] longValue]; int albumMimutes = (playbackDuration / 60); NSString * albumDuration; if (albumMimutes> 1) albumDuration = [NSString stringWithFormat: @ "% i Min.", albumMimutes]; else albumDuration = [NSString stringWithFormat: @ "1 Min."]; return [NSString stringWithFormat: @ "% @,% @", trackCount, albumDuration];
In questo metodo, creiamo una stringa con informazioni sul numero di brani nell'album selezionato e sulla durata dell'album. Per prima cosa, creiamo la nostra query e aggiungiamo il filtro per il titolo dell'album. Quindi creiamo un array con gli elementi della query. Successivamente, controlliamo se l'album ha uno o più brani. Se ha una canzone, impostiamo la stringa trackCount su "1 Song" oppure impostiamo quella stringa sul numero di canzoni. Dopodiché, creiamo una variabile per la durata dell'album. Otteniamo la durata in secondi, ma poiché vogliamo mostrarli in minuti dividiamo la variabile playbackDuration di 60. Una volta fatto, controlliamo se l'album è più lungo di 1 minuto. Se è vero, impostiamo la stringa di durata dell'album sul numero di minuti altrimenti diciamo che è uguale a 1 minuto. Alla fine, restituiamo una stringa con il numero di brani e la durata dell'album.
Ora che abbiamo creato i nostri primi tre metodi, aggiungi il seguente codice per l'ultimo metodo:
- (BOOL) sameArtists MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicate]; NSArray * albumTracks = [albumQuery items]; per (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;
In questo metodo, controlliamo se l'artista delle canzoni è uguale o no. Usa un ciclo for per verificare se l'artista della prima canzone è uguale all'artista dal numero di loop corrente. Se i valori dell'artista non sono uguali, il metodo restituisce il NO booleano, ma se è terminato con il ciclo e nessuno degli artisti è lo stesso, i metodi restituiscono il valore booleano YES.
È stato un sacco di codice, ma darà alla nostra app un'esperienza migliore, quindi ne vale la pena. Per mostrare effettivamente le informazioni e le canzoni dell'album, dobbiamo modificare il file tableView: cellForRowAtIndexPath:
metodo. Vai a quel metodo e modifica il codice da leggere come segue:
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath if ([indexPath row] == 0) static NSString * CellIdentifier = @ "InfoCell"; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier forIndexPath: indexPath]; UIImageView * albumArtworkImageView = (UIImageView *) [cella viewWithTag: 100]; albumArtworkImageView.image = [self getAlbumArtworkWithSize: albumArtworkImageView.frame.size]; UILabel * albumArtistLabel = (UILabel *) [cella viewWithTag: 101]; albumArtistLabel.text = [self getAlbumArtist]; UILabel * albumInfoLabel = (UILabel *) [cella viewWithTag: 102]; albumInfoLabel.text = [self getAlbumInfo]; cella di ritorno; else static NSString * CellIdentifier = @ "Cell"; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier forIndexPath: indexPath]; MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicate]; NSArray * albumTracks = [albumQuery items]; 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]; if ([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]; else cell.detailTextLabel.text = @ ""; restituisci cella;
Questo è un metodo molto grande, ma il codice non è veramente difficile. Iniziamo dall'inizio.
Inizia controllando quale riga stiamo usando. Se stiamo usando la prima riga, vogliamo mostrare la prima cella che abbiamo creato nel nostro storyboard. Come puoi vedere, utilizziamo lo stesso CellIdentifier che abbiamo usato per la cella nel nostro storyboard. Abbiamo creato UIImageView e l'abbiamo assegnato alla visualizzazione di immagini nella cella con il tag 100, che è ovviamente lo stesso di quello usato in precedenza. Dopo ciò, chiamiamo il getAlbumArtworkWithSize:
metodo che abbiamo creato in precedenza per ottenere la grafica dell'album e aggiornare la visualizzazione dell'immagine per quella grafica. Abbiamo usato la dimensione della vista dell'immagine per la dimensione della nostra opera d'arte. Dopodiché, facciamo lo stesso per le due etichette. Per il testo della prima etichetta, chiamiamo il getAlbumArtist
metodo e per la seconda etichetta che chiamiamo il getAlbumInfo
metodo.
Quando non usiamo la prima riga, ma un'altra, vogliamo mostrare i brani dell'album. Qui prima creiamo una query e aggiungiamo un filtro a quella query, quindi archiviamo gli elementi di quella query in una matrice. Dopodiché, otteniamo il numero di traccia nell'album e controlliamo se ce n'è uno. Se è disponibile un numero di traccia, aggiungiamo che davanti al titolo del brano o semplicemente mostriamo il titolo della canzone. Come puoi vedere, abbiamo usato (Indexpath.row-1) per l'indice delle tracce. Lo facciamo perché la prima cella della vista tabella viene utilizzata per le informazioni sull'album.
Dopodiché, controlliamo se le canzoni hanno gli stessi artisti chiamando il sameArtists
metodo che abbiamo creato in precedenza. Se gli artisti sono gli stessi, cancelliamo il testo del detailTextLabel della cella, ma se gli artisti sono diversi e la traccia contiene un artista, impostiamo il testo del detailTextLabel all'artista di quella traccia.
Infine, dobbiamo aggiornare la classe del nostro controller di visualizzazione tabella, quindi apri lo storyboard, seleziona il controller di visualizzazione tabella creato in questo tutorial, apri Identity Inspector e modifica la classe in "AlbumViewController".
Ora che abbiamo riempito le nostre celle con le informazioni e le canzoni, penso che sia un buon momento per testare la nostra app. Clic Costruisci ed esegui per testare l'app. Se vai alla scheda album e selezioni un album, dovresti vedere una vista tabella con un'immagine di un album, alcune informazioni sull'album e, naturalmente, le canzoni che sono in quell'album.
Ora che abbiamo creato un'app interessante che mostra i nostri brani e album, sarebbe bello se il nostro lettore musicale potesse effettivamente riprodurre questi brani e questi album. Apri lo storyboard e trascina un controller di visualizzazione dalla libreria degli oggetti nell'area di disegno. Utilizzeremo questo View Controller nel prossimo tutorial per mostrare la canzone in riproduzione, ma abbiamo già bisogno dei segues per riprodurre i brani. Trascinare CTRL dalla seconda cella del Controller Vista tabella che abbiamo creato in questo tutorial e selezionare "push" nella sezione "Segmento di selezione" dal menu a comparsa. Ora fai lo stesso per la cella nel controller della vista tabella delle song.
Apri SongsViewController.m e aggiungi il seguente metodo:
- (vuoto) prepareForSegue: (UIStoryboardSegue *) segue mittente: (id) mittente MPMediaQuery * songsQuery = [MPMediaQuery songsQuery]; NSArray * songs = [songsQuery items]; int selectedIndex = [[self.tableView indexPathForSelectedRow] row]; MPMediaItem * selectedItem = [[songs objectAtIndex: selectedIndex] representativeItem]; MPMusicPlayerController * musicPlayer = [MPMusicPlayerController iPodMusicPlayer]; [musicPlayer setQueueWithItemCollection: [MPMediaItemCollection collectionWithItems: [songsQuery items]]]; [musicPlayer setNowPlayingItem: selectedItem]; [riproduzione di MusicPlayer];
Abbiamo usato questo metodo prima in questo tutorial, ma questa volta lo usiamo per riprodurre una traccia selezionata. Per prima cosa creiamo una query per i nostri brani e inseriamo gli elementi in un array. Quindi otteniamo un MPMediaItem dall'array che abbiamo creato. Abbiamo usato lo stesso indice della riga che abbiamo selezionato, quindi possiamo usare questo MPMediaItem più avanti in questo metodo per aggiornare l'elemento attualmente in riproduzione. Successivamente, creiamo un oggetto MPMusicPlayerController e lo impostiamo su un iPodMusicPlayer. Ciò significa che la nostra app condivide lo stato dell'iPod e se abbandoniamo la nostra app, la musica continuerà a essere riprodotta. Quindi aggiorniamo la coda del lettore musicale agli elementi della query e impostiamo l'elemento in riproduzione su MPMediaItem creato in precedenza in questo metodo. Alla fine, iniziamo a suonare la musica.
Ora apri AlbumViewController.m e aggiungi il seguente metodo:
- (vuoto) prepareForSegue: (UIStoryboardSegue *) segue mittente: (id) mittente MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumTitle forProperty: MPMediaItemPropertyAlbumTitle]; [albumQuery addFilterPredicate: albumPredicate]; NSArray * albumTracks = [albumQuery items]; int selectedIndex = [[self.tableView indexPathForSelectedRow] row]; MPMediaItem * selectedItem = [[albumTracks objectAtIndex: selectedIndex-1] representativeItem]; MPMusicPlayerController * musicPlayer = [MPMusicPlayerController iPodMusicPlayer]; [musicPlayer setQueueWithItemCollection: [MPMediaItemCollection collectionWithItems: [albumQuery items]]]; [musicPlayer setNowPlayingItem: selectedItem]; [riproduzione di MusicPlayer];
Qui in realtà facciamo lo stesso come nel metodo che abbiamo creato in SongsViewController.m, ma impostiamo la coda del musicplayer sull'album selezionato.
Ora la nostra app può riprodurre i brani, fare clic su Build & Run per testare questa app!
In questa seconda parte della serie sulla costruzione di un lettore musicale, abbiamo spiegato come creare una cella personalizzata per una tableview con uno storyboard, come utilizzare un MPMediaPropertyPredicate e come riprodurre i brani e gli album che mostriamo nella nostra app. Nella parte successiva e finale della serie, creeremo la schermata di riproduzione in corso e creeremo un design dell'interfaccia personalizzata per la nostra app.