<?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>Tables &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/tables/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Tue, 08 Aug 2023 22:35:38 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.7</generator>
	<item>
		<title>iOS: Leading Actions on iOSMobileTable</title>
		<link>https://blog.xojo.com/2023/08/09/ios-leading-actions-on-iosmobiletable/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Wed, 09 Aug 2023 13:30:00 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Tables]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11747</guid>

					<description><![CDATA[Starting with Xojo 2023r2 you will be able to add Leading Actions to the rows in your iOSMobileTable instances on iOS, in addition to the regular actions previously available. This introduces many more options and user interface flexibility to the table rows.]]></description>
										<content:encoded><![CDATA[
<p>Starting with Xojo 2023r2 you can add Leading Actions to the rows in your <a href="https://documentation.xojo.com/api/ios/iosmobiletable.html#iosmobiletable">iOSMobileTable</a> instances on iOS, in addition to the regular actions previously available. This introduces many more options and user interface flexibility to the table rows.</p>



<span id="more-11747"></span>



<p>Regular actions attached to the iOSMobileTable rows are those shown (if implemented) when the user drags a row from the right to the left. This is something you can do using the following snippet of code in the <a href="https://documentation.xojo.com/api/ios/iosmobiletable.html#iosmobiletable-applyactionsforrow">ApplyActionsForRow</a> event handler of a MobileTable instance, in this example named TeamTable:</p>



<pre id="Xojo" class="wp-block-preformatted"><code>Var actions(0) As iOSMobileTableRowAction
// Create the Delete button
actions(0) = New iOSMobileTableRowAction(iOSMobileTableRowAction.Styles.Destructive, "Delete", "Delete" + row.ToString)
Return actions</code></pre>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img fetchpriority="high" decoding="async" width="838" height="826" src="https://blog.xojo.com/wp-content/uploads/2023/07/Screenshot-2023-07-19-at-11.35.25.png" alt="" class="wp-image-11748" srcset="https://blog.xojo.com/wp-content/uploads/2023/07/Screenshot-2023-07-19-at-11.35.25.png 838w, https://blog.xojo.com/wp-content/uploads/2023/07/Screenshot-2023-07-19-at-11.35.25-300x296.png 300w, https://blog.xojo.com/wp-content/uploads/2023/07/Screenshot-2023-07-19-at-11.35.25-768x757.png 768w" sizes="(max-width: 838px) 100vw, 838px" /></figure>
</div>


<p>Now you will be able to implement the new ApplyLeadingActionsForRow event handler in your iOSMobileTable instances. In doing that, you will be able to add new actions to the row that will be shown when the user drags the row from left to right. Of course, as you can do with the regular actions, you can add as many of these as you need.</p>



<p>For example, the following snippet of code implemented in this new event will be in charge of adding a total of three leading actions on every row of the TeamTable used in our example:</p>



<pre id="Xojo" class="wp-block-preformatted"><code>Var actions() As iOSMobileTableRowAction

Var act1, act2, act3 As iOSMobileTableRowAction
act1 = New iOSMobileTableRowAction(iOSMobileTableRowAction.Styles.Normal, "Normal", "Normal " + row.ToString)
act2 = New iOSMobileTableRowAction(iOSMobileTableRowAction.Styles.Normal, "Potato", "Potato " + row.ToString)
act3 = New iOSMobileTableRowAction(iOSMobileTableRowAction.Styles.Normal, "Tomato", "Tomato " + row.ToString)

act1.BackgroundColor = Color.RGB(System.Random.InRange(0,255), System.Random.InRange(0,255), System.Random.InRange(0,255))
act2.BackgroundColor = Color.RGB(System.Random.InRange(0,255), System.Random.InRange(0,255), System.Random.InRange(0,255))
act3.BackgroundColor = Color.RGB(System.Random.InRange(0,255), System.Random.InRange(0,255), System.Random.InRange(0,255))

act1.Image = Xojo16

actions.add act1
actions.add act2
actions.add act3
Return actions</code></pre>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img decoding="async" width="834" height="806" src="https://blog.xojo.com/wp-content/uploads/2023/07/Screenshot-2023-07-19-at-11.35.39.png" alt="" class="wp-image-11749" srcset="https://blog.xojo.com/wp-content/uploads/2023/07/Screenshot-2023-07-19-at-11.35.39.png 834w, https://blog.xojo.com/wp-content/uploads/2023/07/Screenshot-2023-07-19-at-11.35.39-300x290.png 300w, https://blog.xojo.com/wp-content/uploads/2023/07/Screenshot-2023-07-19-at-11.35.39-768x742.png 768w" sizes="(max-width: 834px) 100vw, 834px" /></figure>
</div>


<p>Finally, the RowActionSelect event handler of the table will be fired when any of the actions —both regular and leading— are selected by the user. You can rely on the received Section, Row and ActionTag parameters to execute the code of your iOS app in response to every one of the actions added to the row just as in previous Xojo releases.</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>PDFTable from a RowSet</title>
		<link>https://blog.xojo.com/2023/01/17/pdftable-from-a-rowset/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 17 Jan 2023 16:00:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Eddie&#039;s Electronics]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Tables]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11146</guid>

					<description><![CDATA[Xojo recently introduced the ability to add (aka draw) tables in PDFDocument using the PDFTable class and the PDFTableDataSource class interface together. Perhaps you already know how to use it, but what if you want to add a table using data from a RowSet? Continue reading and I will show you a technique that will have you doing just that!]]></description>
										<content:encoded><![CDATA[
<p>Xojo recently introduced the ability to add (aka draw) tables in <a href="https://documentation.xojo.com/api/pdf/pdfdocument.html#pdfdocument">PDFDocument</a> using the <a href="https://documentation.xojo.com/api/pdf/pdftable.html#pdftable">PDFTable</a> class and the <a href="https://documentation.xojo.com/api/pdf/pdftabledatasource.html#pdftabledatasource">PDFTableDataSource</a> class interface together. Perhaps you already know how to use it, but what if you want to add a table using data from a <a href="https://documentation.xojo.com/api/databases/rowset.html#rowset">RowSet</a>? Continue reading and I will show you a technique that will have you doing just that!</p>



<span id="more-11146"></span>



<p>But before we dive into the code,&nbsp;this example project requires the &#8220;EddiesElectronics.sqlite&#8221; SQLite database file. You can find the Eddie&#8217;s Electronics example, along with the other example projects provided with Xojo, in the Examples section of the Project Chooser. Because I am such a kind person, you can also <a href="https://drive.google.com/file/d/1zts_ZL2ZQujW7fWD1m2qr_XpQGq3dbHD/view?usp=share_link">download it directly from this link</a>.</p>



<p>And, if you want, it is also possible to download the resulting <a href="https://drive.google.com/file/d/1Z5Eurwxm7UXlCLU_aj270SNKnlDmpT7Z/view?usp=share_link">Xojo Project file (for Desktop) from this link</a>.</p>



<p>I&#8217;m pretty sure you will be able to adapt the example project so it works for you with other databases too!</p>



<figure class="wp-block-image is-style-default"><img decoding="async" width="809" height="1024" src="https://blog.xojo.com/wp-content/uploads/2023/01/GeneratedPDF-809x1024.png" alt="" class="wp-image-11149" srcset="https://blog.xojo.com/wp-content/uploads/2023/01/GeneratedPDF-809x1024.png 809w, https://blog.xojo.com/wp-content/uploads/2023/01/GeneratedPDF-237x300.png 237w, https://blog.xojo.com/wp-content/uploads/2023/01/GeneratedPDF-768x972.png 768w, https://blog.xojo.com/wp-content/uploads/2023/01/GeneratedPDF-1214x1536.png 1214w, https://blog.xojo.com/wp-content/uploads/2023/01/GeneratedPDF.png 1342w" sizes="(max-width: 809px) 100vw, 809px" /></figure>



<h3 class="wp-block-heading">Helper class to the rescue!</h3>



<p>All the work of drawing the table in the PDF document will be done by a helper class. That is, a class that we are going to use to &#8220;delegate&#8221; the work. With Xojo open and a new Desktop project created, the first thing we are going to do is add a new Class to the project (Insert &gt; Class).</p>



<p>With the added Class selected in the Navigator, go to the associated Inspector Panel and use the following values:</p>



<ul class="wp-block-list">
<li><strong>Name:</strong> PDFRenderer</li>



<li><strong>Interfaces:</strong> Click on the &#8220;Choose&#8221; button and select the PDFTableDataSource class interface</li>
</ul>



<p>The just added Class will be populated with all the methods defined by the PDFTableDataSource class interface. Do not worry about them now.</p>



<p>Next, let&#8217;s add a few properties to our PDFRenderer class:</p>



<ul class="wp-block-list">
<li><strong>Name:</strong> data</li>



<li><strong>Type:</strong> RowSet</li>



<li><strong>Scope:</strong> Protected</li>
</ul>



<ul class="wp-block-list">
<li><strong>Name:</strong> document</li>



<li><strong>Type:</strong> PDFDocument</li>



<li><strong>Scope:</strong> Protected</li>
</ul>



<ul class="wp-block-list">
<li><strong>Name:</strong> DrawingFromRowSet</li>



<li><strong>Type:</strong> Boolean</li>



<li><strong>Scope:</strong> Protected</li>
</ul>



<ul class="wp-block-list">
<li><strong>Name:</strong> Headers()</li>



<li><span style="font-size: revert;"><strong>Type:</strong> String</span></li>



<li><span style="font-size: revert;"><strong>Scope:</strong> Protected</span></li>
</ul>



<p>We are going to use the DrawingFromRowSet as a flag, so the PDFRenderer knows when the table is going to be created from a RowSet. You could use any other data source, you are limited to RowSet. That&#8217;s just something you will need to implement yourself! Take it as an exercise.</p>



<p>Next, add a new Method to the PDFRenderer class (while still selected in the Navigator) using the following values in the associated Inspector Panel:</p>



<ul class="wp-block-list">
<li><strong>Name:</strong> Constructor</li>



<li><strong>Parameters:</strong> document As PDFDocument</li>



<li><strong>Scope:</strong> Public</li>
</ul>



<p>And type the following line of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted xojo"><code>Self.Document = document</code></pre>



<p>Yep, it is truly that simple. Assign the received PDFDocument object to the &#8220;Document&#8221; property of the object created from the PDFRenderer class.</p>



<p>Add a second method using the following values:</p>



<ul class="wp-block-list">
<li><strong>Name:</strong> DrawTable</li>



<li><strong>Parameters:</strong> rs As RowSet, headers() As String</li>



<li><strong>Scope:</strong> Public</li>
</ul>



<p>And type the following code in the associated Code Editor:</p>



<pre class="wp-block-preformatted"><code>// This is the method we call on the Class to draw
// a table on a PDFDocument based on a RowSet

If document &lt;&gt; Nil And rs &lt;&gt; Nil Then

  // Assign the received RowSet to the "Data" property
  Self.data = rs

  // Assign the received headers to the "Headers" property
  Self.Headers = Headers

  // Hey! We are going to create a table from a RowSet
  // so we use a Boolean property as a flag for that
  // (Yeah, we can do it using other techniques, but this
  // is easy enough for this purpose…&nbsp;while leave this
  // helper class "open" enough for drawing tables based on other
  // data sources).
  Self.DrawingFromRowSet = True

  // How many columns are we going to draw?
  // Well… as many as columns in the RowSet.
  Var totalColumns As Integer = rs.ColumnCount

  // This is going to be the "drawable area" on the page
  // for the table = total page width less the left and right margins
  Var totalWidth As Double = document.Graphics.Width - 40 // 40 = 20 points left/right margins

  // Creating the PDFTable object here!
  Var table As New PDFTable

  // We want to repeat the headers on every page
  table.HasRepeatingHeader = True

  // Setting the column count for the table
  table.ColumnCount = totalColumns

  // …and the width for every column.
  table.ColumnWidths = CalculateColumnWidths(TotalWidth, totalColumns)

  // The object from this class will be the responsible
  // for handling all the methods associated with the
  // PDFTableDataSouce Class Interface
  table.DataSource = Self

  // Setting the Top and Bottom margins for the drawing
  // of the table on every PDF page
  table.TopMargin = 20
  table.BottomMargin = 20

  // …and finally we instruct the PDFDocument object
  // to draw the table!
  document.AddTable(table, 20, 0)

  // Lastly, clearing the flag
  Self.DrawingFromRowSet = False

End If</code></pre>



<p>As you can see here, we are calling the &#8220;CalculateColumnWidths&#8221; method in order to get the expected string for the column widths for the PDFTable.ColumnWidths property; so add a new method to the PDFRenderer class using the following values:</p>



<ul class="wp-block-list">
<li><strong>Name:</strong> CalculateColumnWidths</li>



<li><strong>Parameters:</strong> TotalWidth As Double, NumberOfColumns As Double</li>



<li><strong>Return Type:</strong> String</li>



<li><strong>Scope:</strong> Protected</li>
</ul>



<p>And type the following snippet of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted"><code>Var ColumnWidth As Integer = TotalWidth / NumberOfColumns
Var s() As String

For n As Integer = 0 To NumberOfColumns-1
  s.Add(Str(ColumnWidth))
Next

Return String.FromArray(s, ",")</code></pre>



<h3 class="wp-block-heading">PDFTableDataSource Methods with RowSet data!</h3>



<p>Let&#8217;s fill the required methods from the PDFTableDataSource class interface so they work in combination with the received RowSet.</p>



<h4 class="wp-block-heading">AddNewRow Method</h4>



<p>Add this snippet of code for the &#8220;AddNewRow&#8221; method:</p>



<pre class="wp-block-preformatted"><code>If DrawingFromRowSet And data &lt;&gt; Nil Then

  // We are going to draw as many rows as rows are in the
  // "data" rowset
  Return rowCount &lt;&gt; data.RowCount

End If</code></pre>



<p>As you can see, that fragment of code will only run when both conditions are meet. That is, when the &#8220;DrawingFromRowSet&#8221; is set to True and the &#8220;data&#8221; property is set to a not niled RowSet. If this is the case, we then instruct our PDFTable to set the number of rows to be drawn to the same number of rows in the RowSet.</p>



<h4 class="wp-block-heading">Completed Method</h4>



<p>This is the method that will be called once the drawing of the PDFTable has been completed. We will use it to draw the page numbers at the bottom of every page in the PDFDocument. As you probably already know, it is really easy to change the active graphic context to a given page of the PDF document using the CurrentPage property, so we will use that to iterate every one of our PDF document pages, adding the page number to it as a footer.</p>



<p>This is the snippet of code responsible for doing just that:</p>



<pre class="wp-block-preformatted"><code>// This method is called once the table has been drawn
// so let's "print" the page number on every page
// of the PDF Document

Static pageNumber As String = "Page: "

If document &lt;&gt; Nil Then
  Var g As Graphics = document.Graphics

  For n As Integer = 1 To document.PageCount
    document.CurrentPage = n
    g.DrawText(pageNumber + Str(n), g.Width - g.TextWidth(pageNumber+Str(n))-20, g.Height-g.FontAscent)
  Next

End If</code></pre>



<h4 class="wp-block-heading">HeaderHeight Method</h4>



<p>This is the method called so we can set the PDFTable the desired height for the drawing of the Header. In this case we are going to use a fixed value: 20 points. The code for that method is:</p>



<pre class="wp-block-preformatted"><code>// Fixed header height
Return 20</code></pre>



<h4 class="wp-block-heading">PaintCell Method</h4>



<p>This is the method responsible for drawing every cell of the PDFTable. It receives as parameters the Graphic context for a particular cell (so its origin is at 0,0) and the row and column values corresponding for such cell.</p>



<p>In this case, draw the outline of a rectangle for the cell plus the text itself retrieved from the RowSet based on the received Column value. The text will be draw vertically centered in the cell:</p>



<pre class="wp-block-preformatted"><code>If DrawingFromRowSet And data &lt;&gt; Nil Then
  // Drawing the outer rectangle for the cell
  g.DrawRectangle(0, 0, g.Width, g.Height)

  // retrieving the text to be drawn from the RowSet,
  // using the column parameter for that.
  Var s As String = data.ColumnAt(column)

  // Centering vertically the text on the table cell
  // while the X offset is fixed at 5 points.
  g.DrawText(s, 5, g.Height / 2 + g.FontAscent / 2)

  // Have we drawn all the columns for this row?
  If column = data.ColumnCount - 1 Then

    // if that is the case, then move to the next row
    // in the RowSet!
    data.MoveToNextRow
  End If

End If</code></pre>



<h4 class="wp-block-heading">PaintHeaderContent Method</h4>



<p>This is the method called in order to draw the Header of the table itself. It is a more simple version of the previous method. In this case, the text will be centered both vertically and horizontally on every header cell:</p>



<pre class="wp-block-preformatted"><code>If column &lt;= Self.Headers.LastIndex Then

  Var s As String = headers(column)
  g.DrawingColor = Color.Black
  g.FillRectangle(0, 0, g.Width, g.Height)
  g.DrawingColor = Color.White
  g.DrawText(s, g.Width / 2 - g.TextWidth(headers(column)) / 2, g.Height / 2 + g.FontAscent / 2)

End If</code></pre>



<h4 class="wp-block-heading">RowHeight Method</h4>



<p>As it happen with the HeaderHeight method, this is the method called to set the height for a given row. As we did for the HeaderHeight method we are going to use a fixed value of 20 points, so type the following line of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted"><code>Return 20</code></pre>



<h3 class="wp-block-heading">Testing The PDFRenderer class</h3>



<p>In order to test our PDFRenderer class in combination with a RowSet object, we need to do some additional work. First, select the Window1 window in the project Navigator and add a property using the following values:</p>



<ul class="wp-block-list">
<li><strong>Name:</strong> db</li>



<li><strong style="font-size: revert;">Type:</strong><span style="font-size: revert;"> SQLiteDatabase</span></li>



<li><strong style="font-size: revert;">Scope:</strong><span style="font-size: revert;"> Private</span></li>
</ul>



<p>Next, click the Window1 window in the Navigator so it is displayed in the Layout Editor. Then, drag a DesktopLabel from the Library and drop it on the left/top edge of the layout observing the aligning guides so it leaves the expected margin over the left and top edges of the Window. Use the dragging handlers of the DesktopLabel on the layout to resize it to the maximum width (once again, less the expected margins). Use the following values in the associated Inspector Panel:</p>



<ul class="wp-block-list">
<li><strong>Locking:</strong> Left, Top and Right locked. Bottom, unlocked.</li>



<li><strong>Multiline:</strong> on.</li>



<li><strong>Text:</strong> This example project needs to use the EddiesElectronics.sqlite database file. Click on the button in order to select it!</li>
</ul>



<p>The layout at this point should look like this:</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="331" src="https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.17.36-1024x331.png" alt="" class="wp-image-11147" srcset="https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.17.36-1024x331.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.17.36-300x97.png 300w, https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.17.36-768x248.png 768w, https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.17.36.png 1274w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p>Now, drag a DesktopButton from the Library and drop it below the previous Label so it is horizontally centered, using the following values in the associated Inspector Panel:</p>



<ul class="wp-block-list">
<li><strong>Caption:</strong> Select EddiesElectronics database file</li>
</ul>



<p>The finished layout should look like this:</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="747" src="https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.19.13-1024x747.png" alt="" class="wp-image-11148" srcset="https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.19.13-1024x747.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.19.13-300x219.png 300w, https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.19.13-768x561.png 768w, https://blog.xojo.com/wp-content/uploads/2023/01/Screenshot-2023-01-10-at-15.19.13.png 1422w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p>Double click the button to add the &#8220;Pressed&#8221; Event Handler. Then, add the following code in the associated Code Editor:</p>



<pre class="wp-block-preformatted"><code>Try

  // Assigning SQLite object to property
  db = New SQLiteDatabase

  // Setting the database file to the SQLite object
  db.DatabaseFile = FolderItem.ShowOpenFileDialog(".sqlite")

  // Just a simple check to see if this is the expected
  // file based on the name = "EddiesElectronics.sqlite"

  If db.DatabaseFile = Nil Or db.DatabaseFile.Name &lt;&gt; "EddiesElectronics.sqlite" Then Return

  //…and "connecting" to it!
  db.Connect

  // Let's select all the rows from the Customers table
  Var rs As RowSet = db.SelectSQL("SELECT FirstName,LastName,Address FROM Customers")

  // Creating a new PDFDocument Instance
  Var d As New PDFDocument

  // Creating the PDFTable renderer helper object (we pass the PDFDocument object to it in the Constructor)
  Var PDFRender As New PDFRenderer(d)

  // These will be the headers drawn in the Table
  Var headers() As String = Array("Name", "Surname", "Address")

  // And let's instruct the PDFTable renderer helper to draw the table
  // based in the SQLite database rowset we got in the previous step
  PDFRender.DrawTable(rs, headers)

  // …and save the resulting PDF File to the Desktop
  Var f As FolderItem = SpecialFolder.Desktop.Child("TableFromRowSet.pdf")

  If f &lt;&gt; Nil Then
    d.Save(f)
    f.Open
  End If

Catch e As DatabaseException
  System.DebugLog(e.Message)
Catch e As NilObjectException
  System.DebugLog(e.Message)
End Try</code></pre>



<p>As you can see, all this does is create a new SQLiteDatabase object and assign it to the &#8220;db&#8221; property. Then, we set the &#8220;DataBaseFile&#8221; property of that object to the file selected by the user. The code will do a simple check to see if the selected file is the expected &#8220;EddiesElectronics&#8221; database file. If that is the case, then it will connect to the database, getting a RowSet from a simple query that retrieves the &#8220;name&#8221;, &#8220;surname&#8221; and &#8220;address&#8221; columns from the &#8220;Customers&#8221; database table.</p>



<p>After creating the PDFDocument instance, the code creates a new instance from our PDFRenderer class and calls the &#8220;DrawTable&#8221; method on that object passing along both the RowSet and the Headers we want to use for drawing the table.</p>



<p>Lastly, the PDFDocument will be saved to disk and opened in the by default PDF viewer app.</p>



<p>Run the app, select the &#8220;EddiesElectronics&#8221; SQLite database file&nbsp;and the resulting PDF file will be opened after a few seconds. It will display the table generated from a RowSet data source!</p>



<h3 class="wp-block-heading">In Summary</h3>



<p>It is quite possible to draw tables in a PDFDocument when the data to render comes from a RowSet. Nearly everything was done through the use of a helper class. As always, this can be improved in several ways! For example, we are using a fixed height for every row of the table, but in a more realistic scenario may be using variable heights for the table rows based in the height / amount of data to be drawn. That is something that is doable too!</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>New iOS Table Features in Xojo</title>
		<link>https://blog.xojo.com/2016/07/12/new-ios-table-features-in-xojo/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Tue, 12 Jul 2016 11:00:17 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Tables]]></category>
		<guid isPermaLink="false">http://blog.xojo.com/?p=1367</guid>

					<description><![CDATA[Making iOS apps just got a lot easier with the updates and enhancements to to the Table control in Xojo 2016r2. New features include: Scroll to&#8230;]]></description>
										<content:encoded><![CDATA[<p>Making iOS apps just got a lot easier with the updates and enhancements to to the Table control in Xojo 2016r2. New features include:</p>
<ul>
<li>Scroll to a specific row in the table</li>
<li>Row actions</li>
<li>Row re-ordering</li>
<li>Row editing</li>
<li>Custom cells</li>
</ul>
<h2><span id="more-1367"></span>Scroll</h2>
<p>You can now easily scroll the table (with animation) to a specific section and row using the <a href="http://developer.xojo.com/iostable$ScrollToRow">iOSTable.ScrollToRow</a> method. The following code scrolls to section 2, row 10 with animation and leaves the selected row in the middle of the table:</p>
<pre>myTable.ScrollToRow(2, 10, True, iOSTable.ScrollPositions.Middle)</pre>
<h2>Row Actions</h2>
<p>Row actions are what appear when the user swipes left across a row in the table. For example, if you swipe left across an email message in the Mail app, you&#8217;ll see &#8220;More&#8221;, &#8220;Flag&#8221; and &#8220;Trash&#8221; buttons. Xojo row action buttons are added using the iOSTableRowAction class in conjunction with the iOSTable.ActionsForRow event. When the user selects one of the buttons, then the iOSTable.RowAction event is called.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-1375" src="https://blog.xojo.com/wp-content/uploads/2016/07/2016-07-06_10-26-00.png" alt="Row Actions" width="217" height="400" /></p>
<h2>Row Editing and Re-Ordering</h2>
<p>Both row editing and row re-ordering are enabled by putting the table into &#8220;editing&#8221; mode. You do this by setting the iOSTable.EditingEnabled property to True. Row editing displays &#8220;+&#8221; and &#8220;-&#8221; widgets to the left of each row that can be used to add and remove rows in the table. Row re-ordering displays a &#8220;drag&#8221; control to the right of each row that you can drag around to move the row within the table.</p>
<p>Row editing uses the iOSTableDataSourceEditing interface and row re-ordering uses the iOSTableDataSourceReordering interface.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-1372" src="https://blog.xojo.com/wp-content/uploads/2016/07/2016-07-06_10-22-48.png" alt="Row Editing and Re-ordering" width="217" height="400" /></p>
<h2>Custom Cells</h2>
<p>Perhaps the most significant change to iOSTable is that you can now add your own custom cells. This means that a table cell can contain any collection of controls, designed however you want. To use this powerful feature, you add an iOSCustomTableCell class to your project and drag the controls that you want to it. Then when you add rows (using a data source or manually), you can provide the custom table cell. This allows you to have tables that consist of multiple columns, buttons, switches, edit fields or whatever else your design requires.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-1373" src="https://blog.xojo.com/wp-content/uploads/2016/07/2016-07-06_10-22-22.png" alt="Custom Cells" width="218" height="400" /></p>
<p>To learn more about these powerful iOS Table features, be sure to read the <a href="http://developer.xojo.com/userguide/ios-working-with-tables">Working with Tables</a> topic in the Xojo Dev Center and check out the examples included with the Xojo download: iOS/Controls/Table.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Being Efficient with iOS Tables</title>
		<link>https://blog.xojo.com/2016/05/23/being-efficient-with-ios-tables/</link>
		
		<dc:creator><![CDATA[Geoff Perlman]]></dc:creator>
		<pubDate>Mon, 23 May 2016 00:00:00 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Tables]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2016/05/23/being-efficient-with-ios-tables/</guid>

					<description><![CDATA[iOSTable's DataSource property dynamically loads data into the table saving memory and making your Xojo app more responsive.]]></description>
										<content:encoded><![CDATA[<p>Anyone who has built an app in Xojo has used the Listbox method <em>AddRow</em> to create new rows. The iOSTable control in Xojo also has an <em>AddRow</em> method. However, unlike building a desktop app, <em>AddRow</em> is not always appropriate for iOS apps.</p>
<p><span id="more-237"></span></p>
<p><img decoding="async" style="width: 320px; margin: 0px auto 10px; display: block;" title="iOSTable.png" src="https://blog.xojo.com/wp-content/uploads/2016/05/iOSTable.pngt1466486449161ampwidth320" sizes="(max-width: 320px) 100vw, 320px" alt="iOSTable.png" width="320" />Desktop and laptop computers generally have plenty of RAM so loading a lot of data into memory is not a problem. Call <em>AddRow</em> all you want and it won&#8217;t likely matter. iOS devices however don&#8217;t have nearly as much RAM. iOS does quite a bit of gymnastics to manage memory efficiently, but it can only do so much and sometimes it needs your help.</p>
<p>When your iOS app has a table that will only display a small number of rows, less than 50 for example, then <em>AddRow</em> is fine. You are likely duplicating your entire data set (one set being the original and the other being the rows in the iOSTable) but an extra 50 rows isn&#8217;t going to be a problem.</p>
<p>Once you get into hundreds of rows, it starts to really make a difference. For example, in an iOS app I built one particular table has over 1000 rows. However, at any given moment, there are only 11 rows displayed because that&#8217;s as much as my iPhone screen will show. I can swipe up and down of course, but only 11 rows are displayed at a time.</p>
<p>In cases like this, you need something that only duplicates the rows that the user can actually see at any given moment. The more rows of data, the more important this becomes. That&#8217;s where the iOSTable&#8217;s DataSource property comes in. With this property you can dynamically load data from your data set into the table allowing iOS to be more efficient with memory by unloading rows that are no longer visible. With large data sets, this not only saves memory but makes your app more responsive as well.</p>
<p>So what&#8217;s involved with using iOSTable&#8217;s DataSource property? Basically, you&#8217;ll add a class to your project that will, on demand, take data from your original source and provide it to the table. As the user scrolls the table, the table will request rows from your class which will get them from the original data source:</p>
<ol>
<li>Create a new class and name it after the type of data it will work with. For example, if it&#8217;s providing Customer data, call it <em>Customers</em>.</li>
<li>In the Inspector, click the Choose button next to Interfaces. When the dialog appears, click the checkbox for iOSTableDataSource to add this interface then click OK. This will add a few methods to the class.</li>
<li>Since this class will need to have access to the original data source, I suggest you add a constructor method to it that takes the original source of the data as a parameter. For example, if you have the data in an Array or Dictionary, pass that in as a parameter to the constructor method you add. Then store that reference in a property in the class so the rest methods you are about to implement will have access to it. If you&#8217;ve never created a constructor method, just add a new method to the class and name it <em>Constructor</em>.</li>
<li>Next take a look at the four methods that were added by choosing the iOSTableDataSource interface. They are RowCount, RowData, SectionCount and SectionTitle. When we are done, your iOSTable will call these methods when it needs their information. In each case, you will simply add the code that returns the requested data. For example, for RowCount, you&#8217;ll return how many rows there are. If the original data is in an array, just return Ubound + 1 (assuming the array starts at zero of course). For RowData, the row number requested will be passed in. You simply return an iOSTableCellData object with the data from that row inserted. The same goes for the sections. If you aren&#8217;t using sections, return 1 in SectionCount and &#8220;&#8221; in SectionTitle.</li>
<li>Last but not least, at whatever point you were calling <em>AddRow</em> to populate the table, remove that code and the loop as well. Instead, you&#8217;ll create a new instance of your Customers class, pass to it the original data, then assign that instance as the table&#8217;s data source. For example, say our data is coming from an array called CustomerList. You&#8217;ll need to add a property to the view that contains the table in order to store an instance of your Customers class. In the example code below, that property is called <em>CustomerData</em>. The code to set up the table to use the data source would look like this:</li>
<li>
<pre>CustomerData = new Customers(CustomerList)</pre>
</li>
<li>
<pre>Table1.DataSource = CustomerData</pre>
</li>
</ol>
<p>That&#8217;s it. You&#8217;re done. Now instead of your app duplicating every row of data from the original source (CustomerList in the example above), it will dynamically fetch rows as it needs them. Your app will be more responsive and will use less memory as well. This will be overkill if the table never shows more than a few dozen rows. However, if it&#8217;s showing hundreds or even thousands of rows, it&#8217;s a necessity.</p>
<p>If you&#8217;d like to see an example project, there&#8217;s one included with the <a href="https://www.xojo.com/download/" target="_blank">Xojo download</a> (Example Projects/iOS/Controls/Table/TableDataSource.)</p>
<p><!--HubSpot Call-to-Action Code --> <span id="hs-cta-wrapper-e647e3ff-c813-4005-8e7e-170f214d8cea" class="hs-cta-wrapper"> <span id="hs-cta-e647e3ff-c813-4005-8e7e-170f214d8cea" class="hs-cta-node hs-cta-e647e3ff-c813-4005-8e7e-170f214d8cea"><br />
<!-- [if lte IE 8]>


<div id="hs-cta-ie-element"></div>


<![endif]--> <a href="http://blog.xojo.com/2016/05/18/ios-view-navigation-tips/" target="_blank"><img loading="lazy" decoding="async" id="hs-cta-img-e647e3ff-c813-4005-8e7e-170f214d8cea" class="hs-cta-img aligncenter" style="border-width: 0px; margin: 0 auto; display: block; margin-top: 20px; margin-bottom: 20px;" src="https://blog.xojo.com/wp-content/uploads/2016/05/e647e3ff-c813-4005-8e7e-170f214d8cea.png" alt="Xojo iOS Tips View Navigation Blog Post" width="596" height="107" align="middle" /></a></span></span> <!-- end HubSpot Call-to-Action Code --></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
