標籤:

讓不懂編程的人愛上iPhone開發系列2 iOS12+Swift4.2版-Checklists-12

說明:

本系列教程改編自raywenderlich.com中的iOS Apprentice系列,有需要的童鞋請移步到這裡購買英文版原教程:store.raywenderlich.com

歡迎繼續我們的課程。

在上?篇的內容中我們成功的創建了第?個數據模型,雖然是?最蠢的辦法來實現的,但好?也是實現了。 但之所以說這種?法很蠢,是因為我們這?只顯?了5?數據,如果有100?甚?1000?數據要顯?呢?難不成你要分別創建1000個變數來存儲這些數據信息? 要知道程序猿通常是最會偷懶的?個群體,雖然他們經常和代碼打交道,但其實是最懶得寫代碼的。

為了讓?己可以更好的偷懶,於是?個新的事物誕?了,那就是-數組(array) 。

在這一課的內容中,我們會接觸數組的概念,這也是我們最常接觸的「數據結構」之一~

數組

那麼什麼是數組呢?

不知道哪個喜歡賣弄懸殊的傢伙把array翻譯成了數組,但千萬不要顧名思義,array(數組)可不是數字的組合,確切的說是「對象陣列」,也就是?堆對象的有序排列。 當然,勉強解釋為一組數據也不算太離譜。

我們現在已經知道了變數可以?來保存?個數值或者?個對象,?數組則可以保存多個數值或對象。

當然,在Swift/Objective-C中,array本?也是?個對象(也就是NSArray對象),我們可以在這個對象?面放入變數。還有?件更酷的事情,因為array本?也是對象,所以我們可以在array數組中保存其它數組。

所以從這個角度來看,array翻譯成數組實在是太不知趣了。

好了,吐槽這些術語翻譯也沒?,誰叫你不是第?批接觸國外計算機科學的?呢?說不定有人還會找出?大堆理由說這種翻譯很有道理很有深度呢。但新手小白肯定不會這麼認為。

這也是我為什麼?再強調學習編程最好直接看英?書籍、?檔和博客,因為老外很少裝B。哪怕是成名已久的科學家,在寫科普類文章和教材的時候仍然是時刻把小白的需求放在?上。比如霍金寫的《時間簡史》,我在上初中的時候就愛不釋手,偷偷在課堂看。當然,這個也不是絕對的。

現在國內的不少科普書籍和文章也不再像以前那樣喜歡賣弄了,比如《三體中的物理學》,還真心寫的不錯。再舉個例子,相比Ian Goodfellow的《深度學習》,周志華老師的西瓜書《機器學習》同樣精彩經典而且不再晦澀難懂。

不過就目前而言,可以說至少在平均水平上,國內大多數的科普類文章和開發教程還是不如英文原版的。所以我們需要繼續努力~

廢話不多說,我們繼續學習數組。

數組中的元素是使?數字來編號的,按照代碼世界的慣例,當然還是以0開始,而不是一般人習慣的從1開始。

比如對於某個數組中的第?個對象,可以?array[0]表示。需要注意的是,數組是」有序」排列的對象組合,因此對象在數組中的排列順序是很重要的。

實際上在Swift/Objective-C中,數組其實還是一個collection(集合)對象。除了數組之外,還有 Dictionary和 Set也屬於集合類對象,它們的區別在於對象在集合中的排列組合方式不同。以Dictionary對象為例,?面所保存的對象都是以鍵值對的形式存在。好吧,?不?心我也裝B了。 什麼是鍵值對?如果你?過現實?活中的字典就會知道,字典中的內容形式都是詞條和對詞條的解釋。也就是?個詞條對應?個解釋。鍵值對也是這個意思,?個主鍵對應?個數值。你可以把Dictionay看做?個對象詞典。只是?面的詞條和解釋都是對象。

數組中對象的組織形式和表視圖中的?有些類似,它們都是對象的有序排列,因此這?我們可以考慮把表視圖中?數據的數據模型放到?個數組中。

數組可以根據index序號來有序存儲對象,但現在?中包含兩部分數據,?本和選中狀態。如果我們可以讓每??只有?個對象就好辦了,這樣?來,表視圖中的?編號就直接等同於數組中的index編號。為了實現這?點, 我們需要把?本內容和勾選狀態整合到?個自創的新對象??面。

動手時間到了~

打開Xcode,在項目導航部分選中Checklists群組,然後右鍵單擊。從彈出菜單中選擇New File...

然後選擇Swift File。

點擊Next繼續,將新的文件保存為ChecklistItem(不需要手動添加.swift後綴)。

點擊Create,我們就創建了一個新的文件。

打開ChecklistItem.swift文件,並更改代碼如下:

//
// ChecklistItem.swift
// Checklists
//
// Created by eseedo on 3/6/19.
// Copyright ? 20
19 icode. All rights reserved.
//
import Foundation
class ChecklistItem{

var text = ""
var checked = false
}

好了,這其實就是在iOS中創建?個新對象的最簡單方法。

注意,我們這裡使用了關鍵詞class來定義對象,然後使用var來添加了兩個實例變數。

這裡的text屬性將用來保存待辦事務的描述文字,而checked屬性則用於保存cell是否被勾選的狀態。

細心的童鞋可能會看到我們這裡又用了兩個名詞,property(屬性)和instance variable(實例變數)。

在Swift的術語表中,屬性跟實例變數完全是一回事。

當然在Objective-C中就不太一樣了,雖然兩者很接近,但卻有所差異。

好了,這樣就?了。ChecklistItem對象當前的主 要作用就是將?本和勾選標誌合併到?個對象之中。

如果你對這種組合?式覺得有點理解不能,可以考慮下?己當前的投資組合(或者假裝自己有也行~)。假定你是個土豪,那麼很有可能你的資產不會全部是黃金,也不會全部是房產,更不會全部是現鈔。。。很有可能你的資產中既有黃金,還有比特幣,還有地產,還有多種外幣,還有現金,還有現在快上天的股票,還有期權,甚至還有專利和知識產權。

假定你的資產是?個數組對象MyAsset,那麼它可以有多個屬性(實例變數),或許它們根本無法用同一個單位進行衡量,但卻依然可以保存在同一個數組之中,而無需先強行轉化成同一種貨幣。

使用對象

在開始使?數組之前,先讓我們使?ChecklistItem對象來替代視圖控制器中的String和BOOL實例變數吧。

在ChecklistViewController.swift中,刪除之前的屬性值定義(就是分別使用let和var定義的),然後使用ChecklistItem對象來取而代之。

var row0item = ChecklistItem()
var row1item = ChecklistItem()
var row2item = ChecklistItem()
var row3item = ChecklistItem()
var row4item = ChecklistItem()

小技巧

如果你擔心出錯,可以先使用注釋的方式把原來的代碼注釋掉。後面新添加的代碼萬一出錯了,還可以立即恢復可用狀態~

然鵝,這一切看起來似乎非常的怪異。

之前的代碼幾乎人人都可以看懂,我們定義了一堆變數而已,要嗎是string字元串屬性的,要嗎是數值。但這裡又是什麼鬼?看起來似乎我們把方法賦給了變數?這樣做,確定系統真的不會炸?

是的,這是一種特殊的方法,因為所有的類其實都會偷偷調用一個初始化方法。這個初始化方法會創建指定對象的實例,這裡就是ChecklistItem。而通過這種方式,我們就可以創建了一個ChecklistItem的空白實例,其默認值就是我們定義類時所設置的~

除了這種方法,我們其實還可以用另外一種方式來定義對象:

var row0item: ChecklistItem

但如果這樣做的話,那麼row0item並不會有默認的初始值,只是創建了一個ChecklistItem對象的容器而已。在這種情況下,我們仍然需要隨後在代碼中手動創建ChecklistItem的實例。

所以,使用 var row0item = ChecklistItem() 這種看起來頗為怪異的代碼,我們一舉兩得。

需要再次強調的是,只是定義一個變數並不代表你就實實在在擁有了一個對應的對象。所定義的變數只是對象的容器,我們還需要初始化對象,然後將其放置到容器之中。幸運的是,在swift中只需要在類名之後加上一對括弧,就幫我們搞定了後面的一半工作~

好了,這樣就行了嗎?

顯然你並不能這麼樂觀,因為你會看到Xcode提示出現大量的錯誤?~

Don』t panic!一切盡在掌握之中!

這是因為在視圖控制器的?些方法中會用到之前所定義的實例變數。現在我們?股腦兒全部刪除了, Xcode不瘋掉才怪。

為了讓Xcode不再冷眼相對,?先我們要修復這些錯誤。

1.替換tableView(_:cellForRowAt:) 方法中的代碼如下:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "ChecklistItem", for: indexPath)
//添加下面的代碼
let label = cell.viewWithTag(1000) as! UILabel

if indexPath.row == 0 {
label.text = row0item.text
} else if indexPath.row == 1{
label.text = row1item.text
} else if indexPath.row == 2{
label.text = row2item.text
} else if indexPath.row == 3{
label.text = row3item.text
}else if indexPath.row == 4{
label.text = row4item.text
}
//結束以上的新代碼段
configureCheckmark(for: cell, at: indexPath)
return cell
}

2.替換tableView(_:didSelectRowAt:) 方法的代碼如下:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

if let cell = tableView.cellForRow(at: indexPath){

if indexPath.row == 0 {
row0item.checked = !row0item.checked

} else if indexPath.row == 1 {
row1item.checked = !row1item.checked
} else if indexPath.row == 2 {
row2item.checked = !row2item.checked
} else if indexPath.row == 3 {
row3item.checked = !row3item.checked
} else if indexPath.row == 4 {
row4item.checked = !row4item.checked
}
configureCheckmark(for: cell, at: indexPath)

}
tableView.deselectRow(at: indexPath, animated: true)
}

3. 最後更改configureCheckmark(for:at:)方法的代碼如下:

func configureCheckmark(for cell: UITableViewCell, at indexPath: IndexPath){

var isChecked = false

if indexPath.row == 0{
isChecked = row0item.checked
}else if indexPath.row == 1{
isChecked = row1item.checked
}else if indexPath.row == 2{
isChecked = row2item.checked
}else if indexPath.row == 3{
isChecked = row3item.checked
}else if indexPath.row == 4{
isChecked = row4item.checked
}

if isChecked {
cell.accessoryType = .checkmark
}else{
cell.accessoryType = .none
}
}

以上代碼看起來?大堆,其實改動很少,只不過用ChecklistItem對象的屬性變數替代了之前所定義

的實例變數。 就好?之前你直接在這?定義了?個實例變數:我的房產估值,我的股票市值,我的現?,而現在?我的資產.房產估值,我的資產.股票價值,我的資產.現金來替代了它們。道理是?樣的,只是沒那麼直觀。

需要再次提醒大家的是:

如果你想學的不紮實,就還是別讓自己太勞累了,敲什麼代碼啊,直接拷貝粘貼代碼吧。保證你看完全部課程最後啥也不剩下~

那啥賣油翁不是說過的嗎,?它,唯手熟爾。?日敲代碼千百?,不會AB也會C。

好了,編譯運行一下看看是什麼情況?

?老夫看到的竟然是一片空白?難道是昨晚夜觀天象被神雷傷目?

當然不是,試著點擊前五行。奇怪了,竟然會看到勾選標記隨著你的操作時而出現,時而消失。

這麼神奇的事情,究竟是怎麼導致的?

欲知後事如何,且聽下回分解~

溫馨提示:笨貓愛編程會員圖文課程(年度),即將上線,敬請期待!

聯繫方式:

  • 微信討論群請先添加個人微信iseedo,說明要加入iOS開發討論
  • QQ討論群:375143733
  • 微信公眾號:icodefun

答疑說明:

有相關的問題請到課程答疑專區提問:icode.fun/ask/forum.php

推薦閱讀:

TAG:iOS開發 |