歡迎您光臨本站 註冊首頁
  
iPhone 和 iPod touch 使 Mobile Safari 成為風靡美國的手機瀏覽器。雖然使用 Mobile Safari 呈現普通 Web 頁面綽綽有餘,但是許多 Web 開發人員都創建了針對 iPhone 的應用程序版本。本文是 “使用 Ruby on Rails 和 Eclipse 開發 iPhone 應用程序” 系列的第 3 部分,介紹當用戶瀏覽到列表結構末尾而應用程序實際上還需要顯示一些內容時,應當如何執行操作。

本系列的前兩部分介紹了構造一個 Ruby on Rails 應用程序的兩個重要方面,這個應用程序可以為 iPhone 和 iPod touch 中的 Mobile Safari 瀏覽器的用戶服務特殊內容。第 1 部分 討論了如何設置伺服器以檢測和為 Mobile Safari 提供替代內容。所選用的機制(並不是惟一的實現方法)涉及創建偽 MIME 類型,匹配用戶代理字元串和使用 Rails 的 respond_to 機制。

第 2 部分 探究了可能為 iPhone 或 iPod touch 創建的實際內容。使用 iUI 庫作為確保 Web 應用程序遵循 Apple 的界面外觀指南的機制。得到的應用程序很像是原生的 iPhone 應用程序。該文章介紹了如何創建向下展開的列表結構,類似於 iPhone 的原生郵件應用程序。Apple 建議使用這種結構,因為這種結構易於瀏覽並且尺寸較小,即使使用較慢的 Edge 網路連接,也可以快速下載。

本系列的最後這一篇文章將介紹當用戶瀏覽到列表結構末尾而應用程序實際上還需要顯示一些內容時,應當如何執行操作。iUI 給內容及表單布局提供一些有用功能。本文還介紹一些為應用程序提供特別改進的功能,例如,捕捉用戶電話的旋轉以及添加顯示在 iPhone 主屏幕中的圖標。

要運行示例,需要一些工具。當然,您需要 Ruby 和 Rails。與 Rails 結合使用的編輯器或者集成開發環境(IDE)十分有幫助,例如 Eclipse with Aptana Studio。iPhone 視圖屏幕的模擬器也十分有幫助(第 1 部分 討論了一些選項的優點)。本文使用的示例是 Soups OnLine,這是在我的 Professional Ruby on Rails 一書中最初創建的菜譜交易站點。不過,對於本文來說,該站點的具體細節並不重要。iUI 工具包提供了帶有層疊樣式表(Cascading Style Sheets,CSS)和 JavaScript 的 iPhone 感觀。創建了 rails_iui 插件以將 iUI 功能封裝到 Rails 助手以及其他最佳實踐的 Rails 用法中。

使用面板處理列表

在撰寫完 第 2 部分 時,我已經創建了瀏覽結構,可以向 iPhone 用戶或者 iPod-touch 用戶呈現瀏覽選項列表。一些選項指向按字母順序或者按最近訪問組織的另一個菜譜列表。在這些清單中單擊一個菜譜將可能把用戶引導到介紹該菜譜的頁面。

在設計 iPhone 顯示頁面中的各個元素時,必須牢記 iPhone 屏幕的細節。我為該應用程序所選的視窗設置將把頁面的寬度設為設備當前方位的寬度。由於我希望此 Web 應用程序看上去像是一個原生的 iPhone 應用程序,因此我還禁用了用戶進一步放大的功能。因此,確保我的設計在垂直方向不超出 320 像素的 iPhone 寬度十分重要(我將簡要介紹定向更改)。如果可以確保頁面不超出像素為 320x480 的屏幕,則十分理想。但是,如果用戶不得不朝一個方向滾動頁面,那麼也沒問題。

iPhone 界面的其他方面將混合小屏幕尺寸的效果。與普通桌面屏幕相比,iPhone 的像素排列得更加密集,意味著實際手機中顯示的字體和圖像比模擬屏幕中顯示得更小。您可能必須放大字體大小才能看得清。而且,用戶用手指點擊屏幕不會像滑鼠單擊一樣精確。Apple 建議可單擊的目標至少為 44 像素的正方形以獲得最佳可用性。

記住這一點,圖 1 顯示了我在菜譜顯示頁面中提供的內容。我保持了 iUI 中提供的樣式以使一切變得更簡單。


圖 1. 菜譜顯示頁面


此頁面的 Rails 代碼利用一些 rails_iui 助手以簡化對 iUI 功能的訪問。此文件為 app/views/recipes/show.iphone.erb。啟用此功能所需的惟一一處控制器更改是將 format.iphone 代碼行添加到相應控制器操作的 respond_to 代碼塊中,如下所示:


清單 1. 菜單顯示代碼
                      <% panel do %>        <% if @recipe.has_image? %>          <%= image_tag(@recipe.soup_image.public_filename, :align => :left,              :height => 80, :width => 80,               :style => "padding: 5px" ) %>        <% else %>          &nbsp;        <% end %>        <div>Servings: <%= @recipe.servings %></div>        <br/>        <div>Description:</div>        <div><%= @recipe.description %></div><br/>        <div>Ingredients:</div>        <% fieldset do %>          <% for ingredient in @recipe.ingredients %>            <% row_label do %>              <%= h ingredient.display_string %>            <% end %>          <% end %>        <% end %>        <div>Directions:</div>        <% fieldset do %>          <%= row @recipe.directions %>        <% end %>        <div>Tags: <%= h @recipe.tag_list.to_s %></div>      <% end %>              

在撰寫本文時,iUI CSS 結構有一些特殊的地方,大多數情況與一些限制有關,即一些特殊類的出現必須響應其他的標記。無論如何,這段代碼都使用一些 rails_iui 代碼塊助手,這些助手將用 iUI 所定義的特定 CSS 類封裝 div 標記。

第一個助手是位於代碼段頂部的處理程序 panel,這是帶有 panel 類的 div 標記的包裝器。panel 類將把元素的邊界設為設備框的大小,添加 10 個像素的填充,並且設置頁面的背景顏色和條紋。這將模擬 iPhone 設置頁面。

此屏幕的另一個獨特的特徵是圓角矩形。在 Mobile Safari 中,用名為 -webkit-border-radius 的自定義 CSS 屬性可以輕鬆地進行處理,在本例中,該屬性被設為 10px。在 iUI 面板內,fieldset 標記用於指定圓角矩形的邊界。除了邊界半徑以外,面板 > 欄位集選擇器還將設置頂部空白、白色背景、邊界及 16 個點的右對齊文本(就像您在 iPhone 設置頁面的單個元素中看到的那樣)。rails_iui 將 fieldset 代碼塊助手定義為放置 fieldset 標記對。

現在,當看到圖 1 中的文本都是左對齊時,fieldset 中的文本是右對齊的。那是因為有更多更改文本對齊的 CSS 類。您在配料清單中看到的 row 類將設置 42 像素高的塊,該塊適用於圓角矩形內的一疊行中的一行。在 row 類中,label 標記將把文本設為粗體並將它放回到該行的末尾。可以在設置頁面中看到其最初版本,其中標籤左對齊,設置切換在右側。

rails_iui 為行定義了兩個助手,出於演示目的,本例中同時使用了這兩個助手。row 版本將獲取一個實參、字元串和可選塊。該字元串用作標籤文本,塊是行內容(與所有 Rails 塊助手一樣,非塊版本使用 ERb 模板的輸出對 <%= 分隔,而塊版本只使用 %lt;%)。row_label 助手將獲取一個塊並將塊文本(而非其他行內容)放入標籤標記中。





表單

Mobile Safari 提供了很多精心設計的功能,用於克服在小型觸摸屏中輸入表單數據的潛在限制。這些功能中最顯而易見的是用於文本輸入的軟鍵盤和用於 select 列表的較大的滾動條,iPhone Web 開發人員必然會用到這些功能。但是,在調用時,這些元素需要佔用屏幕空間,因此請記住,如果超出欄位和 Mobile Safari 輸入面板,您的用戶無法看到太多頁面。

對於文本欄位,Mobile Safari 將定義用於控制軟鍵盤行為的兩個自定義屬性:autocorrect 和 autocapitalize。默認情況下,兩個屬性的值都為 on,但是可以設為 off 以刪除功能。自動更正功能將控制用戶是否會看到顯示在輸入欄位下方的常見拼寫錯誤的更正建議。自動大寫功能將使用一個大寫字母開始一條新語句。您可以使用 Rails 進行控制,方法是將屬性作為文本的 HTML 選項的一部分傳遞,或者是使用密碼標記控制::autocorrect => "off"。如果用戶極有可能鍵入非單詞或語句的文本,例如登錄欄位或密碼欄位,請將這些標記關閉。

下面是我為 Soups OnLine 創建的搜索表單。如 第 1 部分 中所指定,工具欄中的 Search 按鈕是由 rails_iui 工具欄助手方法 <%= iui_toolbar "Soups OnLine", new_search_url %> 繪製的。

我對 第 1 部分 中所示的助手方法做了一處小改動:按鈕鏈接改為 self 目標,這將導致刷新整個屏幕,而不是對列表橫向瀏覽。我做出這項更改是基於如下理論:搜索不屬於真正的列表瀏覽行為並且其行為應當有所不同。工具欄方法現在類似清單 2。


清單 2. iui_toolbar 助手方法
                      def iui_toolbar(initial_caption, search_url = nil)        back_button = button_link_to("", "#", :id => "backButton")        header = content_tag(:h1, initial_caption, :id => "header_text")        search_link = if search_url                       then button_link_to("Search", search_url, :id => "searchButton",                          :target => "_self")                       else ""                      end         content = [back_button, header, search_link].join("\n")        content_tag(:div, content, :class => "toolbar")      end              

我構建的搜索屏幕十分簡單,再次使用了一個最小功能集,並用於一個較小的屏幕。


圖 2. 搜索界面


該表單包含文本輸入欄位、選擇下拉框和切換開關,該開關是由 iUI 構建的,用於模擬原生 iPhone 切換控制項。為了讓此表單正常工作,我從控制器開始處理。SearchController 類已經在 Soups OnLine 應用程序中,用於創建桌面搜索表單。修改 new 控制器操作十分簡單。


清單 3. SearchController 操作
                      def new        @search = Search.new        @tag_cloud = TagCloud.calculate(Recipe)        @tag_counts = TagCloud.tag_counts(Recipe)        @tags = @tag_cloud.keys.sort        respond_to do |format|          format.html           format.iphone        end      end      

Search 對象是一個小模型對象,用於允許 Rails 視圖使用那些需要將表單映射到 Rails 模型對象的表單構建器方法。這個對象比較小 — 此時,該類只是存取器列表:

      class Search          attr_accessor :keyword, :tags, :ingredients        end                  

稍後,該類將是放置實際搜索邏輯的好位置,以防阻礙 Recipe 類。

TagCloud 代碼行用於創建放在下拉列表中的可用標記列表。代碼將使用 acts_as_taggable_on_steroids 插件,該插件的詳細信息與本文無關。需要注意的是 @tags 將包含字元串列表。

最後,respond_to 塊將處理 iPhone 請求。注意,儘管本文的第二部分中的列表操作曾經很細緻地指定 :layout => false,但是此控制器並非如此。差別在於調用操作的方式。列表操作是通過默認的 iUI Asynchronous JavaScript + XML (Ajax) 操作調用的,意味著它們要替代現有元素,並且因此無需刷新整個布局。如本文所示,Search 按鈕是用 _self 的目標調用的,iUI 將它解析為普通 HTML 鏈接,刷新整個屏幕 — 意味著需要繪製布局。

繪製此布局的視圖屏幕幾乎是典型的 Rails 表單,如下所示:


清單 4. 搜索表單的視圖代碼
                      <%= iui_toolbar "Soups OnLine", new_search_url %>      <div selected="true">        <% form_for @search do |f| %>          <table>            <tr>              <th>Keyword:</th>              <td><%= f.text_field :keyword %></td>            </tr>            <tr>              <th>Tag</th>              <td><%= f.select :tags, @tags,                   :include_blank => true %></td>            </tr>            <tr>              <th>Ingredients?</th>              <td>                <%= f.toggle(:ingredients) %>              </td>            </tr>          </table>          <%= f.submit "Search" %>        <% end %>      </div>              

這段代碼的前四分之三是一個鎖定標準(lock-standard)Rails 表單。視圖將首先刷新工具欄,因為該視圖負責整個頁面。然後有一個普通的 form_for 並且文本欄位和下拉標記也是標準的。toggle 調用是使用 iUI 提供的 toggle 類的 rails_iui 助手。通過該助手得到的 HTML 類似清單 5:


清單 5. toggle 控制項的 HTML
                      <input id="search_ingredients" name="search[ingredients]"           type="hidden" value="OFF" />      <div class="row">        <div class="toggle" id="search_ingredients_toggle"           onclick="$('search_ingredients').value =               ($('search_ingredients').value == 'OFF') ? 'ON' : 'OFF';"           toggled="OFF">            <span class="thumb"></span>            <span class="toggleOn">ON</span>            <span class="toggleOff">OFF</span>        </div>      </div>              

iUI 工具包將提供 toggle、thumb、toggleOn 和 toggleOff 的 CSS 類,它們將繪製 indowx.cn/news/hot/2008718/0871882C12G62K71A29HCK52G.html 控制項以及一些 JavaScript,從而在被單擊后可以切換控制項。但是,iUI 不會將 toggle 開關與表單控制項綁定在一起,因此在這裡引入 rails_iui。首先,該助手將插入帶有 toggle 初始值的隱藏欄位。該值將被送回到表單。rails_iui 助手還將為 toggle div 添加 JavaScript onclick 事件處理程序。該處理程序將基於當前值的相反值來回更改隱藏欄位的值。如果載入 rails_iui,toggle 助手可用於任意一個 form_for 塊。

為了進一步優化 Submit 按鈕,iUI 提供了 whiteButton、blueButton 和 grayButton CSS 類,這其中的任意一個類都將使按鈕變得更大並且更類似 iPhone 風格。





旋轉

Mobile Safari 瀏覽器最特殊的功能之一是用戶可以將它旋轉 90 度以使用橫向或縱向瀏覽器。雖然瀏覽器本身可以很好地刷新站點以適應不同的寬度,但是您可能需要更好地控制站點對方向變化的響應。iUI 和 rails_iui 的組合將給您提供兩種方法來指定方向變化的行為。

iUI 工具包將跟蹤方向變化,並且將 document.body.orient 屬性的值更改為 profile 或 landscape。然後,可以根據該屬性的值指定 CSS 行為,如清單 6 中的行所示,如果設備處於橫向模式,則將更改 h1 標記的邊緣和寬度。


清單 6. 基於方向的樣例 CSS 更改
                      body[orient="landscape"] > .toolbar > h1 {          margin-left: -125px;          width: 250px;      }   

要更精細地控制方向變化行為,rails_iui 插件允許您定義一個回調,當檢測到方向變化時,該回調將把一個 Ajax 請求送回到 Rails 應用程序中。Mobile Safari 將定義 onorientationchange 事件處理程序和 window.orientation 屬性以處理方向事件。Rails 可以為該事件創建一個 Ajax 監視器,並且對伺服器執行一次遠程回調。

要使用此回調,請將布局更改為類似清單 7。


清單 7. 使用方向變化回調的布局
                      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"             "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">      <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">      <head>        <meta http-equiv="content-type" content="text/html;charset=UTF-8" />        <title>Recipes: <%= controller.action_name %></title>        <meta name = "viewport"             content = "width = device-width, user-scalable=no">         <%= stylesheet_link_tag 'iphone' %>        <%= include_iui_files %>        <%= javascript_include_tag :defaults %>         <%= observe_orientation_change :controller => 'browsers',             :action => :orientation_change %>      </head>        <body <%= register_orientation_change %>>        <%= yield %>      </body>      </html>              

此布局文件與在本系列第 1 部分中創建的布局文件之間有三處不同。首先,包括了默認的 JavaScript 庫 — Ajax 回調所需的原型。另外兩處更改包括 observe_orientation_change 和 register_orientation_change rails_iui 助手方法。register 方法是這兩種方法中較為簡單的。它所做的只是將字元串輸出到設置事件處理程序的主體標記中,如下所示:


清單 8. register 方向變化助手
                      def register_orientation_change        'onorientationchange="updateOrientation();"'      end              

observe 方法將獲取可以作為實參傳遞給遠程助手的 :url 選項的內容,並且創建由 register 助手暗示的 updateOrientation() 方法。


清單 9. Observe 方向變化助手
                      def observe_orientation_change(url_options = {})        remote = remote_function :url => url_options, 	      				:with => "'position=' + String(window.orientation)"        func = "function() { #{remote}; };"        javascript_tag("function updateOrientation() { #{remote}; }")      end    

此方法將使用 Rails 標準 remote_function 助手創建一個 JavaScript 回調(使用傳遞給該助手的 URL 信息),並且在 script 標記內輸出函數。對伺服器的回調包含一個參數:position。如果設備處於正常的垂直縱向位置,則變數值為 "0",如果電話沿逆時針方向轉動,則變數值為 "90",而如果電話沿順時針方向轉動,則變數值為 "-90"(設備目前不能識別顛倒位置,但是如果將來可以支持這種旋轉,則值將是 "180")。通過回調,您可以完成 Rails RJS JavaScript 模板可以完成的所有操作,包括更改屏幕中的任意一個文檔對象模型(Document Object Model,DOM)對象。

通過這兩種機制,您可以輕鬆地對改變瀏覽器方向作出反應。





最後幾點兼容性說明

本系列應當為創建 iPhone 專用的 Web 應用程序提供了良好開端。下面是需要牢記的幾點:

  • iPhone 將自動檢測諸如電話號碼之類的內容,並且允許用戶使用電話鍵入這些內容來打電話(iPod 不執行此檢測)。您可以用 <meta name = "format-detection" content = "telephone=no"> 元標記關閉頁面中的這項功能。然後,通過將電話號碼轉換為表單 <a href="tel:555-1234">555-1234</a> 的 HTML 鏈接,您可以明確地識別電話號碼。
  • 指向 Google Maps 頁面的鏈接將退出 Mobile Safari 並打開 Maps 應用程序。同樣,指向 YouTube 頁面的鏈接將打開 YouTube 應用程序。
  • JavaScript 函數 alert、confirm 和 prompt 也可以在 iPhones 中工作,但是 showModalDialog 不可以。在 iUI 中,dialog CSS 類將模擬一些對話框行為,覆蓋在屏幕上面。
  • 現在,不能在 Mobile Safari 瀏覽器中使用 Flash、Java™ 應用程序、無線標記語言(Wireless Markup Language,WML)、可伸縮向量圖形(Scalable Vector Graphics,SVG)和可擴展樣式表語言轉換(Extensible Stylesheet Language Transformation,XSLT)。不支持文件上傳和下載,儘管這種情況可能在 iPhone 固件 2.0 版本中改變。Mouse-over 事件、工具提示和懸浮樣式也不起作用。
  • 解碼時,圖形交換格式(Graphics Interchange Format,GIF)、可移植網路圖形(Portable Network Graphics,PNG)和標籤圖像文件格式(Tagged Image File Format,TIFF)圖像必須小於或等於 2M 像素。子採樣為大於 2M 像素、小於 32M 像素的 JPEG 圖像。單個文本或媒體文件必須小於 10 MB。
  • iPhone 和 iPod touch 允許用戶在主屏幕中放置表示特定 Web 應用程序的圖標。要給應用程序提供自定義圖標,請在 /apple-touch-icon.png 中放置 PNG 文件。圖標應當是 57 個像素的方角正方形。請不要嘗試包括手機圖標擁有的光澤。iPhone 或 iPod-touch 操作系統將自動把角變圓,並且添加光澤效果。




結束語

今年是 iPhone 和 iPod touch 輝煌的一年。當 2.0 版本添加第三方原生應用程序時,對於支持 iPhone 的 Web 應用程序的需求只會增長。iUI 工具包和 rails_iui 插件將繼續幫助所有開發人員輕鬆地創建優秀的 Mobile Safari 應用程序。(責任編輯:A6)



[火星人 ] 使用 Ruby on Rails 和 Eclipse 開發 iPhone 應用程序,第 3 部分: 開發 iPhone 的高級視圖已經有527次圍觀

http://coctec.com/docs/linux/show-post-69070.html