首先了解要開發(fā)的這個(gè)游戲有哪些規(guī)則和功能,游戲是如何進(jìn)行的,然后才能知道怎么進(jìn)行開發(fā)。也就是平時(shí)產(chǎn)品部門的工作。這里我們有一份簡(jiǎn)單的產(chǎn)品描述:
出現(xiàn)我們要出現(xiàn)一個(gè)隨機(jī)整數(shù)作為目標(biāo)數(shù)值,隨機(jī)整數(shù)范圍在1-100之間,然后用戶滑動(dòng)這個(gè)Slider,這個(gè)Slider數(shù)值在1到100之間,盡可能的滑動(dòng)到能夠代表目標(biāo)數(shù)值的位置,也就是用戶憑感覺來滑動(dòng)了,比如App顯示目標(biāo)數(shù)值是80,那用戶需要憑感覺將Slider滑動(dòng)到代表80的位置,點(diǎn)擊Hit Me按鈕,彈出提示框,程序讀取用戶滑動(dòng)位置的實(shí)際數(shù)值,這個(gè)位置的實(shí)際數(shù)值越接近目標(biāo)數(shù)值,那么得分越高,提示框中顯示用戶的表現(xiàn)和得分,每點(diǎn)擊一次Hit Me,游戲就進(jìn)行了一局,局?jǐn)?shù)加1。點(diǎn)擊提示框中的確定按鈕,提示框消失,然后得分和局?jǐn)?shù)的數(shù)值就會(huì)加入剛剛完成的這局游戲的值。還有重現(xiàn)開始的按鈕,點(diǎn)擊這按鈕,所有的得分和局?jǐn)?shù)都清零。還有一個(gè)關(guān)于我們的按鈕,點(diǎn)擊會(huì)跳轉(zhuǎn)到關(guān)于我們的頁面。
剛剛完成了產(chǎn)品的工作,那么就需要設(shè)計(jì)師進(jìn)行設(shè)計(jì)切圖了,下面就是設(shè)計(jì)師給的最終效果圖:
拿到切圖文件和最終效果圖后,我們就可以進(jìn)行代碼的邏輯設(shè)計(jì)。理順一下自己的思路和步驟,一步步來,就能輕松完成開發(fā)。
下面這個(gè)清單是作者的寫的Todo清單,作者建議不管開發(fā)什么應(yīng)用,在開發(fā)之前,都要寫一個(gè)Todo清單,有了這個(gè)清單,能夠事半功倍。一開始寫的不全沒有關(guān)系,但是一定要寫一個(gè)。我把作者寫的清單簡(jiǎn)單翻譯了一下:
- 放上按鈕Hit Me,點(diǎn)擊后出現(xiàn)提示框,告訴用戶的表現(xiàn)和游戲結(jié)以及計(jì)算出來的得分。
- 放上Label得分score和局?jǐn)?shù)round,根據(jù)用戶的游戲情況顯示相對(duì)應(yīng)的得分和局?jǐn)?shù),這兩個(gè)Label的文案是可以根據(jù)情況變化的。
- 放上滑動(dòng)條Slider,滑動(dòng)數(shù)字范圍在1到100之間。
- 點(diǎn)擊Hit Me后可以讀取到Slider的數(shù)值。
- 生成一個(gè)隨機(jī)數(shù)作為目標(biāo)數(shù)字,顯示在界面上,讓用戶滑動(dòng)Slider盡可能接近這個(gè)目標(biāo)數(shù)字。
- 對(duì)比Slider數(shù)值和目標(biāo)數(shù)字之間的差距,得出得分score,同時(shí)局?jǐn)?shù)round加1,顯示在提示框里。。
- 放上一個(gè)Start Over按鈕,點(diǎn)擊清空之前的得分score和局?jǐn)?shù)round。
- 讓這個(gè)App只能橫屏顯示。
- 完善界面,使用設(shè)計(jì)切圖達(dá)到效果圖的效果,適配各個(gè)機(jī)型。
一、Storyboard中搭建界面、基礎(chǔ)設(shè)置
拿到設(shè)計(jì)圖或者產(chǎn)品部的線框圖后,我們就可以根據(jù)線框圖或設(shè)計(jì)圖布局App的界面了。
1.新建工程,設(shè)置App支持的方向僅限橫屏(工程詳細(xì)信息中General->Deployment Info->Device Orientation)。
2.打開Storyboard,點(diǎn)擊ViewControllerScene。
1)把Supported Device Orientations設(shè)置為橫向(選中controller->Attribute Inspector->Orientation);
2)模擬器也改成橫向顯示;
3)不勾選Use Size Classes;
4)選中Scene設(shè)置好對(duì)應(yīng)的.swift文件(Identity Inspector中的Class);
5)放入Button、Label、Slider等各種控件,修改控件的Text屬性,也就是顯示文字;
6)Slider的值范圍設(shè)置為1-100,當(dāng)前值是0;
操作完成后的樣子見下圖:
3.關(guān)于我們頁面。
1)從Object Library庫中拖入一個(gè)View Controller,這個(gè)是關(guān)于我們頁面;
2)把Supported Device Orientations設(shè)置為橫向(選中controller->Attribute Inspector->Orientation);
2)放入需要的控件Text View和Button,修改Text屬性改變控件顯示文案,Text View不勾選Editable選項(xiàng);
3)新建文件,選擇CocoaTouch類型->Subclass為UIViewController。
4)選中Scene設(shè)置好對(duì)應(yīng)的.swift文件(Identity Inspector中的Class);
操作完成后的樣子見下圖:
5)Control拖拽法創(chuàng)建Segue,Segue:modal,Transition:Flip Horizontal
4.創(chuàng)建Outlet和Action連接
首先分析一下,哪些控件需要?jiǎng)?chuàng)建連接,Outlet有:目標(biāo)數(shù)值,得分Score,局?jǐn)?shù)Round和滑動(dòng)條Slider;所有的Button控件都建立Action連接。
打開Assistant Editor,給需要建立連接的控件建立相對(duì)應(yīng)的Outlet和Action連接(Control拖拽法)。
1)Outlet連接
@IBOutlet weak var targetLabel: UILabel!
@IBOutlet weak var scoreLabel: UILabel!
@IBOutlet weak var roundLabel: UILabel!
@IBOutlet weak var slider: UISlider!
2)Action連接
首頁的Slider控件,Event選擇Value Changed,Type選擇UISlider:
@IBAction func sliderMoved(sender: UISlider) {
}
首頁的Hit Me控件,Event選擇Touch Up Inside,Type選擇AnyObject:
@IBAction func showAlert(sender: AnyObject) {
}
首頁的Start Over控件,Event選擇Touch Up Inside,Type選擇AnyObject:
@IBAction func startOver(sender: AnyObject) {
}
關(guān)于我們頁面的Close按鈕選擇Touch Up Inside,選擇AnyObject。
@IBAction func close(sender: AnyObject) {
}
二、寫代碼
通過上面的步驟,我們的布局完成了,我們需要理順一下邏輯關(guān)系,好寫代碼了。
1.創(chuàng)建實(shí)例變量。
根據(jù)首頁上的布局,有一個(gè)目標(biāo)數(shù)值Label會(huì)顯示在App中,有一個(gè)ScoreLabel顯示分?jǐn)?shù),有一個(gè)局?jǐn)?shù)Round顯示分?jǐn)?shù),這三個(gè)都需要實(shí)例變量,根據(jù)游戲規(guī)則需要獲取Slider中的實(shí)際數(shù)值對(duì)比目標(biāo)數(shù)值,算出得分,所以還需要一個(gè)實(shí)際數(shù)值變量,所以我們需要四個(gè)實(shí)例變量(目標(biāo)數(shù)值、當(dāng)前實(shí)際數(shù)值、分?jǐn)?shù)、局?jǐn)?shù)):
1)一個(gè)代表目標(biāo)值的變量,整型類型,初始值是0。
var targetValue : Int = 0
2)一個(gè)代表Slider當(dāng)前的實(shí)際數(shù)值的變量,整型類型,初始值是0(要和Storyboard中當(dāng)前值對(duì)應(yīng))。
var currentValue : Int = 0
3)一個(gè)能記錄分?jǐn)?shù)的變量,整型類型,初始值是0
var score = 0
4)一個(gè)能記錄局?jǐn)?shù)的變量,整型類型,初始值是0
var round = 0
2.顯示隨機(jī)整數(shù)+開啟新游戲方法。
這個(gè)游戲的開頭是現(xiàn)有目標(biāo)數(shù)值(隨機(jī)整數(shù))然后才有后面的操作,那么,我們要保證程序啟動(dòng)時(shí)以及開啟新的一局游戲時(shí),這個(gè)目標(biāo)數(shù)值都會(huì)變化。那么,開啟新的一局游戲時(shí),除了要更新目標(biāo)數(shù)值外,還需要做什么事情呢?想一想,要把Slider的值重新調(diào)回到0的位置,Round局?jǐn)?shù)也要增加1。我們把這些事情都集合到一個(gè)方法中,命名startNewRound:
func startNewRound() {
//獲取新的目標(biāo)數(shù)值
targetValue = 1 + Int(arc4random_uniform(100))
//Slider的值調(diào)整到0的位置
currentValue = 0
slider.value = Float(currentValue)
//新的局?jǐn)?shù)要加1
round += 1
}
程序員啟動(dòng)后,是不是也需要做這些事情呢?那么把這個(gè)方法放在viewDidLoad中。
override func viewDidLoad() {
super.viewDidLoad()
startNewRound()
}
3.Slider的值。
上一步我們?cè)O(shè)計(jì)了目標(biāo)數(shù)值,用戶看到了這個(gè)目標(biāo)數(shù)值,接下來就是滑動(dòng)Slider,滑到某個(gè)位置。程序需要獲取這個(gè)位置所代表的數(shù)值,然后和目標(biāo)數(shù)值對(duì)比,方能算出得分。那么,接下來就需要我們寫一個(gè)獲取Slider值的方法,之前在建立Action連接時(shí),Slider的值一有變化,就會(huì)觸發(fā)事件:
@IBAction func sliderMoved(sender: UISlider) {
currentValue = lroundf(sender.value)
}
4.點(diǎn)擊Hit Me按鈕。
好了,目標(biāo)數(shù)值有了,當(dāng)前數(shù)值也有了,可以開始做對(duì)比了吧。用戶滑動(dòng)結(jié)束后,點(diǎn)擊Hit Me,程序會(huì)進(jìn)行對(duì)比、計(jì)算、顯示結(jié)果,顯示結(jié)果用彈出框表示。用戶只會(huì)看到彈出框顯示的結(jié)果,出結(jié)果之前的對(duì)比計(jì)算需要我們?cè)诖a中進(jìn)行,但是不顯示出來。同時(shí)我們?cè)谖陌干峡梢栽O(shè)計(jì)一下,根據(jù)不同的得分段,在提示框中顯示不同的話。用戶看到結(jié)果后,彈出框有個(gè)OK按鈕,點(diǎn)擊OK按鈕,此局游戲結(jié)束,開始新的一局,同時(shí),App中的分?jǐn)?shù)和局?jǐn)?shù)以及目標(biāo)數(shù)值,都需要更新,分?jǐn)?shù)加上剛剛這局的得分,局?jǐn)?shù)也增加1,顯示新的目標(biāo)數(shù)值。那么接下來的代碼需要在點(diǎn)擊Hit Me按鈕的方法中編寫,還好我們之前已經(jīng)建立了Action連接showAlert
方法,用戶每次Touch Up Inside,都會(huì)觸發(fā)事件:
1)先寫計(jì)算過程:
@IBAction func showAlert(sender: AnyObject) {
//對(duì)比差值
let difference = abs(targetValue - currentValue)
//計(jì)算分?jǐn)?shù),在此規(guī)則下,用戶猜的再差也能得1分
let points = 100 - difference
//把這次的得分加入到總分中
score += points
}
2)再寫提示框:
點(diǎn)擊OK其實(shí)代表兩件事情,此局游戲結(jié)束,開始新的一局。那么可以用到我們之前的方法startNewRound,但是這個(gè)方法只是讓代碼更新了,顯示在Label上的內(nèi)容沒有變化,用戶沒有看到這個(gè)變化,所以我們寫一個(gè)方法updateLabels,把所有的Label更新文案的事情都放這里面,這樣當(dāng)用戶點(diǎn)擊OK的時(shí)候,可以直接調(diào)用這個(gè)方法:
func updateLabels() {
targetLabel.text = String(targetValue)
scoreLabel.text = String(score)
roundLabel.text = String(round)
}
App啟動(dòng)時(shí),也需要更新Label,不然會(huì)顯示我們?cè)诖罱ń缑鏁r(shí)胡亂輸入的文案了,那么把這個(gè)方法放在viewDidLoad中。
override func viewDidLoad() {
super.viewDidLoad()
startNewRound()
updateLabels()
}
然后我們開始寫提示框代碼,注意要判斷一下用戶的得分屬于哪個(gè)階段,對(duì)應(yīng)不同的提示語:
@IBAction func showAlert() {
let difference = abs(targetValue - currentValue)
let points = 100 - difference
score += points
//開始提示框代碼
//判斷得分的不同階段,給出不同的提示語
let title: String
if difference == 0 {
title = "Perfect!"
} else if difference < 5 {
title = "You almost had it!"
} else if difference < 10 {
title = "Pretty good!"
} else {
title = "Not even close..."
}
let message = "You scored \(points) points"
let alert = UIAlertController(title: title, message: message,preferredStyle: .Alert)
//用戶點(diǎn)擊OK時(shí),用了閉包語法,這樣只有在用戶點(diǎn)擊OK后,這兩個(gè)方法才會(huì)被調(diào)用
let action = UIAlertAction(title: "OK", style: .Default, handler: { action in
self.startNewRound()
self.updateLabels()
})
alert.addAction(action)
presentViewController(alert, animated: true, completion: nil)
}
點(diǎn)擊Hit Me按鈕寫到這里就結(jié)束了。
5.點(diǎn)擊Start Over按鈕。
點(diǎn)擊Start Over后,局?jǐn)?shù)要清零,分?jǐn)?shù)要清零,Slider的位置也要?dú)w位,各個(gè)Label上顯示的內(nèi)容也要清零,這些事情,都在上面兩個(gè)方法startNewGame()和updateLabels()中做過了,所以我們可以直接調(diào)用這兩個(gè)方法:
@IBAction func startOver() {
score = 0
round = 0
startNewGame()
updateLabels()
}
書中寫到這里時(shí),把App第一次啟動(dòng)后的效果,等同于點(diǎn)擊了Start Over,完全開啟新的一輪游戲。這是因?yàn)闀袥]有數(shù)據(jù)持久化的教程,畢竟是入門書籍。但是,如果我們已經(jīng)會(huì)了數(shù)據(jù)持久化,再來優(yōu)化這個(gè)App時(shí),App啟動(dòng)后,就不一定是開啟新的游戲了,有可能只是開啟新的一局游戲而已。所以這個(gè)viewDidLoad()里用哪些方法,還要根據(jù)產(chǎn)品需求來決定。一般要考慮幾個(gè)方面:App啟動(dòng)后,App進(jìn)入后臺(tái)后,App被強(qiáng)行關(guān)閉后,這三個(gè)地方一定要考慮一下如何對(duì)持久化的數(shù)據(jù)進(jìn)行處理,不然就會(huì)出現(xiàn)用戶游戲進(jìn)度(用戶數(shù)據(jù))改變或者沒有保存的情況。
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillEnterForeground(application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
在AppDelegate.swift文件中,還有幾種情況,也要考慮一下才好。
6.點(diǎn)擊Close按鈕。
App中目前就還剩下一個(gè)按鈕的方法沒有寫了,那就是關(guān)于我們中的Close按鈕。點(diǎn)擊Close按鈕,回到首頁。鑒于Segue是Modal,所以我們使用 dismissViewControllerAnimated(),這個(gè)方法要寫在關(guān)于我們的.swift文件中,不能寫在首頁的.swift文件里:
@IBAction func close() {
dismissViewControllerAnimated(true, completion: nil)
}
三、增加規(guī)則
1.如果用戶的猜測(cè)水平在Perfect階段,則再加100分作為獎(jiǎng)勵(lì),如果在You almost had it階段,則再加50分作為獎(jiǎng)勵(lì):
@IBAction func showAlert() {
let difference = abs(targetValue - currentValue)
var points = 100 - difference
let title: String
if difference == 0 {
title = "Perfect!"
points += 100
} else if difference < 5 {
title = "You almost had it!"
if difference == 1 {
points += 50
}
} else if difference < 10 {
title = "Pretty good!"
} else {
title = "Not even close..."
}
//因?yàn)樯厦鎝oints還會(huì)根據(jù)不同的情況變化,所以一定要在points不再有變化后再加到score中,所以把這行放到這個(gè)位置
score += points
let message = "You scored \(points) points"
let alert = UIAlertController(title: title, message: message,preferredStyle: .Alert)
let action = UIAlertAction(title: "OK", style: .Default, handler: { action in
self.startNewRound()
self.updateLabels()
})
alert.addAction(action)
presentViewController(alert, animated: true, completion: nil)
}
四、幾個(gè)疑問
1.為什么單獨(dú)寫一個(gè)startNewGame()方法?
2.startNewRound()和updateLabels()為啥要分成兩個(gè)方法,能不能寫在一方法里?
這篇文章中的步驟和一些代碼并沒有完全按照書中的來,比如書中還有一個(gè)startNewGame()方法,我直接把這方法寫在了@IBAction func startOver(sender: AnyObject)方法里了。因?yàn)槲矣X得沒有必要寫startNewGame這個(gè)方法。至于作者為什么這么寫,我暫時(shí)不理解,歡迎達(dá)人指點(diǎn)。
還有一處地方就是startNewRound()和updateLabels()這兩個(gè)方法,為什么不寫在同一個(gè)方法中?
我的理解是一個(gè)代表舊的一局游戲結(jié)束更新Label顯示出結(jié)束的信息,一個(gè)代表的開始新的一局,程序內(nèi)部已經(jīng)準(zhǔn)備好新的數(shù)據(jù)了。可是書中的代碼顯示,都是startNewRound()在前,updateLabels()在后,所以我的這個(gè)理解也就錯(cuò)了。
那么,真正的原因是什么呢?
還好這個(gè)問題我已經(jīng)寫郵件直接問作者了,感動(dòng)的是,當(dāng)時(shí)我是2015年12月31號(hào)晚上寫的郵件, 沒想到作者時(shí)隔5個(gè)小時(shí)就回復(fù)了,馬上就過元旦了,還要回復(fù)讀者郵件,好感動(dòng)。
如果你曾經(jīng)看過這本書,那么,請(qǐng)把你的理解告訴我,評(píng)論或者私信皆可,我會(huì)分享給你作者的回復(fù)原因。如果你沒有看過這本書,那么,實(shí)在是沒有必要知道原因啊,因?yàn)槟疾恢牢以趩柹秵栴}啊親們!
?
五、完善外表
書中這部分,從106頁一直寫到結(jié)束150頁,著實(shí)讓我知道了開發(fā)App大部分的工作都用到了哪里,150頁的書籍,1/3都在寫完善界面的方法。看來要達(dá)到設(shè)計(jì)稿的效果,還需要程序員做出特別多的努力,花很多的時(shí)間。
需要考慮的有:設(shè)計(jì)圖等設(shè)計(jì)效果,動(dòng)畫,自動(dòng)布局AutoLayout也就是適配多個(gè)設(shè)備
看來做出一些細(xì)節(jié)優(yōu)化神馬的,確實(shí)比較花費(fèi)時(shí)間。剩下的這部分可以略過不看了,我純粹是整理自己的思路,沒有太多干活。而且AutoLayout和AdaptiveLayout在不同的應(yīng)用上差別太大。
- 橫屏?xí)r去掉status bar:
Main.storyboard -> select the View Controller -> Attributes inspector -> Simulated Metrics -> Status Bar -> None.
Project Settings screen and under-> Deployment Info -> Status BarStyle -> Hide status bar.
設(shè)計(jì)切圖導(dǎo)入Xcode
只開發(fā)iPhone端App,只需要放入@2x和@3x即可。拖宅Image View控件,放入背景圖片,設(shè)置屬性(width568,Height320),Editor->Arrange->Send to Back(或在outline pane中拖動(dòng))。在About View Controller中進(jìn)行同樣的操作
修改Label控件效果:Color+Shadow+Shadow Offset+Font+FontStyle+FontSize+Autoshrink+Size to Fit
修改Button控件效果:
1)
Hit Me按鈕+關(guān)于我們頁面的Close按鈕:
State Config為Default時(shí)的設(shè)置:Size Inspector中的Width+Height,Attribute Inspector下的Type->Custom + Background + Font + FontSize + FontStyle + TextColor + Shadow Color
2)
Hit Me按鈕+關(guān)于我們頁面的Close按鈕:
State Config為Highlighted時(shí)的設(shè)置:Attribute Inspector下 Background + TextColor + Shadow Color + Reverses on Highlight
3)
Start Over按鈕+i按鈕(關(guān)于我們按鈕):
Type->Custom + 去掉text中文案 + Image + Background + Width + HeightSlider
在ViewController.swift文件中,把代碼輸入到viewDidLoad()方法中:
let thumbImageNormal = UIImage(named: "SliderThumb-Normal")
slider.setThumbImage(thumbImageNormal, forState: .Normal)
let thumbImageHighlighted = UIImage(named: "SliderThumb-Highlighted")
slider.setThumbImage(thumbImageHighlighted, forState: .Highlighted)
let insets = UIEdgeInsets(top: 0, left: 14, bottom: 0, right: 14)
if let trackLeftImage = UIImage(named: "SliderTrackLeft") {
let trackLeftResizable = trackLeftImage.resizableImageWithCapInsets(insets)
slider.setMinimumTrackImage(trackLeftResizable, forState: .Normal)
}
if let trackRightImage = UIImage(named: "SliderTrackRight") {
let trackRightResizable =trackRightImage.resizableImageWithCapInsets(insets)
slider.setMaximumTrackImage(trackRightResizable, forState: .Normal)
}
在輸入圖片名稱時(shí),可以不寫@2x和.png,只寫名字即可
- 關(guān)于我們頁面使用web view控件展示HTML內(nèi)容
1)
storyboard中刪掉Text view放入web view控件然后建立Outlet連接,在Project Navigator中右鍵新建文件Add Files to "BullsEye",選中BullsEye.html文件點(diǎn)擊Add完成新建。
2)
在AboutViewController.swift文件中,把代碼輸入到viewDidLoad()方法中:
override func viewDidLoad() {
super.viewDidLoad()
if let htmlFile = NSBundle.mainBundle().pathForResource("BullsEye",ofType: "html") {
if let htmlData = NSData(contentsOfFile: htmlFile) {
let baseURL = NSURL(fileURLWithPath:NSBundle.mainBundle().bundlePath)
webView.loadData(htmlData, MIMEType: "text/html",textEncodingName: "UTF-8", baseURL: baseURL)
}
}
}
使用Preview預(yù)覽不同設(shè)備下的效果
用Auto Layout適配不同的設(shè)備
1)
主頁和關(guān)于我們頁面的背景圖Image view控件:
Align ->( Horizontally in Container + Vertically in Container ) -> Update Frames Items of New Constraints -> Add...
2)
關(guān)于我們頁面的Close按鈕:
Align -> Horizontally in Container -> Add...,Pin -> Spacing to nearest neighbor -> Check Constrain to margins-> down bar 20 -> Update Frames Items of New Constraints -> Add...
3)
關(guān)于我們頁面的web view控件:
Pin -> Spacing to nearest neighbor -> Uncheck Constrain to margins -> ( left bar 20 + up bar 20 + right bar 20 + down pin 20 ) -> Update Frames Items of New Constraints -> Add...
主頁支持3.5-inch和4-inch:
選中控件(見下圖)點(diǎn)擊Editor->Embed In -> View。剛剛嵌入的View起名叫做container view。
給container view設(shè)置: Pin -> ( Width491 + Height285 ) -> Add...,Align ->( Horizontally in Container + Vertically in Container ) -> Update Frames Items of New Constraints -> Add...
最后設(shè)置container view的Background color屬性為Clear Color
5)
支持iPhone 6和 6 Plus:
刪除LaunchScreen.storyboard,到Project Settings->App Icons and Launch Images ->清空Lunch Screen File;按住Option鍵,點(diǎn)擊Product -> Clean Build Folder -> Clean;在Project Navigator中右鍵新建文件Add Files to "BullsEye",選中Default@2x.png和Default-568h@2x.png文件點(diǎn)擊Add完成新建。
我的小疑問:這個(gè)步驟有必要嗎?這樣就真可以適配iPhone 6和6 Plus嗎?
- 淡入淡出效果Crossfade
在點(diǎn)擊Start Over按鈕后,增加動(dòng)畫效果:
在ViewController.swift文件中:
import QuartzCore
修改StartOver的方法:
@IBAction func startOver() {
startNewGame()
updateLabels()
let transition = CATransition()
transition.type = kCATransitionFade
transition.duration = 1
transition.timingFunction = CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseOut)
view.layer.addAnimation(transition, forKey: nil)}
增加圖標(biāo)icon
雖然此應(yīng)用沒有適配iPad,但是并不能阻止iPad運(yùn)行此應(yīng)用,iPad上會(huì)出現(xiàn)iPhone大小的框,在框里運(yùn)行此應(yīng)用,所以之前的圖片沒有1x,但是icon最好能夠適配iPad,也就是需要1x的icon。修改應(yīng)用在手機(jī)上顯示的名字
Project Navigator -> Info.plist -> Editor -> Add Item -> Bundle display name -> 輸入你想要的名字在真機(jī)上運(yùn)行測(cè)試
好啦,終于結(jié)束啦~
下篇文章見~