Desarrollar un reproductor de música para iOS: UI Theming
Spanish (Español) translation by CYC (you can also view the original English article)
Esta serie de tutoriales en tres partes le enseñará cómo construir un reproductor de música personalizado con el SDK de iOS. Sigue leyendo
Formato de serie:
Bienvenido a la tercera y última parte de esta serie de tutoriales sobre la creación de un reproductor de música personalizado con el SDK de iOS. En esta última entrega, terminaremos nuestra pantalla de reproducción y le daremos a nuestra aplicación un diseño personalizado con el Protocolo de Apariencia UIA . Una vez que finalice nuestro reproductor de música, se verá como el iPod predeterminado de iOS 6.



Paso 1: Añadiendo las imágenes
Descargue el código fuente adjunto a este proyecto y arrastre todas las imágenes de la carpeta titulada Imágenes Parte 3 al proyecto. Asegúrese de que la opción "Copiar elementos en la carpeta del grupo de destino (si es necesario)" esté marcada y haga clic en "Finalizar".



Paso 2: Diseña la pantalla de reproducción actual
Abra el Guión gráfico y seleccione el Controlador de vista (no la vista). Abra el inspector de atributos y seleccione la casilla de verificación "Ocultar barra inferior en empujar". También cambie la barra inferior en la sección Métricas simuladas de "Inferido" a "Ninguno". Ahora selecciona la vista y dale un fondo negro. Si está listo para eso, arrastre una vista de imagen desde la Biblioteca de objetos en la vista y configure el Modo de "Escala para rellenar" a "Ajuste de aspecto". Con estas opciones configuradas, las ilustraciones del álbum no se estirarán para ajustarse a la vista de la imagen. Ahora abra el inspector de tamaño y cambie su tamaño a 320 por 320 píxeles. También modifique el autoresizing como sigue:

Con esta configuración de tamaño automático, la imagen se mantendrá en la parte superior de la vista y no se estirará en un iPhone con una pantalla Retina de 3.5 ". Ahora arrastre otra vista de imagen a la vista actual y modifique las opciones de tamaño para que luzcan como sigue:

Con estas opciones de tamaño, la vista de la imagen se mantendrá en la parte inferior de la pantalla. Ajustamos esta opción de tamaño automático para que nuestro reproductor de música se vea bien en el nuevo iPhone 5, pero también en un iPhone o iPod touch más antiguo. Ahora abra el inspector de atributos y configure la imagen en "Music-controls-background.png".
Ahora que hemos creado el fondo para los controles, creamos los controles. Primero arrastre un control deslizante desde la Biblioteca de objetos sobre la vista de imagen que acabamos de crear. Cambie la configuración de tamaño automático, para que se vean igual que la vista de imagen de los controles. Después de eso, asigne al control deslizante un tamaño de 228 por 23 píxeles, establezca la X en 46 y establezca la Y en 470. Ahora abra el inspector de Atributos y configure el "Tinte de pista mínimo" a un color muy oscuro, por lo que es casi negro. Puede dejar el "Max Track Tint" por defecto.
Arrastre tres botones desde la Biblioteca de objetos sobre la vista de imagen de los controles, cambie su tipo a "Personalizado", elimine el texto y seleccione la casilla de verificación "Mostrar toque en resaltado". Establezca la imagen del primer botón en Previous-icon.png , la imagen del segundo botón en Play-icon.png y la imagen del tercer botón en Next-icon.png . Ahora abra el inspector de tamaño y cambie la configuración de tamaño automático para que sean iguales a las del control deslizante. Ahora cambie el tamaño y la posición de los botones de la siguiente manera:
- Botón 1: ancho: 106 altura: 47 X: 0 Y: 408
- Botón 2: ancho: 108 altura: 47 X: 106 Y: 408
- Botón 3: ancho: 106 altura: 47 X: 214 Y: 408
Ahora la interfaz de la pantalla que se está reproduciendo debería tener el siguiente aspecto:



Lo último que debemos hacer para diseñar la pantalla que se está reproduciendo ahora es agregar tres etiquetas para la información de la canción. Primero, arrastre una vista desde la Biblioteca de objetos sobre la barra de navegación. Cambie el fondo a "Borrar color", establezca el ancho en 196 píxeles y la altura en 36 píxeles. La X y la Y deberían ajustarse automáticamente. Esta vista contendrá las 3 etiquetas para los nombres de artista, título y álbum de la canción. Ahora arrastre tres etiquetas a la vista que acabamos de agregar. Borre el texto, establezca la alineación en el centro y cambie la fuente a "Sistema 12.0" de todas las etiquetas. Ahora cambie el tamaño y la posición de las etiquetas de la siguiente manera:
- Etiqueta 1: ancho: 196 altura: 12 X: 0 Y: 0
- Etiqueta 2: ancho: 196 altura: 12 X: 106 Y: 12
- Etiqueta 3: ancho: 196 altura: 12 X: 214 Y: 24
Por fin, seleccione la segunda etiqueta y cambie la fuente a "System Bold 12.0". Esta etiqueta será para el título de las canciones, por lo que con una fuente en negrita será más prominente.
Ahora que hemos terminado el diseño estándar de nuestra pantalla de reproducción, creo que es un buen momento para probar nuestra aplicación. Haga clic en Construir y Ejecutar para probar la aplicación. Reproduce una canción para ir a la pantalla de reproducción actual. Deberías poder ver los controles, pero por supuesto no funcionarán.
Paso 3: Haciendo los Outlets y Acciones
Para que nuestra pantalla de reproducción actual funcione, primero debemos crear algunos archivos nuevos. Vaya a "Archivo"> "Nuevo"> "Archivo ..." para crear un nuevo archivo. Seleccione "Clase de Objective-C" y luego haga clic en "Siguiente". Ingrese "NowPlayingViewController" para la clase y asegúrese de que sea una subclase de UIViewController y que las dos casillas de verificación no estén seleccionadas. Haga clic en "Siguiente" de nuevo y luego haga clic en "Crear".
Abra NowPlayingViewController.h y modifique el código para que lea como sigue:
1 |
#import <UIKit/UIKit.h>
|
2 |
#import <MediaPlayer/MediaPlayer.h>
|
3 |
|
4 |
@interface NowPlayingViewController : UIViewController |
5 |
{
|
6 |
|
7 |
MPMusicPlayerController *musiPlayer; |
8 |
|
9 |
IBOutlet UIImageView *artworkImageView; |
10 |
|
11 |
IBOutlet UIButton *playPauseButton; |
12 |
IBOutlet UISlider *volumeSlider; |
13 |
|
14 |
IBOutlet UILabel *artistLabel; |
15 |
IBOutlet UILabel *titleLabel; |
16 |
IBOutlet UILabel *albumLabel; |
17 |
|
18 |
|
19 |
}
|
20 |
|
21 |
@property (nonatomic, retain) MPMusicPlayerController *musicPlayer; |
22 |
|
23 |
- (IBAction)playPause:(id)sender; |
24 |
- (IBAction)nextSong:(id)sender; |
25 |
- (IBAction)previousSong:(id)sender; |
26 |
- (IBAction)volumeSliderChanged:(id)sender; |
27 |
|
28 |
- (void) registerMediaPlayerNotifications; |
29 |
|
30 |
@end
|
Aquí primero importamos el marco de MediaPlayer, luego creamos un objeto MPMusicPlayerController que usaremos para controlar la música. Después de eso, creamos algunos puntos de venta para los elementos de la interfaz y, por último, creamos las acciones.
Ahora abre el Guión gráfico y selecciona el Controlador de vistas. Abra el inspector de identidad y cambie la clase al NowPlayingViewController que acabamos de crear. Luego abra el Inspector de conexiones y conecte los enchufes de la siguiente manera:
- Conecte la salida de albumLabel a la primera etiqueta en la barra de navegación.
- Conecte la salida artistLabel a la tercera etiqueta en la barra de navegación.
- Conecte la salida artworkImageView para ampliar la vista de la imagen.
- Conecte la salida playPauseButton al botón con el icono de reproducción.
- Conecte la salida titleLabel a la segunda etiqueta en la barra de navegación.
- Conecte la salida volumeSlider al control deslizante.
Ahora conecta las acciones de la siguiente manera:
- Arrastre desde el siguiente símbolo: acción hasta el botón con el siguiente ícono y seleccione "Retocar el interior" en el menú emergente.
- Arrastre desde la acción playPause: al botón con el ícono play y seleccione "Retocar el interior" en el menú emergente.
- Arrastre desde la acción anteriorSong: al botón con el ícono anterior y seleccione "Retocar el interior" en el menú emergente.
- Arrastre desde la acción volumeSliderChanged: al control deslizante y seleccione "Valor modificado" en el menú emergente.
Paso 4: Actualizar la interfaz de usuario al cargar
Ahora que hemos configurado nuestros puntos de venta y acciones, abra NowPlayingViewController.m y agregue la siguiente línea en @implementation NowPlayingViewController :
1 |
@synthesize musicPlayer; |
A continuación, vaya al método viewDidLoad y modifique el código para que lea como sigue:
1 |
- (void)viewDidLoad |
2 |
{
|
3 |
[super viewDidLoad]; |
4 |
|
5 |
|
6 |
musicPlayer = [MPMusicPlayerController iPodMusicPlayer]; |
7 |
[self registerMediaPlayerNotifications]; |
8 |
|
9 |
|
10 |
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStyleBordered target:self action:@selector(back)]; |
11 |
self.navigationItem.leftBarButtonItem = backButton; |
12 |
|
13 |
|
14 |
artistLabel.textColor = [UIColor colorWithRed:0.278 green:0.278 blue:0.278 alpha:1.0]; |
15 |
artistLabel.shadowColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0]; |
16 |
artistLabel.shadowOffset = CGSizeMake(0, 1); |
17 |
|
18 |
titleLabel.textColor = [UIColor colorWithRed:0.278 green:0.278 blue:0.278 alpha:1.0]; |
19 |
titleLabel.shadowColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0]; |
20 |
titleLabel.shadowOffset = CGSizeMake(0, 1); |
21 |
|
22 |
albumLabel.textColor = [UIColor colorWithRed:0.278 green:0.278 blue:0.278 alpha:1.0]; |
23 |
albumLabel.shadowColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0]; |
24 |
albumLabel.shadowOffset = CGSizeMake(0, 1); |
25 |
}
|
Aquí primero configuramos nuestro controlador de reproductor de música a un iPodMusicPlayer. Básicamente, esto significa que nuestra aplicación comparte el estado del iPod y si abandonamos nuestra aplicación, la música continuará reproduciéndose. Nuestra aplicación también tendrá el modo de reproducción aleatoria y repetición.
El applicationMusicPlayer es el otro tipo. Este reproductor de música reproduce la música localmente dentro de su aplicación. Su reproductor de música puede tener un elemento de reproducción diferente a la aplicación iPod incorporada. Al salir de la aplicación, la música deja de reproducirse. Después de eso, llamamos al método registerForMediaPlayerNotifications , donde registraremos tres observadores para las notificaciones del reproductor multimedia. Vamos a crear ese método más adelante en este tutorial. A continuación, creamos un elemento del botón de la barra con el título "Atrás" y lo convertimos en el elemento del botón de la barra izquierda. Hacemos esto porque un botón de retroceso predeterminado tendrá el título del controlador de vista anterior y puede ser un título largo, que no queremos para la pantalla de reproducción actual. Por fin, cambiamos el color de las etiquetas y le damos una sombra.
A continuación, agregue los siguientes métodos en la sección viewDidLoad :
1 |
- (void) back |
2 |
{
|
3 |
[self.navigationController popViewControllerAnimated:YES]; |
4 |
}
|
5 |
|
6 |
- (void) viewWillAppear:(BOOL)animated |
7 |
{
|
8 |
[super viewWillAppear:YES]; |
9 |
|
10 |
// update control button
|
11 |
|
12 |
if ([musicPlayer playbackState] == MPMusicPlaybackStatePlaying) { |
13 |
|
14 |
[playPauseButton setImage:[UIImage imageNamed:@"Pause-icon.png"] forState:UIControlStateNormal]; |
15 |
} else { |
16 |
[playPauseButton setImage:[UIImage imageNamed:@"Play-icon.png"] forState:UIControlStateNormal]; |
17 |
}
|
18 |
|
19 |
|
20 |
// Update volume slider
|
21 |
|
22 |
[volumeSlider setValue:[musicPlayer volume]]; |
23 |
|
24 |
|
25 |
// Update now playing info
|
26 |
|
27 |
MPMediaItem *currentItem = [musicPlayer nowPlayingItem]; |
28 |
|
29 |
MPMediaItemArtwork *artwork = [currentItem valueForProperty: MPMediaItemPropertyArtwork]; |
30 |
UIImage *artworkImage = [artwork imageWithSize: CGSizeMake (320, 320)]; |
31 |
|
32 |
if (!artworkImage) { |
33 |
artworkImage = [UIImage imageNamed:@"No-artwork.png"]; |
34 |
}
|
35 |
|
36 |
[artworkImageView setImage:artworkImage]; |
37 |
|
38 |
|
39 |
NSString *titleString = [currentItem valueForProperty:MPMediaItemPropertyTitle]; |
40 |
if (titleString) { |
41 |
titleLabel.text = titleString; |
42 |
} else { |
43 |
titleLabel.text = @"Unknown title"; |
44 |
}
|
45 |
|
46 |
NSString *artistString = [currentItem valueForProperty:MPMediaItemPropertyArtist]; |
47 |
if (artistString) { |
48 |
artistLabel.text = artistString; |
49 |
} else { |
50 |
artistLabel.text = @"Unknown artist"; |
51 |
}
|
52 |
|
53 |
NSString *albumString = [currentItem valueForProperty:MPMediaItemPropertyAlbumTitle]; |
54 |
if (albumString) { |
55 |
albumLabel.text = albumString; |
56 |
} else { |
57 |
albumLabel.text = @"Unknown album"; |
58 |
}
|
59 |
|
60 |
}
|
Cuando se presiona el botón Atrás, se llama al primer método y se abrirá el controlador de vista con una animación. El segundo método se llama cada vez que aparece la vista. Utilizamos estos métodos para actualizar nuestra interfaz y la información sobre la pista de reproducción actual. Primero, actualizamos el botón de reproducción / pausa verificando si la música se está reproduciendo. A continuación, establecemos el valor del control deslizante en el volumen actual del reproductor de música. Después de eso actualizamos la vista de imagen de la obra. Si la canción actual no tiene ilustraciones, mostramos una imagen de ilustraciones predeterminada. Finalmente, creamos una NSString para almacenar el título del elemento actual, que es el elemento que se está reproduciendo. Si el elemento currentItem tiene un título, establecemos la etiqueta de título en ese título, pero si no, establecemos el título en "Título desconocido". Hacemos lo mismo para el artista y el álbum.
Paso 5: Notificación de MediaPlayer
Agregue el siguiente método bajo los métodos que acabamos de crear:
1 |
- (void) registerMediaPlayerNotifications |
2 |
{
|
3 |
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; |
4 |
|
5 |
[notificationCenter addObserver: self |
6 |
selector: @selector (handle_NowPlayingItemChanged:) |
7 |
name: MPMusicPlayerControllerNowPlayingItemDidChangeNotification |
8 |
object: musicPlayer]; |
9 |
|
10 |
[notificationCenter addObserver: self |
11 |
selector: @selector (handle_PlaybackStateChanged:) |
12 |
name: MPMusicPlayerControllerPlaybackStateDidChangeNotification |
13 |
object: musicPlayer]; |
14 |
|
15 |
[notificationCenter addObserver: self |
16 |
selector: @selector (handle_VolumeChanged:) |
17 |
name: MPMusicPlayerControllerVolumeDidChangeNotification |
18 |
object: musicPlayer]; |
19 |
|
20 |
[musicPlayer beginGeneratingPlaybackNotifications]; |
21 |
}
|
Este es el método que llamamos en el método viewDidLoadque cambiamos antes. Aquí, registramos tres observadores para las notificaciones del reproductor de medios. El primero es para el MPMusicPlayerControllerNowPlayingItemDidChangeNotification. Usaremos este método para actualizar la información actual del elemento multimedia. El segundo es para el MPMusicPlayerControllerPlaybackStateDidChangeNotification. También utilizamos este para actualizar la interfaz de usuario y para abrir el controlador de vista si el reproductor de música se detuvo. El tercero y el último es para el MPMusicPlayerControllerVolumeDidChangeNotification. Usaremos este para actualizar el valor actual del control deslizante.
Siempre que registre un observador, también debe asegurarse de eliminarlo en didReceiveMemoryWarning , así que vaya a ese método y modifíquelo para que lea como sigue:
1 |
- (void)didReceiveMemoryWarning |
2 |
{
|
3 |
[super didReceiveMemoryWarning]; |
4 |
|
5 |
[[NSNotificationCenter defaultCenter] removeObserver: self |
6 |
name: MPMusicPlayerControllerNowPlayingItemDidChangeNotification |
7 |
object: musicPlayer]; |
8 |
|
9 |
[[NSNotificationCenter defaultCenter] removeObserver: self |
10 |
name: MPMusicPlayerControllerPlaybackStateDidChangeNotification |
11 |
object: musicPlayer]; |
12 |
|
13 |
[[NSNotificationCenter defaultCenter] removeObserver: self |
14 |
name: MPMusicPlayerControllerVolumeDidChangeNotification |
15 |
object: musicPlayer]; |
16 |
|
17 |
[musicPlayer endGeneratingPlaybackNotifications]; |
18 |
}
|
A continuación, agregue el siguiente código bajo el método registerMediaPlayerNotifications :
1 |
- (void) handle_NowPlayingItemChanged: (id) notification |
2 |
{
|
3 |
|
4 |
if ([musicPlayer playbackState] != MPMusicPlaybackStateStopped) { |
5 |
MPMediaItem *currentItem = [musicPlayer nowPlayingItem]; |
6 |
|
7 |
MPMediaItemArtwork *artwork = [currentItem valueForProperty: MPMediaItemPropertyArtwork]; |
8 |
UIImage *artworkImage = [artwork imageWithSize: CGSizeMake (320, 320)]; |
9 |
|
10 |
if (!artworkImage) { |
11 |
artworkImage = [UIImage imageNamed:@"No-artwork.png"]; |
12 |
}
|
13 |
|
14 |
[artworkImageView setImage:artworkImage]; |
15 |
|
16 |
NSString *titleString = [currentItem valueForProperty:MPMediaItemPropertyTitle]; |
17 |
if (titleString) { |
18 |
titleLabel.text = titleString; |
19 |
} else { |
20 |
titleLabel.text = @"Unknown title"; |
21 |
}
|
22 |
|
23 |
NSString *artistString = [currentItem valueForProperty:MPMediaItemPropertyArtist]; |
24 |
if (artistString) { |
25 |
artistLabel.text = artistString; |
26 |
} else { |
27 |
artistLabel.text = @"Unknown artist"; |
28 |
}
|
29 |
|
30 |
NSString *albumString = [currentItem valueForProperty:MPMediaItemPropertyAlbumTitle]; |
31 |
if (albumString) { |
32 |
albumLabel.text = albumString; |
33 |
} else { |
34 |
albumLabel.text = @"Unknown album"; |
35 |
}
|
36 |
|
37 |
}
|
38 |
}
|
Este método responderá a la notificación MPMusicPlayerControllerNowPlayingItemDidChangeNotification. El código que usamos para este método ya debería estar familiarizado, ya que casi usamos el mismo código para el método viewWillAppear . Lo único que agregamos aquí es la primera sentencia if. En esa declaración if, verificamos si el reproductor de música no está detenido, por lo que el código solo se ejecutará cuando el reproductor de música esté en reproducción o en pausa. Hacemos esto porque cuando el reproductor de música se detiene, el controlador de vista se abrirá con una animación y todavía queremos ver la información sobre la última pista reproducida cuando la animación está ocupada.
Agregue el siguiente código bajo el método handle_NowPlayingItemChanged :
1 |
- (void) handle_PlaybackStateChanged: (id) notification |
2 |
{
|
3 |
MPMusicPlaybackState playbackState = [musicPlayer playbackState]; |
4 |
|
5 |
if (playbackState == MPMusicPlaybackStatePaused) { |
6 |
[playPauseButton setImage:[UIImage imageNamed:@"Play-icon.png"] forState:UIControlStateNormal]; |
7 |
|
8 |
|
9 |
} else if (playbackState == MPMusicPlaybackStatePlaying) { |
10 |
[playPauseButton setImage:[UIImage imageNamed:@"Pause-icon.png"] forState:UIControlStateNormal]; |
11 |
|
12 |
} else if (playbackState == MPMusicPlaybackStateStopped) { |
13 |
|
14 |
[playPauseButton setImage:[UIImage imageNamed:@"Play-icon.png"] forState:UIControlStateNormal]; |
15 |
[musicPlayer stop]; |
16 |
|
17 |
[self.navigationController popViewControllerAnimated:YES]; |
18 |
|
19 |
}
|
20 |
|
21 |
}
|
Este método responderá a la notificación MPMusicPlayerControllerPlaybackStateDidChangeNotification. Aquí comprobamos el estado del reproductor de música y actualizamos la imagen del botón PlayPauseButton. Como puede ver, detenemos el reproductor de música si el estado es MPMusicPlaybackStateStopped . Hacemos esto para asegurarnos de que el reproductor de música reproduzca su cola desde el principio. También abrimos el controlador de vista cuando el reproductor de música se detiene, para que el usuario pueda seleccionar una nueva canción para reproducir.
Por último, agregue el siguiente código bajo el método handle_PlaybackStateChanged :
1 |
- (void) handle_VolumeChanged: (id) notification |
2 |
{
|
3 |
[volumeSlider setValue:[musicPlayer volume]]; |
4 |
}
|
Este método responderá a la notificación MPMusicPlayerControllerVolumeDidChangeNotification. Aquí actualizamos el control deslizante de volumen al volumen del reproductor de música. Hacemos esto porque también podemos ajustar el volumen con los botones de hardware.
Paso 6: Hacer que los controles funcionen
Agregue el siguiente código en la sección didReceiveMemoryWarning :
1 |
- (IBAction)playPause:(id)sender |
2 |
{
|
3 |
if ([musicPlayer playbackState] == MPMusicPlaybackStatePlaying) { |
4 |
[musicPlayer pause]; |
5 |
|
6 |
} else { |
7 |
[musicPlayer play]; |
8 |
}
|
9 |
}
|
10 |
|
11 |
- (IBAction)nextSong:(id)sender |
12 |
{
|
13 |
[musicPlayer skipToNextItem]; |
14 |
}
|
15 |
|
16 |
- (IBAction)previousSong:(id)sender |
17 |
{
|
18 |
[musicPlayer skipToPreviousItem]; |
19 |
}
|
20 |
|
21 |
- (IBAction)volumeSliderChanged:(id)sender |
22 |
{
|
23 |
[musicPlayer setVolume:volumeSlider.value]; |
24 |
}
|
En la primera acción, comprobamos si el reproductor de música está reproduciendo. Si se está reproduciendo, haremos una pausa en el reproductor de música. Si no está tocando, empezamos por tocar la música.
En la segunda acción, dejamos que el reproductor de música salte al siguiente elemento y en la tercera acción dejamos que el reproductor de música salte al elemento anterior.
En la cuarta y última acción, configuramos el volumen del reproductor de música al valor del control deslizante.
La pantalla de reproducción actual está completa. A continuación, probemos nuestra aplicación antes de comenzar a darle a nuestro reproductor de música un diseño personalizado. Haga clic en Construir y Ejecutar para probar la aplicación. Ahora todos los controles en la pantalla de reproducción actual deberían funcionar y debería ver la información sobre la pista actual. Las etiquetas ahora son bastante feas, pero se verán muy bien con nuestro diseño personalizado.
Paso 7: Hacer que la barra de estado sea negra
En iOS 6, la barra de estado es por defecto el mismo color que la barra de navegación. Debido a que nuestro reproductor de música tendrá un diseño que se parece al iPod incorporado, cambiaremos la barra de estado a negro.
En el área del navegador, seleccione el nombre del proyecto (en caso de "Música"). A continuación, seleccione el objetivo actual ("Música" aquí nuevamente), y luego seleccione la pestaña "Resumen". Desplácese hasta la "Información de implementación del iPhone / iPod" y luego vaya a las opciones de la "Barra de estado". Cambie el estilo de "Predeterminado" a "Opaco negro" y ahora nuestra barra de estado es negra.



Paso 8: Personalizando la barra de navegación
Desde el lanzamiento de iOS, puede personalizar ciertos aspectos de los componentes UIKit estándar con el Protocolo de Apariencia UIA. Usaremos esto para establecer una imagen de fondo personalizada para nuestra barra de navegación y para cambiar sus propiedades de texto.
Abra AppDelegate.m y agregue el siguiente código debajo de la aplicación: didFinishWithLaunchingOptions:método:
1 |
- (void) createCustomUI |
2 |
{
|
3 |
UIImage *navBarImage = [UIImage imageNamed:@"Navigation-bar.png"]; |
4 |
[[UINavigationBar appearance] setBackgroundImage:navBarImage forBarMetrics:UIBarMetricsDefault]; |
5 |
|
6 |
[[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: |
7 |
[UIColor colorWithRed:0.278 green:0.278 blue:0.278 alpha:1.0], |
8 |
UITextAttributeTextColor, |
9 |
[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0], |
10 |
UITextAttributeTextShadowColor, |
11 |
[NSValue valueWithUIOffset:UIOffsetMake(0, 1)], |
12 |
UITextAttributeTextShadowOffset, |
13 |
nil]]; |
14 |
|
15 |
|
16 |
}
|
Aquí estamos configurando navBarImage como una imagen de fondo predeterminada para todas las barras de navegación. Después de eso, actualizamos el color del texto, el color de la sombra del texto y el desplazamiento de la sombra del texto para todas las barras de navegación.
Ahora vaya a la aplicación: didFinishWithLaunchingOptions: método y modifíquelo para que lea como sigue:
1 |
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions |
2 |
{
|
3 |
[self createCustomUI]; |
4 |
|
5 |
return YES; |
6 |
}
|
Aquí acabamos de añadir [self createCustomUI]; para llamar al método createCustomUI .
Construye y ejecuta la aplicación. Todas las barras de navegación ahora deben ser grises con un título gris oscuro. Si vas a la sección de álbumes y seleccionas un álbum, verás que el botón Atrás sigue siendo azul. Vamos a arreglar esto en un momento.
Vaya al método createCustomUI y agregue el siguiente código:
1 |
UIImage *backButton = [[UIImage imageNamed:@"Nav-bar-back-button.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 6)]; |
2 |
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButton forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; |
3 |
|
4 |
UIImage *backButtonHighlited = [[UIImage imageNamed:@"Nav-bar-back-button-highlited.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 6)]; |
5 |
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonHighlited forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault]; |
6 |
|
7 |
UIImage *navButton = [[UIImage imageNamed:@"Nav-button.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 6, 0, 6)]; |
8 |
[[UIBarButtonItem appearance] setBackgroundImage:navButton forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; |
9 |
|
10 |
UIImage *navButtonHighlited = [[UIImage imageNamed:@"Nav-button-highlited.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 6, 0, 6)]; |
11 |
[[UIBarButtonItem appearance] setBackgroundImage:navButtonHighlited forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault]; |
12 |
|
13 |
[[UIBarButtonItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: |
14 |
[UIColor colorWithRed:0.278 green:0.278 blue:0.278 alpha:1.0], |
15 |
UITextAttributeTextColor, |
16 |
[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0], |
17 |
UITextAttributeTextShadowColor, |
18 |
[NSValue valueWithUIOffset:UIOffsetMake(0, 1)], |
19 |
UITextAttributeTextShadowOffset, |
20 |
nil] forState:UIControlStateNormal]; |
21 |
|
22 |
[[UIBarButtonItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: |
23 |
[UIColor colorWithRed:0.278 green:0.278 blue:0.278 alpha:1.0], |
24 |
UITextAttributeTextColor, |
25 |
[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0], |
26 |
UITextAttributeTextShadowColor, |
27 |
[NSValue valueWithUIOffset:UIOffsetMake(0, 1)], |
28 |
UITextAttributeTextShadowOffset, |
29 |
nil] forState:UIControlStateHighlighted]; |
Aquí en realidad hacemos lo mismo que hicimos para la barra de navegación, pero hay algunos cambios significativos. Para el botón de la barra de navegación y el botón Atrás podemos establecer una imagen para cada estado diferente. Como puede ver, cambiamos las imágenes para UIControlStateNormal y UIControlStateHighlighted . También hicimos el tamaño de la imagen para que las esquinas siempre se vean bien
Paso 9: Personalizando la barra de pestañas
A continuación, agregue el siguiente código al método createCustomUI :
1 |
[[UITabBar appearance] setBackgroundImage:[UIImage imageNamed:@"Tab-bar.png"]]; |
2 |
[[UITabBar appearance] setSelectionIndicatorImage:[UIImage imageNamed:@"Tab-bar-selected.png"]]; |
3 |
|
4 |
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: |
5 |
[UIColor colorWithRed:0.278 green:0.278 blue:0.278 alpha:1.0], |
6 |
UITextAttributeTextColor, |
7 |
[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0], |
8 |
UITextAttributeTextShadowColor, |
9 |
[NSValue valueWithUIOffset:UIOffsetMake(0, 1)], |
10 |
UITextAttributeTextShadowOffset, |
11 |
nil] forState:UIControlStateNormal]; |
Aquí actualizamos la barra de pestañas para su imagen de fondo y la imagen para la pestaña seleccionada. También actualizamos los atributos del texto del título, por lo que serán de color gris oscuro y tendrán una sombra blanca en la parte inferior.
Paso 10: Personalizando la vista de tabla
Finalmente, agregue el siguiente código al método createCustomUI :
1 |
[[UITableView appearance] setBackgroundColor:[UIColor colorWithRed:0.914 green:0.918 blue:0.925 alpha:1.0]]; |
2 |
[[UITableView appearance] setSeparatorStyle:UITableViewCellSeparatorStyleNone]; |
Aquí le damos a todas las vistas de tabla un fondo gris claro y eliminamos la línea separadora gris.
Haga clic en Construir y Ejecutar para probar la aplicación. El diseño de la aplicación se verá muy diferente, pero todavía hay algunas cosas más que debemos hacer.
Paso 11: Agregar imágenes a la barra de pestañas
Abra SongsViewController.m y modifique el código para que lea como sigue:
1 |
- (void)viewDidLoad |
2 |
{
|
3 |
[super viewDidLoad]; |
4 |
|
5 |
UITabBarItem *item1 = [[self.tabBarController.tabBar items] objectAtIndex:0]; |
6 |
[item1 setFinishedSelectedImage:[UIImage imageNamed:@"Songs-tab-bar-icon.png"] withFinishedUnselectedImage:[UIImage imageNamed:@"Songs-tab-bar-icon.png"]]; |
7 |
|
8 |
UITabBarItem *item2 = [[self.tabBarController.tabBar items] objectAtIndex:1]; |
9 |
[item2 setFinishedSelectedImage:[UIImage imageNamed:@"Albums-tab-bar-icon.png"] withFinishedUnselectedImage:[UIImage imageNamed:@"Albums-tab-bar-icon.png"]]; |
10 |
|
11 |
}
|
Aquí primero creamos un elemento de la barra de pestañas a partir de la matriz de todos los elementos del controlador de la barra de pestañas. Como tenemos 2 pestañas, usamos los índices 0 y 1. Después de eso, actualizamos las imágenes seleccionadas y no seleccionadas de los elementos de la barra de pestañas a la misma imagen.
Aquí personalizamos los elementos de la barra de pestañas, porque queremos una imagen diferente para cada elemento de la barra de pestañas y no podemos recibir la matriz de elementos de la barra de pestañas en AppDelegate.
Paso 12: Personaliza las celdas de la vista de tabla
A continuación, vaya al método tableView: cellForRowAtIndexPath: y agregue el siguiente código sobre la celda de retorno:
1 |
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Table-view-background.png"]]; |
2 |
|
3 |
cell.textLabel.textColor = [UIColor colorWithRed:0.278 green:0.278 blue:0.278 alpha:1.0]; |
4 |
|
5 |
cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Table-view-selected-background.png"]]; |
6 |
|
7 |
cell.textLabel.backgroundColor = [UIColor clearColor]; |
8 |
cell.detailTextLabel.backgroundColor = [UIColor clearColor]; |
Aquí primero actualizamos la vista de fondo de la celda a una imagen personalizada. Luego cambiamos el color del texto de la etiqueta del texto a un color gris oscuro. Después de eso, actualizamos la vista de fondo para cuando se selecciona la celda a una imagen personalizada y, por último, configuramos el color de fondo de las etiquetas para borrar el color, porque el color de fondo predeterminado es blanco.
Haga lo mismo para el método tableView: cellForRowAtIndexPath: en el archivo AlbumsViewController.m y para las celdas de la canción en el archivo AlbumViewController.m. Ahora agregue el siguiente código a la celda de información del álbum en el archivo AlbumViewController.m:
1 |
albumArtistLabel.textColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:1.0]; |
2 |
albumInfoLabel.textColor = [UIColor colorWithRed:0.35 green:0.35 blue:0.35 alpha:1.0]; |
3 |
|
4 |
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Table-view-album-background.png"]]; |
Aquí le damos a las etiquetas un color gris y la celda una imagen personalizada como vista de fondo.
A continuación, abra el guión gráfico y seleccione la celda en el controlador de vista de tabla de canciones. Abra el inspector de atributos y cambie el tipo de accesorio de "Indicador de divulgación" a "Ninguno". Haga lo mismo para la celda en el controlador de vista de álbum.
Ahora que hemos terminado el diseño y nuestro reproductor de música parece el iPod incorporado, creo que es un buen momento para probar nuestra aplicación. Haga clic en Construir y Ejecutar para probar la aplicación.
Nuestro reproductor de música está casi terminado, pero hay una última cosa que hacer. Todavía no podemos ir a la pantalla que se está reproduciendo sin seleccionar una nueva canción. Agregaremos un botón en la barra de navegación para ir a la pantalla que se está reproduciendo. Este botón solo será visible cuando el reproductor de música no esté parado.
Paso 13: Crea el botón Reproduciendo ahora
Abra el Guión gráfico y seleccione el segmento de la celda en el controlador de vista de tabla de canciones al controlador de vista que se está reproduciendo. Abra el inspector de atributos y configure el identificador en "NewSong". El siguiente CTRL arrastra desde el Controlador de vista de canciones (no la celda o la vista de tabla) al controlador de vista que se está reproduciendo y seleccionó "pulsar en el menú emergente". Cambie el identificador de este segmento a "Reproducción en curso".
Ahora abra SongsViewController.h y modifique el código para que lea como sigue:
1 |
#import <UIKit/UIKit.h>
|
2 |
#import <MediaPlayer/MediaPlayer.h>
|
3 |
|
4 |
@interface SongsViewController : UITableViewController |
5 |
{
|
6 |
UIBarButtonItem *nowPlayingButton; |
7 |
}
|
8 |
|
9 |
@end
|
A continuación, abra SongsViewController.m y agregue el siguiente código al método viewDidLoad :
1 |
nowPlayingButton = [[UIBarButtonItem alloc] initWithTitle:@"NP" style:UIBarButtonItemStyleBordered target:self action:@selector(goToNowPlaying)]; |
2 |
|
3 |
if ([[MPMusicPlayerController iPodMusicPlayer] playbackState] == MPMusicPlaybackStateStopped) { |
4 |
self.navigationItem.rightBarButtonItem = nil; |
5 |
} else { |
6 |
self.navigationItem.rightBarButtonItem = nowPlayingButton; |
7 |
}
|
8 |
|
9 |
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; |
10 |
|
11 |
[notificationCenter addObserver: self |
12 |
selector: @selector (handle_PlaybackStateChanged:) |
13 |
name: MPMusicPlayerControllerPlaybackStateDidChangeNotification |
14 |
object: [MPMusicPlayerController iPodMusicPlayer]]; |
15 |
|
16 |
[[MPMusicPlayerController iPodMusicPlayer] beginGeneratingPlaybackNotifications]; |
Este código ya debería estar familiarizado, porque lo usamos todo antes. Primero creamos un elemento del botón de la barra con el título "NP" (Reproduciendo ahora), luego actualizamos el elemento del botón de la barra derecha de la barra de navegación al botón de reproducción actual si el reproductor de música no se detiene. Por último, registramos un observador para una notificación del reproductor multimedia, por lo que podemos ocultar o mostrar el botón de reproducción actual cuando cambia el estado de reproducción del reproductor de música.
Ahora agregue los siguientes métodos bajo el método viewDidLoad :
1 |
- (void) goToNowPlaying |
2 |
{
|
3 |
[self performSegueWithIdentifier:@"NowPlaying" sender:self]; |
4 |
}
|
5 |
|
6 |
- (void) handle_PlaybackStateChanged: (id) notification |
7 |
{
|
8 |
if ([[MPMusicPlayerController iPodMusicPlayer] playbackState] == MPMusicPlaybackStateStopped) { |
9 |
self.navigationItem.rightBarButtonItem = nil; |
10 |
} else { |
11 |
self.navigationItem.rightBarButtonItem = nowPlayingButton; |
12 |
}
|
13 |
|
14 |
}
|
Se llama al primer método cuando presionas el botón de reproducción actual y ejecutamos el segmento que acabamos de crear en nuestro guión gráfico. El segundo método ocultará o mostrará el botón de reproducción actual.
También debemos eliminar el observador que creamos anteriormente, así que vaya al método didReceiveMemoryWarning y cambie el código para que lea como sigue:
1 |
- (void)didReceiveMemoryWarning |
2 |
{
|
3 |
[super didReceiveMemoryWarning]; |
4 |
|
5 |
|
6 |
[[NSNotificationCenter defaultCenter] removeObserver: self |
7 |
name: MPMusicPlayerControllerPlaybackStateDidChangeNotification |
8 |
object: [MPMusicPlayerController iPodMusicPlayer]]; |
9 |
|
10 |
[[MPMusicPlayerController iPodMusicPlayer] endGeneratingPlaybackNotifications]; |
11 |
}
|
Lo último que debemos hacer es actualizar el método prepareForSegue: sender: porque no queremos reproducir una nueva canción cuando el usuario presiona el botón de reproducción actual. Vaya a ese método y modifique el código de la siguiente manera:
1 |
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender |
2 |
{
|
3 |
if ([[segue identifier] isEqualToString:@"NewSong"]) |
4 |
{
|
5 |
MPMediaQuery *songsQuery = [MPMediaQuery songsQuery]; |
6 |
NSArray *songs = [songsQuery items]; |
7 |
|
8 |
int selectedIndex = [[self.tableView indexPathForSelectedRow] row]; |
9 |
|
10 |
MPMediaItem *selectedItem = [[songs objectAtIndex:selectedIndex] representativeItem]; |
11 |
|
12 |
MPMusicPlayerController *musicPlayer = [MPMusicPlayerController iPodMusicPlayer]; |
13 |
|
14 |
[musicPlayer setQueueWithItemCollection:[MPMediaItemCollection collectionWithItems:[songsQuery items]]]; |
15 |
[musicPlayer setNowPlayingItem:selectedItem]; |
16 |
|
17 |
[musicPlayer play]; |
18 |
}
|
19 |
}
|
Ahora primero verificamos si el identificador del segmento es "NewSong" por razones obvias.
Haga lo mismo con el AbumsViewController y el AlbumViewConroller, para que también pueda ir desde allí a la pantalla de reproducción actual.
Conclusión
Gracias por leer este tutorial sobre cómo crear un reproductor de música personalizado con el SDK de iOS. En esta tercera y última parte, explicamos cómo controlar el reproductor de música y obtener información sobre la canción que se está reproduciendo actualmente. También aprendimos cómo crear un diseño personalizado con el Protocolo de Apariencia UIA. Espero que te haya gustado esta serie de tutoriales y si tienes preguntas o comentarios sobre este tutorial, ¡déjalos en la sección de comentarios a continuación!



