<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Programación Multimedia</title>
	<atom:link href="https://programacionmultimedia.net/feed/" rel="self" type="application/rss+xml" />
	<link>https://programacionmultimedia.net/</link>
	<description>Diseño Gráfico y Desarrollo Web</description>
	<lastBuildDate>Sat, 26 Jan 2019 21:18:42 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.5</generator>

<image>
	<url>https://programacionmultimedia.net/wp-content/uploads/2021/12/cropped-logo-pm-32x32.png</url>
	<title>Programación Multimedia</title>
	<link>https://programacionmultimedia.net/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>La Edad de Oro del software español</title>
		<link>https://programacionmultimedia.net/la-edad-de-oro-del-software-espanol/</link>
					<comments>https://programacionmultimedia.net/la-edad-de-oro-del-software-espanol/#respond</comments>
		
		<dc:creator><![CDATA[Raúl Flores]]></dc:creator>
		<pubDate>Tue, 30 Oct 2012 14:15:29 +0000</pubDate>
				<category><![CDATA[Noticias]]></category>
		<category><![CDATA[libro]]></category>
		<guid isPermaLink="false">http://programacionmultimedia.net/?p=1729</guid>

					<description><![CDATA[<p>Esta vez quiero comentar la reciente publicación del volumen 2 del fabuloso libro Ocho Quilates. Una historia de la Edad de Oro del software español. Para quién no haya leído todavía el primer volumen o desconozca en absoluto de lo que estoy hablando, le pongo en antecedentes: Durante los primeros compases de los 80, se [&#8230;]</p>
<p>La entrada <a href="https://programacionmultimedia.net/la-edad-de-oro-del-software-espanol/">La Edad de Oro del software español</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Esta vez quiero comentar la reciente publicación del <strong>volumen 2 </strong>del <strong>fabuloso libro</strong> <a href="http://www.ochoquilates.com/" title="Ocho quilates" target="_blank">Ocho Quilates. Una historia de la Edad de Oro del software español</a>.</p>
<p>Para quién no haya leído todavía el primer volumen o desconozca en absoluto de lo que estoy hablando, le pongo en <strong>antecedentes</strong>:</p>
<p>Durante los <strong>primeros compases de los 80</strong>, se gestó una generación de <strong>jóvenes talentos</strong> que, mamando de los primeros ordenadores que veiamos a nivel usuario en España (Spectrum, Amstrad, Commodore, MSX), decidieron dedicarse a esto de la <strong>programación de videojuegos</strong>. Estamos hablando de empresas como Dinamic, Made in Spain, Ópera, Topo&#8230; De juegos como Abu Simbel, Game Over, Sir Fred, Livingstone supongo, Survivor&#8230; Y de distribuidoras como Erbe, Zigurat&#8230;</p>
<p>Durante estos <strong>2 volumenes</strong> de los que consta <strong>Ocho Quilates</strong> nos iremos sumergiendo en la historia de estas empresas, que comenzaron en la buhardilla de su casa y que llegaron a dominar el mercado del <strong>videojuego español</strong>, incluso exportando muchos de sus éxitos fuera de España.<br />
<strong>Lectura totalmente recomendable</strong>.</p>
<p><img fetchpriority="high" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/10/portada-ocho-quilates.jpg" alt="portada ocho quilates" title="portada ocho quilates" width="660" height="946" class="aligncenter size-full wp-image-1742" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/10/portada-ocho-quilates.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/10/portada-ocho-quilates-209x300.jpg 209w, https://programacionmultimedia.net/wp-content/uploads/2012/10/portada-ocho-quilates-400x573.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/10/portada-ocho-quilates-210x301.jpg 210w" sizes="(max-width: 660px) 100vw, 660px" /></p>
<p>La entrada <a href="https://programacionmultimedia.net/la-edad-de-oro-del-software-espanol/">La Edad de Oro del software español</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://programacionmultimedia.net/la-edad-de-oro-del-software-espanol/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>CSS3: Añadir borde a una tipografía</title>
		<link>https://programacionmultimedia.net/css3-anadir-borde-a-una-tipografia/</link>
					<comments>https://programacionmultimedia.net/css3-anadir-borde-a-una-tipografia/#comments</comments>
		
		<dc:creator><![CDATA[Raúl Flores]]></dc:creator>
		<pubDate>Wed, 26 Sep 2012 11:19:22 +0000</pubDate>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[tip]]></category>
		<guid isPermaLink="false">http://programacionmultimedia.net/?p=1711</guid>

					<description><![CDATA[<p>Buscando la forma de crear un borde para algún titular de esta web, sin tener que hacerlo vía imagen/Photoshop, me encontré con un truco que a algún diseñador le puede interesar bastante. Se trata de añadir el borde a una tipografía mediante CSS. Aunque en la especificación de CSS3 existe una propiedad para esta finalidad, [&#8230;]</p>
<p>La entrada <a href="https://programacionmultimedia.net/css3-anadir-borde-a-una-tipografia/">CSS3: Añadir borde a una tipografía</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="tut_bottom">
    <div class="tutorial_details">
    <p><span>Detalles del tutorial</span></p>
    <ul class="fdo_tutorial">
      <li><strong>Tecnología: </strong>CSS3</li><li><strong>Dificultad: </strong>Nivel básico</li><li><strong>Tiempo de realización: </strong>¿5 minutos?</li>    </ul>
  </div>
</div><br />
Buscando la forma de crear un <strong>borde</strong> para algún titular de esta web, sin tener que hacerlo vía imagen/Photoshop, me encontré con un truco que a algún diseñador le puede interesar bastante. Se trata de añadir el <strong>borde a una tipografía</strong> mediante <strong>CSS</strong>.<br />
Aunque en la especificación de <strong>CSS3</strong> existe una propiedad para esta finalidad, <a href="http://www.w3schools.com/cssref/css3_pr_text-outline.asp" title="propiedad text-outline css3" target="_blank">text-outline</a>, ésta todavía no es soportada en la mayoría de los navegadores.</p>
<h3>Creando los estilos CSS</h3>
<p>El truco está en utilizar la propiedad <strong>text-shadow</strong> varias veces, cambiando los valores de posición de la sombra en horizontal-vertical en -1px y 1px con todas las posibles combinaciones, y el valor blur a 0. En la práctica esto es así:</p>
<pre class="brush: css; title: ; notranslate">
.borde {
    color: #000;

    text-shadow:
   -1px -1px 0 #fff,  
    1px -1px 0 #fff,
   -1px 1px 0 #fff,
    1px 1px 0 #fff;
}

</pre>
<p>Esta clase <strong>CSS</strong> nos <strong>añade un borde</strong> blanco de 1px a la <strong>tipografía</strong> de un texto de color negro. Por desgracia si aumentamos el tamaño del borde creado a 2px o valores superiores, los resultados no son los esperados. </p>
<h3>Conclusión</h3>
<p>Este <strong>Tip</strong> no soluciona del todo el asunto de crear bordes mediante <strong>CSS</strong> por su limitación. Esperemos que la propiedad <strong>text-outline</strong> esté pronto disponible.</p>
<p>La entrada <a href="https://programacionmultimedia.net/css3-anadir-borde-a-una-tipografia/">CSS3: Añadir borde a una tipografía</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://programacionmultimedia.net/css3-anadir-borde-a-una-tipografia/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>iOS: Crear vista de tabla personalizada sin usar UITableView</title>
		<link>https://programacionmultimedia.net/ios-crear-vista-de-tabla-personalizada-sin-usar-uitableview/</link>
					<comments>https://programacionmultimedia.net/ios-crear-vista-de-tabla-personalizada-sin-usar-uitableview/#respond</comments>
		
		<dc:creator><![CDATA[Raúl Flores]]></dc:creator>
		<pubDate>Tue, 26 Jun 2012 17:41:21 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[ARC]]></category>
		<category><![CDATA[personalización]]></category>
		<guid isPermaLink="false">http://programacionmultimedia.net/?p=1417</guid>

					<description><![CDATA[<p>Muchas veces queremos crear una vista de tabla usando UITableView y a la hora de personalizarla nos encontramos con ciertas limitaciones que nos impiden reflejar fielmente un diseño previo. En este tutorial vamos a crear una vista de tabla sin usar UITableView ni UITableViewCell y añadiendo los elementos mediante código en nuestro ViewController. Posteriormente tendremos [&#8230;]</p>
<p>La entrada <a href="https://programacionmultimedia.net/ios-crear-vista-de-tabla-personalizada-sin-usar-uitableview/">iOS: Crear vista de tabla personalizada sin usar UITableView</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="tut_bottom">
    <div class="tutorial_details">
    <p><span>Detalles del tutorial</span></p>
    <ul class="fdo_tutorial">
      <li><strong>Tecnología: </strong>iOS</li><li><strong>Dificultad: </strong>Nivel medio</li><li><strong>Tiempo de realización: </strong>45 - 60 minutos</li>    </ul>
  </div>
</div><br />
<div class="content-descarga"><span><a class="descargar" href="https://www.dropbox.com/s/9k7skz8ifarmt2q/tableless.zip?dl=0" title="descargar proyecto Xcode de tabla personalizada">Descargar Proyecto</a></span></div><div class="separador separador-descarga"></div><br />
Muchas veces queremos crear una <strong>vista de tabla</strong> usando <strong>UITableView</strong> y a la hora de personalizarla nos encontramos con ciertas limitaciones que nos impiden reflejar fielmente un diseño previo.<br />
En este tutorial vamos a crear una vista de tabla <strong>sin usar UITableView ni UITableViewCell</strong> y añadiendo los elementos mediante código en nuestro ViewController. Posteriormente tendremos un <strong>controlador de la vista detalle</strong> y un archivo .<strong>xib</strong> que podremos reutilizar en otras vistas detalle de la aplicación.<br />
Para hacer el ejemplo se ha usado <strong>iOS5</strong>, Automatic Reference Counting (<strong>ARC</strong>) y <strong>Storyboard</strong>. Se trata de una <strong>galería de imágenes</strong> en la que primero aparece un listado y al pulsar se muestra la imagen en <strong>otra vista</strong>.</p>
<h3>Crear proyecto y añadir materiales</h3>
<p>Creamos un <strong>nuevo proyecto</strong> en <strong>Xcode</strong> a partir de la plantilla <strong>Single View Aplication</strong> y mantendremos <strong>marcadas</strong> las casillas de las opciones <strong>Use Storyboard</strong> y <strong>Use Automatic Reference Counting</strong>.</p>
<p><img decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-1.jpg" alt="ios tabla personalizada" title="ios tabla personalizada" width="660" height="457" class="aligncenter size-full wp-image-1424" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-1.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-1-300x207.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-1-400x276.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-1-210x145.jpg 210w" sizes="(max-width: 660px) 100vw, 660px" /></p>
<p><img decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-2.jpg" alt="ios tabla personalizada 2" title="ios tabla personalizada 2" width="660" height="442" class="aligncenter size-full wp-image-1427" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-2.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-2-300x200.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-2-400x267.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-2-210x140.jpg 210w" sizes="(max-width: 660px) 100vw, 660px" /></p>
<p>Añadiremos a continuación todo los <strong>materiales gráficos</strong> que va a necesitar la aplicación al proyecto de <strong>Xcode</strong>. Para el ejemplo se muestran <strong>4 celdas</strong> en la tabla, con lo que tendremos 4 imágenes para la tabla, además de otra imagen de separador y otra de fondo. Además para la <strong>vista detalle</strong> tendremos la <strong>versión más grande</strong> de las anteriores 4 imágenes (todas estos materiales con sus correspondientes versiones retina ). </p>
<div class="content-descarga"><span><a class="descargar" href="https://www.dropbox.com/s/0l9qo1gtfgnr2sn/imagenes-tableless.zip?dl=0" title="descargar material">Descargar Materiales</a></span></div><div class="separador separador-descarga"></div>
<div class="separador"></div>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-3.jpg" alt="ios tabla personalizada 3" title="ios tabla personalizada 3" width="660" height="470" class="aligncenter size-full wp-image-1430" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-3.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-3-300x213.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-3-400x284.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-3-210x149.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<h3>Agregamos el controlador de la vista detalle y su XIB</h3>
<p>Vamos a añadir al proyecto la clase <strong>DetalleGaleriaViewController</strong> que es <strong>subclase</strong> de <strong>UIViewController</strong> y será la clase que controlará la vista detalle. Marcamos la opción de <strong>crear XIB</strong>. Este .xib lo podremos usar posteriormente como archivo base de otras vistas detalle.</p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-4.jpg" alt="ios tabla personalizada 4" title="ios tabla personalizada 4" width="660" height="439" class="aligncenter size-full wp-image-1436" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-4.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-4-300x199.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-4-400x266.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-4-210x139.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<h3>Preparamos Storyboard y XIB</h3>
<p>Abrid <strong>MainStoryboard</strong> y vereis que se ha creado un <strong>View Controller por defecto</strong> en nuestra escena. <strong>Borramos</strong> este View Controller y <strong>añadimos</strong> una instancia de <strong>Navigation Controller</strong>, que a su vez ya lleva asociada una instancia de un nuevo View Controller. Asegúrate que Navigation Controller está marcado como <strong>is initial View Controller</strong> y elige en la vista del View Controller, nuestra clase <strong>ViewController</strong> como <strong>clase base</strong> de esta vista.</p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-5.jpg" alt="ios tablapersonalizada 5" title="ios tablapersonalizada 5" width="660" height="349" class="aligncenter size-full wp-image-1442" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-5.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-5-300x158.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-5-400x211.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-5-210x111.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-6.jpg" alt="ios tabla personalizada 6" title="ios tabla personalizada 6" width="660" height="348" class="aligncenter size-full wp-image-1443" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-6.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-6-300x158.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-6-400x210.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-6-210x110.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<p>Añadimos ahora una instancia de <strong>Image View</strong> y de <strong>Scroll View</strong> en la Vista de nuestro View Controller y cambia el título a <strong>Tableless</strong> en las propiedades de <strong>Navigation Item</strong>. A <strong>Image View</strong> le asociamos la imagen del fondo (fondo_vacio.jpg) y a <strong>Scroll View</strong> lo conectamos como un <strong>outlet</strong> en la clase <strong>ViewController</strong> que llamaremos <strong>scrollView</strong>. No nos olvidemos  de <strong>sintetizar</strong> la propiedad en ViewController.m.</p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-7.jpg" alt="ios tabla personalizada 7" title="ios tabla personalizada 7" width="660" height="397" class="aligncenter size-full wp-image-1446" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-7.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-7-300x180.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-7-400x240.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-7-210x126.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<p>Exactamente de igual forma que hemos hecho en el <strong>Storyboard</strong> vamos a proceder con el archivo <strong>DetalleGaleriaViewController.xib</strong>. Añadimos <strong>Image View</strong> y de <strong>Scroll View</strong> en la Vista. A <strong>Image View</strong> le asociamos la imagen del fondo (fondo_vacio.jpg) y a <strong>Scroll View</strong> lo conectamos como un <strong>outlet</strong> en la clase <strong>DetalleGaleriaViewController</strong> que llamaremos <strong>scrollView</strong>. No nos olvidemos  de <strong>sintetizar</strong> la propiedad en <strong>DetalleGaleriaViewController.m</strong>. </p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-8.jpg" alt="ios tabla personalizada 8" title="ios tabla personalizada 8" width="660" height="400" class="aligncenter size-full wp-image-1451" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-8.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-8-300x181.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-8-400x242.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ios-tabla-personalizada-8-210x127.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<h3>Código de ViewController</h3>
<p>Os dejo el código completo de <strong>ViewController</strong> y lo comento. Ya os adelanto que solamente vamos a crear 2 métodos nuevos que son <strong>initialSetup</strong> y <strong>buttonPressed</strong> y que por sus nombres ya podreis adivinar lo que van a hacer. De propiedades tan solo <strong>scrollView</strong>.</p>
<pre class="brush: objc; title: ViewController.h; notranslate">

#import &lt;UIKit/UIKit.h&gt;

@interface ViewController : UIViewController 

@property (strong, nonatomic) IBOutlet UIScrollView *scrollView;

-(void) initialSetup;
-(void) buttonPressed:(id)sender;

@end

</pre>
<p>Declaramos el método <strong>initialSetup</strong> que lo llamaremos desde <strong>viewDidLoad</strong> para disponer todos los elementos en la pantalla. el método <strong>buttonPressed</strong> será llamado cada vez que pulsemos sobre una de las <strong>imágenes/botones</strong> a modo de <strong>celdas</strong> que componen nuestra <strong>tabla/listado</strong>.</p>
<pre class="brush: objc; title: ViewController.m; notranslate">

#import &quot;ViewController.h&quot;
#import &quot;DetalleGaleriaViewController.h&quot;

@implementation ViewController
@synthesize scrollView;

- (void)didReceiveMemoryWarning
{
    &#x5B;super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    &#x5B;self initialSetup];
    &#x5B;super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
   

}

- (void)viewDidUnload
{
    &#x5B;self setScrollView:nil];
    &#x5B;super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    &#x5B;super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    &#x5B;super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
	&#x5B;super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
	&#x5B;super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
   return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown );
}



//*****************************************************************



-(void) initialSetup
{
    
    
    // Custom initialization
    
    NSMutableArray* textosArray = &#x5B;NSMutableArray arrayWithObjects:  @&quot;LIMA&quot;, @&quot;PASEO EN BICICLETA&quot;, @&quot;PUESTA DE SOL&quot;, @&quot;COCHE ABANDONADO&quot;, nil];
    CGFloat  margenY=20.0;
    CGFloat  margenMiniatura=30.0;
    
    CGFloat  margenInicialYSeparador=144.0;
    CGFloat  margenDeSeparador=124.0;
    
    CGFloat  margenInicialYTexto=128.0;
    CGFloat  margenDeTexto=108.0;
    
    
    
    
    for (int i=0; i&lt; &#x5B;textosArray count]; i++) {
        
        //**********miniatura***********************************
        NSString *fileName= &#x5B;NSString stringWithFormat:@&quot;min_galeria_00%i.jpg&quot;,i];
        UIImage *miniatura = &#x5B;&#x5B;UIImage imageNamed:fileName] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
        
        
        UIButton *button = &#x5B;UIButton buttonWithType:UIButtonTypeCustom]; 
        button.frame=CGRectMake( (scrollView.frame.size.width - miniatura.size.width)/2, margenY, miniatura.size.width, miniatura.size.height);
        
        // Set the button's image  
        &#x5B;button setBackgroundImage:miniatura forState:UIControlStateNormal]; 
        button.tag=i;
        
        // Attach an event  
        &#x5B;button addTarget:self action:@selector(buttonPressed:)  
         forControlEvents:UIControlEventTouchUpInside];  
            
        
        //*************separador**********************************
        NSString *separadorName= &#x5B;NSString stringWithFormat:@&quot;separador.jpg&quot;];
        UIImage *separador = &#x5B;&#x5B;UIImage imageNamed:separadorName] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
        UIImageView* separadorView = &#x5B;&#x5B;UIImageView alloc] initWithImage:separador];

        
        separadorView.frame = CGRectMake( 0, margenInicialYSeparador, separadorView.frame.size.width, separadorView.frame.size.height);
        
        
        //*******************texto***********************
        
        UILabel *label =  &#x5B;&#x5B;UILabel alloc]  initWithFrame: CGRectMake(button.frame.origin.x, margenInicialYTexto, button.frame.size.width, 14)];
        &#x5B;label setBackgroundColor:&#x5B;UIColor clearColor ]];
        label.numberOfLines = 1;
        label.textColor=&#x5B;&#x5B;UIColor alloc] initWithRed:164.0 / 255 green:164.0 / 255 blue:164.0 / 255 alpha:1.0];
        
        UIFont* font=&#x5B;UIFont systemFontOfSize:12.0];
        
        &#x5B;label setFont:font];
        label.text = &#x5B;textosArray objectAtIndex:i];
        
        
        //*******************************************
        margenY= button.frame.origin.y + button.frame.size.height  + margenMiniatura ;
        margenInicialYSeparador= margenY  + margenDeSeparador ;
        margenInicialYTexto= margenY  + margenDeTexto ;
        
        
        &#x5B;self.scrollView addSubview:label];
        &#x5B;self.scrollView addSubview:button];  
        &#x5B;self.scrollView addSubview:separadorView];
        
        
    }
    
   
    &#x5B;self.scrollView setContentSize:CGSizeMake(320,margenY + 8)];
    
}

-(void) buttonPressed: (id)sender
{
    //NSLog(@&quot;pulsa: %i&quot;,&#x5B;(UIButton*)sender tag]);
    
    DetalleGaleriaViewController *detalleView = &#x5B;&#x5B;DetalleGaleriaViewController alloc] initWithNibName:@&quot;DetalleGaleriaViewController&quot; bundle:nil] ;
    detalleView.tag=&#x5B;(UIButton*)sender tag];
    
    &#x5B;self.navigationController pushViewController:detalleView animated:YES];
    
    
}


@end


</pre>
<p>Dentro de <strong>viewDidLoad</strong> hemos puesto la llamada a <strong>initialSetup</strong>. En este método tenemos un Array llamado <strong>textosArray</strong> donde van a ir los textos de los títulos de nuestro listado. Aprovecharemos este Array para ir maquetando cada una de las partes que tienen nuestras <em>celdas</em>, que van a tener: Un título, un botón (con una imagen de fondo) y un separador (una imagen). Después tenemos una serie de <strong>variables</strong> que empiezan con <strong>margen&#8230;</strong> y que debemos <strong>inicializar</strong> con los valores que consideremos oportunos.</p>
<pre class="brush: objc; title: ; notranslate">

 // Custom initialization
    
    NSMutableArray* textosArray = &#x5B;NSMutableArray arrayWithObjects:  @&quot;LIMA&quot;, @&quot;PASEO EN BICICLETA&quot;, @&quot;PUESTA DE SOL&quot;, @&quot;COCHE ABANDONADO&quot;, nil];
    CGFloat  margenY=20.0;
    CGFloat  margenMiniatura=30.0;
    
    CGFloat  margenInicialYSeparador=144.0;
    CGFloat  margenDeSeparador=124.0;
    
    CGFloat  margenInicialYTexto=128.0;
    CGFloat  margenDeTexto=108.0;

</pre>
<p>Después de la inicialización recorremos <strong>textosArray</strong>. Las imágenes que van a ir dentro de los botones están nombradas de tal forma que, al recorrer el Array, las podemos llamar fácilmente. Usaremos instancias de <strong>UIImage</strong>, <strong>UIButton</strong> y <strong>UIImageView</strong> y <strong>UILabel</strong> para disponer los elementos y posteriormente añadirlos como <strong>subvistas</strong> de <strong>scrollView</strong>.<br />
Es importante observar como a la <strong>propiedad tag</strong> de nuestra <strong>instancia</strong> de <strong>UIButton</strong> le damos el valor del <strong>iterador i</strong> del <strong>Array</strong> y como le añadimos en el evento <strong>UIControlEventTouchUpInside</strong> una llamada a la función <strong>buttonPressed</strong>.</p>
<pre class="brush: objc; title: ; notranslate">

      button.tag=i;
     
      // Attach an event  
      &#x5B;button addTarget:self action:@selector(buttonPressed:)  
      forControlEvents:UIControlEventTouchUpInside];  

</pre>
<p>Cuando se termina de recorrer el array por completo, <strong>seteamos</strong> el tamaño de <strong>scrollView</strong> convenientemente para que contenga todas nuestras <em>celdas</em>.</p>
<pre class="brush: objc; title: ; notranslate">
 
&#x5B;self.scrollView setContentSize:CGSizeMake(320,margenY + 8)];

</pre>
<p>A continuación definimos el método <strong>buttonPressed</strong> que está ligado al <strong>evento</strong> de pulsar alguno de los <strong>botones</strong> de nuestras <em>celdas</em>. Es muy sencillo lo que hacemos: Creamos una instancia de <strong>DetalleGaleriaViewController</strong> llamada <strong>detalleView</strong>. Esta clase va a tener una <strong>propiedad</strong> llamada <strong>tag</strong> y le damos el valor que ya le dimos al botón en <strong>initialSetup</strong>. Por último mandamos un mensaje a <strong>self.navigationController</strong> para colocar <strong>detalleView</strong> como <strong>controlador</strong> activo. No olvideis <strong>importar DetalleGaleriaViewController.h</strong>.</p>
<pre class="brush: objc; title: ; notranslate">
 
-(void) buttonPressed: (id)sender
{
    
    DetalleGaleriaViewController *detalleView = &#x5B;&#x5B;DetalleGaleriaViewController alloc] initWithNibName:@&quot;DetalleGaleriaViewController&quot; bundle:nil] ;
    detalleView.tag=&#x5B;(UIButton*)sender tag];   
    &#x5B;self.navigationController pushViewController:detalleView animated:YES];
     
}

</pre>
<h3>Código de DetalleGaleriaViewController</h3>
<pre class="brush: objc; title: DetalleGaleriaViewController.h; notranslate">
 
#import &lt;UIKit/UIKit.h&gt;

@interface DetalleGaleriaViewController : UIViewController 

@property (strong, nonatomic) IBOutlet UIScrollView *scrollView;

@property  NSInteger tag;
-(void)initialSetup;


@end


</pre>
<p>Tenemos 2 propiedades, las ya comentadas <strong>scrollView</strong> y <strong>tag</strong>. Tan solo un método, <strong>initialSetup</strong>. De tag y el valor que le pasemos desde <strong>ViewController</strong>, dependerá el mostrar una u otra de las imágenes convenientemente nombradas que ya existen en nuestro proyecto.</p>
<pre class="brush: objc; title: DetalleGaleriaViewController.m; notranslate">
 
#import &quot;DetalleGaleriaViewController.h&quot;

@implementation DetalleGaleriaViewController
@synthesize scrollView;
@synthesize tag;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = &#x5B;super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    &#x5B;super didReceiveMemoryWarning];
    
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    &#x5B;super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    &#x5B;self initialSetup];
}

- (void)viewDidUnload
{
    &#x5B;self setScrollView:nil];
    &#x5B;super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown );
}


//***********************************************************************************************

-(void)initialSetup
{
    
    NSString *fileName= &#x5B;NSString stringWithFormat:@&quot;max_galeria_00%i.jpg&quot;,self.tag];
   
    UIImage *foto = &#x5B;UIImage imageNamed:fileName] ;
    
    UIImageView* fotoView = &#x5B;&#x5B;UIImageView alloc] initWithImage:foto];
    
       
    &#x5B;self.scrollView setContentSize: CGSizeMake(fotoView.frame.size.width, fotoView.frame.size.height)];
    
	    
    
    &#x5B;self.scrollView setScrollEnabled:YES];
    
    &#x5B;self.scrollView addSubview:fotoView];
    
    
    


}

@end


</pre>
<p>llamanos a <strong>initialSetup</strong> desde <strong>viewDidLoad</strong>. Dentro de este método vamos a recuperar nuestra <strong>imagen</strong> nombrada de acuerdo al valor de tag y la añadimos a <strong>scrollView</strong> como <strong>subvista</strong>.</p>
<h3>Conclusión</h3>
<p>Hemos creado una <strong>vista de tabla</strong> de datos maquetada a nuestro antojo y una <strong>vista de detalle</strong> en la que se muestra una imagen dentro de un Scroll View; además <strong>no hemos usado UITableView</strong> ni <strong>UITableViewCell</strong>.<br />
Para el ejemplo he limitado la <strong>orientación</strong> a <strong>UIInterfaceOrientationPortrait</strong> y <strong>UIInterfaceOrientationPortraitUpsideDown</strong> para no complicar en exceso el tutorial. Espero os sea de utilidad, podeis <strong>descargar</strong> el <strong>proyecto</strong> de <strong>Xcode</strong> completo:<br />
<div class="content-descarga"><span><a class="descargar" href="https://www.dropbox.com/s/9k7skz8ifarmt2q/tableless.zip?dl=0" title="descargar proyecto Xcode de tabla personalizada">Descargar Proyecto</a></span></div><div class="separador separador-descarga"></div></p>
<p>La entrada <a href="https://programacionmultimedia.net/ios-crear-vista-de-tabla-personalizada-sin-usar-uitableview/">iOS: Crear vista de tabla personalizada sin usar UITableView</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://programacionmultimedia.net/ios-crear-vista-de-tabla-personalizada-sin-usar-uitableview/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>PHP: Entradas recientes con imagen destacada en WordPress via Shortcode</title>
		<link>https://programacionmultimedia.net/php-entradas-recientes-con-imagen-destacada-en-wordpress-via-shortcode/</link>
					<comments>https://programacionmultimedia.net/php-entradas-recientes-con-imagen-destacada-en-wordpress-via-shortcode/#comments</comments>
		
		<dc:creator><![CDATA[Raúl Flores]]></dc:creator>
		<pubDate>Sun, 24 Jun 2012 17:49:54 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[shortcode]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">http://programacionmultimedia.net/?p=1475</guid>

					<description><![CDATA[<p>Siguiendo con el anterior tutorial en el que creábamos un shortcode personalizado para wordpress, vamos con este pequeño script para crear un shortcode que muestre las entradas recientes de tu blog con sus correspondientes imágenes destacadas. Vamos a poder configurar además algunos parámetros desde el propio shortcode. Código php en tu template de wordpress Abre [&#8230;]</p>
<p>La entrada <a href="https://programacionmultimedia.net/php-entradas-recientes-con-imagen-destacada-en-wordpress-via-shortcode/">PHP: Entradas recientes con imagen destacada en WordPress via Shortcode</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="tut_bottom">
    <div class="tutorial_details">
    <p><span>Detalles del tutorial</span></p>
    <ul class="fdo_tutorial">
      <li><strong>Tecnología: </strong>PHP</li><li><strong>Dificultad: </strong>Nivel básico</li><li><strong>Tiempo de realización: </strong>15 minutos</li>    </ul>
  </div>
</div>Siguiendo con el <strong>anterior tutorial</strong> en el que creábamos un <a href="https://programacionmultimedia.net/php-crear-un-shortcode-personalizado-para-wordpress/" title="PHP: Crear un Shortcode personalizado para WordPress">shortcode personalizado</a> para wordpress, vamos con este pequeño <strong>script</strong> para crear un <strong>shortcode</strong> que muestre las <strong>entradas recientes</strong> de tu <strong>blog</strong> con sus correspondientes <strong>imágenes destacadas</strong>. Vamos a poder configurar además algunos <strong>parámetros</strong> desde el propio <strong>shortcode</strong>.</p>
<h3>Código php en tu template de wordpress</h3>
<p>Abre la carpeta de tu template, localiza el archivo <strong>functions.php</strong> y ábrelo con tu editor; éste archivo está presente en la mayoría de las plantillas de <strong>wordpress</strong>.<br />
A continuación dejo el código y posteriormente comento algunas cosas importantes:</p>
<pre class="brush: php; title: functions.php; notranslate">

function shortcode_recientes($atts, $content = null, $code) {

//Uso: &#x5B;recientes  limite=&quot;3&quot; longitud_titulo=&quot;50&quot; longitud_desc=&quot;50&quot; thumbnail=&quot;1&quot; tamano=&quot;50&quot;]
//thumbnail=&quot;1&quot; muestra imagen destacada. thumbnail=&quot;0&quot; no muestra la imagen
	extract(shortcode_atts(array(
		'limite' =&gt; 5,
		'longitud_titulo' =&gt; 50,
		'longitud_desc' =&gt; 80,		
		'thumbnail' =&gt; false,
		'tamano' =&gt; 65
		
		
	), $atts));

	
	
   	$query = array('showposts' =&gt; $limite,  'orderby'=&gt; 'date', 'order'=&gt;'DESC', 'post_status' =&gt; 'publish', 'ignore_sticky_posts' =&gt; 1);

	
	$q = new WP_Query($query);
	if ($q-&gt;have_posts()) :
	$salida  = '';
	$salida .= '&lt;ul class=&quot;listado-recientes&quot;&gt;';



	/* comienzo while */
	while ($q-&gt;have_posts()) : $q-&gt;the_post();
	$salida .= '&lt;li&gt;';
	if ( has_post_thumbnail() &amp;&amp; $thumbnail == true):
	$salida	.= '&lt;a href=&quot;'.get_permalink().'&quot; title=&quot;'.sprintf( &quot;Enlace permanente a %s&quot;, get_the_title() ).'&quot;&gt;';
	$salida	.= get_the_post_thumbnail(get_the_id(),array($tamano,$tamano),array('title'=&gt;get_the_title(),'alt'=&gt;get_the_title(),'class'=&gt;'imageborder alignleft'));
	$salida	.= '&lt;/a&gt;';
	endif;

	$salida	.= '&lt;div class=&quot;posts_content&quot;&gt;';
	$salida	.= '&lt;a href=&quot;'.get_permalink().'&quot; title=&quot;'.sprintf( &quot;Enlace permanente a %s&quot;, get_the_title() ).'&quot;&gt;';
	$salida	.= wp_html_excerpt (get_the_title(), $longitud_titulo );
	$salida	.= '&lt;/a&gt;';
	$salida	.= '&lt;p&gt;';

        /* Calculo las categorías  */

        $categories = get_the_category();
        $separator = ' ';
        $output = '';
        if($categories){
                foreach($categories as $category) {
                        $output .= $category-&gt;cat_name.''.$separator;
                }
                $salida	.= trim($output, $separator);
        }
	$salida	.= '&lt;/p&gt;';
        /* Escribo fecha  */
	$salida	.= '&lt;p&gt;'.get_the_time().'&lt;/p&gt;';

        /* Escribo extracto  */	

	$excerpt = get_the_excerpt();
	$salida	.= ($excerpt)?'&lt;p&gt;'.wp_html_excerpt($excerpt,$longitud_desc).'...&lt;/p&gt;':'';

	

	$salida	.= '&lt;/div&gt;';
	$salida .= '&lt;/li&gt;';
	endwhile;
	wp_reset_query();
	/* fin while */



	$salida .= '&lt;/ul&gt;';
	endif;

	return $salida;

}
add_shortcode('recientes',    'shortcode_recientes');

</pre>
<p>Podemos configurar los siguientes valores:</p>
<ul>
<li><strong>limite</strong> &#8211; número máximo de entradas a mostrar</li>
<li><strong>longitud_titulo</strong> &#8211; Longitud máxima de caracteres del título</li>
<li><strong>longitud_desc</strong> &#8211; Longitud máxima de caracteres de la descripción</li>
<li><strong>thumbnail</strong> &#8211; Mostrar thumbnail: valores 1 o 0 (mostrar o no mostrar)</li>
<li><strong>tamano</strong> &#8211; Tamaño de la miniatura en píxeles (será cuadrada)</li>
</ul>
<p>Si además queremos meter el <strong>shortcode</strong> en un <strong>widget</strong> lo tenemos muy fácil, añadimos esta línea al final del código anterior:</p>
<pre class="brush: php; title: functions.php; notranslate">
//para insertarlo en un widget del sidebar
add_filter('widget_text', 'do_shortcode');
</pre>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/07/insertar-entradas-relacionadas-widget.jpg" alt="imagen de insertar entradas relacionadas en widget de wordpress" title="insertar entradas relacionadas en widget de wordpress" width="660" height="402" class="aligncenter size-full wp-image-1504" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/07/insertar-entradas-relacionadas-widget.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/07/insertar-entradas-relacionadas-widget-300x182.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/07/insertar-entradas-relacionadas-widget-400x243.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/07/insertar-entradas-relacionadas-widget-210x127.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<p>Con esto vamos a poder incluir <strong>shortcodes</strong> en el <strong>widget</strong> de <strong>Texto o HTML arbitrario</strong> que viene por defecto en <strong>wordpress</strong>.</p>
<h3>Insertar el shortcode</h3>
<p>Podemos utilizar el shortcode en entradas, páginas o en el widget de texto como comentábamos antes. Un ejemplo de uso puede ser: </p>
<pre class="brush: php; title: ; notranslate">
&#x5B;recientes  limite=&quot;3&quot; longitud_titulo=&quot;50&quot; longitud_desc=&quot;50&quot; thumbnail=&quot;1&quot; tamano=&quot;50&quot;]
</pre>
<h3>Conclusión</h3>
<p>Éste código puede ser <strong>ámpliamente mejorado</strong> y es fácil <strong>aumentar sus posibilidades</strong>, como por ejemplo con:</p>
<ul>
<li>Dar la posibilidad de mostrar entradas recientes o relacionadas</li>
<li>Mostrar solamente las entradas de unas determinadas categorías</li>
<li>Mostrar fecha, autor, etc&#8230;</li>
</ul>
<p>&#8230;Estamos abiertos a vuestras aportaciones.</p>
<p>La entrada <a href="https://programacionmultimedia.net/php-entradas-recientes-con-imagen-destacada-en-wordpress-via-shortcode/">PHP: Entradas recientes con imagen destacada en WordPress via Shortcode</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://programacionmultimedia.net/php-entradas-recientes-con-imagen-destacada-en-wordpress-via-shortcode/feed/</wfw:commentRss>
			<slash:comments>80</slash:comments>
		
		
			</item>
		<item>
		<title>PHP: Crear un Shortcode personalizado para WordPress</title>
		<link>https://programacionmultimedia.net/php-crear-un-shortcode-personalizado-para-wordpress/</link>
					<comments>https://programacionmultimedia.net/php-crear-un-shortcode-personalizado-para-wordpress/#comments</comments>
		
		<dc:creator><![CDATA[Raúl Flores]]></dc:creator>
		<pubDate>Fri, 22 Jun 2012 12:37:53 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[shortcode]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">http://programacionmultimedia.net/?p=1385</guid>

					<description><![CDATA[<p>Los shortcodes son una herramienta muy útil para insertar fragmentos de información en tus posts y páginas de wordpress. Vamos a crear un shortcode como el que se usa en esta misma página, justo encima de estas líneas, para mostrar los detalles del tutorial (tecnología, dificultad y tiempo). El shortcode tiene 3 parámetros para los [&#8230;]</p>
<p>La entrada <a href="https://programacionmultimedia.net/php-crear-un-shortcode-personalizado-para-wordpress/">PHP: Crear un Shortcode personalizado para WordPress</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="tut_bottom">
    <div class="tutorial_details">
    <p><span>Detalles del tutorial</span></p>
    <ul class="fdo_tutorial">
      <li><strong>Tecnología: </strong>PHP</li><li><strong>Dificultad: </strong>Nivel básico</li><li><strong>Tiempo de realización: </strong>15 minutos</li>    </ul>
  </div>
</div>Los <strong>shortcodes</strong> son una herramienta muy útil para insertar fragmentos de información en tus posts y páginas de <strong>wordpress</strong>. Vamos a crear un <strong>shortcode</strong> como el que se usa en esta misma página, justo encima de estas líneas, para mostrar los detalles del tutorial (tecnología, dificultad y tiempo). El shortcode tiene 3 parámetros para los 3 campos de este texto.</p>
<h3>A meter código php en tu template de wordpress</h3>
<p>Abre la carpeta de tu template, localiza el archivo <strong>functions.php</strong> y ábrelo con tu editor; éste archivo esta presente en la mayoría de las plantillas de <strong>wordpress</strong>.<br />
A continuación dejo exactamente el mismo código que tiene esta página para mostrar los detalles del tutorial y posteriormente lo explico:</p>
<pre class="brush: php; title: functions.php; notranslate">

function detalle_func( $atts ) {
	extract( shortcode_atts( array(
		'tecnologia' =&gt; 'iOS',
		'dificultad' =&gt; 'Principiante',
		'tiempo' =&gt; '30 - 60 minutos',
	), $atts ) );
	
	$salida='&lt;div class=&quot;tut_bottom&quot;&gt;
    &lt;div class=&quot;tutorial_details&quot;&gt;
    &lt;p&gt;&lt;span&gt;Detalles del tutorial&lt;/span&gt;&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;Tecnología: &lt;/strong&gt;'.$tecnologia.'&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Dificultad: &lt;/strong&gt;'.$dificultad.'&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Tiempo de realización: &lt;/strong&gt;'.$tiempo.'&lt;/li&gt;    &lt;/ul&gt;
  &lt;/div&gt;
&lt;/div&gt;';

	return $salida;
}
add_shortcode( 'detalle', 'detalle_func' );

</pre>
<p>Lo más importante es la línea donde se definen los nombres de las variables del <strong>array</strong> y se les da un valor por defecto. Podemos poner todos los atributos que queramos y les damos nombres y valor para recogerlos luego:</p>
<pre class="brush: php; title: ; notranslate">
extract( shortcode_atts( array(
		'tecnologia' =&gt; 'iOS',
		'dificultad' =&gt; 'Principiante',
		'tiempo' =&gt; '30 - 60 minutos',
	), $atts ) );
</pre>
<p>Luego con las variables<strong> $tecnologia, $dificultad y $tiempo</strong> creamos una salida html para mostrar lo que queremos y lo guardamos en <strong>$salida</strong>:</p>
<pre class="brush: php; title: ; notranslate">
$salida='&lt;div class=&quot;tut_bottom&quot;&gt;
    &lt;div class=&quot;tutorial_details&quot;&gt;
    &lt;p&gt;&lt;span&gt;Detalles del tutorial&lt;/span&gt;&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;Tecnología: &lt;/strong&gt;'.$tecnologia.'&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Dificultad: &lt;/strong&gt;'.$dificultad.'&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Tiempo de realización: &lt;/strong&gt;'.$tiempo.'&lt;/li&gt;    &lt;/ul&gt;
  &lt;/div&gt;
&lt;/div&gt;';
return $salida;
</pre>
<p>No te olvides de <strong>devolver</strong> el html de la variable <strong>$salida</strong>. Por último notifica a <strong>wordpress</strong> que has creado un <strong>shortcode</strong>:</p>
<pre class="brush: php; title: ; notranslate">
add_shortcode( 'detalle', 'detalle_func' );
</pre>
<h3>Creando las css</h3>
<p>Ya está creado el <strong>shortcode</strong>. El siguiente paso sería añadir un poco de <strong>css</strong>. Tu plantilla debería tener un archivo llamado <strong>style.css</strong>. Ábrelo e introduce las css a tu antojo. Para este ejemplo yo he utilizado las siguientes:</p>
<pre class="brush: css; title: style.css; notranslate">
.tut_bottom {
    float: left;    
    padding: 0 ;
    width: 660px;
}

.tut_bottom .tutorial_details {
    float: left;
    margin-right: 20px;
    margin-bottom: 20px;
    
}

.tutorial_details {
    color: #5B6D79;
    float: left;
    font-size: 1em;
    padding-top: 0px;
    width: 100%;
    border-bottom: 1px dotted #8AA7B9;
}

.tutorial_details p{
    color:#5B6D79;
    font-family: &quot;WinterthurCondensedRegular&quot;,Georgia,Times,sans-serif;
    font-size:26px;
    background: url(&quot;images/fdo_titular_pagina.jpg&quot;) repeat-x scroll left bottom transparent;
    line-height: 28px;
    margin-bottom: 12px;
    padding-bottom: 10px;
}

.tutorial_details p span{

    background: url(&quot;images/pm-general-bk.jpg&quot;) repeat-x scroll left center transparent;
    padding-right: 10px;
}

</pre>
<h3>Insertar tu shortcode recién creado en una entrada</h3>
<p>Ahora vamos a utilizar nuestro <strong>shortcode</strong> al comienzo de este post para mostrar los detalles de este tutorial. El código sería el siguiente:</p>
<pre class="brush: php; title: ; notranslate">
&#x5B;detalle tecnologia=&quot;PHP&quot; dificultad=&quot;Nivel básico&quot; tiempo=&quot;15 minutos&quot;]
</pre>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/06/ejemplo-shortcode-wordpress.jpg" alt="crear un shortcode en wordpress" title="ejemplo de shortcode en wordpress" width="660" height="282" class="alignleft size-full wp-image-1400" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/06/ejemplo-shortcode-wordpress.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ejemplo-shortcode-wordpress-300x128.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ejemplo-shortcode-wordpress-400x170.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/06/ejemplo-shortcode-wordpress-210x89.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<h3>Conclusión</h3>
<p>Ya habeis visto que es muy <strong>fácil</strong> crear un <strong>shortcode en wordpress</strong>. Observad que no hay que poner etiquetas de apertura y cierre (como los de crear columnas por ejemplo), tan solo encerrar con corchetes tal y como os he mostrado.</p>
<p>La entrada <a href="https://programacionmultimedia.net/php-crear-un-shortcode-personalizado-para-wordpress/">PHP: Crear un Shortcode personalizado para WordPress</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://programacionmultimedia.net/php-crear-un-shortcode-personalizado-para-wordpress/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>AS3: Dibujar uniendo puntos</title>
		<link>https://programacionmultimedia.net/as3-dibujar-uniendo-puntos/</link>
					<comments>https://programacionmultimedia.net/as3-dibujar-uniendo-puntos/#comments</comments>
		
		<dc:creator><![CDATA[Raúl Flores]]></dc:creator>
		<pubDate>Thu, 07 Jun 2012 17:42:23 +0000</pubDate>
				<category><![CDATA[AS3]]></category>
		<category><![CDATA[flash]]></category>
		<guid isPermaLink="false">http://programacionmultimedia.net/?p=1317</guid>

					<description><![CDATA[<p>Vamos a crear en flash+AS3 la típica actividad/pasatiempo que siempre hemos hecho todos de pequeños alguna vez. Se trata de unir los puntos para hacer un dibujo que en un principio está parcialmente oculto. Este mini-tutorial está hecho a partir del trabajo de uno de los colaboradores latentes de programacionmultimedia.net, Ignacio Calleja. Lo único que [&#8230;]</p>
<p>La entrada <a href="https://programacionmultimedia.net/as3-dibujar-uniendo-puntos/">AS3: Dibujar uniendo puntos</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="tut_bottom">
    <div class="tutorial_details">
    <p><span>Detalles del tutorial</span></p>
    <ul class="fdo_tutorial">
      <li><strong>Tecnología: </strong>AS3</li><li><strong>Dificultad: </strong>Nivel medio</li><li><strong>Tiempo de realización: </strong>30 - 45 minutos</li>    </ul>
  </div>
</div><br />
<div class="content-descarga"><span><a class="descargar" href="https://www.dropbox.com/s/c3fmwn7th0roudw/unirPuntos.fla?dl=0" title="descargar fla">Descargar Proyecto</a></span></div><div class="separador separador-descarga"></div><br />
Vamos a crear en <strong>flash+AS3</strong> la típica actividad/pasatiempo que siempre hemos hecho todos de pequeños alguna vez. Se trata de <strong>unir los puntos</strong> para hacer un <strong>dibujo</strong> que en un principio está parcialmente oculto. Este <strong>mini-tutorial</strong> está hecho a partir del trabajo de uno de los colaboradores latentes de <strong>programacionmultimedia.net</strong>, <strong>Ignacio Calleja</strong>. Lo único que he hecho yo es volver a crear la actividad, eliminando otros elementos que contenía originalmente y refinar un poco la librería/fotogramas del .fla. En principio la idea es terminar de dibujar una casa uniendo los números del 20 al 39 y que cuando los terminemos de unir la casa se pinte de color. Al final de este tutorial podreis descargar el <strong>.fla</strong>.</p>
<h3>Comenzando con los materiales a usar</h3>
<p>Vamos a necesitar <strong>2 imágenes</strong> para este tutorial de <strong>1024x768px.</strong> La primera será con los puntos numerados y la segunda con el dibujo con color. Las podeis descargar aquí:<br />
<div class="content-descarga"><span><a class="descargar" href="https://www.dropbox.com/s/nc2wmpoj7my59o6/material_unir_puntos.zip?dl=0" title="descargar material">Descargar Materiales</a></span></div><div class="separador separador-descarga"></div></p>
<p>Una vez tengamos el material creamos en flash un nuevo documento ActionScript3 y le damos al escenario un tamaño de <strong>1024x768px</strong>. Añadimos <strong>2 capas</strong> (dibujo trazado y dibujo sin trazar) y añadimos en cada una la imagen que le corresponde, centrándolas en el escenario.</p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-1.jpg" alt="flash unir puntos 1" title="flash unir puntos 1" width="660" height="561" class="aligncenter size-full wp-image-1320" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-1.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-1-300x255.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-1-400x340.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-1-210x178.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<p>La imagen del dibujo coloreado la vamos a convertir en símbolo de <strong>Movieclip</strong> y le pondremos nombre de instancia <strong>dibujo_trazado_mc</strong> para poder mostrarla y ocultarla mediante <strong>AS3</strong>.</p>
<h3>Preparando el resto del escenario y Movieclips</h3>
<p>Bien vamos a la línea de tiempo y creamos ya todas las capas que vamos a necesitar: <strong>as, puntos, botón repetir</strong>. En la capa as va a haber <strong>2 keyframe</strong> en los que va a ir todo el código. llamaremos a estos <strong>keyframes/fotogramas inicio y repetir</strong>.</p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-2.jpg" alt="flash unir puntos 2" title="flash unir puntos 2" width="660" height="205" class="aligncenter size-full wp-image-1323" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-2.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-2-300x93.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-2-400x124.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-2-210x65.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<p>Ahora <strong>creamos un botón</strong> para repetir la actividad cuando la completemos. Yo he optado por un <strong>Movieclip</strong> sencillo, lo he colocado en la <strong>capa botón repetir</strong> a la altura del <strong>keyframe repetir</strong> y le he puesto de nombre de instancia <strong>repetirActividad_mc</strong>.</p>
<p>Seguidamente vamos a crear un <strong>símbolo de botón</strong> consistente en un círculo de color rojo que será cada uno de los puntos a seguir para hacer el dibujo. Creo el símbolo de botón con el <strong>primer fotograma vacío</strong> para que sea <strong>invisible</strong> pero tenga <strong>hit-area</strong>.</p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-3.jpg" alt="flash unir puntos 3" title="flash unir puntos 3" width="660" height="330" class="aligncenter size-full wp-image-1324" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-3.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-3-300x150.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-3-400x200.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-3-210x105.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<p>En la <strong>capa puntos</strong> vamos a colocar una instancia de este <strong>símbolo del punto en cada uno de los puntos</strong> que tiene el dibujo (20 en este caso) y los vamos a nombrar como nombre de instancia de la siguiente manera: <strong>mc_pto20, mc_pto21, mc_pto22&#8230;</strong> Colocándolos como corresponda numéricamente de acuerdo con el dibujo.</p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-4.jpg" alt="flash unir puntos 4" title="flash unir puntos 4" width="661" height="476" class="aligncenter size-full wp-image-1325" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-4.jpg 661w, https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-4-300x216.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-4-400x288.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-4-210x151.jpg 210w" sizes="auto, (max-width: 661px) 100vw, 661px" /></p>
<h3>Metiéndole AS3</h3>
<p>Llegados a este punto la mécanica del programa es sencilla. Tenemos <strong>2 variables de configuración</strong> que son el punto inicial y el punto final y un array <strong>arrClips</strong> que se va a llenar solito con todos esos moviclips que hemos metido en la capa puntos. También tenemos otro array auxiliar, <strong>arrClipsUsados</strong>, que medirá los nombres de los clips usados. Estas son las variables más importantes. Tenemos como vereis otras variables más que vienen comentadas en el código que os dejo a continuación y que está todo explicado en su línea correspondiente. Solamente tenemos código en los <strong>keyframes inicio y repetir</strong>.</p>
<pre class="brush: as3; title: keyframe inicio; notranslate">
import  flash.display.MovieClip;
import  flash.events.MouseEvent;

//******INICIALIZACIÓN******************

var numInicialPunto:Number=20;//número inicial de punto
var numFinalPunto:Number=39;//número final de punto
var arrClips:Array=new Array();//array de todos los clips de puntos
var arrClipsUsados:Array=new Array(); // Para almacenar SOLO EL NOMBRE de cada clip pulsado, cuando tenga la misma longitud que arrClips significa que hemos pulsado sobre todos



for(var j:Number=numInicialPunto;j&lt;numFinalPunto+1;j++)
{
	//relleno el array con los puntos que hay en el escenario
	arrClips.push(this&#x5B;&quot;mc_pto&quot;+j]);
	
}



var numPunto:Number=0;

var i:String=new String(); //variable de iteración

dibujo_trazado_mc.alpha=0;// Borra el dibujo coloreado

// CREA LA FORMA PARA DIBUJAR LAS LÍNEAS Y DEFINE EL ESTILO
var sh_lienzo:Shape = new Shape();
addChild(sh_lienzo);

stop();

init();

//**********************************

function init(){
	
	arrClipsUsados= &#x5B;]; // limpia la lista de clips usados
	activaBtns();// activa botones
	
}
//**********************************

function activaBtns(){ 
	
	
	if (numPunto == 0){ // Sólo activa los botones al empezar la actividad
		for (i in arrClips){
			arrClips&#x5B;i].addEventListener(MouseEvent.CLICK,dibujaLinea);
			//arrClips&#x5B;i].buttonMode=true;	
			arrClips&#x5B;i].enabled=true;
		}			
	}
}
//**********************************

function desactivaBtns(){
	//desactivamos eventos en los clips de los puntos
	for (i in arrClips){
		arrClips&#x5B;i].removeEventListener(MouseEvent.CLICK,dibujaLinea);
		arrClips&#x5B;i].enabled=false;
	}	
}
//**********************************

function dibujaLinea(e:MouseEvent){
	if (e.target.name == arrClips&#x5B;numPunto].name){ // Si hemos pinchado en el punto que toca
		// Dibuja la línea desde el punto anterior
		if (numPunto &gt; 0){ // ...pero no teniendo en cuenta el punto de origen
		    trace(&quot;Dibujando línea de &quot; + arrClips&#x5B;numPunto-1].name + &quot; a &quot; + arrClips&#x5B;numPunto].name);
			sh_lienzo.graphics.lineStyle(3, 0x000000, 1);
			sh_lienzo.graphics.moveTo(arrClips&#x5B;numPunto-1].x, arrClips&#x5B;numPunto-1].y);
			sh_lienzo.graphics.lineTo(arrClips&#x5B;numPunto].x,arrClips&#x5B;numPunto].y); 
		}
		// Incluye el clip en la lista de clips usados
		arrClipsUsados.push(e.target.name);
		// Desactívalo como botón
		e.target.removeEventListener(MouseEvent.CLICK,dibujaLinea);
		e.target.enabled=false;
		
		numPunto++;
		
		// Comprueba si has pulsado todos comparando el tamaño de los 2 arrays
			
		if (arrClipsUsados.length &gt;= arrClips.length) {
				desactivaBtns();
				dibujo_trazado_mc.alpha=1; // Colorea el dibujo
				// pequeño retardo (en este caso el cuádruple, para que de tiempo a escuchar la frase)
				terminaActividad();
		}
	}
}

//**********************************

function terminaActividad(){
	gotoAndPlay(&quot;repetir&quot;);
}
</pre>
<pre class="brush: as3; title: keyframe repetir; notranslate">
stop();

//botón de repite actividad******************-
repetirActividad_mc.addEventListener(MouseEvent.CLICK,repiteActividad);
repetirActividad_mc.buttonMode=true;

//****************************************
function repiteActividad(e:MouseEvent){
	
	repetirActividad_mc.removeEventListener(MouseEvent.CLICK,repiteActividad);
	repetirActividad_mc.buttonMode=false;
	
	sh_lienzo.graphics.clear();// Limpia el lienzo
	desactivaBtns();
	gotoAndPlay(&quot;inicio&quot;);
}
</pre>
<h3>Conclusión</h3>
<p>Si todo va <strong>correcto</strong>, <strong>compilais</strong> y terminais el dibujo, os aparecerá una cosa tal que así:</p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-5.jpg" alt="flash unir puntos 5" title="flash unir puntos 5" width="660" height="656" class="aligncenter size-full wp-image-1332" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-5.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-5-150x150.jpg 150w, https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-5-300x298.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-5-400x397.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/06/flash-unir-puntos-5-210x208.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<p>Espero os sea útil en un futuro este tutorial, podeis <strong>descargar el .fla</strong> completo si quereis:<br />
<div class="content-descarga"><span><a class="descargar" href="https://www.dropbox.com/s/c3fmwn7th0roudw/unirPuntos.fla?dl=0" title="descargar fla">Descargar Proyecto</a></span></div><div class="separador separador-descarga"></div></p>
<p>La entrada <a href="https://programacionmultimedia.net/as3-dibujar-uniendo-puntos/">AS3: Dibujar uniendo puntos</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://programacionmultimedia.net/as3-dibujar-uniendo-puntos/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>iOS: Sable láser con UIAccelerometer y sonido (III)</title>
		<link>https://programacionmultimedia.net/ios-sable-laser-con-uiaccelerometer-y-sonido-iii/</link>
					<comments>https://programacionmultimedia.net/ios-sable-laser-con-uiaccelerometer-y-sonido-iii/#respond</comments>
		
		<dc:creator><![CDATA[Raúl Flores]]></dc:creator>
		<pubDate>Sat, 26 May 2012 09:01:10 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[acelerómetro]]></category>
		<category><![CDATA[ARC]]></category>
		<category><![CDATA[sonidos]]></category>
		<category><![CDATA[vibración]]></category>
		<guid isPermaLink="false">http://localhost:8888/programacionmultimedia/?p=1150</guid>

					<description><![CDATA[<p>Comenzamos con la 3ª y última parte del tutorial. Ya tenemos todas las clases necesarias creadas y lo que necesitamos es ir picando un poco de código dentro de ellas para rematar la cuestión. En la 2ª parte habiamos creado la vista SaberOnView que será controlada por SaberOnViewController. SaberOnView ya no necesita más código por [&#8230;]</p>
<p>La entrada <a href="https://programacionmultimedia.net/ios-sable-laser-con-uiaccelerometer-y-sonido-iii/">iOS: Sable láser con UIAccelerometer y sonido (III)</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="tut_bottom">
    <div class="tutorial_details">
    <p><span>Detalles del tutorial</span></p>
    <ul class="fdo_tutorial">
      <li><strong>Tecnología: </strong>iOS</li><li><strong>Dificultad: </strong>Nivel medio</li><li><strong>Tiempo de realización: </strong>45 - 60 minutos</li>    </ul>
  </div>
</div><br />
<div class="content-descarga"><span><a class="descargar" href="https://www.dropbox.com/s/q3bo8w1zuq51cif/sablelaser.zip?dl=0" title="descargar Proyecto xcode de sable láser">Descargar Proyecto</a></span></div><div class="separador separador-descarga"></div><br />
Comenzamos con la <strong>3ª y última parte</strong> del tutorial. Ya tenemos todas las clases necesarias creadas y lo que necesitamos es ir picando un poco de código dentro de ellas para rematar la cuestión. En la 2ª parte habiamos creado la vista <strong>SaberOnView</strong> que será controlada por <strong>SaberOnViewController</strong>. SaberOnView ya no necesita más código por lo que nos vamos a meter de lleno con <strong>SaberOnViewController</strong>.</p>
<h3>SaberOnViewController</h3>
<p>Vamos a utilizar un <strong>patrón de delegación</strong> para poder devolver el control a <strong>ViewController</strong> cuando desaparezca la vista modal <strong>SaberOnView</strong> mediante un toque del usuario en la pantalla. Presuponemos unos conocimientos básicos de creación de protocolos para este tutorial. Crearemos el protocolo <strong>SaberOnViewControllerDelegate</strong> y su delegado estará en <strong>ViewController</strong>. Aquí vamos a tener toda la lógica del desplazamiento del láser y de disparar sonidos y vibración. Los valores de las <strong>constantes</strong> se pueden variar a gusto, yo les he dado esos valores después de testear bastante.</p>
<p><strong>Cuando apretemos el botón de lanzar el sable ocurrirán las siguientes cosas:</strong></p>
<ul>
<li>Lanzamos la vista modal <strong>SaberOnView</strong> y se activará de inicio, un <strong>sonido</strong> constante (pulse) y una <strong>vibración</strong> será disparada</li>
<li>Se activará el <strong>acelerómetro</strong> y dependiendo de nuestros movimientos en el <em>espacio</em> y la brusquedad de estos, serán lanzados determinados sonidos y vibración algunos de forma <strong>aleatoria</strong> y otros <strong>fija</strong>. Además el sable se moverá por el <strong>eje X</strong></li>
<li>Cuando <strong>toquemos</strong> la pantalla será disparado un sonido de final y la vista <strong>SaberOnView</strong> se ocultará y volveremos a la vista inicial</li>
</ul>
<p>Os dejo el <strong>código completo</strong> de la clase:</p>
<pre class="brush: objc; title: SaberOnViewController.h; notranslate">

#import &lt;uikit /UIKit.h&gt;
#import &lt;avfoundation /AVFoundation.h&gt;

#import &quot;SaberOnView.h&quot;

@protocol SaberOnViewControllerDelegate;

@interface SaberOnViewController : UIViewController &lt;uiaccelerometerdelegate , AVAudioPlayerDelegate&gt;{

    AVAudioPlayer *pulse;
    AVAudioPlayer *startLaser;
    AVAudioPlayer *stopLaser;
    AVAudioPlayer *pasada1;
    AVAudioPlayer *pasada2;
    AVAudioPlayer *pasada3;
    AVAudioPlayer *pasada4;

    NSMutableArray *saberSoundsArray;
    UIAccelerometer *acelerometro;
    //SaberOnView *saberOnView;

    double min;
    double max;
    double negMin;

}

@property (nonatomic, assign) id &lt;saberonviewcontrollerdelegate&gt; delegate;

@property (nonatomic, strong) SaberOnView *saberOnView;
@property (nonatomic, strong)  NSMutableArray *saberSoundsArray;

- (void) done;
- (void) createSounds;

@end

@protocol SaberOnViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(SaberOnViewController *)controller;
@end

</pre>
<pre class="brush: objc; title: SaberOnViewController.m; notranslate">

#import &quot;SaberOnViewController.h&quot;
#import &lt;audiotoolbox /AudioToolbox.h&gt;

@implementation SaberOnViewController

@synthesize delegate=_delegate;
@synthesize saberOnView;
@synthesize saberSoundsArray = _saberSoundsArray;

double const kminimum = 0.8;
double const knegativeMinimum = -0.8;
double const kmaximum = 1.3;
double const knegativeMaximum = -1.3;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = &#x5B;super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    &#x5B;super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidUnload
{
    &#x5B;super viewDidUnload];
    self.saberOnView=nil;
    acelerometro=nil;
    self.saberSoundsArray=nil;
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)loadView {

    UIApplication *thisApp = &#x5B;UIApplication sharedApplication];
    thisApp.idleTimerDisabled = YES;

	saberOnView = &#x5B;&#x5B;SaberOnView alloc] initWithFrame:CGRectZero];
	&#x5B;saberOnView canBecomeFirstResponder];
	&#x5B;saberOnView becomeFirstResponder];

    &#x5B;self createSounds];

    acelerometro = &#x5B;UIAccelerometer sharedAccelerometer];

    &#x5B;acelerometro setUpdateInterval:0.0416];

    &#x5B;acelerometro setDelegate:self];

    //variables del acelerometro
    min=kminimum;
    max=kmaximum;
    negMin=knegativeMinimum;

	NSLog(@&quot;monitoring accelerometer&quot;);

	self.view = saberOnView;

    &#x5B;startLaser play];

    &#x5B;pulse play];

}

- (void)touchesBegan:(NSSet *)touches
           withEvent:(UIEvent *)event
{
    NSLog(@&quot;stopLaser!!&quot;);
    &#x5B;self done];

}

- (void)done
{
    &#x5B;acelerometro setDelegate:nil];
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
    &#x5B;pulse stop];

    &#x5B;stopLaser play];

    UIApplication *thisApp = &#x5B;UIApplication sharedApplication];
    thisApp.idleTimerDisabled = NO;

    NSLog(@&quot;not monitoring accelerometer&quot;);

    &#x5B;self.delegate flipsideViewControllerDidFinish:self];

}

- (void)accelerometer:(UIAccelerometer *)meter didAccelerate:(UIAcceleration *)accel
{

    saberOnView.xShift = saberOnView.xShift * 0.8 + &#x5B;accel x] * 20.0;
    NSLog(@&quot;monitoring accelerometer2&quot;);

    // Redraw the view
    &#x5B;self.view setNeedsDisplay];

    if (  accel.x &gt; min &amp;&amp; accel.x &lt; kmaximum)

    {

        &amp;#91;pasada1 play&amp;#93;;
        min=accel.x;
        negMin=knegativeMinimum;

    }

    if (  accel.x &lt; negMin &amp;&amp; accel.x &gt; knegativeMaximum)

    {

        &#x5B;pasada2 play];
        negMin=accel.x;
        min=kminimum;
    }

    if (  accel.y &gt; min &amp;&amp; accel.y &lt; kmaximum)

    {

        &amp;#91;pasada3 play&amp;#93;;
        min=accel.y;
        negMin=knegativeMinimum;
        max=kmaximum;
    }

    if (  accel.y &lt; negMin &amp;&amp; accel.y &gt; knegativeMaximum)

    {

        &#x5B;pasada4 play];
        negMin=accel.y;
        min=kminimum;
    }

    if (  accel.y &gt; max)

    {
        int randomHit = 7 + arc4random() % 7;
        //NSLog(@&quot;randomHit:%i&quot;,randomHit);

        &#x5B;(AVAudioPlayer *)&#x5B;self.saberSoundsArray objectAtIndex:randomHit]    play] ;
        max=accel.y;

        AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

    }

    //NSLog(@&quot;accel.x:%f&quot;,accel.x);
    //NSLog(@&quot;accel.y:%f&quot;,accel.y);
    //NSLog(@&quot;accel.z:%f&quot;,accel.z);

}

- (void)viewDidDisappear:(BOOL)animated
{
    &#x5B;super viewDidDisappear:animated];

}

-(void) createSounds
{

    //sonido constante*************************
    pulse = (AVAudioPlayer *)&#x5B;self.saberSoundsArray objectAtIndex:0];

    pulse.numberOfLoops=-1;
    pulse.delegate=self;

    //sonido entrada*************************

    startLaser=(AVAudioPlayer *)&#x5B;self.saberSoundsArray objectAtIndex:1];

    //sonido salida*************************
    stopLaser = (AVAudioPlayer *)&#x5B;self.saberSoundsArray objectAtIndex:2];

    //sonido pasada1*************************

    pasada1 = (AVAudioPlayer *)&#x5B;self.saberSoundsArray objectAtIndex:3];

    //sonido pasada2*************************
    pasada2 = (AVAudioPlayer *)&#x5B;self.saberSoundsArray objectAtIndex:4];

    //sonido pasada3*************************

    pasada3 = (AVAudioPlayer *)&#x5B;self.saberSoundsArray objectAtIndex:5];

    //sonido pasada4*************************

    pasada4 = (AVAudioPlayer *)&#x5B;self.saberSoundsArray objectAtIndex:6];

}

-(void)audioPlayerBeginInterruption:(AVAudioPlayer *)player
{
    //NSLog(@&quot;audioPlayerBeginInterruption&quot;);
    &#x5B;pulse stop];

}
-(void)audioPlayerEndInterruption:(AVAudioPlayer *)player
{
    //NSLog(@&quot;audioPlayerEndInterruption&quot;);
    &#x5B;pulse play];
}

@end

</pre>
<h3>ViewController</h3>
<p>Para concluir vamos a añadir la delegación a esta clase con lo cual añadiremos el protocolo <strong>SaberOnViewControllerDelegate</strong> a <strong>ViewController</strong>, asignaremos como delegado de <strong>SaberOnViewController</strong> a <strong>ViewController</strong> e implementaremos el método <strong>flipsideViewControllerDidFinish</strong>.</p>
<pre class="brush: objc; title: ViewController.h; notranslate">
@interface ViewController : UIViewController &lt;saberonviewcontrollerdelegate&gt;{
</pre>
<p>ViewController.m quedará de la siguiente forma:</p>
<pre class="brush: objc; title: ViewController.h; notranslate">

#import "ViewController.h"

@implementation ViewController
@synthesize saberSoundsArray=_saberSoundsArray;

- (void)didReceiveMemoryWarning
{
    &#x5B;super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    &#x5B;super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
}

- (void)viewDidUnload
{
    &#x5B;super viewDidUnload];
    self.saberSoundsArray = nil;
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    &#x5B;super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    &#x5B;super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
	&#x5B;super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
	&#x5B;super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (IBAction)startLaser:(id)sender {

    //vibración
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

    SaberOnViewController *controller = &#x5B;&#x5B;SaberOnViewController alloc] init];

    &#x5B;controller setDelegate:self];

    &#x5B;controller setSaberSoundsArray: _saberSoundsArray];

    &#x5B;self presentModalViewController:controller animated:YES];

}

- (void)flipsideViewControllerDidFinish:(SaberOnViewController *)controller
{
    &#x5B;self dismissModalViewControllerAnimated:YES];

}

@end

</pre>
<h3>Conclusión</h3>
<p>Supongo que a estas alturas ya habeis compilado en vuestro dispositivo y vereis que cumple <strong>dignamente</strong>, pero hay muchas otras cosas que se pueden hacer&#8230; Tampoco creo que ésta sea la única o mejor forma de hacerlo ni nada parecido, es simplemente <strong>una forma más</strong> que espero os pueda servir de base para otros proyectos.<br />
Espero os haya gustado, podeis <strong>descargar</strong> el <strong>proyecto</strong> completo de <strong>Xcode</strong>:<br />
<div class="content-descarga"><span><a class="descargar" href="https://www.dropbox.com/s/q3bo8w1zuq51cif/sablelaser.zip?dl=0" title="descargar Proyecto xcode de sable láser">Descargar Proyecto</a></span></div><div class="separador separador-descarga"></div><br />
</saberonviewcontrollerdelegate></audiotoolbox></saberonviewcontrollerdelegate></uiaccelerometerdelegate></avfoundation></uikit></p>
<p>La entrada <a href="https://programacionmultimedia.net/ios-sable-laser-con-uiaccelerometer-y-sonido-iii/">iOS: Sable láser con UIAccelerometer y sonido (III)</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://programacionmultimedia.net/ios-sable-laser-con-uiaccelerometer-y-sonido-iii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>iOS: Sable láser con UIAccelerometer y sonido (II)</title>
		<link>https://programacionmultimedia.net/ios-sable-laser-con-uiaccelerometer-y-sonido-ii/</link>
					<comments>https://programacionmultimedia.net/ios-sable-laser-con-uiaccelerometer-y-sonido-ii/#respond</comments>
		
		<dc:creator><![CDATA[Raúl Flores]]></dc:creator>
		<pubDate>Thu, 24 May 2012 15:47:37 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[acelerómetro]]></category>
		<category><![CDATA[ARC]]></category>
		<category><![CDATA[sonidos]]></category>
		<category><![CDATA[vibración]]></category>
		<guid isPermaLink="false">http://localhost:8888/programacionmultimedia/?p=1116</guid>

					<description><![CDATA[<p>Vamos con la 2ª parte del tutorial del sable láser. Empezamos con la clase modelo de los sonidos del sable que llamaremos SaberSoundsModel. Aquí crearemos un array con todos los sonidos inicializados y listos para su reproducción. Modelo de sonidos SaberSoundsModel Creamos una nueva clase Objetive-C que sea subclase de NSObject y la llamamos SaberSoundsModel. [&#8230;]</p>
<p>La entrada <a href="https://programacionmultimedia.net/ios-sable-laser-con-uiaccelerometer-y-sonido-ii/">iOS: Sable láser con UIAccelerometer y sonido (II)</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="tut_bottom">
    <div class="tutorial_details">
    <p><span>Detalles del tutorial</span></p>
    <ul class="fdo_tutorial">
      <li><strong>Tecnología: </strong>iOS</li><li><strong>Dificultad: </strong>Nivel medio</li><li><strong>Tiempo de realización: </strong>45 - 60 minutos</li>    </ul>
  </div>
</div>Vamos con la <strong>2ª parte del tutorial del sable láser</strong>. Empezamos con la clase <strong>modelo</strong> de los sonidos del sable que llamaremos <strong>SaberSoundsModel</strong>. Aquí crearemos un array con todos los sonidos inicializados y listos para su reproducción. </p>
<h3>Modelo de sonidos SaberSoundsModel</h3>
<p>Creamos una nueva clase Objetive-C que sea subclase de NSObject y la llamamos <strong>SaberSoundsModel</strong>. Aquí creamos 2 <strong>Arrays</strong>, uno con los nombres de los ficheros de audio, <strong>filesArray</strong>, que recorreremos para llenar <strong>saberSoundsArray</strong> con los objetos de sonido. Como vereis <strong>saberSoundsArray</strong> es una <strong>property</strong> para poder acceder posteriormente. No se te olvide importar <strong>AVFoundation/AVFoundation</strong> para manejar los objetos de audio.</p>
<pre class="brush: objc; title: SaberSoundsModel.h; notranslate">

#import &lt;Foundation/Foundation.h&gt;

@interface SaberSoundsModel : NSObject{
        
    NSMutableArray *saberSoundsArray;
    NSArray *filesArray;
}

@property (nonatomic, strong) NSMutableArray *saberSoundsArray;

@end

</pre>
<pre class="brush: objc; title: SaberSoundsModel.m; notranslate">

#import &quot;SaberSoundsModel.h&quot;
#import &lt;AVFoundation/AVFoundation.h&gt;

@implementation SaberSoundsModel
@synthesize saberSoundsArray=_saberSoundsArray;

-(id)init
{
    if ((self = &#x5B;super init])) 
    {
        //array con todos los nombres de los archivos de sonido
        filesArray = &#x5B;NSArray arrayWithObjects:@&quot;sabramb1.wav&quot;,
                      @&quot;ltsaberon01.wav&quot;,
                      @&quot;ltsaberoff01.wav&quot;,
                      @&quot;sabrswg1.wav&quot;,
                      @&quot;sabrswg2.wav&quot;,
                      @&quot;sabrswg6.mp3&quot;,
                      @&quot;sabrswg4.mp3&quot;,
                      @&quot;sabhit1.WAV&quot;,
                      @&quot;sabhit2.WAV&quot;,
                      @&quot;sabhit3.WAV&quot;,
                      @&quot;ltsaberhit15.wav&quot;,
                      @&quot;espadazo1.wav&quot;,
                      @&quot;espadazo2.wav&quot;,
                      @&quot;espadazo3.wav&quot;,                      
                      nil];
             
        //array que contendrá los objetos de sonidos
        self.saberSoundsArray = &#x5B;NSMutableArray arrayWithObjects: nil];
        
        for (int i=0; i&lt;&#x5B;filesArray count]; i++)            
        {
                       
            NSString *file = &#x5B;NSString stringWithFormat:@&quot;%@&quot;, &#x5B;&#x5B;filesArray objectAtIndex:i] description]  ];
            
            
            NSURL *url = &#x5B;NSURL fileURLWithPath:&#x5B;NSString stringWithFormat:@&quot;%@/%@&quot;, &#x5B;&#x5B;NSBundle mainBundle] resourcePath],file]];
            
                        
            AVAudioPlayer *sound = &#x5B;&#x5B;AVAudioPlayer alloc]  initWithContentsOfURL:url error:nil] ;
                        
            &#x5B;_saberSoundsArray addObject:sound];
                     
            
        }
        //NSLog(@&quot;saberSoundsArray: %@&quot;,&#x5B;_saberSoundsArray description]);    
        
    }
    
    return self;
    
}

@end


</pre>
<p>Ahora vamos a <strong>AppDelegate</strong> para inicializar el modelo de sonidos y pasarlo a <strong>ViewController</strong> ya inicializado. Crearemos en <strong>ViewController</strong> una <strong>property</strong> llamada <strong>saberSoundsArray</strong> para darle valor desde <strong>AppDelegate</strong>. </p>
<pre class="brush: objc; title: AppDelegate.h; notranslate">

#import &lt;UIKit/UIKit.h&gt;
@class SaberSoundsModel;

@interface AppDelegate : UIResponder &lt;UIApplicationDelegate&gt;{
    
    
    SaberSoundsModel *saberSoundsModel;
}

@property (strong, nonatomic) UIWindow *window;

@end


</pre>
<pre class="brush: objc; title: AppDelegate.m; notranslate">

#import &quot;AppDelegate.h&quot;
#import &quot;SaberSoundsModel.h&quot;
#import &quot;ViewController.h&quot;

@implementation AppDelegate

@synthesize window = _window;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    //inicializamos modelo
    saberSoundsModel = &#x5B;&#x5B;SaberSoundsModel alloc] init];
    //sacamos viewController desde la jerarquía de window
    ViewController *viewController=(ViewController *)self.window.rootViewController;
    //pasamos a saberSoundsArray el modelo inicializado anteriormente
    &#x5B;viewController setSaberSoundsArray: &#x5B;saberSoundsModel saberSoundsArray ]];
    
    return YES;
}

//el resto de código generado por Xcode lo dejamos tal cual

</pre>
<pre class="brush: objc; title: ViewController.h; notranslate">

#import &lt;UIKit/UIKit.h&gt;

@interface ViewController : UIViewController{
    
    NSMutableArray *saberSoundsArray; 
    
}
//creamos la property
@property (nonatomic, strong)  NSMutableArray *saberSoundsArray;
- (IBAction)startLaser:(id)sender;

@end


</pre>
<pre class="brush: objc; title: ViewController.m; notranslate">
//sintetizamos la property
@synthesize saberSoundsArray=_saberSoundsArray;

- (void)viewDidUnload
{
    &#x5B;super viewDidUnload];
    //liberamos saberSoundsArray
    self.saberSoundsArray = nil;
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


</pre>
<h3>Clase SaberOnViewController</h3>
<p><strong>SaberOnViewController</strong> será la clase encargada de controlar la vista que hará posible visualizar el sable láser. Creamos de la manera habitual una nueva clase que sea subclase de <strong>UIViewController</strong>, le añadimos una property llamada <strong>saberSoundsArray</strong> y la sintetizamos.</p>
<pre class="brush: objc; title: SaberOnViewController.h; notranslate">

#import &lt;UIKit/UIKit.h&gt;

@interface SaberOnViewController : UIViewController{
    
     NSMutableArray *saberSoundsArray;
}

@property (nonatomic, strong)  NSMutableArray *saberSoundsArray;

@end

</pre>
<pre class="brush: objc; title: SaberOnViewController.m; notranslate">

@synthesize saberSoundsArray = _saberSoundsArray;

- (void)viewDidUnload
{
    &#x5B;super viewDidUnload];
    self.saberSoundsArray=nil;
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

</pre>
<h3>Clase ViewController</h3>
<p>Ahora vamos a añadir el código necesario a la función <strong>startLaser</strong> de ViewController para que tome el control la clase <strong>SaberOnViewController</strong> de manera modal con presentModalViewController. Primero importamos <strong>SaberOnViewController</strong> y <strong>AudioToolbox/AudioToolbox</strong> para la <strong>vibración</strong>.</p>
<pre class="brush: objc; title: ViewController.h; notranslate">
#import &quot;SaberOnViewController.h&quot;
//añadimos este framework para que se pueda acceder a la vibración
#import &lt;AudioToolbox/AudioToolbox.h&gt;

</pre>
<p>Después vamos a <strong>ViewController.m</strong> y metemos código en la función <strong>startLaser</strong>. A este controlador le pasamos el modelo <strong>saberSoundsArray</strong>.</p>
<pre class="brush: objc; title: ViewController.m; notranslate">

- (IBAction)startLaser:(id)sender {
    
    //vibración
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
    //inicializo SaberOnViewController de nombre controller
    SaberOnViewController *controller = &#x5B;&#x5B;SaberOnViewController alloc] init];
    //pasamos el modelo a controller
    &#x5B;controller setSaberSoundsArray: _saberSoundsArray];
    //presentamos controller de manera modal
    &#x5B;self presentModalViewController:controller animated:YES];
  
}


</pre>
<h3>Vista SaberOnView</h3>
<p>Vamos a crear una vista mediante <strong>código exclusivamente</strong> que contendrá la imagen del sable láser, para lo cual creamos una nueva clase que sea subclase de <strong>UIView</strong>.</p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-6.jpg" alt="ios sable laser 6" title="ios sable laser 6" width="660" height="441" class="aligncenter size-full wp-image-1207" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-6.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-6-300x200.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-6-400x267.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-6-210x140.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<p>En el código de esta clase/vista tendremos una property <strong>xShift</strong> que será para indicar el <strong>desplazamiento horizontal</strong> que se aplicará dependiendo del <strong>acelerómetro</strong>. (El sable se mueve en el eje x de la pantalla dependiendo del movimiento aplicado al iPhone). También tendremos la imagen del fondo y la del sable, siendo esta última la que se va a desplazar manteniendo la otra estática. Para salir del modo láser bastará con tocar la pantalla por lo que <strong>canBecomeFirstResponder</strong> debe de responder <strong>YES</strong>.</p>
<pre class="brush: objc; title: SaberOnView.h; notranslate">

#import &lt;UIKit/UIKit.h&gt;

@interface SaberOnView : UIView   {
         
    float xShift; 
    CGImageRef image;   
    
} 
    @property (nonatomic, assign) float xShift; 
    
@end


</pre>
<pre class="brush: objc; title: SaberOnView.m; notranslate">

#import &quot;SaberOnView.h&quot;

@implementation SaberOnView
@synthesize xShift; 

- (id)initWithFrame:(CGRect)frame
{
    self = &#x5B;super initWithFrame:frame];
    if (self) {
        // Initialization code
        
        //fdo********************************
        UIColor *background = &#x5B;&#x5B;UIColor alloc] initWithPatternImage:&#x5B;UIImage imageNamed:@&quot;fdo_Saber.png&quot;]];
        self.backgroundColor = background;
        
        
        
        //sable*****************************
        NSString *imagePath = &#x5B;&#x5B;NSBundle mainBundle] pathForResource:@&quot;sable.png&quot; ofType:nil];
		UIImage *img = &#x5B;UIImage imageWithContentsOfFile:imagePath];
		image = CGImageRetain(img.CGImage);

        
    }
    return self;
}

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    
    // Drawing code
    // What rectangle am I filling?
	CGRect bounds = &#x5B;self bounds];
	
	// Where is its center?
	CGPoint center;
	center.x = bounds.origin.x + bounds.size.width / 2.0;
	center.y = bounds.origin.y + bounds.size.height / 2.0;
    
	// Get the context being draw upon
	CGContextRef context = UIGraphicsGetCurrentContext();
    
    center.x += xShift; 
    
       
    CGRect imageRect;
	imageRect.origin = CGPointMake(center.x - 71, center.y -240);
	imageRect.size = CGSizeMake(143.0, 480.0);
	
    // Draw the image
	CGContextDrawImage(context, imageRect, image);
	
    
}

- (BOOL)canBecomeFirstResponder 
{ 
    return YES; 
} 

@end


</pre>
<p>Te animo a continuar con la <a href="https://programacionmultimedia.net/ios-sable-laser-con-uiaccelerometer-y-sonido-iii/" title="3ª parte del tutorial Sable láser con UIAccelerometer y sonido (III)">3ª y última parte</a> de este tutorial en la que nos meteremos con el <strong>acelerómetro</strong> para disparar sonidos, vibración y mover el sable láser por el eje x de la pantalla. </p>
<p>La entrada <a href="https://programacionmultimedia.net/ios-sable-laser-con-uiaccelerometer-y-sonido-ii/">iOS: Sable láser con UIAccelerometer y sonido (II)</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://programacionmultimedia.net/ios-sable-laser-con-uiaccelerometer-y-sonido-ii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>iOS: Fundir imagen de carga con primera vista de la aplicación</title>
		<link>https://programacionmultimedia.net/ios-fundir-imagen-de-carga-con-primera-vista-de-la-aplicacion/</link>
					<comments>https://programacionmultimedia.net/ios-fundir-imagen-de-carga-con-primera-vista-de-la-aplicacion/#respond</comments>
		
		<dc:creator><![CDATA[Raúl Flores]]></dc:creator>
		<pubDate>Wed, 23 May 2012 14:52:08 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[animaciones]]></category>
		<category><![CDATA[ARC]]></category>
		<category><![CDATA[fundido]]></category>
		<guid isPermaLink="false">http://localhost:8888/programacionmultimedia/?p=1007</guid>

					<description><![CDATA[<p>Como muchos de vosotros sabéis, a la hora de hacer una aplicación iPhone/iPad es necesario incorporar al proyecto una imagen de precarga (Default.png), que es la que se visualiza nada más comienza a cargar nuestra aplicación. Una vez se ha cargado la imagen desaparece bruscamente y se visualiza la primera vista de nuestra app. Para [&#8230;]</p>
<p>La entrada <a href="https://programacionmultimedia.net/ios-fundir-imagen-de-carga-con-primera-vista-de-la-aplicacion/">iOS: Fundir imagen de carga con primera vista de la aplicación</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="tut_bottom">
    <div class="tutorial_details">
    <p><span>Detalles del tutorial</span></p>
    <ul class="fdo_tutorial">
      <li><strong>Tecnología: </strong>iOS</li><li><strong>Dificultad: </strong>Nivel principiante-medio</li><li><strong>Tiempo de realización: </strong>30 - 45 minutos</li>    </ul>
  </div>
</div><br />
<div class="content-descarga"><span><a class="descargar" href="https://www.dropbox.com/s/lwjkpkag52tmggr/fundido.zip?dl=0" title="descargar Proyecto xcode de fundido">Descargar Proyecto</a></span></div><div class="separador separador-descarga"></div><br />
Como muchos de vosotros sabéis, a la hora de hacer una aplicación <strong>iPhone/iPad</strong> es necesario incorporar al proyecto una <strong>imagen de precarga</strong> (Default.png), que es la que se visualiza nada más comienza a cargar nuestra aplicación. Una vez se ha cargado la imagen <strong>desaparece bruscamente</strong> y se visualiza la primera vista de nuestra app.</p>
<p>Para realizar una transición más fluida de esta imagen, vamos a colocar la imagen en lo más alto de la jerarquía de subvistas de nuestra vista inicial y vamos a realizar un fundido alpha de la imagen, con lo cual, cuando desaparece la imagen de precarga, se ve la misma imagen, que es la que hay también en la misma posición en la primera vista. Para hacer el ejemplo se ha usado <strong>iOS5 y Automatic Reference Counting (ARC)</strong>.</p>
<h3>Crear proyecto y agregar materiales</h3>
<p>Creamos un <strong>nuevo proyecto</strong> en Xcode a partir de la plantilla <strong>Single View Aplication y las opciones por defecto.</strong></p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-1.jpg" alt="ios fundir pantalla inicio 1" title="ios fundir pantalla inicio 1" width="660" height="443" class="aligncenter size-full wp-image-1222" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-1.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-1-300x201.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-1-400x268.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-1-210x140.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-2.jpg" alt="ios fundir pantalla inicio 2" title="ios fundir pantalla inicio 2" width="660" height="443" class="aligncenter size-full wp-image-1223" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-2.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-2-300x201.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-2-400x268.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-2-210x140.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<p>Preparamos nuestras imágenes <strong>Default.png</strong> (320x480px) y <strong>Default@2x.png</strong> (640x960px) y las <strong>añadimos al proyecto</strong> de la manera habitual. En cuanto las añadimos ya nos salen en las propiedades del Target en el apartado <strong>Launch Images</strong>. Podeis descargar las imagenes aquí:<br />
<div class="content-descarga"><span><a class="descargar" href="https://www.dropbox.com/s/pxz8nykdjowaubc/materiales-fundido.zip?dl=0" title="materiales fundido">Descargar Materiales</a></span></div><div class="separador separador-descarga"></div></p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-3.jpg" alt="ios fundir pantalla inicio 3" title="ios fundir pantalla inicio 3" width="660" height="565" class="aligncenter size-full wp-image-1224" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-3.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-3-300x256.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-3-400x342.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-3-210x179.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<h3>Añadimos Outlets y código</h3>
<p>Ahora vamos a ViewController.h y añadimos un <strong>IBOutlet</strong> que va a ser la imagen que se funde. También vamos a añadir la función (void)fadeOut&#8230; que vamos a usar para realizar el fundido y que admite 2 parámetros: La vista a disolver y la duración del efecto, por lo que es bastante reusable.</p>
<pre class="brush: objc; title: ViewController.h; notranslate">

#import &lt;uikit /UIKit.h&gt;

@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutlet UIImageView *entradaView;
-(void)fadeOut:(UIView*)viewToDissolve withDuration:(NSTimeInterval)duration ;

@end

</pre>
<p>En ViewController.m <strong>sintetizamos entradaView</strong> y añadimos el cuerpo de la función <strong>(void)fadeOut&#8230;</strong></p>
<pre class="brush: objc; title: ViewController.m; notranslate">
#import "ViewController.h"

@implementation ViewController
@synthesize entradaView;

-(void)fadeOut:(UIView*)viewToDissolve withDuration:(NSTimeInterval)duration
{
    &#x5B;UIView beginAnimations: @"entradaView" context:nil];
    &#x5B;UIView setAnimationDelegate:self];
	// wait for time before begin
	//&#x5B;UIView setAnimationDelay:wait];

	// druation of animation
    &#x5B;UIView setAnimationDuration:duration];
    viewToDissolve.alpha = 0.0;
    &#x5B;UIView commitAnimations];
}

</pre>
<p>Seguimos en ViewController.m e invocamos al método (void)fadeout.. desde <strong>viewDidLoad</strong> con <strong>entradaView</strong> como vista a disolver y 1 segundo de duración. Aprovechamos también y <strong>seteamos a nil entradaView</strong> en el cuerpo del método <strong>viewDidUnload</strong>.</p>
<pre class="brush: objc; title: ViewController.m; notranslate">
- (void)viewDidLoad
{
    entradaView.alpha = 1;
    &#x5B;self fadeOut : entradaView withDuration: 1  ];
    &#x5B;super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
}

- (void)viewDidUnload
{
    &#x5B;self setEntradaView:nil];
    &#x5B;super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}
</pre>
<h3>En el Storyboard</h3>
<p>Seguidamente vamos al <strong>MainStoryboard</strong>, seleccionamos de la Escena el <strong>View Controller</strong> y añadimos dentro de la vista View una subvista Label para darnos cuenta del efecto y le ponemos algo de texto. Después añadimos una <strong>Image View</strong> en la que cargamos la imagen <strong>Default.png</strong> con coordenadas y tamaño <strong>x=0, y=-20, width=320, height=480</strong>. Esta imagen la vamos a mapear con <strong>entradaView en Referencing Outlets</strong>.</p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-4.jpg" alt="ios fundir pantalla inicio 4" title="ios fundir pantalla inicio 4" width="660" height="569" class="aligncenter size-full wp-image-1225" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-4.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-4-300x258.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-4-400x344.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-4-210x181.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-5.jpg" alt="ios fundir pantalla inicio 5" title="ios fundir pantalla inicio 5" width="660" height="314" class="aligncenter size-full wp-image-1226" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-5.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-5-300x142.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-5-400x190.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-fundir-pantalla-inicio-5-210x99.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<p>Y bueno ya podeis <strong>compilar</strong> y ver el efecto. Hay muchas maneras de hacer esto pero yo he elegido esta por su <strong>simplicidad</strong>, espero os sea de utilidad&#8230;</p>
<p>A continuación puedes descargar el <strong>proyecto Xcode</strong>:<br />
<div class="content-descarga"><span><a class="descargar" href="https://www.dropbox.com/s/lwjkpkag52tmggr/fundido.zip?dl=0" title="descargar Proyecto xcode de fundido">Descargar Proyecto</a></span></div><div class="separador separador-descarga"></div><br />
</uikit></p>
<p>La entrada <a href="https://programacionmultimedia.net/ios-fundir-imagen-de-carga-con-primera-vista-de-la-aplicacion/">iOS: Fundir imagen de carga con primera vista de la aplicación</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://programacionmultimedia.net/ios-fundir-imagen-de-carga-con-primera-vista-de-la-aplicacion/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>iOS: Sable láser con UIAccelerometer y sonido (I)</title>
		<link>https://programacionmultimedia.net/ios-sable-laser-con-uiaccelerometer-y-sonido-i/</link>
					<comments>https://programacionmultimedia.net/ios-sable-laser-con-uiaccelerometer-y-sonido-i/#respond</comments>
		
		<dc:creator><![CDATA[Raúl Flores]]></dc:creator>
		<pubDate>Tue, 22 May 2012 16:32:36 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[acelerómetro]]></category>
		<category><![CDATA[ARC]]></category>
		<category><![CDATA[sonidos]]></category>
		<category><![CDATA[vibración]]></category>
		<guid isPermaLink="false">http://localhost:8888/programacionmultimedia/?p=1053</guid>

					<description><![CDATA[<p>En este tutorial que he dividido en 3 partes, vamos a crear un sable láser que responde al acelerómetro y que incorpora sonidos según el nivel de sacudidas que realicemos. Habrá un sonido constantante que llamaremos pulso, otros sonidos que responderan a la inclinación del iphone y otros sonidos que se lanzarán aleatoriamente al realizar [&#8230;]</p>
<p>La entrada <a href="https://programacionmultimedia.net/ios-sable-laser-con-uiaccelerometer-y-sonido-i/">iOS: Sable láser con UIAccelerometer y sonido (I)</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="tut_bottom">
    <div class="tutorial_details">
    <p><span>Detalles del tutorial</span></p>
    <ul class="fdo_tutorial">
      <li><strong>Tecnología: </strong>iOS</li><li><strong>Dificultad: </strong>Nivel medio</li><li><strong>Tiempo de realización: </strong>45 - 60 minutos</li>    </ul>
  </div>
</div>En este tutorial que he dividido en <strong>3 partes</strong>, vamos a crear un <strong>sable láser</strong> que responde al <strong>acelerómetro</strong> y que incorpora <strong>sonidos</strong> según el nivel de sacudidas que realicemos. Habrá un sonido constantante que llamaremos <strong>pulso</strong>, otros sonidos que responderan a la <strong>inclinación</strong> del <strong>iphone</strong> y otros sonidos que se lanzarán aleatoriamente al realizar <strong>sacudidas</strong>. También incorporaremos <strong>vibración</strong> para dar realismo.</p>
<p><strong>No nos vamos a parar en detalles</strong> como imágenes de precarga, iconos o nociones de manejo básico del storyboard, por lo cual para seguir este tutorial es necesario poseer un conocimiento básico de Xcode. Para hacer el ejemplo se ha usado <strong>iOS5 y Automatic Reference Counting (ARC)</strong>. También debeis saber que para testear correctamente el funcionamiento de los contenidos de este tutorial, será prácticamente <strong>imprescindible</strong> hacerlo en un <strong>dispositivo</strong> (<strong>iPhone</strong> aunque puede ser <strong>iPad</strong>) por razones relativas al uso del <strong>acelerómetro</strong>.</p>
<h3>Crear proyecto y agregar imágenes y sonidos</h3>
<p>Comenzamos creando un <strong>nuevo proyecto</strong> a partir de <strong>Single View Application</strong>, le nombramos <strong>sablelaser</strong> y seleccionamos <strong>Storyboard y ARC</strong> (valores por defecto). </p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-1.jpg" alt="ios sable laser 1" title="ios sable laser 1" width="660" height="443" class="aligncenter size-full wp-image-1202" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-1.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-1-300x201.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-1-400x268.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-1-210x140.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /><br />
<img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-2.jpg" alt="ios sable laser 2" title="ios sable laser 2" width="660" height="445" class="aligncenter size-full wp-image-1203" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-2.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-2-300x202.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-2-400x269.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-2-210x141.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<p>Posteriormente agregamos las <strong>imágenes</strong> sable.png y fdo_Saber.png al proyecto (con sus correspondientes versiones @2x) y los 14 <strong>archivos de sonido</strong> que va a tener el sable láser. Lo coloco todo por grupos dentro del proyecto de Xcode para ordenarlo como veis en la imagen.<br />
<div class="content-descarga"><span><a class="descargar" href="https://www.dropbox.com/s/jd8a45b2qd20oyv/materiales-sablelaser.zip?dl=0" title="descargar material">Descargar Materiales</a></span></div><div class="separador separador-descarga"></div><br />
En la 3ª parte del tutorial podreis descargar el proyecto de Xcode completo.</p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-3.jpg" alt="ios sable laser 3" title="ios sable laser 3" width="660" height="491" class="aligncenter size-full wp-image-1204" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-3.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-3-300x223.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-3-400x297.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-3-210x156.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<h3>Añadimos Outlets, IBActions y Frameworks</h3>
<p>Vamos a añadir un <strong>botón</strong> para lanzar el Láser, para lo cual vamos a <strong>MainStoryboard</strong> y añadimos de la manera habitual una instancia de <strong>Round Rect Button</strong> dentro de nuestra vista de <strong>View Controller</strong>. Mapeamos el evento <strong>Touch Up Inside</strong> con un <strong>IBAction</strong> que llamaremos <strong>startLaser</strong>. Con lo cual quedará nuestro <strong>ViewController</strong> de la siguiente forma:</p>
<pre class="brush: objc; title: ViewController.h; notranslate">

#import &lt;uikit /UIKit.h&gt;

@interface ViewController : UIViewController
- (IBAction)startLaser:(id)sender;

@end

</pre>
<pre class="brush: objc; title: ViewController.m; notranslate">

#import &quot;ViewController.h&quot;

@implementation ViewController

- (void)didReceiveMemoryWarning
{
    &#x5B;super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    &#x5B;super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
}

- (void)viewDidUnload
{
    &#x5B;super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    &#x5B;super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    &#x5B;super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
	&#x5B;super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
	&#x5B;super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
   return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (IBAction)startLaser:(id)sender {
}

@end

</pre>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-4.jpg" alt="ios sable laser 4" title="ios sable laser 4" width="660" height="484" class="aligncenter size-full wp-image-1205" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-4.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-4-300x220.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-4-400x293.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-4-210x154.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<p>Para el tema de <strong>sonido</strong> y <strong>vibración</strong> tendremos que añadir los <strong>frameworks AudioToolbox y AvFoundation</strong>.</p>
<p><img loading="lazy" decoding="async" src="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-5.jpg" alt="ios sable laser 5" title="ios sable laser 5" width="660" height="305" class="aligncenter size-full wp-image-1206" srcset="https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-5.jpg 660w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-5-300x138.jpg 300w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-5-400x184.jpg 400w, https://programacionmultimedia.net/wp-content/uploads/2012/05/ios-sable-laser-5-210x97.jpg 210w" sizes="auto, (max-width: 660px) 100vw, 660px" /></p>
<p>Con esto ya tenemos todo preparado para comenzar a programar las <strong>4 clases</strong> de las que va a constar el proyecto: ViewController, SaberOnViewController, SaberOnView y SaberSoundsModel.<br />
Te animo a continuar con la <a href="https://programacionmultimedia.net/ios-sable-laser-con-uiaccelerometer-y-sonido-ii/" title="2ª parte del tutorial sable láser">2ª parte de este tutorial</a>. </p>
<p>La entrada <a href="https://programacionmultimedia.net/ios-sable-laser-con-uiaccelerometer-y-sonido-i/">iOS: Sable láser con UIAccelerometer y sonido (I)</a> se publicó primero en <a href="https://programacionmultimedia.net">Programación Multimedia</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://programacionmultimedia.net/ios-sable-laser-con-uiaccelerometer-y-sonido-i/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
