跳到內容
關於我 數位花園

iOS

2 篇文章擁有標籤:“iOS”

漢語拼音輸入法介紹與實用技巧

對於使用繁體中文的人來說(尤其是在台灣),漢語拼音或許是一個熟悉又陌生的存在。

我跟大部分的台灣人一樣,從小學的是注音,電腦打字自然也是用注音。直到 2014 那一年(可能吃錯藥,或是頭撞到),開始了學習拼音的道路。然後就一路使用到現在。正好公司月會要介紹這個主題,所以正好順便記錄一下自己的使用體驗及心路歷程。

我想要查詢一下近年台灣各輸入法使用的比例,卻沒什麼相關的統計數據,只有找到 2011 年的一篇統計報告

usage percentage

來源:Pollster 波仕特線上市調網

我想各輸入法在市場上使用率的消長,也不影響注音輸入法的地位,市佔率大幅領先其他各家。無論是老牌的倉頡、或曾經紅極一時的嘸蝦米輸入法,大概也無法追趕上注音的優勢地位。

中文輸入法大致分為兩類:以字音為基礎的輸入法,稱為「拼音輸入法」;以字形為基礎的則稱為「字形輸入法」。

以大家比較熟悉的注音與倉頡來比較,其實可以很明確地分別兩者的差異。注音使用注音符號來拼寫文字(對,聽起來是廢話),也就是以中文字的發音來組合文字;倉頡利用各種字根去拼寫文字,以字形來組合文字。

字形輸入法,是依據字形拼寫的輸入法,簡單來說,會寫就拼得出來。

  • 倉頡輸入法
  • 嘸蝦米輸入法
  • 大易輸入法
  • 行列輸入法
  • 速成輸入法

拼音輸入法,則以字音拼寫的輸入,會唸就拼得出來。

  • (漢語)拼音輸入法
  • 注音輸入法

其實常見的注音輸入法也是拼音輸入法的其中一種,而在中國、新加坡等地最普及的「漢語拼音輸入法」,就是平常所稱呼的「拼音輸入法」。兩者的差異很明顯,一個是用注音符號來拼音,另一個則是用羅馬拼音(英文字)來拼音。

以下整理了依漢語拼音輸入法的使用體驗,整理出的優缺點:

優點缺點
詞彙首碼略拼使用者不普及
拆字模式軟體優化不足
筆畫輸入模式在地化不足
可同時訓練英打、日打
轉換成本低
有聲調拼音
英文拼字檢查
輸入數字無須切換模式
九宮格模式(行動裝置)

這是一個拼音輸入法很普遍的功能。「首碼略拼」是我自己創造的名詞。也有人稱為「字根首碼拼音」。

直接看範例會比較好理解:

assemble-mode

上面這個詞彙,完整的羅馬拼音會是:

xin shi ji fu yin zhan shi

然而,我們有更快的輸入方式,也就是只取每個字拼音開頭的第一個英文字,變成:

x s j f y z s

以 macOS 拼音為例,以下是輸出結果:

assemble-mode

只要是一個常見的詞彙,都很適合用這種首碼略拼的方式輸入,藉此加速打字速度:

assemble-mode

assemble-mode

或許上面的範例詞彙實用性不高(應該也沒有人要手打整首長恨歌吧 😅),然而一些常見人名、地名、常見名詞等,也適用此方式,例如:馬英九(m y j)、蔡英文(c y w)、民進黨(m j d)、拉斯維加斯(l s w j s)⋯⋯

以 macOS 的拼音來說,它具有學習模式,也就是會記憶平常輸入的使用者自訂詞彙,學起來之後,也同樣能夠用首碼略拼的方式打出來。

下圖是關於生難字的一則新聞報導

hard-character

來源:這些生難字你都會嗎? 網友慚愧:除了吃飯什麼也不會 | ETtoday 生活新聞 | ETtoday 新聞雲 (2016)

這些字到底該怎麼唸呢?

i-say-ikea

來源:#轉 話說我都唸 IKEA - 梗圖板 | Dcard

我們常說「有邊讀邊、沒邊讀中間」。但太複雜太難的生難字大概也很難猜出發音。

打出不會唸的生難字,則是字形輸入法的強項,因為不需要知道發音,只需要知道字形結構。同時,拼音輸入法則無用武之地,而這也是漢語拼音輸入法厲害的地方。因為它的「拆字」模式,擁有在拼音輸入架構下,同時又保有拼字輸入特性的一種模式,文字表達有點難理解,就讓我們直接來一探究竟吧!

我們拿上面報導的其中兩個詞來做範例。拆字模式顧名思義,就是將一個字拆成很多區塊來看,拆字方式沒有固定(非倉頡輸入法那種固定拆解方式)。(有錯誤請不吝指教)

hard words

以「覿氅」為例,「覿」字可拆成左右兩個區塊:「賣」與「見」;「氅」字可以拆成上下,「敞」與「毛」。

hard words

因此我們輸入「chang」(敞)與「mao」(毛)之後,按下進入拆字模式的快捷鍵:shift + 空白鍵(以 macOS 為例),會看到選單裡有我們要難字,而且還很貼心附上發音,「氅」字音同「廠」。

我們再來練習這個詞,「曩磲」:

hard words

「曩」字分成「日」、「襄」兩部份;「磲」分成「石」、「渠」兩部份,結果如下:

hard words

除了中文生難字外,某些日文漢字也可以打出來,有些日文漢字源自中文古字,所以古代就存在了,只是現在中文語圈沒在使用。

例如下面這個日文漢字:「雫」。

hard words

會日文的同學,可以馬上切換日文輸入法打出來。「雫」字在日文唸作「しずく」(shi zu ku),意思是眼淚。經過上面兩個範例,相信各位同學應該知道要怎麼拆解了,也就是拆解成「雨」與「下」:

hard words

原來這個字中文發音同「哪」。

我們再來挑戰另一個很常見的日文漢字吧!

hard words

日文漢字:「峠」,日文唸作「とうげ」(to u ge),是棧道的意思。以這個字的結構來說,左邊是「山」,至於右邊 ⋯⋯ 看起來像是「卡」,但卻不是,於是再將右半邊拆成上下兩部份(也就是「上」、「下」二字),所以拆解成「山」、「上」、「下」,來看看結果:

hard words

原來這個字的中文發音同「股」啊 🤔

我認為拆字模式是拼音輸入架構下的一個很不錯備案,彌補了拼音拼寫時,生難字打不出來的缺點,若是注音只能舉雙手投降了

另外值得注意的是,拆字模式只適合輸入單一漢字,而無法連續輸入很多漢字(畢竟不會一整句話都是生難字吧)

「拆字模式」通常可以涵蓋大部分生難字的情境,但難免還是會有拆解過後的,部分字仍不會唸的情況。此時「筆畫輸入法模式」就派上用場了。

漢語拼音輸入法除了「拆字模式」之外,還整合了手機上會搭載的「筆畫輸入法」,可以透過切換「筆畫輸入模式」開啟使用「筆畫輸入法」,並進行輸入。

以 macOS 為例,輸入 u 則進入「筆畫輸入法模式」:

stroke-mode

進入模式之後,就可以開始利用 hspnzx 開始拼寫文字。下面是簡單的範例:

stroke-mode

在我的認知裡,遇到生難字時,「拆字模式」是拼音的備案,那麼「筆畫輸入模式」就是備案中的備案了 💪

mind-explosion

或許有同學會問,這幾個符號是什麼意思?我之後打算寫一篇關於「筆畫輸入法」的文章,就先讓我賣個關子吧 😉

這裡只要知道拼音輸入法,同時自帶筆畫輸入法模式就行了

這裡指的轉換成本低,是針對注音輸入法的使用者,畢竟注音輸入法的使用者佔了大多數,如果要跳槽拼音輸入法,轉換成本(學習成本)就是一個很重要的考量因素。(像是我曾經要學習倉頡最後卻放棄了,因為學習門檻太高 😅)

注音轉換漢語拼音,或是漢語拼音轉換注音,其實只要記憶一張對照表就行了,下面兩張是來自網路的對照表:

pinyin-zhuyin-1

來源:漢語拼音輸入法:學習篇 - Hiraku Dev

pinyin-zhuyin-2

來源:Just Old, So Record.: 注音-漢語拼音 對照表

我在學習拼音輸入法的時候,就是以這個對照表為起點的,簡單的背起來之後,就是大量的實戰練習,不懂的或忘記的,再回去對照表查詢就行了。

對照表中有一些特別標註顏色的拼音,那是身為學習注音的用戶比較不直觀的拼音方式,需要多留意與背誦。

例如:「女」的注音是「ㄋㄩ ˇ」,拼音是「nv」;「呂」的注音是「ㄌㄩ ˇ」,拼音是「lv」。「熊」的注音是「ㄒㄩㄥ ˊ」,拼音是「xiong」。

此外,如果本身注音就不太好,「ㄣ」、「ㄥ」分不清楚,「應該」寫成「因該」,那我只能說 ⋯⋯ 學拼音一樣會寫錯字,因為同為拼音輸入法,會唸錯音,打出來的字就還是錯的,請務必補救一下小學國文:

help-chinese

來源:升大學搶救國文大作戰 (新書、二手書、電子書) - 讀冊生活

好啦,其實這本是高中國文,我只是想借用一下書名而已。

其實漢語拼音輸入法也有跟注音輸入法一樣的聲調系統,例如以下的字,在輸入完 mi 之後,按下 tab 標上聲調「一聲」,讓待選字更少更精準。按第二次 tab 則切換成「二聲」,以此類推。

tone

同拼字模式,聲調切換只限定輸入一個字的時候,不適用連續輸入,所以我個人平常比較少使用到。

由於漢語拼音輸入法是使用英文 26 個字母來拼寫中文字,所以只使用了英文字母的鍵位,不需要像注音輸入法佔用到第二列(數字那一列)的鍵盤,因此鍵位就跟英打是共用的,同樣地,日文的羅馬拼音輸入法也是共用這 26 個英文鍵位。

因此,只要學習一種鍵位(也就是 QWERTY 美式鍵盤排列,如下圖),不需要額外記憶第二種鍵位(例如注音或倉頡鍵位),這對盲打的練習是事半功倍的。試想一下,無論你現在是在打英文、中文或是日文,都是在加強熟悉這個美式鍵盤排列的鍵位,可說是一箭三鵰啊!

us-keyboard-layout

此外,由於沒有佔用到第二列,也讓拼音輸入法可以不用像注音輸入法,需要先切換英數模式才能輸入數字。除了可以直接輸入數字之外,在輸入中英文夾雜的字句時,也是非常地好用,而且還具備英文單字拼音檢查的功能!

例如我常忘記「維護」的英文,到底是 maintenance 還是 maintanance,這時候拼音輸入法就會告訴我答案:

en-spell-check

手機上通常也會有標準 qwerty 全尺寸鍵盤排列的拼音輸入法,以 iOS 為例:

pinyin-qwerty

同時也可以設定成手機上經典九宮格的模式:

t9-pinyin

九宮格輸入法的好處有:

  • 適合小螢幕的行動裝置
  • 適合單手操作

如果有胖手指困擾的同學們,九宮格式的輸入法可說是一大福音啊!

九宮格式的輸入法還包括中文筆畫輸入法(T9 筆畫輸入)、日文假名輸入法、韓文輸入法:

t9-stroke

t9-kana

t9-korean

相信常看日劇、韓劇的同學們,應該對這些鍵盤並不陌生才是 😎

方便與學習中文的外國人溝通,這個是附帶的優點。學習拼音輸入法之後,就等於學會了整套的漢語拼音。

現行世界上學習中文的人,幾乎都是用拼音在學中文的。

可能有同學會反駁:「那是因為外國人學簡體中文的比較多啊!」

但以我的經驗,我有一位來台北的師大華語中心學習繁體中文的日本朋友,他學的也是拼音,而不是注音。

其實想想也是很合理,學中文字前,要先學一套標音符號系統,成本是很高的,但英文字母大家都認得,所以學習成本相對低很多。

在我的認知裡,「注音」與「日文五十音」的地位並不一樣,注音不會出現在正式書信文章裡(注音文不算正式書信,兒童書籍算是特定讀者取向),但五十音會,日文可以沒有漢字,但不能沒有五十音。因此學日文五十音是必要,然而注音則不是。

若有很多世界各地學習中文的外國朋友,學習世界通用的漢語拼音可說是必須的,不然當外國朋友問:「這個字怎麼唸?」的時候,端出注音他們也看不懂啊 ⋯⋯ 這時候拿出漢語拼音,讓身旁的台灣人投以驚訝的眼光,享受當下的優越感

使用族群少的話,就很難推廣出去,然後也沒有機會擠進作業系統預設輸入法的成員裡,像是曾經紅極一時的嘸蝦米輸入法就是如此,因為不是系統內建、屬於第三方輸入法之外,光是需要付費這點,就讓它不會出現在公用電腦(例如圖書館的電腦)上了。

其實跟前一點的不普及因素也有關係,若沒有大量的使用者,開發者就不會去做很多的優化(雖然身為市占率最高的注音輸入法,在微軟上的選字智慧實在是 ⋯⋯ 嗯你懂的)

問問各位在座的各位(沒學過拼音也沒關係),「垃圾」兩字你們會怎麼拼?

  1. le se
  2. la ji

基本上以台灣用語而言,不用說一定是第一個。但以 Google 拼音輸入法為例,必須輸入「la ji」才能打出「垃圾」兩字。而 macOS 內建的繁體拼音輸入法則是輸入正確的「le se」。這就是所謂有無在地化的差異。因為以往的 Google 拼音輸入法,是「繁體模式」,所以整個系統大部分只是簡體字翻譯成繁體字而已,用語是否有針對台灣用語做調整,就是另一回事了。

而這方面,蘋果(包含 iOS 與 macOS)的在地化就做得十分好,這也包含前面所提首碼略拼的例子(台灣政治人物、政黨名字略拼)。

結論是:我都唸垃圾,而不是唸垃圾。

meme-garbage

目前來說,品質最好的漢語繁體拼音輸入法就是蘋果家了(也是我正在使用的),第三方的話,應該就屬 RIME 中州韻輸入法了,畢竟它同時可以安裝在 macOS 與 Windows 上,其他的只是列出來而已,不太推薦使用。

  • macOS 繁體拼音輸入法
  • iOS 繁體拼音輸入法
  • RIME | 中州韻輸入法引擎(Windows, Mac)
  • 微軟拼音輸入法(需添加簡體中文語言,並設定繁體模式,在地化不足)
  • 微軟注音輸入法:拼音模式(不好用,不推薦)
  • Google 拼音輸入法(以停止更新,不建議使用)

行動裝置上 100vh 的奇怪行爲

最近遇到一個手機瀏覽器上,在某個特定排版會發生高度有誤的問題

進而發現手機瀏覽器的特殊行爲

查了一下資料,發現這個問題已經存在許久,也有不少的解法

大致分為用 JS 及 CSS 去解決

CSS 的解決方式比較簡單明瞭

想要直接看結果,可以走傳送門:JS 解決方案CSS 解決方案

這個頁面是滿版的,所以 container 的部分佔滿整個 document.body

container 裡面,由上而下包含三個區域:header、body、footer

header 與 footer 分別固定在 container 上緣與下緣,body 撐滿剩下的空間,如果内容超過就會有捲軸滾動

layout 的示意圖如下:

layout

外層的 container 寬高分別是 100vw、100vh,在電腦上看起來沒什麼問題,然而在手機上就不是那麼回事:

100vh-issue-1

可以看到 container 高度是 100vh,卻仍然可以 scroll 的現象,照理來說應該要剛好撐滿才是

備註:可以在手機上點開連結,看一下真實情況


因此,若將 container 裡面的東西加進來,就會造成內外都有 scroll 的情況:

100vh-issue-2


看來 CSS 所抓到的 100vh,跟實際上的 window 高度不一樣,window 比較小,所以造成了 scroll

於是,試著把 container 元素的高度與 window 的高度印出來

var containerElement = document.getElementById("container");
var containerHeight = containerElement.clientHeight;
var heightElement = document.getElementById("container-height");
heightElement.innerText = "container clientHeight: " + containerHeight + "px";
var windowHeightEl = document.getElementById("window-height");
windowHeightEl.innerHTML = "window innerHeight: " + window.innerHeight + "px";

在電腦瀏覽器上,這兩個數字會是一樣的,在手機上卻不同:

different-height

查了一下網路上的資料,大概有兩種方式可以解

一個是用 JS,一個是用 CSS

於是我加上一個 resize 事件,監聽 window 的高度變化,並顯示在畫面上:

var containerElement = document.getElementById("container");
var containerHeight = containerElement.clientHeight;
var heightElement = document.getElementById("container-height");
heightElement.innerText = "container clientHeight: " + containerHeight + "px";
function updateWindowHeight() {
var windowHeightEl = document.getElementById("window-height");
windowHeightEl.innerHTML = "window innerHeight: " + window.innerHeight + "px";
}
updateWindowHeight();
window.addEventListener("resize", updateWindowHeight);

在 iOS Chrome 上,可以看出兩者的高度並不一致:

100vh-issue-3-ios-chrome

iOS 的 Safari,除了 container 與 window 高度不同之外,還發現了另一個現象

100vh-issue-3

在最頂的時候往下滑動,window 的高度是動態的

mind-explosion

在 Android Chrome 上,也出現 window 變化的狀況,但還是有點差異

100vh-issue-3-android-chrome

原來是彩蛋啊!!🥚

既然 100vh 與 window 的高度會不一致,而且在 iOS Safari 與 Android Chrome 上還會不斷改變, 那麼就在監聽 windowresize 事件時, 將 container 元素的高度複寫成當下的 window 高度就行了:

(function () {
function updateWindowHeight() {
var currentWindowHeight = window.innerHeight;
var windowHeightEl = document.getElementById("window-height");
windowHeightEl.innerHTML = "window innerHeight: " + currentWindowHeight + "px";
var containerElement = document.getElementById("container");
containerElement.style.height = currentWindowHeight + "px";
var containerHeight = containerElement.clientHeight;
var heightElement = document.getElementById("container-height");
heightElement.innerText = "container clientHeight: " + containerHeight + "px";
}
updateWindowHeight();
window.addEventListener("resize", updateWindowHeight);
})();

100vh-issue-4

我們可以看到,container 高度與 window 高度,始終保持同步,也就避免出現外層 scroll 的情況發生了

100vh-issue-rotate

旋轉螢幕也不是問題~

既然 container 的高度解決了,再將 container 裡面的 header、body、footer 加進來:

100vh-issue-final

一切看來都非常美好 😎

至於 resize 事件是否要加入 debounce 增進效能,那就看個人選擇了

CSS 的方法有分幾種:

.container {
display: flex;
flex-direction: column;
width: 100vw;
height: 100vh;
max-height: -webkit-fill-available; // 加上 fill-available
background: lavender;
}

但如同前綴 -webkit- 的字面意義,在 Android Chrome 上仍然有問題

但 Windows 及 macOS 上的 Chrome 卻沒事

ChromeSafari
macOSOO
WindowsONA
iOSOO
AndroidXNA

將 html 與 body 的高度設為 100%,底下的 container 就放心地用 100%

完全將在 mobile 上有爭議的 vh 單位移除了,是一個簡潔的方式

html,
body {
margin: 0;
padding: 0;
height: 100%; // 用 100%
width: 100%;
}
.container {
display: flex;
flex-direction: column;
width: 100%;
height: 100%; // 這裡也用 100%
background: lavender;
}

所有平台及裝置的瀏覽器都通過了考驗 💯

ChromeSafari
macOSOO
WindowsONA
iOSOO
AndroidONA

有一個人分享了利用新 CSS 單位的解法,也是一個不錯的選擇:

.container {
display: flex;
flex-direction: column;
width: 100%;
height: 100dvh; // 用單位 dvh
background: lavender;
}

關於 dvh 的示意圖如下:

new unit

PS. 本圖來自 Google IO

但這個似乎還很新,看來支援度沒有太好

簡單測試了一下,在 Safari 可以正常運作,但是 Chrome 卻不認識這個單位

ChromeSafari
macOSXO
WindowsXNA
iOSOO
AndroidXNA

支援度可以參考:“dvh” | Can I use… Support tables for HTML5, CSS3, etc

之後想要來研究一下關於 dvh 這一類給 mobile 專用的單位

ChromeSafari
MacOSOO
WindowsONA
iOSXX
AndroidXNA
  • O:代表 100vh 與 window 高度一致
  • X:代表 100vh 與 window 高度不同
  • NA:此平台無此瀏覽器
ChromeSafari
iOSXO
AndroidONA
  • O:代表 window 高度會隨 scroll 變化
  • X:代表 window 高度固定
  • NA:此平台無此瀏覽器
OSChromeSafari
iOS15.15103.0.5060.6315.15
Android11103.0.5060.71NA

這次因為使用了滿版 layout 搭配 100vh,而發現了這個水很深的問題

iOS Safari 在往下滑動時,window 會不斷改變的現象,確實是大開眼界

總結下來,JS 的解法需要去監聽 resize 事件, 此外大概不可避免要搭配 debounce,會需要寫很多的程式碼, 還需要在適當的時機取消訂閱 resize 事件,避免記憶體洩漏問題, 簡單來說為了效能及資源,都要額外再做其他事

CSS 的三種解法都相對簡單,沒有太多的程式碼

但唯有第二個解法(html、body 設為 100%)通過了所有瀏覽器的考驗

第三個解法(新單位 dvh)雖然現在有相容性問題,但未來的可用性令人期待