最近前同事問我react-native方面的問題,幾年前我粗略地學(xué)習(xí)過react-native的開發(fā),時(shí)至今日,差不多又還回去了。于是就搜索react-native方面的文章看。看到這篇文章,對評論區(qū)一個(gè)掘友的留言很好奇,這款用react-native開發(fā)的仿掘金APP的應(yīng)用,界面到底長什么樣子?文中的作者并沒有截屏展示。于是打算把文中的項(xiàng)目下載下來,運(yùn)行一下,看看效果。過程沒有我想得那么順利,一波三折,踩了一些坑,好在最后跑起來了,在Android Studio模擬器中的運(yùn)行效果如下圖所示。現(xiàn)在我們回溯一個(gè)過程,把遇到的問題的解決方法給大家分享一下。
npx react-native init react-native-junjin
生成的目錄結(jié)構(gòu)如下圖所示:
react-native-junjin/
├── __tests__/ // 測試目錄,包含測試文件
├── android/ // Android 項(xiàng)目的原生代碼
├── ios/ // iOS 項(xiàng)目的原生代碼
├── node_modules/ // Node.js 模塊目錄,包含所有依賴包
├── .eslintrc.js // ESLint 配置文件,用于 JavaScript 代碼風(fēng)格檢查
├── .gitignore // Git 忽略文件配置
├── .prettierrc.js // Prettier 配置文件,用于代碼格式化
├── .watchmanconfig // Watchman 配置文件,用于監(jiān)視文件變化
├── App.tsx // 主要的 React 組件文件,使用 TypeScript 編寫
├── app.json // 應(yīng)用的配置文件
├── babel.config.js // Babel 配置文件,用于 JavaScript 轉(zhuǎn)譯
├── index.js // JavaScript 入口文件,注冊根組件
├── metro.config.js // Metro bundler 配置文件
├── package.json // 項(xiàng)目的包管理配置文件,定義項(xiàng)目依賴及腳本
├── README.md // 項(xiàng)目說明文件
├── yarn.lock // Yarn 鎖定文件,確保依賴版本一致
├── .bundle/ // 這個(gè)文件夾通常包含打包配置和緩存,用于優(yōu)化打包過程
├── Gemfile // Ruby 的依賴管理文件,,通常與 CocoaPods 一起使用,以管理 iOS 項(xiàng)目的依賴。
├── jest.config.js // Jest 配置文件,用于測試設(shè)置
├── tsconfig.json // TypeScript 配置文件
└── .yarnrc.yml // Yarn 配置文件,定義 Yarn 的行為
別的文件都好理解,對于初學(xué)者,可能不知道Metro和Gemfile是干什么的。
Metro 是 React Native 項(xiàng)目中開發(fā)工具鏈的重要組成部分。Metro 是 React Native 的 JavaScript 打包器,將所有的 JavaScript 文件打包成一個(gè)或多個(gè)文件,以便應(yīng)用程序可以在設(shè)備或模擬器上運(yùn)行。它會(huì)解析項(xiàng)目中的依賴關(guān)系樹,將所有依賴項(xiàng)捆綁在一起,生成一個(gè)高效的包。它具有快速增量構(gòu)建、熱重載和代碼拆分等功能使得開發(fā)過程更加高效和便捷。項(xiàng)目的根目錄下有一個(gè) metro.config.js 文件,用于配置 Metro 的行為。這個(gè)文件可以包含如下配置:
配置示例:
module.exports={
transformer: {
babelTransformerPath: require.resolve('react-native-typescript-transformer'),
},
resolver: {
sourceExts: ['jsx', 'js', 'ts', 'tsx'], // 支持的文件擴(kuò)展名
},
};
Gemfile 在一個(gè) React Native 項(xiàng)目中,Gemfile 通常用于管理 iOS 開發(fā)所需的 RubyGems。RubyGems 是 Ruby 的包管理系統(tǒng),Gemfile 的主要作用是列出項(xiàng)目所依賴的所有 gems(RubyGems所管理的包或者依賴,我們稱之為 gem),并確保在不同環(huán)境下這些依賴項(xiàng)的一致性,其中一個(gè)比較重要的gem是 CocoaPods,這是一個(gè)流行的依賴管理器,用于管理和集成 iOS 項(xiàng)目的第三方庫。
一個(gè)典型的 Gemfile 文件結(jié)構(gòu)如下:
# 指定 gem 的源,這通常是 `https://rubygems.org`,這是官方的 RubyGems 倉庫
source "https://rubygems.org"
# 指定 Ruby 版本
ruby ">=2.6.10"
# 指定項(xiàng)目所需的 gem 及其版本
gem 'cocoapods', '>=1.13', '< 1.15'
gem 'activesupport', '>=6.1.7.5', '< 7.1.0'
# 可以定義不同的組,例如開發(fā)環(huán)境和測試環(huán)境
group :development, :test do
gem "rspec"
end
先介紹一個(gè)檢測工具react-native doctor ,它是 React Native 開發(fā)環(huán)境中一個(gè)非常有用的命令行工具,能幫助開發(fā)者檢測和修復(fù)本機(jī)系統(tǒng)中的各種開發(fā)工具和依賴項(xiàng),確保安裝正確且版本合適。會(huì)檢查 Node.js、yarn, Metro,JDK,Android Studio、Android SDK,Xcode 以及其它相關(guān)工具,并提供自動(dòng)修復(fù)問題的選項(xiàng)。如果 doctor 無法自動(dòng)解決問題,它將顯示消息和鏈接,說明如何手動(dòng)修復(fù)此問題。
執(zhí)行下面的命令,就會(huì)開始檢查React Native開發(fā)依賴的大多數(shù)軟件和工具是否正確安裝且版本正確
npx react-native doctor
這是檢查結(jié)果,因?yàn)楣P者已經(jīng)安裝好了各種軟件和工具,所以只有一項(xiàng)是打叉的。這一項(xiàng)打叉是因?yàn)闆]有在Android Studio中啟動(dòng)模擬器。
要在PC端運(yùn)行一下Android應(yīng)用,如果你是初學(xué)者,百分之百會(huì)遇到一些跟Android平臺(tái)相關(guān)的專業(yè)名詞如JDK、Android Studio,Android SDK,Gradle、Gradlew,不知道這些名稱概念的含義的話,就算效果運(yùn)行正確,也不代表你會(huì)了。別人對你談起這些名詞,你會(huì)感覺一頭霧水,不知所以然, 無法與別人交流。所以我們先夯實(shí)一下基礎(chǔ),了解一下這些名詞概念。
在 React Native 和 Android 開發(fā)中,JDK、Android Studio、Android SDK 和 Gradle 是幾個(gè)核心組件,它們之間相互關(guān)聯(lián),為開發(fā)和構(gòu)建 Android 應(yīng)用提供完整的支持。它們各自的功能和彼此的關(guān)系如下:
總結(jié)一下就是:
它們共同構(gòu)成了 Android 應(yīng)用開發(fā)和構(gòu)建的完整工具鏈,相互依賴且緊密集成。
ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
去Oracle官網(wǎng),下載win版的jdk安裝包 。注意版本jdk版本,doctor提示jdk的版本必須是>=17,<=20, 去官網(wǎng)一看, 只有22,21,17三個(gè)版本可以下載,那只能選擇jdk17。衍生問題-jdk下載過慢。解決方法: 將下載鏈接的協(xié)議頭由https改成http,由于下載時(shí)默認(rèn)是https,所以會(huì)慢一些,使用http之后會(huì)好很多,速度能穩(wěn)定在400k左右,十分鐘之內(nèi)就可以下完,速度還可以。另外,配置JAVA_HOME環(huán)境變量的時(shí)候,路徑后面不能帶bin。
安裝Android Studio時(shí),直接搜索Android Studio下載地址,去官網(wǎng)下載,發(fā)現(xiàn)國內(nèi)用戶直接下載不了。訪問這個(gè)地址,界面的語言默認(rèn)是英文,卻可以正常下載,默認(rèn)打開的Android Studio頁面語言是中文的話,就下載不了。莫非是美國佬不讓大陸開發(fā)者使用Android Stduio.
安裝好Android Studio之后,需要?jiǎng)?chuàng)建一個(gè)模擬器。就不會(huì)報(bào)這個(gè)錯(cuò)誤了。Android模擬器查看和啟動(dòng)方法
emulator -list-avds
emulator -avd 模擬起名稱
用 java -version命令查看發(fā)現(xiàn)返回為空,是因?yàn)榘惭b了兩個(gè)版本的JDK所致。一個(gè)是本次在Android Studio安裝中,一個(gè)是以前手動(dòng)安裝的。要?jiǎng)h除一個(gè)。刪除jdk時(shí),搜索的應(yīng)用名稱應(yīng)該是Java,此外,手動(dòng)刪除JDK的安裝目錄文件,是不行的,必須用系統(tǒng)的軟件卸載功能進(jìn)行卸載。
安裝Android Studio時(shí)不要自定義安裝路徑,安裝到默認(rèn)路徑。
出現(xiàn)這個(gè)報(bào)錯(cuò)是因?yàn)橄螺dgradle-8.6-all.zip包超時(shí)引起的,可以修改一下項(xiàng)目根目錄下的 android\gradle\wrapper\gradle-wrapper.properties文件配置,把gradle的下載路徑改成本地路徑,然后手動(dòng)下載這個(gè)壓縮包,放到配置的本地路徑中。
distributionUrl=gradle-8.6-all.zip
這個(gè)錯(cuò)誤的意思是在 Gradle 構(gòu)建過程中,嘗試將臨時(shí)工作空間移動(dòng)到最終位置時(shí)出錯(cuò),錯(cuò)誤原因通常與文件系統(tǒng)權(quán)限或路徑問題有關(guān)。默認(rèn)配置下載的gradle-8.6-all.zip會(huì)報(bào)這個(gè)錯(cuò)誤,將gradle工作包降級為gradle-8.5-bin.zip后,此問題消失。
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
操作菜單路徑 File==> Settings==> Languages & Frameworks==>Android SDK==>Edit,如下圖所示。
SDK安裝目錄為:
C:\Users\Administrator\AppData\Local\Android\Sdk
如果用pnpm安裝會(huì)出現(xiàn)這個(gè)問題,用yarn安裝則不會(huì),因?yàn)閥arn會(huì)安裝自動(dòng)隱式依賴。
Settings file 'D:\juejin-main\android\settings.gradle' line: 2 apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) Could not read script '項(xiàng)目路徑\node_modules@react-native-community\cli-platform-android\native_modules.gradle' as it does not exist.
補(bǔ)充安裝這兩個(gè)包
pnpm add -D @react-native-community/cli-platform-android @react-native/gradle-plugin
What went wrong: A problem occurred configuring project ':react-native-screens'. [CXX1101] NDK at C:\Users\Administrator\AppData\Local\Android\Sdk\ndk.1.10909125 did not have a source.properties file
Android NDK(Native Development Kit)是一個(gè)工具集,允許開發(fā)者使用 C 和 C++ 代碼來構(gòu)建 Android 應(yīng)用程序的一部分。NDK 提供了構(gòu)建和打包原生代碼的工具和庫,幫助開發(fā)者創(chuàng)建高性能的應(yīng)用程序,尤其是在涉及到計(jì)算密集型任務(wù)時(shí),如游戲、圖形處理和信號處理等。
通過 Android Studio 安裝 NDK,操作步驟:
注意下載版本要與報(bào)錯(cuò)的NDK版本保持一致。
解決方法:修改項(xiàng)目下的android\build.gradle項(xiàng)目依賴項(xiàng)的像源地址。添加阿里云鏡像地址,并配置在前面,優(yōu)先使用。
buildscript {
// 定義了 Gradle 構(gòu)建腳本所需的依賴項(xiàng)應(yīng)該從哪些存儲(chǔ)庫中獲取。常見的存儲(chǔ)庫有 `google()` 和 `mavenCentral()`。
repositories {
maven { url "https://maven.aliyun.com/repository/public" }
maven { url "https://maven.aliyun.com/nexus/content/repositories/jcenter" }
maven { url "https://maven.aliyun.com/nexus/content/repositories/google" }
google()
jcenter()
mavenCentral()
}
// ...
}
allprojects {
// 定義了所有子項(xiàng)目在解析依賴項(xiàng)時(shí)使用的存儲(chǔ)庫
repositories {
maven { url "https://maven.aliyun.com/repository/public" }
maven { url "https://maven.aliyun.com/nexus/content/repositories/jcenter" }
maven { url "https://maven.aliyun.com/nexus/content/repositories/google" }
google()
jcenter()
mavenCentral()
}
}
apply plugin: "com.facebook.react.rootproject"
沒動(dòng)手實(shí)踐之前,本以為依葫蘆畫瓢,能很快把效果做出來。實(shí)際在做的時(shí)候,發(fā)現(xiàn)自己把這件事想得簡單了。在運(yùn)行項(xiàng)目的過程中,出現(xiàn)了許多報(bào)錯(cuò),上面的這些問題我把解決方法都記錄下來了,有些也遺漏了。我踩過的坑,希望你看完這篇文章之后,就不要再重蹈覆轍了。這樣才能體現(xiàn)出你閱讀本文的價(jià)值。還有就是看完一篇技術(shù)文章,不能看一看就覺得自己會(huì)了,最好動(dòng)手做一做。有許多潛在的技術(shù)問題在看的過程中是無法暴露出來的,你以為你會(huì)了,實(shí)操的時(shí)候還是會(huì)遇到一大堆問題,平時(shí)有時(shí)間的話要提前掃雷, 這樣將來遇到相關(guān)問題時(shí)就不會(huì)手忙腳亂。
原文:https://juejin.cn/post/7382891974942048282
息的怎樣了?是否已經(jīng)迫不及待的想要繼續(xù)新的學(xué)習(xí)了呢?
好吧,接下來我們就做點(diǎn)實(shí)際的事情。
添加其它控件
到目前為止,我們的界面上只有以背景和一個(gè)按鈕,接下來還是添加一些其它界面控件吧。下面是我們所創(chuàng)建的界面的最終效果。
如你所見,我在部分標(biāo)簽處放了一些占位用的數(shù)值(比如999)。之所以這樣做,是為了方便查看標(biāo)簽實(shí)際使用時(shí)在界面上的顯示效果。玩家的得分可能會(huì)非常高(永遠(yuǎn)不要低估或高估玩家的智商~),因此最好預(yù)留足夠的空間。
好了,現(xiàn)在該你自己出手了。如果你是個(gè)設(shè)計(jì)人員,相信你會(huì)喜歡下面的操作。打開Main.storyboard,嘗試從Xcode的對象庫拖曳不同的控件放到視圖上。也不用那么精確。
實(shí)際上,要添加的三種界面元素是Label,Button和Slider。
需要注意的是,在這些標(biāo)簽里面我放了一些占位用的標(biāo)簽(比如999999),這樣是為了預(yù)留足夠多的空間,以便玩家實(shí)際體驗(yàn)的時(shí)候有足夠的發(fā)揮空間~
為了調(diào)整界面中UI控件元素的設(shè)置,我們需要用到所謂的Attributes inspector。我們可以在Xcode的右側(cè)面板中找到該視圖,也就是Inspector(檢視)視圖。
Inspector(檢視)視圖中會(huì)顯示所選中的視覺元素的各種屬性,其中Attributes inspector可以用來更改表情的背景顏色,或是按鈕上的文字大小。另外我們之前曾在Connections inspector視圖中檢查按鈕的動(dòng)作方法連接。當(dāng)你逐漸熟悉Interface Builder之后,可能會(huì)用到各種Inspector視圖。
提示:
1.需要注意的是,類似”i”形狀的界面元素其實(shí)也是一個(gè)Button,只是需要把它的類型設(shè)置為Info Light。
2.如何設(shè)置滑動(dòng)條的數(shù)值。
選中Slider,切換到Attributes Inspector,把它的最小數(shù)值設(shè)為1,最大數(shù)值設(shè)為100,當(dāng)前數(shù)值設(shè)為50.
當(dāng)你完成以上操作后,界面已經(jīng)有了12個(gè)用戶界面元素:1個(gè)滑動(dòng)條,3個(gè)按鈕,還有一堆標(biāo)簽。怎么樣,很有成就感吧。
點(diǎn)擊Run運(yùn)行應(yīng)用,然后好好玩上一會(huì)兒。除了之前的按鈕,其它控件現(xiàn)在還做不了具體的事情,不過起碼你可以拖著滑動(dòng)條來回玩。
到目前為止,我們已經(jīng)完成了界面的基本布局,而且不需要寫一行代碼。如果你是一個(gè)設(shè)計(jì)師,肯定要為此歡呼雀躍。可惜好日子到頭了,很快我們就需要使用Swift編寫代碼讓這些控件變得可交互。
喬幫主到目前為止對你的工作還比較滿意,暫時(shí)沒有召喚你去天國猛批一頓的意思。
不過按照他一向的完美標(biāo)準(zhǔn),你還有很多工作要做。
讓滑動(dòng)條變得可交互
在我們to-do list上的下一個(gè)待辦項(xiàng)目是:當(dāng)玩家觸碰按鈕時(shí)讀取滑動(dòng)條上的數(shù)值。
如果你在Interface Builder的時(shí)候沒有故意搞一些麻煩,比如裝作不經(jīng)意間把按鈕和showAlert動(dòng)作的關(guān)聯(lián)取消,那么此時(shí)就可以更改代碼讓應(yīng)用在彈出警告框中顯示滑動(dòng)條的數(shù)值。(如果你的確取消了按鈕到動(dòng)作的關(guān)聯(lián),那么首先需要再次將其關(guān)聯(lián)起來。)
還記得如何在視圖控制器中添加一個(gè)動(dòng)作,從而讓它可以識別用戶對按鈕的觸碰嗎?對于滑動(dòng)條我們可以做同樣的事情。一旦用戶拖曳滑動(dòng)條的手柄,就會(huì)觸發(fā)這個(gè)動(dòng)作。
要實(shí)現(xiàn)這一切,跟之前的操作幾乎完全相同。
首先在Xcode中點(diǎn)擊ViewController.swift,然后在最后一個(gè)花括號前面添加下面的代碼:
@IBAction func sliderMoved(_ slider: UISlider){ print("滑動(dòng)條的當(dāng)前數(shù)值是: \(slider.value)") }
再次強(qiáng)調(diào):輸入代碼的時(shí)候一定要注意全角和半角的切換,特別是代碼中既有中文又有英文的時(shí)候,要切記代碼一律用半角,要打印或輸出的中文(包含標(biāo)點(diǎn))才用全角。這個(gè)問題是新手開發(fā)者甚至是部分老手很容易犯的錯(cuò)誤。
注意到此時(shí)@IBAction func sliderMoved(slider:UISlider)這行代碼的左側(cè)有個(gè)空心圓,代表它還沒有跟storyboard中的界面元素關(guān)聯(lián)起來。
此時(shí)在Xcode中點(diǎn)擊Main.storyboard,按住Ctrl鍵不放,點(diǎn)擊鼠標(biāo)左鍵從視圖中的slider滑動(dòng)條上拖一條線到對象面板(Outline pane)的View Controller(注意不是View Controller Scene)上,然后從彈出菜單中選擇sliderMoved:。
此時(shí)如果你通過Xcode右側(cè)的面板切換到Connections inspector,就可以看到sliderMoved:動(dòng)作和滑動(dòng)條的Value Changed事件關(guān)聯(lián)在一起。
這就意味著每當(dāng)滑動(dòng)條的數(shù)值發(fā)生變化時(shí)(用戶拖動(dòng)滑動(dòng)條),就會(huì)調(diào)用sliderMoved()方法。
再次提醒大家,在Interface Builder的canvas左側(cè),是所謂的Document Outline,其中列出了當(dāng)前視圖中的所有視覺元素。
記住,如果你看不到Document Outline,可以點(diǎn)擊Xcode窗口底部的小圖標(biāo)來顯示:
現(xiàn)在點(diǎn)擊Run運(yùn)行游戲,然后拖動(dòng)滑動(dòng)條看看反應(yīng)。
一旦你開始拖動(dòng),Xcode窗口會(huì)在底部打開一個(gè)新面板,也就是傳說中的Debug Area(調(diào)試區(qū)),然后顯示下面的信息:
如果你把滑動(dòng)條拖到最左邊,會(huì)看到上面顯示的數(shù)值變成1.0,如果拖到最右邊,那么顯示的數(shù)值變成100.0.
print()函數(shù)可以幫忙我們了解應(yīng)用的邏輯是否正常。它的作用就是在Debug調(diào)試區(qū)顯示一條文本信息。這里我們用它來驗(yàn)證滑動(dòng)條是否和指定的動(dòng)作關(guān)聯(lián)在一起。在我每次要添加新的功能前,我都會(huì)用print()來確保之前一切都OK.
提醒:
你是否注意到sliderMoved:方法的名稱后面有一個(gè)冒號,而showAlert卻沒有?這是因?yàn)閟liderMoved:方法有一個(gè)參數(shù)slider,而showAlert則沒有任何參數(shù)。如果某個(gè)動(dòng)作方法有一個(gè)參數(shù),那么Interface Builder就會(huì)在名稱后面添加一個(gè)冒號。很快我們就將了解更多關(guān)于參數(shù)的問題。
科普時(shí)間
好了,馬上又要到科普時(shí)間了。這樣免得你太累,不過如果還是那句話,如果你對理論知識無愛,可以跳過去無視。
首先我們來科普幾個(gè)東西,所謂的iOS開發(fā),App Store,Mac開發(fā),Xcode,Objective-C, Swift,Cocoa, Cocoa Touch究竟是什么關(guān)系。
在我初學(xué)蘋果開發(fā)的時(shí)候,經(jīng)常把這些東西搞混,因?yàn)樵缙诘母鞣N編程書籍中既有iOS開發(fā),又有Objective-C開發(fā),還有Cocoa 開發(fā)。
程序猿最NB之處,同時(shí)也是最讓人討厭的地方就是,喜歡用各種術(shù)語,各種縮寫讓你覺得自己是個(gè)白癡。雖然我們的目標(biāo)不是成為最NB的程序猿,但了解一些相關(guān)的開發(fā)術(shù)語沒有壞處。
我并不指望你一下子就看懂它們的真正用處和區(qū)別,但起碼先留下點(diǎn)印象,然后在后面的教程中再逐步熟悉。對于教程中的其它抽象概念,哥也是類似的做法,先簡單介紹,然后讓你反復(fù)接觸,直到徹底進(jìn)入你的盜夢空間。
iOS開發(fā),在2010年推出iPad之前其實(shí)就是iPhone開發(fā)。所以很多早期的iOS教程都寫的是iPhone應(yīng)用開發(fā)。相信大家都知道2007年macworld上幫主的那次驚天地泣鬼神的神級演講,如果沒看過的強(qiáng)烈建議去重溫一下,絕對是我心目中商業(yè)產(chǎn)品發(fā)布演講中無可爭議的第一。
2008年前第三方只允許開發(fā)Safari上的網(wǎng)頁應(yīng)用。2008年開始,蘋果在當(dāng)時(shí)的SVP Scott Forstall的帶領(lǐng)下向開發(fā)者正式推出了iPhone SDK,并直接打造了一個(gè)完整的生態(tài)系統(tǒng)。
2010年幫主發(fā)布了耶穌之本iPad,同年的WWDC上將iPhone OS更名為iOS。iOS基于Mac OS X系統(tǒng)開發(fā),但針對移動(dòng)設(shè)備特有的硬件特性做了大量的改善和優(yōu)化。
如今的iOS開發(fā)泛指針對所有安裝了iOS操作系統(tǒng)的設(shè)備(當(dāng)然只限蘋果生產(chǎn))開發(fā)應(yīng)用或游戲。主要包括:iPhone全系列,iPod touch全系列,iPad全系列。當(dāng)然,相信還在用iPod touch的童鞋已經(jīng)不多了,這又是一條注定會(huì)消失在歷史中的產(chǎn)品線~
目前除了iOS,還有了針對Apple Watch的Watch OS,還有針對Apple TV的TV OS,不過它們都是基于iOS衍生而來的~
App Store,顧名思義就是蘋果賣針對iOS設(shè)備上應(yīng)用和游戲的軟件商城。
Mac開發(fā),指的是開發(fā)Mac操作系統(tǒng)下的應(yīng)用和游戲軟件。在iOS和App Store取得了巨大的成功后,蘋果把iOS的一些成功特性開始反哺給Mac操作系統(tǒng),同時(shí)在2011年推出Mac版的 App Store。
不過目前看來Mac開發(fā)并沒有吸引足夠多的開發(fā)者。也沒有多少非常成功的案例。
Cocoa和Cocoa Touch上一次的內(nèi)容中提過,同樣是編程環(huán)境,一個(gè)用于Mac開發(fā),一個(gè)用于iOS開發(fā)。
Swift和Objective-C屬于編程語言,和C,C++,Java,C#,Javascript,PHP,Python,Ruby等相似。
Xcode是Mac 平臺(tái)下的軟件開發(fā)環(huán)境,可以開發(fā)Mac和iOS應(yīng)用。
如果和其它開發(fā)平臺(tái)做一下對比,可能很多人就明白了。
Xcode類似于Visual Studio或者Eclipse
Swift和Objective-C類似于C,C++,Java,C#這些開發(fā)語言,
Cocoa 和Cocoa Touch 類似于微軟開發(fā)中的MFC或.NET.
Swift/Objective-C和Cocoa/Cocoa Touch的關(guān)系類似于C++和MFC,或者C#和.NET的關(guān)系。
繼續(xù)科普-什么是字符串
在剛才的print()那行代碼里,我們用到了這樣的一個(gè)東西,
"滑動(dòng)條的當(dāng)前數(shù)值是: \(slider.value)"
這就是個(gè)字符串,到目前為止我們已經(jīng)用了好幾個(gè)類似的東西。比如UIAlertController(提示對話框)里面的就是字符串。
通常來說,這樣一連串的文字被成為字符串,因?yàn)槲覀兛梢园盐淖挚醋鲎帜福瑪?shù)字,標(biāo)點(diǎn)符號的一個(gè)序列,就好像用串在一起的珠子。
在我們開發(fā)應(yīng)用的過程中,將會(huì)大量使用字符串,所以很快你就會(huì)熟悉它的用法。
在Swift里面,為了創(chuàng)建一個(gè)字符串,只需要把文字放到雙引號里面就好了。這個(gè)@符號很重要!如果你之前用其它的編程語言寫過代碼,或許在生成字符串的時(shí)候可以使用雙引號或單引號(比如python),但是Swift只能使用雙引號。
而且很重要的一點(diǎn)是你必須使用半角輸入,不要使用中文輸入法的全角雙引號。
總結(jié)一下:
// 在Swift 中正確使用字符串的方法:
"I am a good string"
// 下面都是錯(cuò)的:
'I should have double quotes'
''Two single quotes do not make a double quote’'
“My quotes are too fancy”
@"I am an Objective-C string"
在print()這行代碼里面,用到的字符串是"滑動(dòng)條的當(dāng)前數(shù)值是: \(slider.value)”
所有在符號 \(…)之間的字符串都是特殊的占位符。
比如下面的這個(gè)占位符:"滑動(dòng)條的當(dāng)前數(shù)值是:: X”,這里的X將被滑動(dòng)條的數(shù)值所替代。
讓變量來幫忙
在調(diào)試面板中用print()打印信息對于開發(fā)和測試非常有用,不過玩家對這種消息可是毫無興趣。因此讓我們來改進(jìn)一下這個(gè)動(dòng)作方法,讓它在一個(gè)提示對話框里面顯示滑動(dòng)條的數(shù)值。那么我們該如何把滑動(dòng)條的數(shù)值送給showAlert()呢?
當(dāng)我們在sliderMoved()中讀取滑動(dòng)條的數(shù)值時(shí),一旦這個(gè)動(dòng)作方法結(jié)束,這個(gè)數(shù)據(jù)信息也就丟失了。我們需要記住這個(gè)數(shù)據(jù),直到玩家觸碰了按鈕為止。
幸運(yùn)的是,Swift(其它語言也是)為我們提供了一個(gè)很好的工具-變量。
在Xcode中打開ViewController.swift,在class ViewController這行代碼的下面添加一行代碼:
var currentValue: Int=0
添加完成后的代碼如下:
import UIKit class ViewController: UIViewController { var currentValue: Int=0 //定義了一個(gè)變量 override func viewDidLoad() { … } override func didReceiveMemoryWarning() { … } @IBAction func showAlert(){ … } @IBAction func sliderMoved(slider: UISlider){ … } }
注意:上面唯一添加注釋的代碼是剛剛新添加的代碼,其它一切都保持不變。省略號…其實(shí)就是之前的代碼內(nèi)容,千萬不要以為哥把那些代碼都刪掉了。如果你不確定的話,最簡單的方式就是參考本章的參考項(xiàng)目源代碼,對比下就知道了~
現(xiàn)在我們就添加了一個(gè)名為currentValue的變量到視圖控制器中。變量被添加到方法的上面,通常我們需要讓這行代碼縮進(jìn)顯示,使用tab鍵或者用空格鍵。
至于使用兩個(gè)空格還是4個(gè)空格取決于你的個(gè)人習(xí)慣,我們可以通過Xcode的偏好設(shè)置來設(shè)置這一點(diǎn)。在Xcode的頂部菜單中點(diǎn)擊Xcode -Preferences..-Text Editing,然后跳轉(zhuǎn)到Indentation選項(xiàng)卡即可。
還記得幫主當(dāng)年的話嗎?由內(nèi)到外都要美。哪怕是代碼的縮進(jìn)顯示這樣小的細(xì)節(jié),以后也會(huì)給你節(jié)省很多時(shí)間,讓你讀代碼沒那么累。更重要的是,真正的美,由內(nèi)到外。
很多偷懶的程序猿在這方面都過于隨意,我毫不奇怪他們的代碼里面經(jīng)常會(huì)出現(xiàn)各種bug。這個(gè)無關(guān)技術(shù),和心態(tài)有關(guān)。用心做,才能成為食神;用心演,才能成為喜劇之王~
很多事情談不上需要多高深的技巧,談不上拼爹和干爹,談不上苦逼和潛規(guī)則,唯用心與否而已。
在之前的教程中曾提過視圖控制器,或是任何一個(gè)對象都有自己的數(shù)據(jù)和功能。
showAlert()和sliderMoved()動(dòng)作就是功能的典型例子,而currentValue變量則是數(shù)據(jù)的一部分。
通過使用變量,可以讓我們的應(yīng)用擁有記憶。你可以把變量看做是存儲(chǔ)某個(gè)數(shù)據(jù)的臨時(shí)儲(chǔ)物箱。正如儲(chǔ)物箱有各種類型和尺寸的一樣,數(shù)據(jù)也五花八門。
你不能把東西扔到儲(chǔ)物箱里面然后撒手不管,因?yàn)榻?jīng)常會(huì)放入一些新的東西。當(dāng)你的應(yīng)用需要記住一些變化時(shí),就需要把舊的數(shù)據(jù)拿出來,然后把新的數(shù)據(jù)放進(jìn)去。
這就是變量(variable)的本質(zhì)-變(vary)。比如說,每次玩家拖動(dòng)滑動(dòng)條的時(shí)候,我們都會(huì)使用滑動(dòng)條的當(dāng)前位置來更新currentValue。
儲(chǔ)物箱的大小和變量可以保存的數(shù)值種類由datatype(數(shù)據(jù)類型)決定。這里我們指定currentValue這個(gè)變量的數(shù)據(jù)類型為Int(也就是integer),意味著儲(chǔ)物箱里面可以放入整數(shù)(又稱為integer),范圍在正負(fù)20億之間。Int是最經(jīng)常用到的數(shù)據(jù)類型,不過很快我們會(huì)接觸到其它的類型。
變量就象小孩的玩具積木一樣:
我們需要把正確的形狀放到正確的儲(chǔ)物箱里面。儲(chǔ)物箱就是變量,而它的數(shù)據(jù)類型(datatype)決定了里面能放什么形狀的東西。形狀就是你可以放入變量的可能數(shù)值。
我們可以隨后更改每個(gè)箱子里面的內(nèi)容,可以拿出藍(lán)色的方塊積木,放進(jìn)紅色的方塊積木,但前提是它們都是方塊形狀的。你不能把方塊積木放到一個(gè)圓孔里面去:數(shù)值的數(shù)據(jù)類型和變量的數(shù)據(jù)類型必須是匹配的。
剛才也說了,變量是一個(gè)臨時(shí)的儲(chǔ)物箱。既然是臨時(shí),那么能保存多久呢?每個(gè)變量都有自己的生命周期(或者叫scope,術(shù)語狗滾粗),它的生命長短取決于你在程序的哪個(gè)位置定義變量。在這里,currentValue的聲明和它的擁有者一樣長,它的擁有者是ViewController。它們的命運(yùn)交織在一起。在這里,只要我們不退出應(yīng)用,這個(gè)視圖控制器,還有currentValue就會(huì)活著。當(dāng)然,很快我們就會(huì)了解到壽命很短的變量。
在程序這樣一個(gè)虛擬世界中,每個(gè)變量,每個(gè)視圖控制器都是一個(gè)虛擬的生命。世界毀了,所有的生命都會(huì)消亡。世界沒有毀,有的生命也會(huì)消亡。這方面似乎可以和人類與宇宙的關(guān)系類比。
八卦時(shí)間:
剛才在談到變量的時(shí)候,舉了個(gè)例子,說是’不能把方塊積木放到一個(gè)圓孔里面去’,英文原文是,you can’t put a square in a round hole
這讓我想到了蘋果著名的品牌廣告Think Different的臺(tái)詞,人跟變量終究還是不同的。
變量不能做到隨心所欲不逾矩,而人需要與眾不同。
Think Different
Here's to the crazy ones.獻(xiàn)給狂放不羈的一群人
The misfits. 他們是:不和主流的怪才
The rebels. 叛逆?zhèn)鹘y(tǒng)的勇士
The troublemakers. 制造麻煩的一小撮
The round pegs in the square holes. 方鑿圓枘、特立獨(dú)行
The ones who see things differently. 他們觀察問題與眾不同
They are not fond of rules. 他們不喜歡條條框框
And they have no respect for the status quo. 更不把正統(tǒng)放在眼里
You can quote them, 你可以引用他們,
disagree with them, 也可以否決他們,
glorify or vilify them. 贊揚(yáng)或是詆毀他們
About the only thing you can't do, 但只有一件事你不能做
is ignore them. 那就是漠視他們
Because they change things. 因?yàn)樗麄兏淖兞耸挛?/p>
They push the human race forward. 他們推動(dòng)了人類的進(jìn)程
And while some see them as the crazy ones, 雖然有些人把他們當(dāng)作瘋子
We see genius. 但我們看見的卻是天才
Because the people who are crazy enough to think 因?yàn)橹挥心切┳銐虔偪裾J(rèn)為
they can change the world, 可以改變世界的人
Are the ones who do. 才能真正做到這一點(diǎn)
本人聯(lián)系方式:
微信:iseedo
郵件:eseedo@gmail.com
QQ討論群: 375143733
示例項(xiàng)目:eseedo/iOSCourse
如有疑問,請先發(fā)送郵件到我的郵箱:eseedo@gmail.com
我會(huì)在收到郵件后盡早答復(fù)。
也可以加微信,但可能不是很合適的答疑途徑。
另外,為了節(jié)省大家的寶貴時(shí)間,提高溝通效率,請?jiān)谔釂柕臅r(shí)候盡量附上項(xiàng)目源代碼以及以下信息:
1.開發(fā)環(huán)境(系統(tǒng)版本,Xcode和iOS版本)
2.問題描述及重現(xiàn)(想實(shí)現(xiàn)什么效果,結(jié)果是怎樣的,具體涉及到什么操作)
3.為解決問題所做的努力(做了哪些嘗試,分別是怎樣的結(jié)果)
迎繼續(xù)我們的iPhone開發(fā)學(xué)習(xí),接下來的內(nèi)容應(yīng)該是產(chǎn)品和設(shè)計(jì)人員的最愛-美化界面。
為了讓玩家得到更好的沉浸體驗(yàn),我們必須讓產(chǎn)品的外在和內(nèi)在一樣美,甚至更美。
在這部分的內(nèi)容中,我們將完成三個(gè)小的任務(wù):
1.繼續(xù)優(yōu)化橫屏顯示
2.使用定制化的UI替代系統(tǒng)默認(rèn)的界面
3.添加一個(gè)關(guān)于界面,來介紹這款應(yīng)用~
在本篇內(nèi)容中,我們首先完成第一個(gè)小任務(wù)- 優(yōu)化橫屏顯示。
還記得我們的to-do list(待辦事務(wù)清單)嗎?里面有一條是“讓應(yīng)用在橫屏模式下運(yùn)行“。我們已經(jīng)完成了這一任務(wù),不過還可以進(jìn)一步的優(yōu)化。
在橫屏狀態(tài)下運(yùn)行的應(yīng)用不會(huì)顯示IPhone的狀態(tài)欄,除非我們強(qiáng)制顯示。這一點(diǎn)會(huì)給我們的應(yīng)用帶來更多的展示空間,這當(dāng)然是好事。
不過即便系統(tǒng)會(huì)自動(dòng)隱藏狀態(tài)欄,但我們?nèi)匀豢梢愿倪M(jìn)這款游戲處理狀態(tài)欄的方式。
在Xcode中點(diǎn)擊TARGETS下面的BullsEye,并在General設(shè)置的Deployment Info中找到Status Bar Style,然后勾選Hide status bar。
當(dāng)應(yīng)用運(yùn)行時(shí)隱藏狀態(tài)欄是比較恰當(dāng)?shù)淖龇ā2僮飨到y(tǒng)需要花上一會(huì)兒將應(yīng)用加載到內(nèi)存中并將其啟動(dòng),在這段時(shí)間里狀態(tài)欄會(huì)保持可見,除非我們通過這個(gè)選項(xiàng)將其隱藏。
雖然這只是一個(gè)很小的可能不為人所注意的細(xì)節(jié),不過真正偉大的應(yīng)用和平庸之作的區(qū)別就在于這些細(xì)節(jié)。
好了,搞定了。
點(diǎn)擊Run跑一下,會(huì)看到游戲界面的狀態(tài)欄已經(jīng)消失了。
接下來是科普時(shí)間,如果你是新手,很可能會(huì)看不懂。你可以選擇現(xiàn)在來攻堅(jiān),也可以選擇等以后熟悉iOS開發(fā)了再深入去了解。
科普:關(guān)于Info.plist文件
在任何一個(gè)iOS應(yīng)用或游戲中,如同AppDelegate類一樣,都有一個(gè)以項(xiàng)目名稱開頭的Info.plist文件,比如這里的Info.plist文件。
Info.plist是每個(gè)iOS應(yīng)用都會(huì)有的配置文件,比如設(shè)備的朝向、狀態(tài)欄是否在啟動(dòng)時(shí)可見等等,這些信息其實(shí)都保存在Info.plist文件中。
在之前的Xcode版本中,我們經(jīng)常需要手動(dòng)來編輯Info.plist文件。不過從Xcode之后基本上不需要這么做了,我們可以直接從剛才的Project Setting界面上完成。
不過了解下Info.plist的作用倒也沒有什么壞處。
在Project navigator中找到Info.plist,點(diǎn)擊并查看其中的內(nèi)容:
它的內(nèi)容通常由三列組成,最左邊是Information Property List(屬性列表),中間是Type(屬性值的類型),而最右邊則是Value(屬性值)。
Info.plist文件其實(shí)是一個(gè)XML文檔。XML其實(shí)就是可擴(kuò)展性標(biāo)記語言(extensible markup language),它并非iOS中所特有的,在幾乎任何一種編程語言的使用過程中,我們都會(huì)碰到XML文檔。XML是所謂標(biāo)準(zhǔn)通用標(biāo)記語言(SGML)的子集,其作用是以規(guī)范的形式(成對出現(xiàn)的標(biāo)記)來保存數(shù)據(jù)。XML與傳統(tǒng)的Access,Oracle,SQL Server, MySQL數(shù)據(jù)庫不同。傳統(tǒng)的數(shù)據(jù)庫功能強(qiáng)大,提供了強(qiáng)大的數(shù)據(jù)存儲(chǔ)和分析能力,而XML僅僅用來存儲(chǔ)數(shù)據(jù),需要自行編寫代碼來進(jìn)行數(shù)據(jù)的分析和處理。但XML的好處是它超級簡單易用,可以在任何語言編寫的任何應(yīng)用程序中讀寫數(shù)據(jù),已經(jīng)成了網(wǎng)絡(luò)數(shù)據(jù)交互的唯一公共語言。
你可能不知道XML文檔,但或許多半聽說過HTML文檔吧。XML文檔只不過是HTML文檔的規(guī)范式表達(dá)。它們的區(qū)別在于,XML的核心是數(shù)據(jù)內(nèi)容本身,而HTML的核心是如何顯示數(shù)據(jù)。
plist文件的本質(zhì)就是XML文檔,只不過其中的內(nèi)容都和iOS應(yīng)用的相關(guān)設(shè)置有關(guān)。
在Xcode中右鍵單擊Info.plist,選中open as,選中source code,就可以看到下面的內(nèi)容:
很顯然,plist文檔其實(shí)就是滿足蘋果DTD標(biāo)準(zhǔn)的XML文檔。
那么,Info.plist文件中這些鍵值的作用是什么呢?
這里大概說明一下,更詳細(xì)的可以參考蘋果的官方文檔( https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Introduction/Introduction.html )
Localization native development region --- 本地化相關(guān),如果用戶所在地沒有相應(yīng)的語言資源,則用這個(gè)key的value來作為默認(rèn).
Executable file -- 程序安裝包的名稱
Bundle identifier --- 該束的唯一標(biāo)識字符串,該字符串的格式類似com.yourcompany.yourapp,如果使用模擬器跑你的應(yīng)用,這個(gè)字段沒有用處,如果你需要把你的應(yīng)用部署到設(shè)備上,你必須生成一個(gè)證書,而在生成證書的時(shí)候,在apple的網(wǎng)站上需要增加相應(yīng)的app IDs.這里有一個(gè)字段Bundle identifier,如果這個(gè)Bundle identifier是一個(gè)完整字符串,那么文件中的這個(gè)字段必須和后者完全相同,如果app IDs中的字段含有通配符*,那么文件中的字符串必須符合后者的描述。
設(shè)置程序安裝后顯示的名稱。應(yīng)用程序名稱限制在10-12個(gè)字符,如果超出,將被顯示縮寫名稱。
InfoDictionary Version- Info.plist格式的版本信息
Bundle name-產(chǎn)品名稱
Bundle OS Type code-用來標(biāo)識束類型的四個(gè)字母長的代碼,
Bundle version string, short- 面向用戶市場的束的版本字符串
Bundle version-應(yīng)用程序版本號,每次部署應(yīng)用程序的一個(gè)新版本時(shí),將會(huì)增加這個(gè)編號,在app store上用的。
Application requires iPhone environment-用于指示程序包是否只能運(yùn)行在iPhone OS 系統(tǒng)上。Xcode自動(dòng)加入這個(gè)鍵,并將它的值設(shè)置為true。您不應(yīng)該改變這個(gè)鍵的值。
Launch screen interface file base name -啟動(dòng)界面的文件名稱
Main storyboard file base name- 一個(gè)字符串,指定應(yīng)用的主storyboard文件名稱
Required device capabilities-跟設(shè)備相關(guān)的屬性設(shè)置
Status bar is initially hidden-這個(gè)字符串的作用應(yīng)該很清楚了,就是剛才是否隱藏狀態(tài)欄
Supported interface orientations- 程序默認(rèn)支持的方向。
Supported interface orientations(iPad)- 程序默認(rèn)支持的方向(iPad)。
好了,又見福利時(shí)間。
本人聯(lián)系方式:
微信:iseedo
郵件:eseedo@gmail.com
QQ討論群: 375143733
不喜歡QQ的童鞋可以加微信,然后進(jìn)群。
*請認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。