<?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>Judson Bandy, Author at HangZone</title>
	<atom:link href="https://hangzone.com/author/judson/feed/" rel="self" type="application/rss+xml" />
	<link>https://hangzone.com/author/judson/</link>
	<description>Mobile App and Game Development</description>
	<lastBuildDate>Fri, 28 Feb 2020 14:32:24 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://hangzone.com/wp-content/uploads/2022/04/cropped-HZ-Logo-32x32.png</url>
	<title>Judson Bandy, Author at HangZone</title>
	<link>https://hangzone.com/author/judson/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Local Security Measures in Xamarin.Forms</title>
		<link>https://hangzone.com/local-security-measures-xamarin-forms/</link>
		
		<dc:creator><![CDATA[Judson Bandy]]></dc:creator>
		<pubDate>Fri, 28 Feb 2020 14:32:24 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<guid isPermaLink="false">https://hangzone.com/?p=2085</guid>

					<description><![CDATA[<p>There are many types of mobile apps where security is of the utmost importance. When dealing with banking, payment, health, or other sensitive information, it is crucial to keep data ...</p>
<p>The post <a href="https://hangzone.com/local-security-measures-xamarin-forms/">Local Security Measures in Xamarin.Forms</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>There are many types of mobile apps where security is of the utmost importance. When dealing with banking, payment, health, or other sensitive information, it is crucial to keep data safe. There may even be legal ramifications for exposing user data. This conversation typically begins with a secure login, protecting data in transit, and data access. While these are the most important aspect, we’re going to look at a different aspect of protection.</p>
<p>How can we best protect users from exposing data locally? Yes, a secure login is the first step, but what if a user logs in, and then exits the app without hard closing it. If someone else uses their phone, are we able to protect the data? Also, what if they put their phone down with the app still up? There are several little steps that can be done to help the user protect their data. Let’s look at a few ways to help further secure your apps.</p>
<h2>Create the Xamarin.Forms Project</h2>
<p>First, we will create a Xamarin.Forms project. I am doing it on a Windows computer, but it can also be done on Visual Studio for Mac. Open Visual Studio and click to create a new project. Select Mobile App (Xamarin.Form) in C# and press Next. I’m going to name my project, “XamarinSecurityExample.” Then, press Create. On the template selection, we are going with Blank, and Android and iOS for platforms. The app is now created. Now, we are just going to make a simple two page application to show how our security features can be plugged in.</p>
<p>Open MainPage.xaml. This is the first page that opens when you start the app and it will be our mock login page. Start by deleting everything inside the StackLayout and add the following.</p>
<pre><code>&lt;StackLayout&gt;
    &lt;Label Text="Login Page"
      FontSize="Medium"
      HorizontalOptions="Center"
      VerticalOptions="CenterAndExpand" /&gt;
    &lt;Button Text="Very Secure Login"
      HorizontalOptions="Center"
      VerticalOptions="CenterAndExpand"
      Clicked=“LoginButton_Clicked”/&gt;
&lt;/StackLayout&gt;</code></pre>
<p>This code simply puts a title of Login Page in the top half of the screen, and a button in the bottom half of the page. The button has a function that we will define in the codebehind when it is clicked.</p>
<p>Let’s do that now. Open the MainPage.xaml.cs. Define our new method like this.</p>
<pre><code>private void LoginButton_Clicked(object sender, EventArgs e)
{
    Application.Current.MainPage = new SecurePage();
}</code></pre>
<p>This will navigate to our a new page when the button is pressed. Now, we have to create the new page.</p>
<p>Right click on our shared project, and click Add-&gt;New Item… Select Content Page, and name it, “SecurePage.xaml.” Let’s add some content to SecurePage.xaml. Replace the StackLayout with the following.</p>
<pre><code>&lt;StackLayout&gt;
    &lt;Label Text="Very private information that should not be seen"
      FontSize="Medium"
      HorizontalOptions="Center"
      VerticalOptions="CenterAndExpand" /&gt;
    &lt;Button Text="Logout"
      HorizontalOptions="Center"
      VerticalOptions="CenterAndExpand"
      Clicked="LogoutButton_Clicked"/&gt;
&lt;/StackLayout&gt;</code></pre>
<p>The UI on this page is just like our login page. There is a label at the top that talks about all of our secure data, and then, a button at the bottom. Again, we need to go to the codebehind to define our Clicked method. Open SecurePage.xaml.cs, and add the following method.</p>
<pre><code>private void LogoutButton_Clicked(object sender, EventArgs e)
{
    Application.Current.MainPage = new MainPage();
}</code></pre>
<p>Our base app is now finished. It’s clearly nothing to write home about, but it will get the job done for our example. There is a login page, and a page that you navigate to after “logging in” that has secure information.</p>
<h2>Auto Logout When Returning to App</h2>
<p>The first thing we’ll tackle is auto logout when returning to the app. This will happen if a user is logged in, exits the app (but does not hard close), then clicks to reopen the app. If the user is only gone for a short period of time, it should be fine to keep the user logged in. Otherwise, we certainly want to auto logout the user. Let’s jump back into the code. This one should be fairly straightforward. First, open App.xaml.cs. Add the following code.</p>
<pre><code>public static bool IsUserLoggedIn = false;
private DateTime? SleepTime = null;

protected override void OnSleep()
{
    SleepTime = DateTime.Now;
}

protected override void OnResume()
{
    if (SleepTime != null)
    {
        if (DateTime.Now.Subtract((DateTime)SleepTime) &gt; TimeSpan.FromSeconds(120))
        {
            LogOutUser();
        }
    }
}

public static void LogOutUser()
{
    if (!IsUserLoggedIn)
        return;

    Application.Current.MainPage = new MainPage();
}</code></pre>
<p>To start with, we added two variables. One is SleepTime, which keeps track of time away from the app, and the other is IsUserLoggedIn, which tracks if the user is logged in. Then, we override the OnSleep method to set the SleepTime variable to the time that the app went to sleep. Next, we override OnResume. There, we check to see how long we have been away from the app, and if it was longer than 2 minutes, we call the LogOutUser method. In that method, we check to see that the user is logged in, and if so, we return the app to the login page.</p>
<p>Finally, we need to adjust the IsUserLoggedIn method when the user logs in and out. In LoginButton_Clicked in MainPage.xaml.cs, add the following.</p>
<pre><code>App.IsUserLoggedIn = true;</code></pre>
<p>Then, in LogoutButton_Clicked in SecurePage.xaml.cs, add this.</p>
<pre><code>App.IsUserLoggedIn = false;</code></pre>
<p>That’s it! The user will be able to resume their session if they return to the app within 2 minutes of closing it. Otherwise, they will be auto logged out and have to log in again to access their data.</p>
<h2>Auto Logout for Inactivity</h2>
<p>That is an excellent solution for a user that exits the app and then returns, but what if the user leaves their phone with the app still up? Sensitive data could easily be exposed. To try to prevent this, we would like to auto logout the user after a certain amount of inactivity. Unfortunately, this code is a little more complicated. This is due to the fact that user input is detected in the Android and iOS sections, respectively, depending on your device type. Let’s get started and try the Android version first.</p>
<h2>Android Inactivity</h2>
<p>Open MainActivity.cs in the Android section of the project. Our strategy will be to throw a popup after a certain amount of inactivity, and then if there is no activity, log the user out. Let’s start by defining variables for those amounts of time and for a handler.</p>
<pre><code>public static long DISCONNECT_WARNING = 240000; // 4 min = 4 * 60 * 1000ms = 240000
public static long DISCONNECT_TIMEOUT = 60000; // 1 min = 1 * 60 * 1000ms = 60000
public Handler DisconnectWarningHandler;</code></pre>
<p>We create 2 static variables. First, the warning amount of time will be 4 minutes, and then the actual logout will occur if there is no activity for another minute. Next, add the following code to the OnCreate method.</p>
<pre><code>DisconnectWarningHandler = new Handler(new WarningHandlerICallback(this));</code></pre>
<p>Now, we need to define the WarningHandlerICallback class. This is still inside the MainActivity class. Then, we will add our code to start and stop the inactivity handlers.</p>
<pre><code>public Handler disconnectWarningHandler;

public class WarningHandlerICallback : Java.Lang.Object, Handler.ICallback
{
    private MainActivity mainActivity;

    public WarningHandlerICallback(MainActivity mainActivity)
    {
        this.mainActivity = mainActivity;
    }

    public bool HandleMessage(Message msg)
    {
        App.WarnUserAboutInactivity();
        mainActivity.resetDisconnectTimer();
        return true;
    }
}

System.Action LogoutAction = () =&gt;
{
    App.LogOutUser();
};

public void resetWarningTimer()
{
    DisconnectWarningHandler.RemoveMessages(1);
    DisconnectWarningHandler.SendEmptyMessageDelayed(1, DISCONNECT_WARNING);
}

public void stopWarningTimer()
{
    DisconnectWarningHandler.RemoveMessages(1);
}

public void resetDisconnectTimer()
{
    DisconnectWarningHandler.RemoveCallbacks(LogoutAction);
    DisconnectWarningHandler.PostDelayed(LogoutAction, DISCONNECT_TIMEOUT);
}

public void stopDisconnectTimer()
{
    DisconnectWarningHandler.RemoveCallbacks(LogoutAction);
}

protected override void OnStop()
{
    base.OnStop();
    stopWarningTimer();
    stopDisconnectTimer();
}

protected override void OnResume()
{
    base.OnResume();
    resetWarningTimer();
    stopDisconnectTimer();
}

public override void OnUserInteraction()
{
    resetWarningTimer();
    stopDisconnectTimer();
}</code></pre>
<p>That’s a lot to take in, but we’ll try to explain it. OnUserInteraction is where we are able to register user activity. When the user does anything, we reset our warning timer and stop our disconnect timer. Only one of these timers is ever actually on a once, but this does a full reset if one or none of the timers are running. The ResetWarningTimer method calls to send an empty delayed message for the disconnect warning length of time that we set. If that time passes with no activity, HandleMessage in our WarningHandlerICallback class gets called. There, we call the App.xaml.cs file to throw a warning popup, and we start our disconnect timer.</p>
<p>The disconnect timer does a PostDelayed for the length of time that we set for disconnect. This performs an action that we call LogoutAction, which calls the App.xaml.cs LogOutUser method that we created earlier. OnStop and OnResume are also overridden so that the timers are reset when you exit and reenter the app.</p>
<p>Finally, go back to App.xaml.cs. We have to add the inactivity warning method that we called from MainActivity.</p>
<pre><code>public static async void WarnUserAboutInactivity()
{
    if (!IsUserLoggedIn)
        return;

    await Application.Current.MainPage.DisplayAlert("Inactivity Warning", "Are you still there? If you don't return to the application, you will be logged out.", "OK");
}</code></pre>
<p>As you can see, if the user is logged in, they will receive a popup warning that they will soon be logged out for inactivity. That’s it. The Android solution is done.</p>
<p>***A quick word of warning. I would strongly suggest using custom popups instead of the built in DisplayAlert popups. There is no way to programmatically close these popups, which can be problematic in a number of different situations. For instance, you would likely want to close the warning popup about the impending logout once the user is actually logged out. There also can be issues with multiple popups being displayed at once. Finally, clicking the button on the system popup doesn’t register through OnUserInteraction (you can easily use MessagingCenter to alert the MainActivity class when/if the popup is dismissed though).</p>
<h2>iOS Inactivity</h2>
<p>Next, we’ll set up the iOS inactivity check. In the iOS section of the project, open AppDelegate.cs. Add the following code.</p>
<pre><code>public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    …

    <del>return base.FinishedLaunching(app, options);</del>
    var success = base.FinishedLaunching(app, options);

    var allGesturesRecognizer = new AllGesturesRecognizer(delegate
    {
        ResetIdleTimer();
    });

    this.Window.AddGestureRecognizer(allGesturesRecognizer);

    if (IdleTimer == null)
    {
        IdleTimer = NSTimer.CreateRepeatingScheduledTimer(TimeSpan.FromSeconds(10), delegate
        {
            LogOutMethod();
        });
    }

    return success;
}

private NSTimer IdleTimer = null;
private bool TouchDetected = false;
private int LogoutCounter = 0;
private bool IsInactivityPopupDisplayed = false;

[Export("applicationWillResignActive:")]
override public void OnResignActivation(UIApplication uiApplication)
{
    IdleTimer.Invalidate();
    IdleTimer = null;
    LogoutCounter = 0;

    base.OnResignActivation(uiApplication);
}

[Export("applicationDidBecomeActive:")]
override public void OnActivated(UIApplication uiApplication)
{
    if (IdleTimer == null)
    {
        IdleTimer = NSTimer.CreateRepeatingScheduledTimer(TimeSpan.FromSeconds(10), delegate
        {
            LogOutMethod();
        });
    }

    base.OnActivated(uiApplication);
}

private void ResetIdleTimer()
{
    TouchDetected = true;
}

private void LogOutMethod()
{
    if (TouchDetected)
    {
        if (IsInactivityPopupDisplayed)
        {
            IsInactivityPopupDisplayed = false;
        }

        LogoutCounter = 0;
        TouchDetected = false;
        return;
    }

    LogoutCounter++;

    if (LogoutCounter == 24) //24 4 min = 4 * (6 * 10sec)
    {
        App.WarnUserAboutInactivity();
    }
    else if (LogoutCounter &gt;= 30) //30 5 min = 5 * (6 * 10sec)
    {
        App.LogOutUser();
        LogoutCounter = 0;
    }
}

class AllGesturesRecognizer : UIGestureRecognizer
{
    public delegate void OnTouchesEnded();

    private OnTouchesEnded touchesEndedDelegate;

    public AllGesturesRecognizer(OnTouchesEnded touchesEnded)
    {
        this.touchesEndedDelegate = touchesEnded;
    }

    public override void TouchesEnded(NSSet touches, UIEvent evt)
    {
        this.State = UIGestureRecognizerState.Failed;
        this.touchesEndedDelegate();

        base.TouchesEnded(touches, evt);
    }
}</code></pre>
<p>This is all of the iOS code at once. Let’s try to break it down. In the FinishedLaunching method, we create a GestureRecognizer that calls ResetIdleTimer whenever touch is detected. The ResetIdleTimer method sets TouchDetected, an instance variable, to true. Next in FinishedLaunching, a timer is created that calls LogOutMethod every ten seconds. If TouchDetected is true, the LogoutCounter is reset. Otherwise, the inactivity warning method in App.xaml.cs is called after 4 minutes, and the logout method is called after an additional minute of inactivity.</p>
<p>Test it out, and you’ll see an inactivity warning after you sit around on the secure page for a while. Start interacting with the application and nothing will happen. Otherwise, you will be auto logged out after another minute of inactivity.</p>
<h2>Obscure Information When Looking at Recent Apps</h2>
<p>The final issue we want to tackle is the view that shows recently open apps. On iOS this is called the App Switcher, and on new iPhone and iPad devices, you get to this screen by swiping up from the bottom to the middle of the screen and holding. On Android, it’s the recent apps overview, and you get there by pressing the square button on older devices or a quick swipe from the bottom on newer devices.</p>
<p>Regardless of platform, this view shows recently open apps that are currently in the background. Each app shows a picture of your last screen in the app. You are able to click on the picture to reenter an app or you can hard close the app. The issue here is information potentially shown on the picture. If we were on a page containing sensitive information when we exited the app, that sensitive information would now be visible. To prevent this, we are going to obscure what the user sees.</p>
<h2>Obscure Display in Android</h2>
<p>Let’s start with Android. This time it’s the simple option. In the OnCreate method in MainActivity.cs, add the following line.</p>
<pre><code>Window.SetFlags(WindowManagerFlags.Secure, WindowManagerFlags.Secure);</code></pre>
<p>That’s it. If you go to the recent apps overview, you will see that it shows a white screen with no content, which you can see below. We’ve done it! Besides hiding the display, this flag also prevents the user from taking screenshots inside the app.</p>
<p><a href="https://hangzone.com/wp-content/uploads/2020/02/Blog-Local-Security-Xamarin-Secure-Flag.png"><img fetchpriority="high" decoding="async" class="alignnone size-medium wp-image-2086" src="https://hangzone.com/wp-content/uploads/2020/02/Blog-Local-Security-Xamarin-Secure-Flag-178x300.png" alt="Blog Local Security Xamarin Secure Flag" width="178" height="300" srcset="https://hangzone.com/wp-content/uploads/2020/02/Blog-Local-Security-Xamarin-Secure-Flag-178x300.png 178w, https://hangzone.com/wp-content/uploads/2020/02/Blog-Local-Security-Xamarin-Secure-Flag-608x1024.png 608w, https://hangzone.com/wp-content/uploads/2020/02/Blog-Local-Security-Xamarin-Secure-Flag.png 671w" sizes="(max-width: 178px) 100vw, 178px" /></a></p>
<h2>Obscure Display in iOS App Switcher</h2>
<p>Open the AppDelegate.cs file, and we will get started with the iOS version. First add a private instance variable of UIView.</p>
<pre><code>private UIView _view;</code></pre>
<p>Next, we will add lines to the OnResignActivation and OnActivated methods that we overrode for the inactivity check.</p>
<pre><code>override public void OnResignActivation(UIApplication uiApplication)
{
    var window = UIApplication.SharedApplication.KeyWindow;
    var rect = UIScreen.MainScreen.Bounds;
    _view = new UIView { Frame = rect };
    _view.BackgroundColor = UIColor.FromRGB(60,179,113);
    window.AddSubview(_view);

    …
}

override public void OnActivated(UIApplication uiApplication)
{
    …

    if (_view != null)
    {
        _view.RemoveFromSuperview();
        _view.Dispose();
    }

    …
}</code></pre>
<p>When we resign active, we instantiate our UIView, make it the size of the screen, give it a green color, and then add it as a subview over our app. When the app is activated, we remove the view. That’s it. Test it out and you will see a solid green color covering the app’s screen when the App Switcher is up.</p>
<h2>Conclusion</h2>
<p>Great work! We were able to look at several ways to improve local security in our apps. First, we added an auto logout for when the app is in the background for too long. Then, we added an auto logout if the user is inactive inside the app for five minutes. Finally, we secured any sensitive information that could be displayed when the App Switcher is displayed. Good luck implementing these security concepts into your next app that requires dealing with delicate information. As always, thanks for reading the HangZone blog.</p>
<p>The post <a href="https://hangzone.com/local-security-measures-xamarin-forms/">Local Security Measures in Xamarin.Forms</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Custom Renderers in Xamarin.Forms Part 2</title>
		<link>https://hangzone.com/custom-renderers-xamarin-forms-part-2/</link>
		
		<dc:creator><![CDATA[Judson Bandy]]></dc:creator>
		<pubDate>Wed, 27 Nov 2019 18:25:13 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://hangzone.com/?p=2056</guid>

					<description><![CDATA[<p>In part 2 of our custom renderer blog post, we will continue to look at uses for custom renderers in Xamarin.Forms. In part 1, we made a navigation page in ...</p>
<p>The post <a href="https://hangzone.com/custom-renderers-xamarin-forms-part-2/">Custom Renderers in Xamarin.Forms Part 2</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In part 2 of our custom renderer blog post, we will continue to look at uses for custom renderers in Xamarin.Forms. In part 1, we made a navigation page in Xamarin.Forms. The toolbar item on the page used an icon from <a href="http://material.io">material.io</a> for the Android version and used a system icon for the iOS version. We were able to use the system icon thanks to a custom renderer. If you have not read it, you can find part 1 <a href="https://hangzone.com/custom-renderers-xamarin-forms-part-1/">here</a>. We will start this project where part 1 left off.</p>
<h2>Extending an Element</h2>
<p>Let’s continue with the same Xamarin.Forms solution, which I named CustomRendererSample. The next thing that we want to add is a gradient underneath the toolbar. A shadow can be added to the Android project by adding an elevation property definition under the Resources-&gt;layout-&gt;Toolbar.axml file. This is not what we’re after though. We are going to add a loud, slightly obnoxious gradient on both iOS and Android under the toolbar.<span class="Apple-converted-space"> </span></p>
<p>The Xamarin.Forms control that we want to use is the BoxView. Unfortunately, we only have the ability to give it a single uniform color. To add our desired functionality, we will subclass BoxView and add additional properties to our new control. Then, we will create custom renderers for iOS and Android that will tell the system how to use our new properties. Hopefully, it won’t be too hard.</p>
<h2>Create our Custom BoxView</h2>
<p>Let’s start by creating our new BoxView class. Right click on the Shared Project and select Add-&gt;New Item… Add a new class called GradientBoxView.cs. We could create our properties simply as public properties, but instead, we are going to use BindableProperty. This will allow us to set these properties in a style. Styles do not make much sense if you are only using them once, but they can be quite helpful for maintaining and updating your code if objects with the same appearance are used multiple times.</p>
<p>Add the following code to your GradientBoxView class.</p>
<pre><code>public class GradientBoxView : BoxView
{
    public static readonly BindableProperty StartColorProperty = BindableProperty.Create("StartColor", typeof(Color), typeof(GradientBoxView), Color.Transparent);
    public static readonly BindableProperty EndColorProperty = BindableProperty.Create("EndColor", typeof(Color), typeof(GradientBoxView), Color.Transparent);
    public static readonly BindableProperty IsVerticalProperty = BindableProperty.Create("IsVertical", typeof(bool), typeof(GradientBoxView), true);

    public Color StartColor
    {
        get { return (Color)GetValue(StartColorProperty); }
        set { SetValue(StartColorProperty, value); }
    }

    public Color EndColor
    {
        get { return (Color)GetValue(EndColorProperty); }
        set { SetValue(EndColorProperty, value); }
    }

    public bool IsVertical
    {
        get { return (Color)GetValue(IsVerticalProperty); }
        set { SetValue(IsVerticalProperty, value); }
    }
}</code></pre>
<p>You can see that the class inherits from BoxView, so that we retain all of the functionality of that class. Then, we added variables for StartColor, EndColor, and IsVertical. As the names suggest, these will define the starting color, ending color, and direction of the gradient.</p>
<h2>Implementing the GradientBoxView</h2>
<p>Now, let’s head over to App.xaml to create a style. Like we said, a style is nice in case we want to use the same gradient on a number of pages. In the Application.Resources section, add the following code.<span class="Apple-converted-space"> </span></p>
<pre><code>&lt;ResourceDictionary&gt;
    &lt;Style x:Key=“AwesomeGradientStyle” TargetType=“customrenderersample:GradientBoxView”&gt;
        &lt;Setter Property=“StartColor” Value=“DarkBlue”/&gt;
        &lt;Setter Property=“EndColor” Value=“#10FFFFFF”/&gt;
        &lt;Setter Property=“IsVertical” Value=“True”/&gt;
        &lt;Setter Property=“HeightRequest” Value=“10”/&gt;
    &lt;/Style&gt;
&lt;/ResourceDictionary&gt;</code></pre>
<p>As you can see, a style is added that sets all of our properties for the GradientBoxView. App.xaml will have to add “xmlns:customrendersample=“clr-namespace:CustomRendererSample” so that GradientBoxView will be imported into this class.</p>
<p>Now, we can jump over to MainPage.xaml to add GradientBoxView to the page. Change the ContentPage.Content to look like this.</p>
<pre><code>&lt;ContentPage.Content&gt;
    &lt;Grid&gt;
        &lt;Grid.RowDefinitions&gt;
            &lt;RowDefinition Height="auto"/&gt;
            &lt;RowDefinition Height="*"/&gt;
        &lt;/Grid.RowDefinitions&gt;
        &lt;customrenderersample:GradientBoxView Style=“{StaticResource AwesomeGradientStyle}”/&gt;
        &lt;Label Grid.Row="1" x:Name="SearchLabel" Text="Search" VerticalOptions="Center" HorizontalOptions="Center"/&gt;
    &lt;/Grid&gt;
&lt;/ContentPage.Content&gt;</code></pre>
<p>You can see that we adjusted our grid to put the gradient underneath the toolbar at the top of the page, and our SearchLabel is still in the middle. Again, we need the same CustomRendererSample definition and prefix to use the class. That wraps up the code in our Shared Project. Let’s move on to our custom renderers and set our new GradientBoxView properties in motion.</p>
<h2>iOS Custom Renderer</h2>
<p>Let’s start with the iOS renderer. Its code is a little simpler, so it should be an easier place to begin. Navigate to the iOS project, right click and select Add-&gt;New Item… Choose a class and name it GradientBoxViewRenderer.cs. Click the Add button, and we’re ready to get started.</p>
<p>First, we need to add an assembly line so that this code will be used. Above the line that defines the namespace, add:</p>
<pre><code>[assembly: ExportRenderer(typeof(GradientBoxView), typeof(GradientBoxViewRenderer))]</code></pre>
<p>This line tells our code to use this renderer whenever GradientBoxView occurs in the code. If you get errors in this code, or anywhere else in the custom renderers, you should be able to hover over the error and select for Visual Studio to add the appropriate using directive. Next, we will make this class a subclass of BoxRenderer.</p>
<pre><code>class GradientBoxViewRenderer : <b>BoxRenderer</b></code></pre>
<p>To add our gradient to the boxview, we only need to override one method, the Draw function.</p>
<pre><code>public override void Draw(CGRect rect)
{
    base.Draw(rect);

    var stack = Element as GradientBoxView;
    var topColor = stack.StartColor.ToCGColor();
    var bottomColor = stack.EndColor.ToCGColor();
    var gradientLayer = new CAGradientLayer
    {
        Frame = rect,
        Colors = new CGColor[] { topColor, bottomColor }
    };

    if (!stack.IsVertical)
    {
        gradientLayer.StartPoint = new CGPoint(0, 0.5);
        gradientLayer.EndPoint = new CGPoint(1, 0.5);
    }

    NativeView.Layer.InsertSublayer(gradientLayer, 0);
}</code></pre>
<p>Let’s walk through what is going on. First, we are getting our GradientBoxView and setting it to a local variable, stack. Next, we are getting the start color and end color from it, and converting the colors to CGColors. Then, we create a CAGradientLayer to the size of our BoxView with the gradient colors. Finally, we adjust the direction if horizontal is desired, and we add the gradient to the native iOS BoxView. That’s it! It is fairly straightforward, and just like that, the iOS version is good to go. Now, let’s move to Android.</p>
<h2>Android Custom Renderer</h2>
<p>This custom renderer is a little more involved, but we can do it. Go to the Android project in the Solution Explorer, and add a new class just like we did for the iOS renderer. We will also name this class GrandientBoxViewRenderer.cs. Add the same assembly directive above the namespace definition so that this renderer will be used for all GradientBoxViews when running on Android. Then, add the code so that this class will be a subclass of BoxRenderer. That’s where the same code ends.</p>
<p>First, we’ll add instance variables for our GradientBoxView properties at the top of the renderer class definition and an empty initializer for the class.</p>
<pre><code>public class GradientBoxViewRenderer : BoxRenderer
{
    <b>private Color StartColor { get; set; }
    private Color EndColor { get; set; }
    private bool IsVertical { get; set; }

    public GradientBoxViewRenderer(Context context) : base(context)
    {

    }</b>
}</code></pre>
<p>Then, we will override OnElementChanged. We will use this to set the values of our instance variables.</p>
<pre><code>protected override void OnElementChanged(ElementChangedEventArgs&lt;BoxView&gt; e)
{
    base.OnElementChanged(e);

    if (e.OldElement != null || Element == null)
    {
        return;
    }

    try
    {
        var stack = e.NewElement as GradientBoxView;

        this.StartColor = stack.StartColor;
        this.EndColor = stack.EndColor;
        this.IsVertical = stack.IsVertical;
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(@"ERROR:", ex.Message);
    }
}</code></pre>
<p>Now that we have our variables from GradientBoxView, it’s time to do our drawing code to create the gradient on the Android BoxView.</p>
<pre><code>protected override void DispatchDraw(global::Android.Graphics.Canvas canvas)
{
    if (global::Android.OS.Build.VERSION.SdkInt &gt; global::Android.OS.BuildVersionCodes.O)
    {
        var orientation = GradientDrawable.Orientation.TopBottom;

        if (!this.IsVertical)
        {
            orientation = GradientDrawable.Orientation.LeftRight;
        }

        var specialGradient = new GradientDrawable(orientation, new[] { this.StartColor.ToAndroid().ToArgb(), this.EndColor.ToAndroid().ToArgb() });
        ViewCompat.SetBackground(this, specialGradient);
        return;
    }

    global::Android.Graphics.LinearGradient gradient = null;

    if (this.IsVertical)
    {
        gradient = new global::Android.Graphics.LinearGradient(0, 0, 0, Height, this.StartColor.ToAndroid(),this.EndColor.ToAndroid(), global::Android.Graphics.Shader.TileMode.Clamp);
    }
    else
    {
        gradient = new global::Android.Graphics.LinearGradient(0, 0, Width, 0, this.StartColor.ToAndroid(), this.EndColor.ToAndroid(), global::Android.Graphics.Shader.TileMode.Clamp);
    }

    var paint = new global::Android.Graphics.Paint()
    {
        Dither = true,
    };
    paint.SetShader(gradient);
    canvas.DrawPaint(paint);
    base.DispatchDraw(canvas);
}</code></pre>
<p>As you can see, the technique is different for Android versions greater than O. For the newer versions, we simply get our orientation, then create a GradientDrawable with our colors. Then, we set it as the background on the native ViewCompat. For the older Android versions, we create a LinearGradient based on the gradient direction. Then, we DrawPaint the gradient onto the canvas. That’s it for Android and our GradientBoxView. Run the project and see your custom GradientBoxView in action! You can easily change the color, direction, or size if you so desire.</p>
<p><a href="https://hangzone.com/wp-content/uploads/2019/11/Blog-Xamarin-Forms-Custom-Renderer-Finished-App.png"><img decoding="async" class="alignnone size-medium wp-image-2057" src="https://hangzone.com/wp-content/uploads/2019/11/Blog-Xamarin-Forms-Custom-Renderer-Finished-App-188x300.png" alt="Blog Xamarin Forms Custom Renderer Finished App" width="188" height="300" srcset="https://hangzone.com/wp-content/uploads/2019/11/Blog-Xamarin-Forms-Custom-Renderer-Finished-App-188x300.png 188w, https://hangzone.com/wp-content/uploads/2019/11/Blog-Xamarin-Forms-Custom-Renderer-Finished-App-640x1024.png 640w, https://hangzone.com/wp-content/uploads/2019/11/Blog-Xamarin-Forms-Custom-Renderer-Finished-App.png 674w" sizes="(max-width: 188px) 100vw, 188px" /></a></p>
<h2>Conclusion</h2>
<p>Great job! We successfully created a custom control in Xamarin.Forms—a GradientBoxView. This is a nice tool for adding gradients under objects in your projects to further set them off or provide separation of sections. Not only that, but you should now have a good idea of how to create other custom controls using custom renderers. It’s not always simple, but you can usually use custom renderers to accomplish any visual look or action that would natively be available on the platform. As always, thanks for reading the HangZone blog!</p>
<p>The post <a href="https://hangzone.com/custom-renderers-xamarin-forms-part-2/">Custom Renderers in Xamarin.Forms Part 2</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Custom Renderers in Xamarin.Forms Part 1</title>
		<link>https://hangzone.com/custom-renderers-xamarin-forms-part-1/</link>
		
		<dc:creator><![CDATA[Judson Bandy]]></dc:creator>
		<pubDate>Mon, 30 Sep 2019 16:06:38 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://hangzone.com/?p=2041</guid>

					<description><![CDATA[<p>Xamarin.Forms is a great tool for cross platform app development. It gives you the ability to write shared code that is used by different operating systems. Not only are you ...</p>
<p>The post <a href="https://hangzone.com/custom-renderers-xamarin-forms-part-1/">Custom Renderers in Xamarin.Forms Part 1</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Xamarin.Forms is a great tool for cross platform app development. It gives you the ability to write shared code that is used by different operating systems. Not only are you able to write shared logic, but you are also able to write shared UI code. This allows you to save time in initial development and makes it much more maintainable since there is only one version of the code. Not only this, but Xamarin.Forms is able to use native elements of each platform so that you are still able to get a native look and feel for each device.</p>
<p>Although this shared code is fast and works well, it doesn’t always provide the granularity that we are looking to use for each platform. Sometimes a finer brush is needed to paint our masterpiece. This is no reason to fret, though. Xamarin.Forms allows us to create custom renderers so that we are able to extend controls to take advantage of native specific elements for each platform. In this blog post, we will create a couple of custom renderers in a Xamarin.Forms project to make elements that are more robust than what comes out of the box.</p>
<h2>Create Xamarin.Forms Project</h2>
<p>Let’s start by creating a new Xamarin.Forms project. I am developing on a Windows computer in Visual Studio 2019. You can do this just as well on Visual Studio for Mac. We are are going to write this app to run for both iOS and Android.</p>
<p>First, open Visual Studio, and create a new project. Select Mobile App (Xamarin.Forms), and click Next. Give your project a name, mine is called “CustomRendererSample,” choose a location, and create the project. Select a Blank template, and for platforms, we are doing Android and iOS. You can certainly do UWP as well, but we are only targeting iOS and Android in this example. Press OK, and our project is now created.</p>
<h2>Toolbar Buttons</h2>
<p>For this example, we are going to make an app with a hierarchical navigation scheme. This has the toolbar at the top, and pages are added to and popped off the stack as you navigate. We are only going to have one page for our example, though. With the toolbar at the top, it is common to have toolbar buttons. These can be save, cancel, back, refresh, and so on. You will find these in many of the first party phone apps (like Settings) or pretty much any native enterprise style app. Toolbar buttons can be created through Xamarin.Forms, but as an extension to the control, we are going to have the app use System toolbar buttons on iOS to get a totally native look.</p>
<p>First, let’s get the navigation page set up for the app. Open App.xaml.cs in the Shared Project of your Solution. Make the following edit to the constructor.</p>
<pre><code>MainPage = <b>new NavigationPage(</b>new MainPage()<b>)</b>;</code></pre>
<p>This creates a NavigationPage as the root page of the app, and then adds MainPage as the content of the navigation page. Feel free to go ahead and run the app. You should now see a blank toolbar at the top of your screen, and the Xamarin.Forms welcome label displayed in the middle of it. We’re off to a good start!</p>
<p>Now, open MainPage.xaml. Start by deleting the entire StackLayout and the welcome label that is inside it. We are going to make our own content later.</p>
<pre><code><del>&lt;StackLayout&gt;
    &lt;!-- Place new controls here --&gt;
    &lt;Label Text="Welcome to Xamarin.Forms!"
      HorizontalOptions="Center"
      VerticalOptions="CenterAndExpand" /&gt;
&lt;/StackLayout&gt;</del></code></pre>
<p>Next, we’ll give the page a title to go on the toolbar. Set the title property on ContentPage to “Awesome Page.”</p>
<pre><code>&lt;ContentPage …… <b>Title=“Awesome Page”</b>&gt;</code></pre>
<h2>Android Toolbar Buttons</h2>
<p>We don’t have to add images to our project for iOS since we are using system buttons, but we do need them for Android. We are able to download Android buttons without any problem from the material.io website. All Android icons are open source and are available to be used in any project. We are going to use the search icon in our project. Go to this <a href="https://material.io/resources/icons/?style=baseline">page</a>, select the “search” icon, and download the SVG 24 file.<span class="Apple-converted-space"> </span></p>
<p>I like to open this file in Inkscape (use can use any vector drawing program to edit the file without losing image quality). The image, which is a little larger than 17&#215;17, is designed to be centered on a transparent 24&#215;24 background. Once you do that, we want to change the color of the icon to white, and create 3 different sizes—24&#215;24, 48&#215;48, and 72&#215;72. Now, they are ready to export and add to our project. Please see the image below for what my icons look like.</p>
<p><a href="https://hangzone.com/wp-content/uploads/2019/09/Blog-Xamarin-Forms-Custom-Renderers-Toolbar-Search-Icons.png"><img decoding="async" class="alignnone size-medium wp-image-2045" src="https://hangzone.com/wp-content/uploads/2019/09/Blog-Xamarin-Forms-Custom-Renderers-Toolbar-Search-Icons-300x127.png" alt="Blog Xamarin Forms Custom Renderers Toolbar Search Icons" width="300" height="127" srcset="https://hangzone.com/wp-content/uploads/2019/09/Blog-Xamarin-Forms-Custom-Renderers-Toolbar-Search-Icons-300x127.png 300w, https://hangzone.com/wp-content/uploads/2019/09/Blog-Xamarin-Forms-Custom-Renderers-Toolbar-Search-Icons-1024x435.png 1024w, https://hangzone.com/wp-content/uploads/2019/09/Blog-Xamarin-Forms-Custom-Renderers-Toolbar-Search-Icons.png 1154w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Let’s go back to Visual Studio. Inside the Android project, open the Resource folder. Drag the 24&#215;24, 48-48, and 72&#215;72 icons into the drawable, drawable-hdpi, and drawable-xxhdpi folders, respectively. All three of my icons are named “searchIconDroid.png.” Now that the icons are created and added to the project, we can return to the code.</p>
<p>On a side note, these drawable folders are currently not working in the Microsoft version of Visual Studio. You can look through the File Explorer and see that the folders do not actually exist. To fix it, simply delete the fake folders that are currently shown, and re-add folders with the same names.</p>
<h2>Create the Toolbar Item in XAML</h2>
<p>Open MainPage.xaml again, and add the following code.</p>
<pre><code>&lt;ContentPage.ToolbarItems&gt;
    &lt;ToolbarItem x:Name="SearchButton"
      Text="Search"&gt;
        &lt;ToolbarItem.IconImageSource&gt;
            &lt;OnPlatform x:TypeArguments="FileImageSource"&gt;
                &lt;On Platform="iOS" Value=""/&gt;
                &lt;On Platform="Android" Value="searchIconDroid"/&gt;
            &lt;/OnPlatform&gt;
        &lt;/ToolbarItem.IconImageSource&gt;
    &lt;/ToolbarItem&gt;
&lt;/ContentPage.ToolbarItems&gt;</code></pre>
<p>This code creates a ToolbarItem named “SearchButton.” We aren’t going to reference the button in this project, but it can still be helpful to give a name to your elements. We set the “Text” to “Search.” This is what our iOS custom renderer is going to use to identify what kind of system bar button should be used. Finally, we set the IconImageSource. We use platform specific code where the Android version is set to the name of the search icon that we created, and the iOS version is left empty. You can run this code on an Android device and see our beautiful search icon, but the iOS version still needs a custom renderer.</p>
<h2>iOS Toolbar Button Custom Renderer</h2>
<p>It’s finally time to create our first custom renderer. Right click on the iOS Project in your Solution and select Add-&gt;New Item… Add a new class called CustomNavigationRenderer.cs. To set up the page, we have to add an assembly directive to the top. This line makes all instances of the Xamarin control referenced flow through this custom renderer. Add the following line (note: many of the lines will require additional using namespaces to be added. Visual Studio should show errors and tell you which namespaces need to be added).</p>
<pre><code>[assembly: ExportRenderer(typeof(ContentPage), typeof(CustomNavigationRenderer))]</code></pre>
<p>You can see that this names ContentPage, which is the page type that we are using in the Shared Project, and the name of this renderer. Next, add that our new renderer class inherits from PageRenderer.</p>
<pre><code>class CustomNavigationRenderer : <b>PageRenderer</b></code></pre>
<p>Now we add the logic to the page.</p>
<pre><code>protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
    base.OnElementChanged(e);
    CreateNativeToolbarItems();
}

private void CreateNativeToolbarItems()
{
    if (this.NavigationController == null)
        return;
    if (this.NavigationController.TopViewController == null)
        return;
    if (this.NavigationController.TopViewController.NavigationItem == null)
        return;
    if (this.NavigationController.TopViewController.NavigationItem.RightBarButtonItems == null)
        return;

    var rightList = new List&lt;UIBarButtonItem&gt;();
    foreach (var item in this.NavigationController.TopViewController.NavigationItem.RightBarButtonItems)
    {
        if (string.IsNullOrEmpty(item.Title))
        {
            continue;
        }
        if (item.Title.ToLower() == "search")
        {
            var newItem = new UIBarButtonItem(UIBarButtonSystemItem.Search)
            {
                Action = item.Action,
                Target = item.Target
            };
            rightList.Add(newItem);
        }
        else
        {
            rightList.Add(item);
        }
    }
    if (rightList.Count &gt; 0)
    {
        this.NavigationController.TopViewController.NavigationItem.RightBarButtonItems = rightList.ToArray();
    }
}</code></pre>
<p>We override the OnElementChanged method, which is defined in the parent class. This is called when the ContentPage is created or changed. We use this method to call our CreateNativeToolbarItems method. After checking that the NavigationController and toolbar pieces exist, we cycle through the toolbar buttons that have been created. If the title is set to “search,” which we did in the xaml code by setting the text property, we create a new UIBarButtonItem. This bar button is the system search icon and we put it into our RightBarButtonItems array instead of the button that was created by the XAML.</p>
<p>Run the project on iOS and you will find a system search icon nestled on the right side of the toolbar. Good job!</p>
<h2>Toolbar Action</h2>
<p>It’s not necessary, but we might as well have something happen when we press the toolbar button. Go back to MainPage.xaml, and add the following property to our ToolbarItem.</p>
<pre><code>Clicked=“SearchButton_Clicked”</code></pre>
<p>We will also add a label to be manipulated when the button is pressed. Below the ToolbarItems code, add the following.</p>
<pre><code>&lt;ContentPage.Content&gt;
    &lt;Grid&gt;
        &lt;Label x:Name”SearchLabel” Text=“Search” VerticalOptions=“Center” HorizontalOptions=“Center”/&gt;
    &lt;/Grid&gt;
&lt;/ContentPage.Content&gt;</code></pre>
<p>Now, let’s go to the MainPage.xaml.cs file to define the click method. Add the following.</p>
<pre><code>private void SearchButton_Clicked(object sender, EventArgs e)
{
    if (SearchLabel.TextColor == Color.Black)
    {
        SearchLabel.TextColor = Color.Green;
    }
    else
    {
        SearchLabel.TextColor = Color.Black;
    }
}</code></pre>
<p>This code will change the color of the label on the middle of the screen each time you click the search icon. Run the code and watch it in action. The label changes to black, then green, then black again on subsequent clicks.</p>
<h2>Conclusion</h2>
<p>Great job! In this tutorial, we put a toolbar item on a page in Xamarin.Forms. For Android, we used icons from <a href="http://material.io">material.io</a>, sized them properly, and added them to our project. For iOS, we used a custom renderer to display system icons in the project. Even though we are using Xamarin.Forms, we were able to display a completely native look on each device. Feel free to further extend our iOS custom renderer to have left side toolbar buttons, different colored toolbar buttons, or anything else you can think of. As always, thanks for reading the HangZone blog.</p>
<p>The post <a href="https://hangzone.com/custom-renderers-xamarin-forms-part-1/">Custom Renderers in Xamarin.Forms Part 1</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>iPadOS and More from WWDC 2019</title>
		<link>https://hangzone.com/ipados-more-wwdc-2019/</link>
		
		<dc:creator><![CDATA[Judson Bandy]]></dc:creator>
		<pubDate>Fri, 28 Jun 2019 21:49:40 +0000</pubDate>
				<category><![CDATA[Developer Insights]]></category>
		<guid isPermaLink="false">https://hangzone.com/?p=2007</guid>

					<description><![CDATA[<p>Earlier this month, Apple held its annual Worldwide Developers Conference, known as WWDC. The event is an annual tradition for Apple with the inaugural WWDC held in 1987. You may ...</p>
<p>The post <a href="https://hangzone.com/ipados-more-wwdc-2019/">iPadOS and More from WWDC 2019</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Earlier this month, Apple held its annual Worldwide Developers Conference, known as WWDC. The event is an annual tradition for Apple with the inaugural WWDC held in 1987. You may be familiar with Apple’s spectacular press conferences where they announce new iPhones to get everyone excited about their latest products. This is a similar event, but at WWDC, the target audience is developers. Upcoming software, platforms, and tools are the shiny new objects put on display. WWDC always leaves developers with a lot to be excited about, and the 2019 version was no different. Let’s take a quick look around some of the highlights.</p>
<h2>General Mac Highlights</h2>
<p>A new operating system was introduced called MacOS Catalina. This continues the California theme that has been used to name the recent versions of MacOS. After a long run, the iTunes app is being replaced with separate Music, Podcast, and Apple TV apps. This isn’t especially meaningful for developers, but it’s alway interesting to take note of changes that Apple makes to its first party apps. The Mac and iPad will also be able to work better together than ever before. Through a new app called Sidecar, the iPad will be able to be used as a second display for your Mac either wirelessly or with a wired connection. This has been possible through third-party apps before, but it’s exciting to have Apple support and extend the functionality. Besides traditional second screen use, this has some cool possibilities for using the iPad as a drawing tool with the Apple Pencil where the devices are both working in the same app.<span class="Apple-converted-space"> </span></p>
<p>Although this isn’t typically a hardware conference, a new Mac Pro computer was also introduced. The computer is available with up to a 28-core processor and is an impressive high-end machine. To go along with it, a new 32 inch 6K monitor was announced. My favorite tidbit about the monitor is the stand that Apple made for it. The stand can be purchased for an additional $999. At that price, I can only imagine how majestic it sits on a desk and caresses your monitor (but it seems like it should probably make your coffee too).</p>
<h2>General iOS Highlights</h2>
<p>The new operating system, iOS 13, comes with a number of enhancements as well. A new dark mode has been one of the most talked about features. A dark mode has already been available for Mac, but this is its first appearance on mobile. The feature will darken your background and change to a lighter text color so that it is easier on your eyes at night. This is absolutely relevant to developers, as it offers a new appearance for users to view your app. Typically if users are requesting a dark mode, you would like to have your app enabled to show a mode consistent with that display.<span class="Apple-converted-space"> </span></p>
<p>Apple has also introduced a new “swipe” keyboard named QuickPath. This has been in Android for some time and can be handy for one handed typing. The issue has always been how well it can guess what you are trying to type. We’ll gauge its quality with time. Apple also announced a new “Sign in With Apple” feature. This is to compete with Facebook, Google, and other third party log-ins that are used in apps, and it will be based on users existing Apple IDs. This is of particular note because it will be required as an option for log-in in apps where third party log-in options are offered.</p>
<h2>iPadOS</h2>
<p>All of these are nice, but what I really want to highlight is iPadOS and then quickly mention Project Catalyst. First, we will start with iPadOS. For the last several years, Apple has been slowly positioning the iPad as something closer to a full blown computer. This involved giving it a “Files” folder, attaching a keyboard, several enhancements to multitasking, and drag and drop features while using multiple apps to name a few things. Well, Apple is taking a step further in differentiating the iPad from the iPhone by giving it a dedicated operating system called iPadOS. This immediately brings a lot of questions to mind, so let me clear a few things up before going any further.</p>
<p>First, your current iPad apps will continue to work on iPadOS. This operating system is based on iOS, and is still in parallel with iOS. It is called iPadOS 13 to mirror iOS 13. The primary reason for the renaming is to better differentiate that the iPad and iPhone have different sets of features. As a basic example, Apple pencil support is only available on the iPad, so it’s easier to understand that it’s an iPadOS feature. As more and more features are only available for the iPad, and specifically new iPads, compatibility is easier to understand through the operating system.</p>
<p>Speaking of compatibility, what devices are eligible to upgrade to iPadOS 13? It requires devices that use an Apple A8/A8X chip or later and have over 1 GB of RAM. This includes all iPad Pro models, iPad Air 2nd generation and newer, iPad mini 4th generation and newer, and iPad 5th generation and newer.</p>
<h2>What’s new with iPadOS</h2>
<p>Now that we’ve covered compatibility and reasoning for the operating system name, what exactly does is it do? Well, the first thing that you will notice is a new home screen. You will still see a grid of app icons like before, but they have been moved to the right. This frees up the left side for the time, date, and Apple’s widgets. The dock of app’s is still at the bottom. None of the elements are exactly new, but it seems to be a nice design and a further departure from the traditional iOS look to accompany the new name.</p>
<p>Safari has also gotten a substantial upgrade. It retrieves full versions of websites, same as you would expect on a Mac. You can still easily request the mobile version from a toolbar button if that’s what you’re after. We also now have the ability to easily manage and see downloads, just like on the Mac version of Safari. Having greater control and ability to manage files is a crucial piece to being able to use the iPad more like a full computer.</p>
<p>This bring us nicely into talking about the Files app. You can now connect a USB drive to your Mac, and it shows up nicely in your Files app. Along with integration with Google Drive and Dropbox, the Files app finally allows you to manage apps like you would expect. It may not seem like a lot, but again, this is key to using an iPad for greater productivity. The Files app also lets you drill down by columns, like in Finder on Mac, so you can navigate with ease.</p>
<p>Finally, mouse support has been added. It doesn’t appear to be a core feature by any means, but the support exists. It’s an AssistiveTouch feature under the Accessibility section of Settings.<span class="Apple-converted-space">  </span>Given where and how it is included, mouse support inside your app is not necessary as the system still works off of touches and gestures. It is certainly something to note as it is likely a sign of something to come in the future though.</p>
<p>There are a number of other multitasking and performance improvements that go along to round out the changes for iPadOS.</p>
<h2>Project Catalyst</h2>
<p>Finally, let’s talk about Project Catalyst. This is new, but it was mentioned at WWDC 2018 under the name of Project Marzipan. Apple was using the project internally to build a single app that would work for iOS and macOS. That’s a big deal! Many of Apple’s apps, such as News, Home, and Stocks are apparently built with the the technology. Cross platform building between the Mac and iOS isn’t fully there yet, but this certainly is an encouraging step in the right direction.</p>
<p>Project Catalyst is an SDK for Xcode that will allow developers to convert iPad apps to Mac apps. The app must have an iPad version (it doesn’t work for iPhone only apps). The developer would then be able to submit versions to the iOS and Mac app stores separately. A universal app between the platforms is not available at this time. I have yet to use it, so I can’t speak to the ability to tweak changes to make your app more Mac friendly and whatnot, but it is certainly exciting and could make developing cross platform software for the two systems substantially faster.</p>
<h2>Conclusion</h2>
<p>WWDC 2019 was packed with many exciting new features. For app developers, any time we hear about completely new operating systems, like iPadOS, there is an initial fear of backwards compatibility for our current apps and excitement for what’s new. Luckily, iPadOS isn’t too much of a deviation from the previous version and is more about an exciting future. If you are interested in learning more about any of these features or other happenings from WWDC, I strongly recommend checking out Apple’s site. We didn’t come close to covering everything. As always, thanks for reading the HangZone blog!</p>
<p>The post <a href="https://hangzone.com/ipados-more-wwdc-2019/">iPadOS and More from WWDC 2019</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Data Binding and Model-View-ViewModel in UWP Part 2</title>
		<link>https://hangzone.com/data-binding-uwp-part-2/</link>
		
		<dc:creator><![CDATA[Judson Bandy]]></dc:creator>
		<pubDate>Thu, 28 Feb 2019 16:18:48 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://hangzone.com/?p=1967</guid>

					<description><![CDATA[<p>This tutorial starts where Part 1 leaves off. If you haven&#8217;t read it, you can find it here. As a quick refresher, we are creating an application that highlights data ...</p>
<p>The post <a href="https://hangzone.com/data-binding-uwp-part-2/">Data Binding and Model-View-ViewModel in UWP Part 2</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>This tutorial starts where Part 1 leaves off. If you haven&#8217;t read it, you can find it here.</p>
<p>As a quick refresher, we are creating an application that highlights data binding and the MVVM architectural design pattern in UWP. There is a clear separation of concerns in our code, and data binding is used for the UI to communicate with the data. So far, we have created a model, view, and viewmodel. We will continue to add code (including data binding code) to each of these classes to achieve our desired functionality. Remember, we have a one page application with two pivots. The &#8220;All Foods&#8221; pivot allows you to select your favorite foods from a list of all foods. The &#8220;Favorite Foods&#8221; pivot will then show a list of your favorite foods. Let&#8217;s jump back in by finishing up our view!</p>
<h2>Finishing our View</h2>
<p>Now that we have collections to work with in the viewmodel and some data, let’s go back and complete our view. If you remember, we laid out a simple structure, but we need to finish our pivot sections for all foods and favorite foods.</p>
<p>First, we need to go to the code-behind file of the view to add our viewmodel as the data context for the view. At the top of the FoodView.xaml.cs file, add “using MyFavoriteFoods.ViewModel.”</p>
<p>Next, we will add the viewmodel as an instance variable, and set it as the datacontext in the constructor.</p>
<pre><code><b>public FoodViewModel ViewModel { get; set; } = new FoodViewModel();</b>

public FoodView()
{
    <b>DataContext = ViewModel;</b>
    this.InitializeComponent();
}</code></pre>
<p>Now, back to the .xaml file. We first choose a control that includes ItemTemplate to be used to display the data. ListView, GridView, ListBox, and ItemsControl are all potential options. I will use ItemsControl since it does less manipulation to the view than the other options (no highlighting, selecting, etc). Inside ItemTemplate, we will have a DataTemplate that defines the datatype and the UI layout for each instance of the object. We are using data templates of type FoodModel so we need to add our model namespace to the definitions. In the definitions at the top, add:</p>
<pre><code>xmlns:models=“using:MyFavoriteFoods.Model”</code></pre>
<p>Now, fill in the pivot items as follows.</p>
<pre><code>&lt;PivotItem Header=“Favorite Foods”&gt;
    &lt;ItemsControl ItemsSource=“{x:Bind ViewModel.FavoriteFoods, Mode=OneWay}”&gt;
        &lt;ItemsControl.ItemTemplate&gt;
            &lt;DataTemplate x:DataType=“models:FoodModel”&gt;
                &lt;Grid Height=“40”&gt;
                    &lt;TextBlock VerticalAlignment=“Center” Text=“{x:Bind Name}”/&gt;
                &lt;/Grid&gt;  
            &lt;/DataTemplate&gt;
        &lt;/ItemsControl.ItemTemplate&gt;
    &lt;/ItemsControl&gt;
&lt;/PivotItem&gt;
&lt;PivotItem Header=“All Foods”&gt;
    &lt;ItemsControl ItemsSource=“{x:Bind ViewModel.AllFoods}”&gt;
        &lt;ItemsControl.ItemTemplate&gt;
            &lt;DataTemplate x:DataType=“models:FoodModel”&gt;
                &lt;Grid Height=“40”&gt;
                    &lt;Grid.ColumnDefinitions&gt;
                        &lt;ColumnDefinition Width=“*”/&gt;
                        &lt;ColumnDefinition Width=“auto”/&gt;
                    &lt;/Grid.ColumnDefinitions&gt;
                    &lt;TextBlock VerticalAlignment=“Center” Text=“x:Bind Name”/&gt;
                    &lt;ToggleSwitch Grid.Column=“1” HorizontalAlignment=“Right” VerticalAlignment=“Center” IsOn=“{x:Bind IsFavorite, Mode=TwoWay}”/&gt;
                &lt;/Grid&gt;
            &lt;/DataTemplate&gt;
        &lt;/ItemsControl.ItemTemplate&gt;
    &lt;/ItemsControl&gt;
&lt;/PivotItem&gt;</code></pre>
<h2>Explanation of Data Binding Code</h2>
<p>You will notice that on the data binding for the ItemsControl.ItemSource in the favorite foods section, we used “Mode=OneWay.” Also, for the toggle switch in the all foods section, we used “Mode=TwoWay.” There are three different modes for binding: one time (the default if not specified), one way, and two way. For one way, the view reads the property when the view is created and uses that value going forward. With one way, the view will update its display if the value that it is bound to changes. For two way, the view will update the display if the bound property is changed, like with one way, but it will also update the bound property if the view is manipulated. For instance, if a toggle switch is toggled or a text box changed by the user, the property that is bound to that control will be updated with the information entered by the user.</p>
<p>We need to use one way binding for our favorite foods item source because the bound collection will be modified when we add or remove foods as favorites. The ToggleSwitch.IsOn binding needs two way because the IsFavorite property for the FoodModel object needs to be updated when the user toggles the switch.</p>
<p>Feel free to run the project and take a look at our progress. All of our data and controls should now be displayed correctly. Congratulations! The only problem is that the favorite foods list does not update when the switches are toggled on the all foods pivot.</p>
<h2>Using INotifyPropertyChanged</h2>
<p>With our two way binding, the IsFavorite property on the corresponding FoodModel object is updated when a switch is toggled. We need to be notified when the property is changed so that we can either add or remove the FoodModel from the favorite foods collection. To do this, we need to implement INotifyPropertyChanged for the IsFavorite property in the FoodModel class. Then, we can add code to the FoodViewModel to execute code whenever the property’s value changes.</p>
<p>Go to FoodModel.cs. Add “using System.ComponentModel” to the class. Now, we are going to change the IsFavorite property so that you can subscribe to be notified when the property changes.</p>
<pre><code><del>public bool IsFavorite { get; set; }</del>

private bool _isFavorite;
public bool IsFavorite
{
    get { return _isFavorite; }
    set
    {
        _isFavorite = value;
        RaisePropertyChanged(“IsFavorite”);
    }
}

public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string name)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
}</code></pre>
<p>Now, whenever the IsFavorite property is modified, the PropertyChanged event handler is called. This handler will be used to trigger a method to adjust our favorite foods collection in the viewmodel. Let’s go to the FoodViewModel.</p>
<h2>Subscribing to Property Changed</h2>
<p>We need to subscribe to the PropertyChanged event on each FoodModel in the AllFoods collection so that we can adjust our FavoriteFoods collection. The action is rather simple. First, add “using System.ComponentModel” at the top of the page. In the LoadFoodData method, where we loop through each FoodModel in AllFoods, we add the following line.</p>
<pre><code>foreach(FoodModel eachFood in AllFoods)
{
    <b>eachFood.PropertyChanged += IsFavoritePropertyChanged;</b>
    if (eachFood.IsFavorite)
    {
        FavoriteFoods.Add(eachFood)
   }
}</code></pre>
<p>Now, we define that method to handle the addition or removal of the toggled FoodModel.</p>
<pre><code>public void IsFavoritePropertyChanged(object sender, PropertyChangedEventArgs e)
{
    FoodModel toggledFood = sender as FoodModel;
    if (toggledFood.IsFavorite)
    {
        FavoriteFoods.Add(toggledFood);
    }
    else
    {
        FavoriteFoods.Remove(toggledFood);
    }
}</code></pre>
<p>That’s it. Our code is notified when the IsFavorite property changes for each instance of FoodModel in the viewmodel, and the FavoriteFoods collection is adjusted accordingly. Run the project and see your work in action!</p>
<p><a href="https://hangzone.com/wp-content/uploads/2018/12/Blog-UWP-Data-Binding-Favorite-Foods.png"><img decoding="async" class="alignnone size-medium wp-image-1957" src="https://hangzone.com/wp-content/uploads/2018/12/Blog-UWP-Data-Binding-Favorite-Foods-300x266.png" alt="Blog UWP Data Binding Favorite Foods" width="300" height="266" srcset="https://hangzone.com/wp-content/uploads/2018/12/Blog-UWP-Data-Binding-Favorite-Foods-300x266.png 300w, https://hangzone.com/wp-content/uploads/2018/12/Blog-UWP-Data-Binding-Favorite-Foods.png 980w" sizes="(max-width: 300px) 100vw, 300px" /></a><a href="https://hangzone.com/wp-content/uploads/2018/12/Blog-UWP-Data-Binding-All-Foods.png"><img decoding="async" class="alignnone size-medium wp-image-1956" src="https://hangzone.com/wp-content/uploads/2018/12/Blog-UWP-Data-Binding-All-Foods-300x266.png" alt="Blog UWP Data Binding All Foods" width="300" height="266" srcset="https://hangzone.com/wp-content/uploads/2018/12/Blog-UWP-Data-Binding-All-Foods-300x266.png 300w, https://hangzone.com/wp-content/uploads/2018/12/Blog-UWP-Data-Binding-All-Foods.png 980w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<h2>Conclusion</h2>
<p>In this project, we used data binding and the Model-View-ViewModel pattern to create an application. Our code is nicely segregated so that the view deals only with UI display and the data and logic are handled in the model and viewmodel. Data binding is done to allow the UI to properly communicate with the data to display proper values and relay any user inputs or changes. We use fairly simple binding concepts in this project, but it is a good introduction to how they work. As always, thanks for reading the HangZone blog!</p>
<p>The post <a href="https://hangzone.com/data-binding-uwp-part-2/">Data Binding and Model-View-ViewModel in UWP Part 2</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Data Binding and Model-View-ViewModel in UWP Part 1</title>
		<link>https://hangzone.com/data-binding-uwp-part-1/</link>
		
		<dc:creator><![CDATA[Judson Bandy]]></dc:creator>
		<pubDate>Thu, 31 Jan 2019 17:07:52 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://hangzone.com/?p=1954</guid>

					<description><![CDATA[<p>Data Binding is a powerful and important tool in Windows development. Whether targeting UWP, WPF, Xamarin.Forms, or something else, binding is crucial to your app design. The idea of binding ...</p>
<p>The post <a href="https://hangzone.com/data-binding-uwp-part-1/">Data Binding and Model-View-ViewModel in UWP Part 1</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Data Binding is a powerful and important tool in Windows development. Whether targeting UWP, WPF, Xamarin.Forms, or something else, binding is crucial to your app design. The idea of binding is simple. It is used to connect a binding target to a binding source. The binding target is typically the property of a control or some type of UI element. This could be the text of a label, whether a switch is on, or a selection in a combo box. The binding source is a property from another class, usually a viewmodel or model. This is the data that tells the binding target what to display.<span class="Apple-converted-space"> </span></p>
<p>Now, we have a high level understanding of data binding, but why are we using it? The main purpose is to decouple our UI code from our non-UI code. This strategy is utilized in Microsoft&#8217;s recommended UI architectural design pattern, Model-View-ViewModel (MVVM), and has a number of benefits. Decoupling different sections of your code creates a separation of concerns. Testing becomes easier since your code is more isolated, different programmers can focus on different parts of the project (front end and back end programmers can simultaneously work on different aspects), and the code is much more maintainable and reusable.<span class="Apple-converted-space"> </span></p>
<h2>Model-View-ViewModel</h2>
<p>Although somewhat self-explanatory, let’s take a quick look at the 3 layers of the MVVM paradigm. The model is the first layer. This houses all of your software’s business data. Core app logic, class definitions, and data can all typically be found here. The view is the user interface of your project. In UWP, which we are using for this project, this is done with XAML files that define your views and controls. Code-behind files can also be used to further define elements of the view. The viewmodel binds and processes information between the model and view classes. Now that we have a quick idea of the elements of MVVM and data binding, let’s jump into a project and see it in action.</p>
<h2>Our Test Project</h2>
<p>Let’s quickly lay out what we want to do for our project. We are going to create a UWP application. It is going to be a single page with tabs on it. One tab will have a list of our favorite foods. The other tab will have a list of all included foods with a toggle switch to tag them as a favorite.</p>
<p>The project will need one model class where we will define our food model, one view class where we layout the UI for the page, and one viewmodel class where we get everything to work together. Let’s get started!</p>
<h2>Create Our Project</h2>
<p>I am going to do this project in Visual Studio on a Windows device targeting UWP. You could easily do this project in Visual Studio for Mac and target Xamarin.Forms, although some of the UI code will be slightly different.</p>
<p>Open Visual Studio and go to File-&gt;New-&gt;Project… Select Windows Universal in the left pane under Visual C#, and select Blank App (Universal Windows). Feel free to name the app anything you want (I’ll call mine MyFavoriteFoods), and click OK. I’m going to target Windows 10, version 1809 and set the minimum version to Windows 10 Creators Update. Press OK. Our project is now created.<span class="Apple-converted-space"> </span></p>
<p>Start by deleting MainPage.xaml and its code-behind file, MainPage.xaml.cs. I want to create my own view file inside a folder to better delineate the layers of the project.<span class="Apple-converted-space"> </span></p>
<h2>Creating our Model</h2>
<p>Right click on the MyFavoriteFoods project, and click Add-&gt;New Folder. Name the folder “Model” and press enter. Right click your new model folder and select Add-&gt;New Item… Select Class and name it FoodModel.cs. Press Add. We will start by just adding the bare bones properties to this class. Make the class public and add properties to make it look like this.</p>
<pre><code><b>public</b> class FoodModel
{
    <b>public string Name { get; set; }</b>
    <b>public bool IsFavorite { get; set; }</b>
}</code></pre>
<p>You can see, we have a string property for the name of the each food and a bool for whether this is a favorite food or not. Let’s move on to our View.</p>
<h2>Creating our View</h2>
<p>Create another folder in the project; this time called View. Create a Blank Page inside the folder named FoodView.xaml.<span class="Apple-converted-space"> </span></p>
<p>Before we make any changes on this page, let’s set this new view as our first page for startup. Open the App.xaml.cs file. At the top, add the view namespace: “using MyFavoriteFoods.View”. Then change the following line to set the first page as our new view, FoodView.xaml.<span class="Apple-converted-space"> </span></p>
<pre><code><del>rootFrame.Navigate(typeof(MainPage), e.Arguments);</del>
rootFrame.Navigate(typeof(FoodView), e.Arguments);</code></pre>
<p>Let’s go back to FoodView.xaml. We’re going to put a large title at the top, and then a pivot to swap between our favorite foods and all foods. Add the following code to the page.</p>
<pre><code>&lt;Grid&gt;
    &lt;Grid.RowDefinitions&gt;
        &lt;RowDefinition Height = “auto”/&gt;
        &lt;RowDefinition Height = “*”/&gt;
    &lt;/Grid.RowDefinitions&gt;
    &lt;TextBlock Text=“Food” FontSize=“30” Margin=“10,0,0,0”/&gt;
    &lt;Pivot Grid.Row = “1”&gt;
        &lt;PivotItem Header=“Favorite Foods”&gt;

        &lt;/PivotItem&gt;
        &lt;PivotItem Header=“All Foods”&gt;

        &lt;/PivotItem&gt;
    &lt;/Pivot&gt;
&lt;/Grid&gt;</code></pre>
<p>As you can see, we created two rows inside our grid. The first has an auto height so that it is allocated the amount of space that its contents need. The second row is set to height “*” so that it is allocated the remaining height of the grid. We use a text block in the first row of the grid to set a title of “Food” for the page. We use a pivot in the second row with two pivot items. The first is given a header of “Favorite Foods” and the second is “All Foods.” Feel free to run the project. You will see what we laid out and be able to select the pivots. We still need to fill out their content. Let’s move on to our viewmodel, and then, we will come back to finish the view.</p>
<h2>Creating Our ViewModel</h2>
<p>We need to create another folder in our project. This one should be called “ViewModels.” Create a new class file inside the folder and call it “FoodViewModel.cs.” This will be the viewmodel for our FoodView class.</p>
<p>Let’s start by creating two instance variables for the class. One will be a list that will house all of the foods that are in our universe. The second will be an ObservableCollection of all of our favorite foods. It is helpful to use an ObservableCollection as the type for our favorite foods because we will be adding and removing foods from this collection. The all foods collection will remain constant as there is currently no way to add new foods while the project is running. The ObservableCollection provides a notification to its binding target when items get added, removed, or when a whole list is refreshed. This is helpful for updating our view as selections get manipulated.</p>
<p>First, we need to add the Model namespace to the class, and another namespace to use ObservableCollection objects. At the top of the page, add the following lines.</p>
<pre><code>using MyFavoriteFoods.Model;
using System.Collection.ObjectModel;</code></pre>
<p>Then, make the class public like this.</p>
<pre><code><b>public </b>class FoodViewModel</code></pre>
<p>Next, create the instance variables in a manner like this.</p>
<pre><code>public List&lt;FoodModel&gt; AllFoods = new List&lt;FoodModel&gt;();

public ObservableCollection&lt;FoodModel&gt; FavoriteFoods = new ObservableCollection&lt;FoodModel&gt;();</code></pre>
<h2>ViewModel Methods</h2>
<p>Now, we need to load initial data into these collections. This data would normally come from either a local or external server, but that is far beyond the scope of this tutorial. We could create a data section to house this data, as well, but again, the purpose of this is to focus on MVVM and binding. We are simply going to load the data in a method in the viewmodel. This is not typical work for a viewmodel in a larger scale project, and if this project was more than one page, we would certainly want to move the data elsewhere. Let’s add a constructor method for the viewmodel and call another method inside it.</p>
<pre><code>public FoodViewModel()
{
    LoadFoodData();
}</code></pre>
<p>Now, let’s define that method to populate data in the collections.</p>
<pre><code>private void LoadFoodData()
{
    AllFoods.Add(new FoodModel()
    {
        Name = “Apple”,
        IsFavorite = false
    };

    AllFoods.Add(new FoodModel()
    {
        Name = “Banana”,
        IsFavorite = false
    };

    AllFoods.Add(new FoodModel()
    {
        Name = “Pizza”,
        IsFavorite = true
    };

    AllFoods.Add(new FoodModel()
    {
        Name = “Spinach”,
        IsFavorite = false
    };

    AllFoods.Add(new FoodModel()
    {
        Name = “Turnip”,
        IsFavorite = false
    };

}

foreach(FoodModel eachFood in AllFoods)
{
    if (eachFood.IsFavorite)
    {
        FavoriteFoods.Add(eachFood);
    }
}</code></pre>
<h2>Conclusion</h2>
<p>Now, we have our collections of data defined and available to use. In part 2 of this tutorial, we will bind these collections to their corresponding pivots so that each collection is displayed in the user interface. On the all foods pivot, you will be able to select whether a particular food is one of your favorites. Upon selecting or unselecting a food, the binding change will alert our code to update the collection of favorite foods. We set up a great MVVM structure in part 1, but there is a lot of exciting coding to look forward to in part 2. As always, thanks for reading the HangZone blog!</p>
<p>The post <a href="https://hangzone.com/data-binding-uwp-part-1/">Data Binding and Model-View-ViewModel in UWP Part 1</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Font Awesome Icons in Xamarin.Forms</title>
		<link>https://hangzone.com/font-awesome-icons-xamarin-forms/</link>
		
		<dc:creator><![CDATA[Judson Bandy]]></dc:creator>
		<pubDate>Thu, 30 Aug 2018 21:45:21 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://hangzone.com/?p=1895</guid>

					<description><![CDATA[<p>Xamarin.Forms is a powerful tool that allows you to build native apps for iOS, macOS, Android, and UWP, largely from a single codebase. This codebase is able to then render ...</p>
<p>The post <a href="https://hangzone.com/font-awesome-icons-xamarin-forms/">Font Awesome Icons in Xamarin.Forms</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Xamarin.Forms is a powerful tool that allows you to build native apps for iOS, macOS, Android, and UWP, largely from a single codebase. This codebase is able to then render native views for each platform. Toolbars, tableviews, and other views will all have their native appearance depending on device. You may have to use custom renderers for different platforms depending on the complexity of your app and which native classes and tools you wish to leverage, but for the most part, a single codebase is used for both UI and logic. This makes for a fast, easy way to get a consistent look and feel across platforms.</p>
<p>There are still areas where you will have to look outside Xamarin.Forms tools to achieve a consistent look. Icons are one of those areas. If you are developing on UWP, you would likely use native icons from the Segoe MDL2 font family. On iOS, system icons are an easy choice. Unfortunately, there is no built in set of system icons to use for Xamarin.Forms across devices. You could import images, but an easier and more flexible solution is to use Font Awesome.</p>
<p>Font Awesome in a font and icon toolkit. It is currently on version 5.3, which has a free version with over 1,300 icons, and a pro version with 2,600 more icons. The free version is open source and free to use in any commercial or other type of project. It has a wide array of icons that should be a great fit for most any need.</p>
<h2>Create a Xamarin.Forms Project</h2>
<p>Let’s get started with using Font Awesome in Xamarin.Forms by creating a new Xamarin.Forms project. We are going to be doing this project on a Mac, but you can also do it in Windows. Start by opening Visual Studio. Press the button for “New Project.” Under Multiplatform-&gt;App, select Blank Forms App under Xamarin Forms. The language we’ll use is C#. Next, give your app a name, I called mine FontAwesomeTest, and use the .NET Standard. Press next, then create on the next page to create your project.</p>
<p><a href="https://hangzone.com/wp-content/uploads/2018/08/Blog-Create-Xamarin-Forms-App.png"><img decoding="async" class="alignnone wp-image-1897 size-large" src="https://hangzone.com/wp-content/uploads/2018/08/Blog-Create-Xamarin-Forms-App-1024x744.png" alt="Blog Create Xamarin Forms App" width="800" height="581" srcset="https://hangzone.com/wp-content/uploads/2018/08/Blog-Create-Xamarin-Forms-App-1024x744.png 1024w, https://hangzone.com/wp-content/uploads/2018/08/Blog-Create-Xamarin-Forms-App-300x218.png 300w, https://hangzone.com/wp-content/uploads/2018/08/Blog-Create-Xamarin-Forms-App.png 1804w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Go ahead and run the project. After it loads, you should see a white background, with “Welcome to Xamarin.Forms!” in the middle of the screen. We are not trying to do anything fancy with the layout, so let’s go ahead and add Font Awesome to the project.</p>
<h2>Download and Add Font Awesome to the Project</h2>
<p>Go to <a href="http://fontawesome.com">fontawesome.com</a>. You should see a header that says “Download Font Awesome Free” with a button that says “For the Web” beneath it. This will download a folder called “fontawesome-free-5.3.1-web.” Inside this folder, there are three files that we are interested in that are inside the webfonts folder. These files are fa-brands-400.ttf, fa-regular-400.ttf, and fa-solid-900.ttf. These are all collections of icons that you may be interested in using in your project. We’re only going to work with fa-solid-900.ttf in our example, but feel free to use the others.</p>
<p>We need to add this .ttf file to the .Android and .iOS sections of our project. If we had a UWP section, it would also need to be added there under the Assets folder. Let’s start by adding the file to the .Android section. You simple need to drag the .ttf file into the Assets folder. Select &#8220;Copy the file to the directory&#8221; and press OK. Next, we drag in the file to the Resources folder in the iOS section and do the same thing.</p>
<p><a href="https://hangzone.com/wp-content/uploads/2018/08/Blog-Add-Font-Awesome.png"><img decoding="async" class="alignnone size-medium wp-image-1896" src="https://hangzone.com/wp-content/uploads/2018/08/Blog-Add-Font-Awesome-300x129.png" alt="Blog Add Font Awesome" width="300" height="129" srcset="https://hangzone.com/wp-content/uploads/2018/08/Blog-Add-Font-Awesome-300x129.png 300w, https://hangzone.com/wp-content/uploads/2018/08/Blog-Add-Font-Awesome-1024x439.png 1024w, https://hangzone.com/wp-content/uploads/2018/08/Blog-Add-Font-Awesome.png 1200w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>The iOS version needs one more thing. Open Info.plist, and press the Source button and the bottom. Add a new entry with the property key UIAppFonts and a string of fa-solid-900.ttf in the array it creates.</p>
<p><a href="https://hangzone.com/wp-content/uploads/2018/08/Blog-Add-Font-Awesome-iOS-Info.png"><img decoding="async" class="alignnone wp-image-1900 size-large" src="https://hangzone.com/wp-content/uploads/2018/08/Blog-Add-Font-Awesome-iOS-Info-1024x684.png" alt="Blog Add Font Awesome iOS Info" width="800" height="534" srcset="https://hangzone.com/wp-content/uploads/2018/08/Blog-Add-Font-Awesome-iOS-Info-1024x684.png 1024w, https://hangzone.com/wp-content/uploads/2018/08/Blog-Add-Font-Awesome-iOS-Info-300x200.png 300w, https://hangzone.com/wp-content/uploads/2018/08/Blog-Add-Font-Awesome-iOS-Info.png 1866w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<h2>Create Button With Font Awesome Icon</h2>
<p>It is finally time to use our Font Awesome Icons! Let’s start by creating a simple button with just the icon. Open MainPage.xaml. Let’s delete the current label and add a button with a smiley face icon.</p>
<pre><code><del>&lt;Label Text="Welcome to Xamarin.Forms!" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" /&gt;</del>
&lt;Button Text="&amp;#xf118;" TextColor="Black" HorizontalOptions="Center" VerticalOptions="CenterAndExpand"&gt;
    &lt;Button.FontFamily&gt;
        &lt;OnPlatform x:TypeArguments="x:String" Android="fa-solid-900.ttf#Font Awesome 5 Free Solid" iOS="Font Awesome 5 Free" /&gt; 
    &lt;/Button.FontFamily&gt;
&lt;/Button&gt;</code></pre>
<p>You can see that our text input looks really strange and not a whole lot like a smiley face. You can find the correct codes for all of your Font Awesome icons on their cheatsheet, <a href="https://fontawesome.com/cheatsheet">fontawesome.com/cheatsheet</a>. Simply put &amp;#x before the code and a semicolon after. Now, run your project, and you should see a black smiley face in the center of the screen. Tap it and you will see the typical button animation.<span class="Apple-converted-space"> </span></p>
<h2>Creating a button with an Icon and Text</h2>
<p>The button control allows you to set an icon and text. However, since we are setting our font awesome icon in the text property, there is no spot for a text label to accompany the icon. This means, we have to use a different solution to accomplish an icon with text. We will delete our button and replace it with a grid. We will make two columns for the grid with the width set to auto. In the first column, we will use a label for the font awesome icon. In the second, we will have a label for our text. See the code below.</p>
<pre><code>&lt;Grid HorizontalOptions="Center" VerticalOptions="CenterAndExpand"&gt;
    &lt;Grid.ColumnDefinitions&gt;
        &lt;ColumnDefinition Width="auto"/&gt;
        &lt;ColumnDefinition Width="auto"/&gt;
    &lt;/Grid.ColumnDefinitions&gt;
    &lt;Label Grid.Column="0" Text="&amp;#xf118;" TextColor="Black"&gt;
        &lt;Label.FontFamily&gt;
            &lt;OnPlatform x:TypeArguments="x:String" Android="fa-solid-900.ttf#Font Awesome 5 Free Solid" iOS="Font Awesome 5 Free" /&gt;
        &lt;/Label.FontFamily&gt; 
    &lt;/Label&gt; 
    &lt;Label Grid.Column="1" Text="Smiley Face" TextColor="Black"/&gt; 
&lt;/Grid&lt;</code></pre>
<p>Run the project, and you should see your smiley face with a text label next to it. Good job! Unfortunately, we’re not quite there yet. If you try to click on the fake button, you will see that there is no click animation. We need to add a gesture recognizer to process taps, and add an animation in that method to have our fake button look like it was tapped.</p>
<p><a href="https://hangzone.com/wp-content/uploads/2018/08/Blog-Xamarin-Forms-Font-Awesome-Final.png"><img decoding="async" class="alignnone size-medium wp-image-1898" src="https://hangzone.com/wp-content/uploads/2018/08/Blog-Xamarin-Forms-Font-Awesome-Final-139x300.png" alt="Blog Xamarin Forms Font Awesome Final" width="139" height="300" srcset="https://hangzone.com/wp-content/uploads/2018/08/Blog-Xamarin-Forms-Font-Awesome-Final-139x300.png 139w, https://hangzone.com/wp-content/uploads/2018/08/Blog-Xamarin-Forms-Font-Awesome-Final-473x1024.png 473w, https://hangzone.com/wp-content/uploads/2018/08/Blog-Xamarin-Forms-Font-Awesome-Final.png 1125w" sizes="(max-width: 139px) 100vw, 139px" /></a></p>
<h2>Adding a Tap Gesture Recognizer</h2>
<p>Let’s add tap gesture recognizer inside our grid. It should look like this.</p>
<pre><code>&lt;Grid.GestureRecognizers&gt;
    &lt;TapGestureRecognizer Tapped="OnSmileyButtonTapped"/&gt;
&lt;/Grid.GestureRecognizers&lt;</code></pre>
<p>Now, we need to define the OnSmileyButtonTapped method in our code-behind class. This method will use await to do a fade animation on the button when it is tapped. Because of this, the class must be defined as async. Add the following method to your MainPage.xaml.cs class.</p>
<pre><code>public async System.Threading.Tasks.Task OnSmileyButtonTapped(object sender, EventArgs args) 
{ 
    Grid tappedGrid = (Grid)sender; 
    Label label1 = (Label)tappedGrid.Children[0]; 
    Label label2 = (Label)tappedGrid.Children[1];  
    await System.Threading.Tasks.Task.WhenAll( 
        label1.FadeTo(0.3, 100), 
        label2.FadeTo(0.3, 100) 
    );  
    await System.Threading.Tasks.Task.WhenAll( 
        label1.FadeTo(1, 100), 
        label2.FadeTo(1, 100) 
    ); 
} </code></pre>
<p>You can see that we get our icon label and text label off the grid, which is the sender, from the children array. Then, we do a quick fade animation on both labels to lower the opacity and then bring it back to full. Run the project and you should see an icon and label combination that acts much like an iOS button. If we wanted the button to have a background, or different appearance, we could add a frame with a background color, corner radius, or other features to the object.</p>
<p>We can also add any actions that we want to our tapped method. Let’s try changing the screen color and label colors between black and white. Add the following code snippet below our definition for label1 and label2.</p>
<pre><code> if (this.BackgroundColor == Color.Black) 
{
    this.BackgroundColor = Color.White; 
    label1.TextColor = Color.Black;
    label2.TextColor = Color.Black; 
} else { 
    this.BackgroundColor = Color.Black;
    label1.TextColor = Color.White;
    label2.TextColor = Color.White; 
}</code></pre>
<h2>Conclusion</h2>
<p>There you go! We successfully added Font Awesome icons to our Xamarin.Forms project. Then, we created an icon button using a Font Awesome icon. We decided that we wanted a label with our icon, so we created a grid with a font awesome label and a text label that functioned like a button. You can give further styling to this custom button as needed. I hope you enjoyed this tutorial. As always, thanks for reading the HangZone blog.</p>
<p>The post <a href="https://hangzone.com/font-awesome-icons-xamarin-forms/">Font Awesome Icons in Xamarin.Forms</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Escape &#038; Avenge: A Developer Preview</title>
		<link>https://hangzone.com/escape-avenge-developer-preview/</link>
		
		<dc:creator><![CDATA[Judson Bandy]]></dc:creator>
		<pubDate>Mon, 02 Apr 2018 18:31:57 +0000</pubDate>
				<category><![CDATA[Apps]]></category>
		<category><![CDATA[Developer Insights]]></category>
		<guid isPermaLink="false">http://hangzone.com/?p=1851</guid>

					<description><![CDATA[<p>The HangZone Game Studio is still working hard. Since the release of Spelldom in 2015, we have been focusing more on contract work and enterprise app development, but the creative ...</p>
<p>The post <a href="https://hangzone.com/escape-avenge-developer-preview/">Escape &#038; Avenge: A Developer Preview</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The HangZone Game Studio is still working hard. Since the release of Spelldom in 2015, we have been focusing more on contract work and enterprise app development, but the creative juices are always flowing. Escape &amp; Avenge was a project that we began in late 2016. We have tinkered with the game on and off since then, and we believe that it’s a special game you will really enjoy.</p>
<p>Escape &amp; Avenge will be released in the App Store worldwide on April 4, 2018. To help you understand the game, this is the App Description from the App Store:</p>
<pre>You’re trapped in the dungeon of a medieval town. The king imprisoned you and killed the wizard—your magical friend and accomplice—for trying to overthrow the crown. At least that’s what the note on the wall says. You can’t remember anything, including who you are or how you got here. Can you escape the dungeon, return to the castle, and avenge your friend’s death? 

Escape and Avenge is an unconventional text-based adventure that reimagines the genre for mobile. With a couple quick taps, you can chain together any command you want—the perfect blend of speed, accuracy, and range of actions! Throw in some minimalist visual mini games and puzzles and you’ve got a new spin on interactive fiction! 

There are no ads or IAP—just a poor soul trapped in a dungeon who is looking for help.</pre>
<p>Now that you know a little about the game, let’s pull back the curtain, and give you a brief look at our thought process in creating E&amp;A.</p>
<h2>Initial Thoughts on Creating the Game</h2>
<p>Our initial wish for a new game was to make a text adventure using completely native iOS UI elements. We wanted a no frills look that would take complete advantage of the clean, understated beauty of the native UI. Any iOS user would feel comfortable and at home with the appearance and function of the UI. Also, a text adventure should take place primarily in the user’s imagination. By going with as standard of a UI as possible, we hoped to let the user’s mind fully engage in the game and create a completely unique view of the world of E&amp;A.</p>
<p>Besides that wish, we knew we wanted to have a map. For anyone who has played Zork, the lack of a map can be either extremely frustrating or it add to the mystique of the game. Maybe both. Regardless, we wanted something as user friendly as possible. Our hope for the map was that the player could understand the layout of the world, they could quickly warp around the world, and they could gauge some idea of progress.</p>
<p>We also wanted players to be able to see their inventory. You pick up all kinds of items, and we wanted a streamlined way for players to see what they had and get a quick description. Given the desire to have a couple of views, we immediately felt that a tabViewController would be a great native fit to display the views. Next, we needed to figure out how to execute them.</p>
<h2>Creating the Story and Text Input View</h2>
<p>The first and most glaring problem that we faced was finding a graceful way to deal with text/command input. As you probably know, most traditional text adventures have a text entry spot where the user can enter literally any command. The game certainly can’t respond appropriately to everything, but it can give a response of at least, “you can’t do that,” no matter what. The beauty is that nothing is given away to the user. The player must figure out every command, and there can even be cool easter egg responses when entering certain commands.</p>
<p>Unfortunately, mobile devices are not the easiest for inputing a large amount of text. We aren’t just talking about a few quick sentences. There’s a lot of guessing and failed attempts involved in text adventures. You’re going to try to give or use a certain item in all kinds of ways before you finally find the solution. In my mind, typing all inputs for a mobile text adventure will only appeal to a dedicated subset of regular text adventure players. You’re cannibalizing a large part of your potential audience by doing straight user text input on mobile.</p>
<p>Nevertheless, the alternative isn’t suited either. Simply giving a choice of possible commands completely written out takes away much of the allure of the text adventure. Sure, you’re still making choices and progressing through the story, but it minimizes how you think through items and how to use them.</p>
<h2>Our Answer to Text Input</h2>
<p>We are extremely happy with how our text input solution turned out. Our solution leverages native iOS tableViews, and allows the user to construct their sentences piece by piece with simple, quick taps.</p>
<p>The user is presented with all possible action verbs to begin with. Upon tapping one, they are given options for an object or modifier to go with that action. Sentences can build even further as you might start with “Use,” and then have to select an object, then a person or place to put or give the object to. It’s simple, quick, and very open-ended. Yes, it does restrict certain off the wall text inputs, but we feel the speed, accuracy, and efficiency make it the ideal solution for a mobile text adventure. We can’t wait for you to try it and get your feedback!</p>
<p><a href="http://hangzone.com/wp-content/uploads/2018/03/Blog-EA-Preview-Text-Entry.png"><img decoding="async" class="alignnone wp-image-1854 size-medium" src="http://hangzone.com/wp-content/uploads/2018/03/Blog-EA-Preview-Text-Entry-300x258.png" alt="Blog E&amp;A Preview Text Entry" width="300" height="258" srcset="https://hangzone.com/wp-content/uploads/2018/03/Blog-EA-Preview-Text-Entry-300x258.png 300w, https://hangzone.com/wp-content/uploads/2018/03/Blog-EA-Preview-Text-Entry-1024x879.png 1024w, https://hangzone.com/wp-content/uploads/2018/03/Blog-EA-Preview-Text-Entry-300x258@2x.png 600w, https://hangzone.com/wp-content/uploads/2018/03/Blog-EA-Preview-Text-Entry-1024x879@2x.png 2048w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<h2>Other Design Choices</h2>
<p>The design of the other elements of the game are a little more straightforward. The map and mini games (Yes, mini games!) get laid out in a storyboard along with all of the other views. Some of them are certainly nice exercises in constraints, but all were designed to be as fluid, simplistic, and minimalist as possible.</p>
<h2>On-Boarding New Players</h2>
<p>That gives you some idea on the interface design choices behind the game. There is still the issue of on-boarding new players, though. Do we need a tutorial? Do players already know how text adventures work well? There’s always the worry of on-boarding players too slowly with content that is too easy, or throwing players recklessly into a challenging, confusing world with unknown controls. Both are problems and are quick ways to lose users.</p>
<p>Our solution is one that I feel is optimal for all games if you can make it work. There is no tutorial. Players jump immediately into the game. However, the game restricts their movement as they try to solve puzzles to understand how to navigate the game. A quick mini-game opens the experience, and then, players find themselves locked in a dungeon with no way out. Both of these tasks allow the player to focus completely on a known problem as they understand the feel and objective of the game.</p>
<h2>The Story</h2>
<p>Don’t worry, no spoilers here, but know that the story is beautiful. There are a vibrant cast of characters, dropped hints, red herrings, and the satisfaction of solving puzzles to advance the story. And the twists, oh the twists! We hope that you will be engaged and brimming with emotion throughout.</p>
<p>To add more flavor to the experience, we have a number of minimalist mini games throughout the story. These will hopefully add action, fun, and excitement to the game. They also help bring the story to life. You can’t always just say you want something; sometimes you have to get it yourself!</p>
<h2>Conclusion</h2>
<p>Thanks so much for reading about our latest game, Escape &amp; Avenge. We hope that you enjoy playing the game as much as we enjoyed making it for you! You can see more about the game at our dedicated <a href="http://hangzone.com/escape-and-avenge/">Escape &amp; Avenge page</a>. If you have any questions about the game, please feel free to reach out to us. As always, thanks for reading the HangZone blog!</p>
<p>The post <a href="https://hangzone.com/escape-avenge-developer-preview/">Escape &#038; Avenge: A Developer Preview</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ARKit in iOS Part 2</title>
		<link>https://hangzone.com/arkit-ios-part-2/</link>
		
		<dc:creator><![CDATA[Judson Bandy]]></dc:creator>
		<pubDate>Wed, 14 Mar 2018 14:05:54 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">http://hangzone.com/?p=1830</guid>

					<description><![CDATA[<p>Welcome to part 2 of our ARKit in iOS tutorial. In part 1, we created an iOS app using ARKit in which we could add a chair on the ground ...</p>
<p>The post <a href="https://hangzone.com/arkit-ios-part-2/">ARKit in iOS Part 2</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Welcome to part 2 of our ARKit in iOS tutorial. In part 1, we created an iOS app using ARKit in which we could add a chair on the ground in the surrounding area. We will begin this tutorial using the app from part 1. Please visit <a href="http://hangzone.com/arkit-ios-part-1/">Part 1</a> of this tutorial if you have not already.</p>
<h2>Hopes for Part 2</h2>
<p>Currently, our app shows you the area around you, which is seen through our device’s camera. Horizontal surfaces are identified, and a transparent plane is shown over the horizontal surfaces to help us understand what ARKit has determined is a surface. Then, we are able to tap any predetermined horizontal surface to add a chair object to the scene. This chair will sit perfectly on top of the horizontal surface that ARKit has found.</p>
<p>In this tutorial, we will start by adding additional on screen logging so that we can better understand and follow along as ARKit processes the scene to look for horizontal surfaces. Then, we will find a table model to add to our scene. Finally, we will add buttons to the screen so that we can pick whether to add a table or a chair into our scene. Although there may be less room for activities, a table to go with the chair will hopefully bring the room together.</p>
<h2>Add Visual ARKit Logging UI</h2>
<p>Let’s open our app and get started! We need to add a section to our display that is going to be able to handle the label that we will use for the logging. Open Main.storyboard. Unfortunately, you will see that our current View Controller only has the ARSCNView inside of it. We cannot add a label directly inside the view controller. We need to add a View directly under the View Controller, and then, the ARSCNView and our logging label will be children of that view.</p>
<p>First, delete the ARSCNViewController. Then, add a new View to the scene, which should automatically position itself to take up the entire space. It will automatically add “Safe Area” as a child. We will use this later for some of our constraints. Next, drag an ARKit SceneKit View onto the storyboard as a child of the View. Stretch the ARSCNView so that it takes up the entire view. Add constraints so that the left and right edges are equal to the safe area leading and trailing edges and the top and bottom edges are equal to the top and bottom edges of the superview. We use superview instead of safe area for top and bottom because we want the ARSCNView to take up the entire screen, not just the safe area.</p>
<h2>Add Label and Background Effect</h2>
<p>Next, we will add the label, but instead of just adding it directly, we’ll use a transparent visual effect to set it off from the scene without obscuring what’s behind it. Drag a “Visual Effect View with Blur” to the scene and place it in the bottom left corner using the guides to keep it off the edge. Add a leading edge constraint from the Visual Effect View to the leading edge of the safe area and a bottom edge constraint to the bottom edge of the safe area. Xcode may throw layout areas, but ignore them for now. They should work themselves out by the end. Then, add a new label as a child of the view inside the Visual Effect View. Set constraints between each side of the label and the effect view container, and set the constants to “Use Standard Value.” Next, give the label a width of less than or equal to 220 and a height of greater than or equal to 22. Finally, go the the Attributes Inspector for the label and set the initial text to “Initializing AR Session.” and “Lines” to 0.</p>
<p>Now that all of the elements are set up on the scene, we need to rig the objects to our code. Press the Assistant Editor button (the one with two overlapping circles in the top right). Control drag the ARSCNView to the “sceneView” IBOutlet variable, which we had used before. Next, control drag the label into the scene to create a new outlet called sessionInfoLabel.</p>
<h2>Add Visual ARKit Logging Code</h2>
<p>Open the ViewController.swift. Add ARSessionDelegate as a new protocol at the top. The line should now look like this.</p>
<pre><code>class ViewController: UIViewController, ARSCNViewDelegate, ARSessionDelegate {
</code></pre>
<p>In the viewWillAppear method, add the following code to set the delegate immediately after the line sceneView.session.run(configuration).</p>
<pre><code>sceneView.session.delegate = self
</code></pre>
<p>Next, add the following methods to the bottom of the class.</p>
<pre><code>// MARK: - ARSessionDelegate

func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
    guard let frame = session.currentFrame else { return }
    updateSessionInfoLabel(for: frame, trackingState: frame.camera.trackingState)
}

func session(_ session: ARSession, didRemove anchors: [ARAnchor]) {
    guard let frame = session.currentFrame else { return }
    updateSessionInfoLabel(for: frame, trackingState: frame.camera.trackingState)
}

func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) {
    updateSessionInfoLabel(for: session.currentFrame!, trackingState: camera.trackingState)
}

// MARK: - ARSessionObserver

func sessionWasInterrupted(_ session: ARSession) {
    // Inform the user that the session has been interrupted, for example, by presenting an overlay.
    sessionInfoLabel.text = "Session was interrupted"
}

func sessionInterruptionEnded(_ session: ARSession) {
    // Reset tracking and/or remove existing anchors if consistent tracking is required.
    sessionInfoLabel.text = "Session interruption ended"
    resetTracking()
}

func session(_ session: ARSession, didFailWithError error: Error) {
    // Present an error message to the user.
    sessionInfoLabel.text = "Session failed: \(error.localizedDescription)"
    resetTracking()
}

// MARK: - Private methods

private func updateSessionInfoLabel(for frame: ARFrame, trackingState: ARCamera.TrackingState) {
    // Update the UI to provide feedback on the state of the AR experience.
    let message: String

    switch trackingState {
        case .normal where frame.anchors.isEmpty:
        // No planes detected; provide instructions for this app's AR interactions.
        message = "Move the device around to detect horizontal surfaces."

        case .normal:
            // No feedback needed when tracking is normal and planes are visible.
            message = "Plane detected and tracking."

        case .notAvailable:
            message = "Tracking unavailable."

        case .limited(.excessiveMotion):
            message = "Tracking limited - Move the device more slowly."

        case .limited(.insufficientFeatures):
            message = "Tracking limited - Point the device at an area with visible surface detail, or improve lighting conditions."

        case .limited(.initializing):
            message = "Initializing AR session."

    }

    sessionInfoLabel.text = message
}

private func resetTracking() {
    let configuration = ARWorldTrackingConfiguration()
    configuration.planeDetection = .horizontal
    sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
}
</code></pre>
<p>As you should be able to see, the delegate will receive updates on what ARKit is currently doing. We use these updates to change the label and provide the user with feedback as to what is happening. Run the app, and watch it in action.</p>
<p>Note: Much of this logging section is derived from Apple’s &#8220;Building Your First AR Experience&#8221; project. You can download that project to see more. <a href="https://developer.apple.com/documentation/arkit/building_your_first_ar_experience">https://developer.apple.com/documentation/arkit/building_your_first_ar_experience</a></p>
<h2>Download a Table Model</h2>
<p>Like in part 1, I am going to download a free 3d model from Turbo Squid. I covered things in more detail in part 1, but feel free to use any model or draw your own. Remember that lower poly counts typically work better for mobile, and we need the format to be DAE. I am going to use this model: <a href="https://www.turbosquid.com/FullPreview/Index.cfm/ID/1182368">https://www.turbosquid.com/FullPreview/Index.cfm/ID/1182368</a>.</p>
<h2>Add Model to Project</h2>
<p>Add the table model into the project the same way that we added the chair in part 1. You may see errors on the model when you look at it in Xcode if it has a material/texture that isn’t imported in Xcode. You can click on the object, go to the Material inspector, and remove the material to remove the visible error texture. If your model has multiple pieces, select all of them and click on the Node inspector. Name the table “FullTable” under Identity section. Then, under Transforms, set the Position to 0, 0, 0 and the Scale to 0.05, 0.05, 0.05 (if you are using a different model, you may need to use a different scale).</p>
<h2>Add Switch to User Interface</h2>
<p>Now that we have two items that we can place in our AR world, we need a way to decide which object to place or move. To accomplish this, we are going to add a switch to the top of our user interface. The switch will default to off, which will be for the chair, and it will change to the table when the switch is turned on.</p>
<p>Go back to our Main.storyboard to add the switch. Drag a switch object to the top middle of the screen. Under the Attributes inspector, set the state to off. This will let our app default to the chair. Put a constraint between the top of the switch and the top of the safe area using a standard value. Then, add a constraint to horizontally center the switch in the view. Drag a label to the left side of the switch, and set the text to “Chair.” Drag a label to the right side of the switch, and set the text to “Table.” Add constraints to vertically center each label with the switch, constraints to set each label a standard value away from the switch, and greater than or equal to standard value constraints between the labels and the superview on the sides opposite the switch. Our UI is now complete, and should look like the image below.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2018/03/Blog-ARKit-2-Layout.png"><img decoding="async" class="alignnone wp-image-1832 size-large" src="http://hangzone.com/wp-content/uploads/2018/03/Blog-ARKit-2-Layout-1024x566.png" alt="ARKit 2 Layout" width="800" height="442" srcset="https://hangzone.com/wp-content/uploads/2018/03/Blog-ARKit-2-Layout-1024x566.png 1024w, https://hangzone.com/wp-content/uploads/2018/03/Blog-ARKit-2-Layout-300x166.png 300w, https://hangzone.com/wp-content/uploads/2018/03/Blog-ARKit-2-Layout-1024x566@2x.png 2048w, https://hangzone.com/wp-content/uploads/2018/03/Blog-ARKit-2-Layout-300x166@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>We still need to let the code know whether the switch is on or off. Press the Assistant editor button in the top right, and control drag from your switch into the code. Create an IBOutlet called theSwitch. This will allow us to know the current state of the switch whenever we attempt to move or place one of our objects. We are all set to head to the code now!</p>
<h2>New Code for the Project</h2>
<p>Open ViewController.swift again. We need one new instance variables for the class. We need to add tableNode, which is type SCNNode and will handle similar duties to chairNode. Our instance variables now look like the following.</p>
<pre><code>@IBOutlet var sceneView: ARSCNView!
@IBOutlet weak var sessionInfoLabel: UILabel!
@IBOutlet weak var theSwitch: UISwitch!
var chairNode: SCNNode?
<strong>var tableNode: SCNNode?</strong>
</code></pre>
<p>In viewDidLoad, we need to create our tableNode much like we created the chairNode in part 1. However, I ran into issues with how the table was placed based on my touch. This comes from issues with where the pivot point (much like an anchor point when dealing with regular 2d objects) is positioned on the model. To adjust this, I’ve set a new pivot point for the tableNode. If your model positions fine, you can simply ignore the pivot portion of the code. Finally, we change the way that we add the nodes to the sceneView so that we can add both child nodes.</p>
<pre><code>// Create a table scene
let scene2 = SCNScene(named: "art.scnassets/Table.dae")!
tableNode = scene2.rootNode.childNode(withName: "FullTable", recursively: true)
tableNode?.pivot = SCNMatrix4MakeTranslation((tableNode?.boundingBox.max.x)! - (tableNode?.boundingBox.min.x)! * 0.5, (tableNode?.boundingBox.max.y)! - (tableNode?.boundingBox.min.y)! * 0.5, (tableNode?.boundingBox.max.z)! + (tableNode?.boundingBox.min.z)! * 0.5)
tableNode?.position = SCNVector3Make(0, 0, -3)
tableNode?.isHidden = true

// Set the scene to the view
<del>sceneView.scene = scene</del>
sceneView.scene.rootNode.addChildNode(chairNode!)
sceneView.scene.rootNode.addChildNode(tableNode!)
</code></pre>
<p>Finally, we need to adjust our touchesBegan code to place the chair or table depending on our switch. This is done with a simple if statement on our switch to see if we want our chair or table.</p>
<pre><code><del>chairNode?.position = hitPosition;</del>
<del>chairNode?.isHidden = false;</del>
if !theSwitch.isOn {
    chairNode?.position = hitPosition;
    chairNode?.isHidden = false;
} else {
    tableNode?.position = hitPosition;
    tableNode?.isHidden = false;
}</code></pre>
<p><a href="http://hangzone.com/wp-content/uploads/2018/03/Blog-ARKit-2-Finished-App.png"><img decoding="async" class="alignnone size-medium wp-image-1831" src="http://hangzone.com/wp-content/uploads/2018/03/Blog-ARKit-2-Finished-App-139x300.png" alt="ARKit 2 Finished App" width="139" height="300" srcset="https://hangzone.com/wp-content/uploads/2018/03/Blog-ARKit-2-Finished-App-139x300.png 139w, https://hangzone.com/wp-content/uploads/2018/03/Blog-ARKit-2-Finished-App-473x1024.png 473w, https://hangzone.com/wp-content/uploads/2018/03/Blog-ARKit-2-Finished-App.png 1125w, https://hangzone.com/wp-content/uploads/2018/03/Blog-ARKit-2-Finished-App-139x300@2x.png 278w, https://hangzone.com/wp-content/uploads/2018/03/Blog-ARKit-2-Finished-App-473x1024@2x.png 946w" sizes="(max-width: 139px) 100vw, 139px" /></a></p>
<h2>Conclusion</h2>
<p>That’s it! We successfully added visual text logging to our app to help get a better understanding of ARKit in action. Although you likely wouldn’t have full logging like this in a production app, alerting the user of what’s happening if things aren’t working is a good idea. Then, we added another piece of furniture to our AR room. With a table and chair, we finally have a good place to sit down and do more virtual programming. Until next time, thanks for following the HangZone blog!</p>
<p>The post <a href="https://hangzone.com/arkit-ios-part-2/">ARKit in iOS Part 2</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ARKit in iOS Part 1</title>
		<link>https://hangzone.com/arkit-ios-part-1/</link>
		
		<dc:creator><![CDATA[Judson Bandy]]></dc:creator>
		<pubDate>Wed, 06 Dec 2017 11:19:13 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">http://hangzone.com/?p=1755</guid>

					<description><![CDATA[<p>The release of iOS 11 this year brought an exciting new framework with it—ARKit! This framework is designed to greatly aid in the creation of augmented reality apps for iOS ...</p>
<p>The post <a href="https://hangzone.com/arkit-ios-part-1/">ARKit in iOS Part 1</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The release of iOS 11 this year brought an exciting new framework with it—ARKit! This framework is designed to greatly aid in the creation of augmented reality apps for iOS devices. Augmented reality itself certainly isn’t a new idea. Pokemon Go brought it to the forefront, but developers have been working with it for some time. The hats, glasses, and mustache effects that are available in Google Hangout are examples of augmented reality, as are live filters that you may have in a camera app. Adding any computer generated objects to reality turns an app into augment reality.</p>
<p>The ability to create augmented reality apps already existed on iOS. ARKit simply makes the task much easier. This new framework is able to detect horizontal surfaces, which is key in being able to easily place new AR objects on the ground in your scene. No one wants their AR foot enemies to be flying instead of walking. It also does a great job of tracking objects in the world as you move through it.</p>
<p>ARKit can be used a couple of different ways. Through Xcode, ARKit can be run through either Metal, SpriteKit, or SceneKit. SpriteKit is Apple’s 2d game engine, and as you might guess, this is for 2d augmented reality. You can add 2 dimensional images to your world. This might be useful for adding signs, overlays, or invading squares. ARKit with SceneKit is used for 3d augmented reality. This is what we’ll be using in this tutorial. You can add any 3d objects you like to your world. Besides Xcode, ARKit can also be used through Unity and Unreal Engine.</p>
<h2>Requirements</h2>
<p>ARKit utilizes powerful computing tools to operate, and as such, it cannot be used with older devices. ARKit requires an Apple A9 processor or higher and iOS 11. The oldest compatible phone is the iPhone 6S. All iPad Pros and the 2017 iPad are also compatible.</p>
<h2>Our Project</h2>
<p>For part 1, we are going to add a chair in the room or space around you. Just remember not to try to sit on it! From there, we will create a richer augmented reality sequence in subsequent parts. Let’s get started by finding an image to use and putting it into our augmented world.</p>
<h2>Finding a 3D Image</h2>
<p>Before we open Xcode, we need to find a 3d model to use in or project. You can certainly draw you own 3d image in a number of different 3d art programs (Blender is a great free option), and I encourage you to do it. For this tutorial, though, we will simply download a 3d model. My favorite place to go for this is TurboSquid. They have really high quality models that are available for download. Some of these are quite expensive, but they also have a great selection of free models.</p>
<p>We are looking for a chair to go in our room, so I would recommend searching for “chair”. Once the search is complete, go under “Price” and enter a custom price range of 0-0. This will give you only free options. Now, you can pick any chair you want, but there are a couple of things to keep in mind.</p>
<p>First, not every model on the site is made for mobile. Although high end PC gaming and static 3d scenes can use really detailed models, you want to use simpler designs. A polygon count over 15k is probably a little high for mobile. Too many large images can start to reduce your project’s ability to run smoothly. Second, SceneKit needs your model to be in a DAE format. If the image you want to use doesn’t have a DAE format, it may still work. You simply need to export the image into a DAE format through a different program.</p>
<p>For example, one chair model that I downloaded did not have a .dae version, so I downloaded the .fbx (Autodesk FBX). I opened Blender, and went to File-&gt;Import-&gt;Autodesk FBX and selected my chair model. You may not notice a difference because the cube might be obstructing your image. In the top-right “View” menu, unselect the eye icon on the Cube, which is already shown on the screen. Then, zoom in on the screen by doing a pinch zoom, and you should see your chair! Finally, go to File-&gt;Export-&gt;Collada (Default) (.dae).</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/12/AR-Blender-Chair-Export.png"><img decoding="async" class="alignnone size-medium wp-image-1760" src="http://hangzone.com/wp-content/uploads/2017/12/AR-Blender-Chair-Export-300x188.png" alt="AR Blender Chair Export" width="300" height="188" srcset="https://hangzone.com/wp-content/uploads/2017/12/AR-Blender-Chair-Export-300x188.png 300w, https://hangzone.com/wp-content/uploads/2017/12/AR-Blender-Chair-Export-1024x640.png 1024w, https://hangzone.com/wp-content/uploads/2017/12/AR-Blender-Chair-Export-480x300.png 480w, https://hangzone.com/wp-content/uploads/2017/12/AR-Blender-Chair-Export-640x400.png 640w, https://hangzone.com/wp-content/uploads/2017/12/AR-Blender-Chair-Export-300x188@2x.png 600w, https://hangzone.com/wp-content/uploads/2017/12/AR-Blender-Chair-Export-1024x640@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/12/AR-Blender-Chair-Export-480x300@2x.png 960w, https://hangzone.com/wp-content/uploads/2017/12/AR-Blender-Chair-Export-640x400@2x.png 1280w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Feel free to download a .dae model from TurboSquid, convert a model that is a different format, or draw your own image and export it as .dae. I am using this chair, <a href="https://www.turbosquid.com/FullPreview/Index.cfm/ID/831461">https://www.turbosquid.com/FullPreview/Index.cfm/ID/831461</a>.</p>
<h2>Getting Started in Xcode</h2>
<p>Open Xcode and select “Create New Xcode Project”. Under the iOS tab, select “Augmented Reality App” under the Application section. As you set up the details for your project, make sure to select SceneKit for your “Content Technology”. This is one of the options that we detailed at the start of this post. Pick a place to save your project, and we’re ready to go!</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/12/AR-Create-App.png"><img decoding="async" class="alignnone size-medium wp-image-1761" src="http://hangzone.com/wp-content/uploads/2017/12/AR-Create-App-300x167.png" alt="AR Create App" width="300" height="167" srcset="https://hangzone.com/wp-content/uploads/2017/12/AR-Create-App-300x167.png 300w, https://hangzone.com/wp-content/uploads/2017/12/AR-Create-App-1024x571.png 1024w, https://hangzone.com/wp-content/uploads/2017/12/AR-Create-App-300x167@2x.png 600w, https://hangzone.com/wp-content/uploads/2017/12/AR-Create-App-1024x571@2x.png 2048w" sizes="(max-width: 300px) 100vw, 300px" /></a>  <a href="http://hangzone.com/wp-content/uploads/2017/12/AR-Create-Options.png"><img decoding="async" class="alignnone size-medium wp-image-1762" src="http://hangzone.com/wp-content/uploads/2017/12/AR-Create-Options-300x167.png" alt="AR Create Options" width="300" height="167" srcset="https://hangzone.com/wp-content/uploads/2017/12/AR-Create-Options-300x167.png 300w, https://hangzone.com/wp-content/uploads/2017/12/AR-Create-Options-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/12/AR-Create-Options-300x167@2x.png 600w, https://hangzone.com/wp-content/uploads/2017/12/AR-Create-Options-1024x572@2x.png 2048w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Feel free to go ahead and run the project. You will see a 3d fighter plane looking object appear. Don’t worry—it’s not going to crash into you. It’s only augmented reality. You can walk around the plane and admire it from different angles.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/12/AR-Plane.png"><img decoding="async" class="alignnone size-medium wp-image-1765" src="http://hangzone.com/wp-content/uploads/2017/12/AR-Plane-169x300.png" alt="AR Plane" width="169" height="300" srcset="https://hangzone.com/wp-content/uploads/2017/12/AR-Plane-169x300.png 169w, https://hangzone.com/wp-content/uploads/2017/12/AR-Plane-576x1024.png 576w, https://hangzone.com/wp-content/uploads/2017/12/AR-Plane.png 750w, https://hangzone.com/wp-content/uploads/2017/12/AR-Plane-169x300@2x.png 338w" sizes="(max-width: 169px) 100vw, 169px" /></a></p>
<h2>Adding Our Image</h2>
<p>In our Xcode project, under art.scnassets, you will see the image and texture that you saw when you ran the project. Let’s add our chair to the project. You may want to drag the DAE file into the art.scnassets folder in Finder instead of directly into Xcode (the image didn’t want to copy to the new location when I pulled the file directly to Xcode). When you click on your chair model in the project, you should see the 3d chair against a large white checkered plane.</p>
<p>Let’s see the chair in our project. Go to ViewController.swift. Now, we’ll simply change the image from a fighter plane to our chair. Change the following line in viewDidLoad() to your chair image name.</p>
<pre><code><del>let scene = SCNScene(named: “art.scnassets/ship.scn")!</del>
let scene = SCNScene(named: “art.scnassets/LowPolyChair.dae")!
</code></pre>
<p>Run the project. It may appear as if there is nothing there. However, if you look up, you should see a giant chair positioned directly above you with its legs going down around you. We need to get out of our chair jail now.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/12/AR-Large-Chair.png"><img decoding="async" class="alignnone size-medium wp-image-1764" src="http://hangzone.com/wp-content/uploads/2017/12/AR-Large-Chair-169x300.png" alt="AR Large Chair" width="169" height="300" srcset="https://hangzone.com/wp-content/uploads/2017/12/AR-Large-Chair-169x300.png 169w, https://hangzone.com/wp-content/uploads/2017/12/AR-Large-Chair-576x1024.png 576w, https://hangzone.com/wp-content/uploads/2017/12/AR-Large-Chair.png 750w, https://hangzone.com/wp-content/uploads/2017/12/AR-Large-Chair-169x300@2x.png 338w" sizes="(max-width: 169px) 100vw, 169px" /></a></p>
<h2>Adjusting our 3d model</h2>
<p>Let’s move the chair in front of us, resize it, and see how it looks. We can make this change either programmatically, or in the Node Inspector for the model. Let’s position the chair in the code, but we’ll scale the chair in the Node Inspector first. Click on the chair model. Then, under the utility sidebar on the right side, click on the Node Inspector (the cube icon). Under Scale, change the x, y, and z values to 0.2, 0.2, and 0.2 respectively (if you&#8217;re using a different image, the scale will likely be different). Also, you should see a “Name” field under Identity. Change it to “Chair”. Now, return to the ViewControler.swift right below where we changed the code in the viewDidLoad(). Add the following.</p>
<pre><code>let chairNode = scene.rootNode.childNode(withName: "Chair", recursively: true)
chairNode?.position = SCNVector3Make(0, 0, -3)
</code></pre>
<p>We created a local constant, chairNode, by searching for the child node named “Chair” in the newly created scene. This lets us select our chair, and then put a position on it. We put it at (0, 0, -3), which is straight in front of us. If you run your project and are in a space with enough room, you can walk up to the chair and see that it is strangely floating, but it looks good besides that. Let’s figure out how to put it on the ground!</p>
<h2>Finding Flat Horizontal Surfaces</h2>
<p>One of the great features of ARKit is its ability to determine the ground and other flat horizontal surfaces like a table top. We are going to expose this ability by adding planes to the ground once ARKit has discovered them. The base configuration in the ViewController.swift already creates an ARWorldTrackingConfiguration. This class provides detailed motion tracking and allows the ability to place virtual objects in relation to real surfaces. We will add horizontal plane detection to our configuration to leverage this feature. You need to add the plane detection line inside the viewWillAppear method.</p>
<pre><code>// Create a session configuration
let configuration = ARWorldTrackingConfiguration()
<strong>configuration.planeDetection = .horizontal</strong>
// Run the view's session
sceneView.session.run(configuration)
</code></pre>
<p>Tracking and plane detection is now setup! ARKit will now add and update anchors for each plane—specifically the ARSCNView class adds an SCNNode object to the SceneKit scene for each anchor. The ARSCNViewDelegate, which is already on the ViewController, will call delegate methods whenever a new anchor is added or updated. Now, we will add the delegate methods for adding and updating anchors. We will use these methods to add and update our own 3d planes where the anchors are found. This will give us a visual cue to see the detected planes. These planes will be added to the nodes that ARKit uses as anchors for the planes.</p>
<pre><code>/// - Tag: PlaceARContent
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    // Place content only for anchors found by plane detection.
    guard let planeAnchor = anchor as? ARPlaneAnchor else { return }

    // Create a SceneKit plane to visualize the plane anchor using its position and extent.
    let plane = SCNPlane(width: CGFloat(planeAnchor.extent.x), height: CGFloat(planeAnchor.extent.z))
    let planeNode = SCNNode(geometry: plane)
    planeNode.simdPosition = float3(planeAnchor.center.x, 0, planeAnchor.center.z)
     

    /* SCNPlane` is vertically oriented in its local coordinate space, so rotate the plane to match the horizontal orientation of `ARPlaneAnchor`.*/
    planeNode.eulerAngles.x = -.pi / 2
     

    // Make the plane visualization semitransparent to clearly show real-world placement.
    planeNode.opacity = 0.25
     

    /* Add the plane visualization to the ARKit-managed node so that it tracks changes in the plane anchor as plane estimation continues.*/
    node.addChildNode(planeNode)
}

/// - Tag: UpdateARContent
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {

    // Update content only for plane anchors and nodes matching the setup created in renderer(_:didAdd:for:)`.
    guard let planeAnchor = anchor as?  ARPlaneAnchor,
    let planeNode = node.childNodes.first,
    let plane = planeNode.geometry as? SCNPlane
    else { return }
     

    // Plane estimation may shift the center of a plane relative to its anchor's transform.
    planeNode.simdPosition = float3(planeAnchor.center.x, 0, planeAnchor.center.z)
     

    /* Plane estimation may extend the size of the plane, or combine previously detected planes into a larger one. In the latter case, `ARSCNView` automatically deletes the corresponding node for one plane, then calls this method to update the size of the remaining plane.*/
    plane.width = CGFloat(planeAnchor.extent.x)
    plane.height = CGFloat(planeAnchor.extent.z)
}
</code></pre>
<p>Much of the plane detection code comes directly from Apple ARKit tutorials. Feel free to check out their &#8220;Building Your First AR Experience&#8221; project to learn more. <a href="https://developer.apple.com/documentation/arkit/building_your_first_ar_experience">https://developer.apple.com/documentation/arkit/building_your_first_ar_experience</a></p>
<h2>Placing a Chair on the Ground</h2>
<p>Now, we want to place the chair on the ground. Let’s go ahead and create an instance variable for chairNode at the start of the project so we can reference it easier throughout the class. Add the following line as an instance variable.</p>
<pre><code>var chairNode: SCNNode?
</code></pre>
<p>Then, remove the local constant declaration from chairNode so that it references the instance variable when it is created. We will also hide the chairNode, so we don’t have to deal with it floating when the app loads.</p>
<pre><code><del>let </del>chairNode = scene.rootNode.childNode(withName: "Chair", recursively: true)
chairNode?.isHidden = true
</code></pre>
<p>Now that we have simple access to our chair, we want to add it to one of the planes that we have detected. We will override the touchesBegan method to place a chair. If we tap any spot that shows a horizontal plane anchor, the chair will become visible and move to the position. If we tap a spot that does not include an anchor, the chair will stay in the same position (and stay hidden if it has not been set yet). Add the following code.</p>
<pre><code>override func touchesBegan(_ touches: Set&lt;UITouch&gt;, with event: UIEvent?) {
    guard let touch = touches.first else { return }
    let touchResults = sceneView.hitTest(touch.location(in: sceneView), types: [ARHitTestResult.ResultType.existingPlaneUsingExtent])
    if touchResults.count &gt; 0 {
        let hitResult: ARHitTestResult = touchResults.first!
        let hitResultWT = SCNMatrix4(hitResult.worldTransform)
        // m41, m42, m43 are the position entries of the 4x4 matrix
        let hitPos = SCNVector3Make(hitResultWT.m41,
                                    hitResultWT.m42,
                                    hitResultWT.m43)
        chairNode?.position = hitPos;
        chairNode?.isHidden = false;
    }
}
</code></pre>
<p><a href="http://hangzone.com/wp-content/uploads/2017/12/AR-Ground-Chair.png"><img decoding="async" class="alignnone size-medium wp-image-1763" src="http://hangzone.com/wp-content/uploads/2017/12/AR-Ground-Chair-169x300.png" alt="AR Ground Chair" width="169" height="300" srcset="https://hangzone.com/wp-content/uploads/2017/12/AR-Ground-Chair-169x300.png 169w, https://hangzone.com/wp-content/uploads/2017/12/AR-Ground-Chair-576x1024.png 576w, https://hangzone.com/wp-content/uploads/2017/12/AR-Ground-Chair.png 750w, https://hangzone.com/wp-content/uploads/2017/12/AR-Ground-Chair-169x300@2x.png 338w" sizes="(max-width: 169px) 100vw, 169px" /></a></p>
<p>Note: Depending on lighting, surroundings, and other elements, your device may struggle somewhat with horizontal plane recognition. Give it time and continue to move your device around until it works.</p>
<h2>Conclusion</h2>
<p>ARKit is an extremely powerful framework with a plethora of different use cases. Stay tuned for part 2 of the ARKit tutorial where we will add more elements to our AR scene and look at further logging for how ARWorldTrackingConfiguration works. As always, thanks for reading the HangZone blog!</p>
<p>The post <a href="https://hangzone.com/arkit-ios-part-1/">ARKit in iOS Part 1</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
