<?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>KevFoo &#187; UIAlertView</title>
	<atom:link href="http://blog.kevfoo.com/index.php/category/uialertview/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.kevfoo.com</link>
	<description>The weblog of a Chicago based .Net and iPhone developer.</description>
	<lastBuildDate>Wed, 26 May 2010 13:33:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Monotouch: UIAlertView + UITextField = Crazy Delicious</title>
		<link>http://blog.kevfoo.com/index.php/2009/11/monotouch-uialertview-uitextfield-crazy-delicious/</link>
		<comments>http://blog.kevfoo.com/index.php/2009/11/monotouch-uialertview-uitextfield-crazy-delicious/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 17:20:15 +0000</pubDate>
		<dc:creator>Kevin McMahon</dc:creator>
				<category><![CDATA[UIAlertView]]></category>
		<category><![CDATA[UITextField]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[monotouch]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Button Setup]]></category>
		<category><![CDATA[Cancel Button]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Configured]]></category>
		<category><![CDATA[Control]]></category>
		<category><![CDATA[Default Button]]></category>
		<category><![CDATA[Itunes]]></category>
		<category><![CDATA[Message Label]]></category>
		<category><![CDATA[New Control]]></category>
		<category><![CDATA[Stock Control]]></category>
		<category><![CDATA[Two Ways]]></category>
		<category><![CDATA[Ui]]></category>

		<guid isPermaLink="false">http://blog.kevfoo.com/index.php/2009/11/monotouch-uialertview-uitextfield-crazy-delicious/</guid>
		<description><![CDATA[If you have ever tried to buy or install anything from the App Store or iTunes on your iPhone, then you certainly have been prompted for your password by a screen that looks like this:
 
The control used by Apple to prompt you for your password isn’t available out-of-the-box in Cocoa Touch, but fortunately it [...]]]></description>
			<content:encoded><![CDATA[<p>If you have ever tried to buy or install anything from the App Store or iTunes on your iPhone, then you certainly have been prompted for your password by a screen that looks like this:</p>
<p><a href="http://blog.kevfoo.com/wp-content/uploads/2009/11/itunes_pw_iphone.jpg"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="itunes_pw_iphone" border="0" alt="itunes_pw_iphone" src="http://blog.kevfoo.com/wp-content/uploads/2009/11/itunes_pw_iphone_thumb.jpg" width="164" height="244" /></a> </p>
<p>The control used by Apple to prompt you for your password isn’t available out-of-the-box in Cocoa Touch, but fortunately it is pretty easy to roll your own.&#160; I’ve put together a <a href="http://github.com/kevinmcmahon/CustomUITextFieldAlertView">sample project</a> that shows a couple different techniques that are available for creating and customizing the control, and I’ll go over a few of them here.</p>
<p>The stock <a href="http://www.go-mono.com/docs/index.aspx?link=T%3AMonoTouch.UIKit.UIAlertView%2FP">UIAlertView</a> control consists of a title label, message label, and typically one or more buttons.&#160; It is important to note that in Monotouch, a default button setup isn’t configured, and buttons have to be added explicitly.&#160; If a UIAlertView is configured without any buttons, then dismissing the control will have to be done programmatically because the user will have no way to dismiss the control.&#160; In both of my examples I’ve configured the control to have two buttons (Cancel and Ok), but I could have gotten by with just one.&#160; If only one button is used, it is important to also note that the button is considered the Cancel button by the control, and the <b><a href="http://www.go-mono.com/docs/monodoc.ashx?link=P%3aMonoTouch.UIKit.UIAlertView.CancelButtonIndex">CancelButtonIndex</a></b> property will refer to that button. </p>
<p><a href="http://blog.kevfoo.com/wp-content/uploads/2009/11/Basic_UIAlertView.png"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Basic_UIAlertView" border="0" alt="Basic_UIAlertView" src="http://blog.kevfoo.com/wp-content/uploads/2009/11/Basic_UIAlertView_thumb.png" width="244" height="121" /></a></p>
<p>The easiest way to go about composing a UIAlertView with a <a href="http://www.go-mono.com/docs/monodoc.ashx?link=T%3aMonoTouch.UIKit.UITextField">UITextField</a> is to create an instance of a UITextField and add it as a sub-view.&#160; Since you’re adding a layer on top of UIAlertView’s view, the key will be fitting this new control into the UI.&#160; There are two ways of going about this.&#160; The first and maybe most obvious way to solve this problem is to make some room between the message label and buttons for the text field ala the iTunes password prompt.&#160; Since the UIAlertView control has already been laid out, moving those controls around within the frame is not as straight forward a task as it may seem.&#160; Before we tackle that we will explore a simpler method that overlays the text field directly on top of the message label.&#160; You sacrifice being able to display an additional message to the user, but the end result looks professional and is very easy to implement.&#160; This will also be the basis for getting the control to have the same look and feel as the iTunes password prompt, so it is important to understand this prior to attempting to move the controls around.</p>
<p>The key to overlaying the text field on top of the message label is setting the bounding rectangle for the UITextField.&#160; The bounding rectangle is where the text field draws the box in which a user enters text.&#160; For our purposes, the rectangle needs to be drawn in between the title label and the buttons.&#160; It is important to make sure that it covers the area where the message label is drawn.&#160; Thanks to the work of others we know that if we start drawing the text field at the x,y offset of 12,45 that the text field will hide the message label.</p>
<p>The code to overlay the text field is as follows:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:5cf6cd71-f852-4415-a2b2-654336f59dbe" class="wlWriterEditableSmartContent">
<pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #0000FF;">void</span><span style="color: #000000;"> PromptForName(HandlerToUse handlerType)
{
    UITextField tf </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> UITextField (</span><span style="color: #0000FF;">new</span><span style="color: #000000;"> System.Drawing.RectangleF (12f, 45f, 260f, 25f));
    tf.BackgroundColor </span><span style="color: #000000;">=</span><span style="color: #000000;"> UIColor.White;
    tf.UserInteractionEnabled </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">true</span><span style="color: #000000;">;
    tf.AutocorrectionType </span><span style="color: #000000;">=</span><span style="color: #000000;"> UITextAutocorrectionType.No;
    tf.AutocapitalizationType </span><span style="color: #000000;">=</span><span style="color: #000000;"> UITextAutocapitalizationType.None;
    tf.ReturnKeyType </span><span style="color: #000000;">=</span><span style="color: #000000;"> UIReturnKeyType.Done;
    tf.SecureTextEntry </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">false</span><span style="color: #000000;">; 

    UIAlertView myAlertView </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> UIAlertView
    {
        Title </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">Please enter your name</span><span style="color: #800000;">"</span><span style="color: #000000;">,
        Message </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">this line is hidden</span><span style="color: #800000;">"</span><span style="color: #000000;">
    };

    myAlertView.AddButton(</span><span style="color: #800000;">"</span><span style="color: #800000;">Cancel</span><span style="color: #800000;">"</span><span style="color: #000000;">);
    myAlertView.AddButton(</span><span style="color: #800000;">"</span><span style="color: #800000;">Ok</span><span style="color: #800000;">"</span><span style="color: #000000;">);
    myAlertView.AddSubview(tf);
    </span><span style="color: #008000;">//</span><span style="color: #008000;"> More Setup Goes Here</span><span style="color: #008000;">
</span><span style="color: #000000;">    myAlertView.Show ();
}</span></pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>The method starts by instantiating a UITextField control with a bounding rectangle passed via its constructor.&#160; The rectangle itself is constructed with four parameters via its constructor: the first two parameters set the x and y offset from the origin point of the control, and the last two parameters set the size of the drawing area.&#160; After the initial construction of the UITextField, a few additional properties are set to customize the display.&#160; </p>
<p>Among the properties set is the <em>SecureTextEntry</em>.&#160; Setting this property to true will make the text field act like a password field and hide all the characters that you’ve entered.&#160; Once the text field has been created and initialized, we move on to creating a UIAlertView.&#160; Via object initialization, the <em>Title</em> and <em>Message</em> properties are set with some text.&#160; Finally, two buttons are created, and the text field is added as a sub-view to the UIAlertView.&#160; Calling the show on the UIAlertView causes the alert to pop up.&#160; Below you can see the rendered control.</p>
<p><a href="http://blog.kevfoo.com/wp-content/uploads/2009/11/TextField_As_Subview_UIAlertView.png"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="TextField_As_Subview_UIAlertView" border="0" alt="TextField_As_Subview_UIAlertView" src="http://blog.kevfoo.com/wp-content/uploads/2009/11/TextField_As_Subview_UIAlertView_thumb.png" width="244" height="122" /></a></p>
<p>So now that we have the basic control setup, we can tweak it so that the text field and the message label can both be displayed.</p>
<p>If you recall our custom UIAlertView control is currently composed of two UILabels, two UIButtons and a UITextField that we added.&#160; The UILabels are derived from UIView and is not a subclass of UIControl; whereas, the UIButton and the UITextField are both derived from UIControls.&#160; Since we want to position the UITextField beneath the labels, we can use this knowledge to selectively shift only the UIControls in the view down leaving the title and message labels in place.</p>
<p>To accomplish this task the following steps need to be performed:</p>
<p>1) The control height needs to be increased to make space for the text field and provide additional space to move the UIControls.&#160; This is done by setting the frame to a larger size.&#160; The frame will be increased by the height of the text field plus a buffer, so the control has space between it and the others. </p>
<p>This is what the frame looks like after being enlarged: </p>
<p><a href="http://blog.kevfoo.com/wp-content/uploads/2009/11/FrameEnlarged_CustomUIAlertView.png"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="FrameEnlarged_CustomUIAlertView" border="0" alt="FrameEnlarged_CustomUIAlertView" src="http://blog.kevfoo.com/wp-content/uploads/2009/11/FrameEnlarged_CustomUIAlertView_thumb.png" width="244" height="153" /></a>&#160;
<p>
  <br />2) Once the frame has been enlarged, we’ll loop through the sub-views looking for UIControls and adjust only those types down by the same text field plus buffer offset </p>
<p>Here is what the control looks like after each UIControl is found during the iteration through the sub-views. </p>
<p><a href="http://blog.kevfoo.com/wp-content/uploads/2009/11/FirstUIControlShifted_CancelButton.png"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="FirstUIControlShifted_CancelButton" border="0" alt="FirstUIControlShifted_CancelButton" src="http://blog.kevfoo.com/wp-content/uploads/2009/11/FirstUIControlShifted_CancelButton_thumb.png" width="244" height="153" /></a><a href="http://blog.kevfoo.com/wp-content/uploads/2009/11/SecondUIControlShifted_OkButton.png"><br />
    <br /><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="SecondUIControlShifted_OkButton" border="0" alt="SecondUIControlShifted_OkButton" src="http://blog.kevfoo.com/wp-content/uploads/2009/11/SecondUIControlShifted_OkButton_thumb.png" width="244" height="153" /></a> </p>
<p><a href="http://blog.kevfoo.com/wp-content/uploads/2009/11/FinalUIControlShifted_TextField.png"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="FinalUIControlShifted_TextField" border="0" alt="FinalUIControlShifted_TextField" src="http://blog.kevfoo.com/wp-content/uploads/2009/11/FinalUIControlShifted_TextField_thumb.png" width="244" height="154" /></a></p>
<p>Here is the code that does the control adjustment:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:ad10f1fa-b7f3-477a-8553-a24998ed586e" class="wlWriterEditableSmartContent">
<pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">class</span><span style="color: #000000;"> TextFieldAlertView : UIAlertView
{
    </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> UITextField _tf;

    </span><span style="color: #008000;">//</span><span style="color: #008000;"> ... </span><span style="color: #008000;">
</span><span style="color: #000000;">
    </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> AdjustControlSize()
    {
        </span><span style="color: #0000FF;">float</span><span style="color: #000000;"> tfExtH </span><span style="color: #000000;">=</span><span style="color: #000000;"> _tf.Frame.Size.Height </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800080;">16.0f</span><span style="color: #000000;">;

        var frame </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> RectangleF(</span><span style="color: #0000FF;">this</span><span style="color: #000000;">.Frame.X,
                                    </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.Frame.Y </span><span style="color: #000000;">-</span><span style="color: #000000;"> tfExtH</span><span style="color: #000000;">/</span><span style="color: #800080;">2</span><span style="color: #000000;">,
                                    </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.Frame.Size.Width,
                                    </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.Frame.Size.Height </span><span style="color: #000000;">+</span><span style="color: #000000;"> tfExtH);

        </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.Frame </span><span style="color: #000000;">=</span><span style="color: #000000;"> frame;

        </span><span style="color: #0000FF;">foreach</span><span style="color: #000000;">(var view </span><span style="color: #0000FF;">in</span><span style="color: #000000;"> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.Subviews)
        {
            </span><span style="color: #0000FF;">if</span><span style="color: #000000;">(view </span><span style="color: #0000FF;">is</span><span style="color: #000000;"> UIControl)
            {
                view.Frame </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> RectangleF(view.Frame.X,
                                            view.Frame.Y </span><span style="color: #000000;">+</span><span style="color: #000000;"> tfExtH,
                                            view.Frame.Size.Width,
                                            view.Frame.Size.Height);
            }
        }
    }
}</span></pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>So now that the desired look and feel of the control has been established, it is time to wire up the control.&#160; There are a couple options for handling events generated by the control: one is more in line with how Cocoa handles events, and another that is similar to how .Net works.&#160; </p>
<p>The Cocoa way to wire up delegates involves subclassing a special delegate class associated to the control and selectively overriding the methods for the actions you want to customize.&#160; In the case of the UIAlertView control, that delegate class is a <a href="http://www.go-mono.com/docs/index.aspx?link=C%3AMonoTouch.UIKit.UIAlertViewDelegate">UIAlertViewDelegate</a>.&#160; The delegate class includes overridable methods like <em>Clicked</em> where you can define the actions to take when a button on the control is clicked or where you can extend behaviors by overriding methods like <em>Preseneted</em> which is called after the control has been displayed to the user.</p>
<p>The .Net way to wire up events is to provide specific delegates for specific events.&#160; To make interacting with the Cocoa Touch controls easier, Monotouch provides public events for each one of the methods that can be overridden in the UIAlertViewDelegate class.&#160; Having the individual public events makes wiring up controls more intuitive for the .Net developer, but it is good to know about the Cocoa-style approach especially when looking at Objective-C examples and/or ADC docs.&#160; I have examples of wiring up the control via both methods in the example source.</p>
<p>The last topic I’d like to cover briefly is how I encapsulated the customization of control by subclassing UIAlertView.&#160; The key to getting the control to look right is to override the LayoutSubviews method and build out the text field, add it to the UIAlertView and shift the controls around there.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:8d5d040c-523d-4749-9da5-93a758fb8e3a" class="wlWriterEditableSmartContent">
<pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">override</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> LayoutSubviews ()
{
    </span><span style="color: #008000;">//</span><span style="color: #008000;"> layout the stock UIAlertView</span><span style="color: #008000;">
</span><span style="color: #000000;">    </span><span style="color: #0000FF;">base</span><span style="color: #000000;">.LayoutSubviews ();

    </span><span style="color: #008000;">//</span><span style="color: #008000;"> build out the text field</span><span style="color: #008000;">
</span><span style="color: #000000;">    _tf </span><span style="color: #000000;">=</span><span style="color: #000000;"> ComposeTextFieldControl(_secureTextEntry);

    </span><span style="color: #008000;">//</span><span style="color: #008000;"> add the text field to the UIAlertView</span><span style="color: #008000;">
</span><span style="color: #000000;">    </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.AddSubview(_tf);

    </span><span style="color: #008000;">//</span><span style="color: #008000;"> shift the UIControls to fit the text field</span><span style="color: #008000;">
</span><span style="color: #000000;">    AdjustControlSize();
}</span></pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>I’ve added some more customizations to my subclassed UIAlertView control that allows you to enable the text field security via a constructor parameter and a tweak to the control’s Transform property to shift the control up so it isn’t hidden by the keyboard.&#160; You can see those changes and the entire working example <a href="http://github.com/kevinmcmahon/CustomUITextFieldAlertView">here on github</a>.</p>
<p>Enjoy.</p>
<p>Links to some of the resources used: </p>
<ul>
<li><a href="http://iphonedevelopment.blogspot.com/2009/02/alert-view-with-prompt.html">Alert View with Prompt (iPhone Development Blog)</a> </li>
<li><a href="http://junecloud.com/journal/code/displaying-a-password-or-text-entry-prompt-on-the-iphone.html">Displaying a password or text entry prompt on the iPhone (Junecode Blog)</a> </li>
<li><a href="http://codesofa.com/blog/archive/2009/07/15/look-uialertview-is-dating-uitableview.html">Look UIAlertView is Dating UITableView (codesofa)</a> </li>
<li><a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIAlertViewDelegate_Protocol/UIAlertViewDelegate/UIAlertViewDelegate.html">iPhone Dev Center: UIAlertViewDelegate Protocol Reference (Apple, <em>login required</em>)</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevfoo.com/index.php/2009/11/monotouch-uialertview-uitextfield-crazy-delicious/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
