顯示具有 iOS 標籤的文章。 顯示所有文章
顯示具有 iOS 標籤的文章。 顯示所有文章

2017年5月19日 星期五

在 iOS 10 之後, 使用手機相機與相簿應注意事項

iOS 的 SDK 每一年至少都會有一次大改版,從 2009 到 2016 年,版號已經到了第 10 版了,很輕易的就追上了 Mac OSX. 每一次的大改版都會有不少新的功能或新的規範,在 iOS 7的改版算的上是幅度最大的,把 iOS 1.0 到 iOS 6.0 以實物視覺與立體視覺的基礎來了個髮夾彎,轉向去跟 Android, Windows 一起走平面化極簡風。(不知道賈柏斯天上有靈會怎麼反應......)
  • iOS 8的改版中,要求使用地理資訊的App需要在 info.plist 當中自己寫出提示的文字
  • iOS 10 的改版中,更進一步要求使用相機、相簿的App也要自己提示。
如果沒有在 info.plist 裡面定義提示文字,App執行到該功能的時候,會直接發生閃退,這對於使用者來說很不方便,所以App開發的人員也只好為了使用者對 App 進行改版。

如果是使用 Xcode 來開發,就需要編輯 info.plist, 加入以下圖片中兩個灰色背景的設定,一個是使用相機,另一個是使用相簿。



這跟是否使用第三方的 Framework 無關喔,即使您使用了 Cocos2D, 或是 CocoaPad, 這些宣告也是跑不掉的。

如果使用的是 Delphi,則需要從專案設定選項 (Project Option)來設定,設定視窗如下圖所示:


叫出這個視窗的方法有兩個,一個是從Delphi的視窗中點選 Project 選項,選擇裡面的 Option。另一個則是用滑鼠右鍵點選視窗右邊的專案名稱,選擇 Menu 裡面的 Option 選項,都可以顯示出這個視窗。

設定好這兩個選項之後,在 Delphi 裡面呼叫 TTakePhotoFromCameraAction 或
TTakePhotoFromLibraryAction的時候,就不會閃退了.

要留意一點,透過 Delphi 取用相機或相簿的時候,OnDidFinishTaking 所取得的照片是 TBitMap 元件,我們可以先對圖片做一些簡單的處理,例如可以把圖片的 解析度弄小一點,或者改變圖片的大小,甚至是儲存成不同格式 (PNG或JPG)。

對 iOS 模擬器處理時,由於模擬器通常沒有相機,所以不用特別設定模擬器的相機使用描述。Delphi 的設定會依照不同的裝置平台做個別的設定,而且還分成 Debug/Release,所以我自己通常會直接編輯 All Configuration。

從 iOS 5S 之後,也已經沒有 32 bit 的新裝置了,所以如果您的 App 不打算提供給 32 bit 裝置使用的話,iOS Device - 32 bit platform 也可以不用理他了。



2015年11月28日 星期六

如何建立自己的 Xcode .a 檔案

在使用 Delphi 建立自己的 app 時, 有時候會需要使用到第三方廠商的 source code, 這些 source 如果是用 Xcode objective-c 撰寫, 用來提供 iOS 的某些功能, 直接使用這些驗證過的程式碼, 會比自己照著原始碼重寫一次來的快、來的可靠。


所以,最快的方法就是用 Xcode 把這些原始碼 (通常會是 .m 跟 .h 檔案) 建立一個 .a 檔案, .a 檔案是靜態函式庫, 等同於在 C 語言裡面的 .lib 檔, 連結後就不能動態改變執行檔的內容了。

以下是建立 .a 檔案的簡單步驟說明:

1.     使用 XCode建立一個新的專案

      

2.     選擇 Framework & Library -> Cocoa Touch Static Library, 然後選Next












3.     填寫 library 的基本資料, 任填就行了.
 
4.     選擇一個 folder 來存放專案檔案, 我選擇在 iOS SDK8 目錄下, Xcode會自動建立專案目錄

5.     從finder找到要加入的.m 跟 .h 檔案, 拖拉進 Xcode 專案中


6.     選擇編譯的專案組態, 必須對Device 跟 Simulator分別都進行 Build.



7.     Device 跟 Simulator 都編譯好了之後, 找到製作好的 .a 檔案, 快速找尋方法: 從 Products 點選 lib, 然後用滑鼠右鍵點選它, 選擇 Show In Finder, 就會出現一個新的 Finder 視窗, 顯示該檔案的位置。





8.     上面的 Finder 是顯示 Debug-iphones 跟 Debug-iphonesimulator兩個目錄裡面的libmyPackage.a 檔案.
9.     在 iphoneos 目錄裡面的, 是給實際裝置使用的 .a 檔案, 在 iphonesimulator目錄裡面的, 是給模擬器使用的 .a 檔案, 我們可以透過以下的 command line 來把兩個檔案合一, 檔案會變大, 但就不用選擇不同的檔案了, 這個指令的用法是 lipo –create 第一個.a檔 第二個.a檔… -output 合併檔案

在 Mac OSX 裡面, Terminal (終端機)有個很方便的設計, 就是可以從 finder 把檔案直接拖拉到終端機畫面, 可以直接把該檔案的完整路徑拖拉進去:




然後 key in –output, 再拖拉 folder 進去:

10. 輸入檔名, 剛剛指令已經完成輸入到 –output 目錄 了, 我們把檔案名輸入一下, 本例中是 libmyPackage.a
11. 按下 Enter, lipo 就會執行, 把兩個 .a 檔案合併成同一個, 完成。

補充: 預設建立的 .a 檔案是 debug 模式的, 裡面會有 debug information, 如果要建立 Release 的版本, 則需要修改一下 Build Configuration:


點選 Edit Scheme, 會出現設定畫面:
下拉 Build Configuration, 選擇 Release 即可.
重複6-12步驟, 這次要選擇 Release-iphoneos 跟 Release-iphonesimulator當中的 .a檔案, 建立出來的 .a 檔, 就會是 Release 版本的了.

注意事項: 如果第三方的 source code 裡面有使用到 Delphi IDE 預設匯入的 iOS framework 以外的 framework, 也要記得把他們透過 Delphi IDE 的 Option->Tool->SDK Manager 匯入, 才能正確運作喔.

2014年9月3日 星期三

Virtual Keyboard 的顯示與隱藏

緣起

在 iOS app 裡面, 很多時機仍舊需要使用者輸入文字, 因此 iDevice (iPhone, iPad, iPod Touch) 上面的虛擬鍵盤就很重要。

然而,在 Delphi 上面,我們要構成一個完整的 app 畫面,需要許多的設計,包含美術設計與介面設計,美術設計會構築美觀的畫面,而介面設計跟程式設計的人則賦予這個畫面完整的功能。

如果您很習慣於使用 XCode 來製作 iOS app, 一定很常使用 UIImageView 或者 TapDetectingImageView 來取代一般的 UIButton, 因為 UIButton 常常在圖片的調整上面不精準,會讓整個畫面跟原來美術設計的構想差距很大。

所以,這個觀念在轉向到 Delphi 設計 app 的時候,也就會有一樣的擔憂,進而也使用 Delphi 的 TImage 來構築畫面,在 TImage 上面建立 onClick 的事件處理常式,把 TImage 當成 TButton 來用,畢竟這樣使用,在畫面的呈現上,要比先把一個 TButton 放到畫面上,再把圖片拉進到 TButton 裡面去要更為精準,也更為直接。

然而,在這種作法之下,居然產生了很大的副作用,所以有了這篇分享文章的誕生。

Virtual Keyboard 的顯示

圖一: 主要討論介面,模擬登入
我們接下來在整篇文章當中都會以圖一作為討論的介面,因為筆者已經把所有重點都濃縮在這個畫面當中了。

一般來說,只要是有需要使用者登入的介面,大多會有帳號、密碼的輸入框,就像上圖當中的 Account 跟 Password 欄位,當我們觸碰輸入框 (在本例是 TEdit) 的時候,虛擬鍵盤就會自動出現,如圖二所示。
圖二:虛擬鍵盤出現了
虛擬鍵盤旁邊有時候會有些 Done, Prev, Next 的功能按鈕,但介面上的設計就是要讓使用者自由自在的使用,所以我們在設計介面的時候,沒辦法規定使用者一定只能照著特定的操作步驟來用 app.

以圖二當中的登入畫面來看,如果密碼欄位旁邊有個『登入』按鈕,大多數的使用者一定會直接點選它,並期盼虛擬鍵盤會自己消失,然後完成登入的動作,切換到下一頁,幾乎不會有使用者先把虛擬鍵盤關掉,然後才去點選『登入』按鈕的,這個程序在 iPad 就更是如此了。

因此,在圖一一開始製作的時候,筆者就設定了三個按鈕在上面,分別是最上方的『By Button』,這是一個 TButton 元件,然後筆者再把 TImage 跟 TLabel 放進裡面去,如果還不知道這個步驟要如何達成,請參考筆者之前這篇文章。

第二列則有兩個按鈕,都是 TImage 當中直接放了一個 TLabel 來製作的,因為有實作出 onClick 事件,所以點選它的時候,也可以跟點選 TButton 有幾乎完全相同的效果,當然,筆者一開始也是這樣以為的,只是,遇到了虛擬鍵盤的時候,就多了很多需要注意的地方,以下,且聽我為您娓娓道來。

使用 TButton

如果我們的『登入』按鈕是一個TButton, 那麼,只需實作它的 onClick 事件處理常式,其他什麼都不用管,點擊它,虛擬鍵盤就會消失,並且執行按鈕的 onClick 事件處理常式,如圖三所示。
圖三: 點選了By Button 按鈕,虛擬鍵盤消失,顯示 ShowMessage 的內容.



使用 TImage

接著,我們用 TImage 來試試看,同樣只實作它的 onClick 事件處理常式,然後點擊這個 TImage 看看,這是圖三當中下面那列按鈕的右方按鈕。
圖四:點擊了 TImage, 虛擬鍵盤卻沒有消失
這時候,TImage 的 onClick 事件處理常式程式碼如下:
procedure TForm1.Image2Click(Sender: TObject);
begin
   ShowMessage('IMage Clicked');
end;

單純的 ShowMessage, 沒辦法隱藏虛擬鍵盤, 如果這個動作還會把整個畫面釋放掉的話,引起的問題就會更多,甚至會造成 Access Violation, 原因是從 iOS 向上層層回傳的 SingleTap 事件沒有元件可以處理,所以造成了 Access Violation.

要解決這個問題,可以無副作用解決的方法有二:
1. 用 TButton 來包覆 TImage, 這樣就不會有上面的問題。
2. 在 TImage 的 onClick 事件處理常式當中,首先就把 Focus 轉移到其他可以取得 Focus 的元件上,例如途中的 CheckBox, 改過後的程式如下:
procedure TForm1.Image3Click(Sender: TObject);
begin
   self.CheckBox1.SetFocus;
   ShowMessage('Image clicked with transfer focus');
end;

而執行後的程式畫面則如圖五:
圖五: 把 Focus 移轉後的畫面

當然,鐵齒如我,也嘗試過了很多方法,例如把 TVirtualKeyboard 從系統中硬鏟出來,然後呼叫它的 HideVirtualKeyboard 方法:

首先宣告
FService: IFMXVirtualKeyboardService;

procedure TForm1.FormCreate(Sender: TObject);
begin
    if TPlatformServices.Current.SupportsPlatformService
        (IFMXVirtualKeyboardService, IInterface(FService)) then begin
    end;
end;

procedure TForm1.Image3Click(Sender: TObject);
begin
   FService.HideVirtualKeyboard;
end;

這樣在畫面上,看起來的確是會把虛擬鍵盤弄不見,但如果沒有把 Focus 先移到別的元件上頭,切換到下一個畫面以後,就會發現不管點什麼,還是會出現 Access Violation, 所以別鐵齒。

要強制虛擬鍵盤出現,就直接在該 Edit/Memo 元件上面設定 Focus, 如前面的程式碼範例中的 self.CheckBox1.SetFocus;

要強制虛擬鍵盤出現,就把 Focus 從編輯文字的元件上移除即可。

本篇文章的範例程式,可以在這裡下載。