說明:示例在XCode7 beta5完成
創建一個Single View Application,填寫相應的信息. Language選擇Swift,把項目存儲到一個目錄,單擊Create完成創建.
Storyboard設計階段
-
打開Main.storyboard文件,取消勾選Use Size Classes,讓設計視圖呈現iphone的大小.
下面是取消勾選后,設計面板的樣子.
現在開始在storyboard中添加要使用到的控件.
從控件庫中拖出一個Segmented Control到設計面板的上方.
選中Segmented Control,給它增加如下約束.
接下來拖一個ScrollView到到設計面板中,讓它鋪滿剩余的空間.
同樣也要給ScrollView增加約束,這樣才可以適應不同屏幕的大小.
接著拖一個TableView到設計面板中,放置在ScrollView上,成為ScrollView的子視圖.
調整它的大小,讓它的大小和ScrollView的相同.
現在給TableView加上約束.
此時設計面板中多了一些紅色的線條,這說明缺少約束或者約束有沖突.
通過以下步驟來增加約束,這樣storyboard就有足夠的信息來確定控件的位置關系.點擊Document Outline左上方的紅色小圓圈,在點擊空心的紅色小圓圈,在彈出框中選擇Add Missing Constraints.
接著個體TableView增加一個Prototype Cell.
然后展開TableView選中Table View Cell,給它設置一個重用ID.
為了區分接下來要添加的TableView,選中當前的TableView,給它設置一個tag,這里設置為101,再給它取一個名字.
接下來添加第二個TableView,為了方便操作,在控件庫中直接把TableView拖放至Document Outline中,讓它位于ScrollView的下方,成為ScrollView的子視圖.
使用相同的方式給剛剛添加的TableView設置一個tag,這里設置為102,給它取一個名字,叫做SecondTableView.再給SecondTableView增加一個Prototype Cell,并設置它的reused identifier為second.
接下來這一步比較關鍵,要改變SecondTableView的位置,這樣才能給SecondTableView添加上正確的約束.把SecondTableView的x坐標設置為320,完成后,會把SecondTableView移動到設計面板之外,如下所示.
現在選中SecondTableView為它增加約束.
此時又出現了紅色的線條.沒關系,有這個方法讓紅色線條消失.選中FirstTableView,按住ctrl鍵,鼠標左鍵從FirstTableView拖出一條箭頭到SecondTableView,松開鼠標在彈出菜單中選擇Equal Widths.這樣做的結果是,兩個TableView具有相同的寬度.
ok,到此為止,storyboard的設計工作完成,接下來進入代碼階段.
代碼階段
打開輔助視圖,為設計面板中的控件生成相應的outlet.同時為Segmented Control綁定一個Action,它的事件類型為Value Changed,可以把Segmented Control上的items當作獨立的button來使用.

完成后,代碼文件會類似于這樣.
import UIKit
class ViewController: UIViewController {
// 1. 拖拽生成控件的outlet
@IBOutlet weak var segmented: UISegmentedControl!
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var firstTableView: UITableView!
@IBOutlet weak var secondTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
// 2. 當Segmented Control選擇的item改變時,會觸發這個Action
@IBAction func tabChanged(sender: AnyObject) {
}
}
為了不讓Segmented Control給狀態欄遮擋,在viewDidLoad()函數的下方,添加以下代碼,把狀態欄隱藏掉.
// 3. 隱藏狀態欄
override func prefersStatusBarHidden() -> Bool {
return true
}
讓當前ViewController遵循UITableViewDataSource協議,這樣就能夠給TableView提供數據.類定義的頭部將會是下面的樣子.
class ViewController: UIViewController, UITableViewDataSource
這里為什么不讓ViewController遵循UITableViewDelegate協議呢.因為這個例子只是給TableView填充數據,并不處理發生在TableView上的行為事件.
接著實現兩個代理方法,為TableView填充數據.把這兩個方法添加在prefersStatusBarHidden()函數的下方.
// 4. 為TableView填充數據
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var reusedID: String!
if tableView.tag == 101 {
reusedID = "first"
}
else {
reusedID = "second"
}
let cell = tableView.dequeueReusableCellWithIdentifier(reusedID) as UITableViewCell!
if tableView.tag == 101 {
cell.textLabel!.text = "第一個TableView"
}
else {
cell.textLabel!.text = "第二個TableView"
}
return cell
}
這里利用tag來判斷是哪一個TableView,然后使用設置好的reused identifier來獲取到cell,給cell的textLabel設置簡單的字符串.
在viewDidLoad()函數中,添加以下兩行代碼.這樣TableView的代理方法將會由當前的ViewController來執行.
firstTableView.dataSource = self
secondTableView.dataSource = self
選擇一個模擬器,運行一下看有什么效果.

第一個TableView已經呈現出來了,試著往左滑動,把第二個TableView呈現出來.滑了幾次,發現不能將SecondTableView呈現出來,為什么會這樣呢??難道SecondTableView沒有添加到ScrollView中.利用前面添加的Action來做個實驗,看是否把SecondTableView添加到了ScrollView中.
首先viewDidLoad()函數的上方,定義一個變量,用來記錄ScrollView的內容偏移量.
// 5. 定義一個變量來記錄scrollview的內容偏移量
var offset: CGFloat = 0.0 {
// 當offset的值改變后會執行didSet代碼塊
didSet {
UIView.animateWithDuration(0.3) { () -> Void in
self.scrollView.contentOffset = CGPoint(x: self.offset, y: 0.0)
}
}
}
didSet代碼塊的作用是,用一個0.3秒的過度來設置ScrollView的內容偏移量.
接著在 tabChanged(sender: AnyObject) Action中添加以下代碼.
// a. 獲取到當前item的下標
let index = (sender as! UISegmentedControl).selectedSegmentIndex
// b. 設置scrollview的內容偏移量
offset = CGFloat(index) * self.view.frame.width
item的下標從0開始.因為TableView的寬度和屏幕的寬度相同,所以呈現FirstTableView時ScrollView的內容偏移量為0,呈現SecondTableView時ScrollView的內容偏移量為一個屏幕的寬度,即(self.view.frame.width).
再運行一遍程序,當點擊Second item時,可以把SecondTableView呈現出來,說明有把SecondTableView加到ScrollView中.

到這個階段的完整代碼如下.
import UIKit
class ViewController: UIViewController, UITableViewDataSource {
// 1. 拖拽生成控件的outlet
@IBOutlet weak var segmented: UISegmentedControl!
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var firstTableView: UITableView!
@IBOutlet weak var secondTableView: UITableView!
// 5. 定義一個變量來記錄scrollview的內容偏移量
var offset: CGFloat = 0.0 {
// 當offset的值改變后會執行didSet代碼塊
didSet {
UIView.animateWithDuration(0.3) { () -> Void in
self.scrollView.contentOffset = CGPoint(x: self.offset, y: 0.0)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
firstTableView.dataSource = self
secondTableView.dataSource = self
}
// 2. 當Segmented Control選擇的item改變時,會觸發這個Action
@IBAction func tabChanged(sender: AnyObject) {
// a. 獲取到當前item的下標
let index = (sender as! UISegmentedControl).selectedSegmentIndex
// b. 設置scrollview的內容偏移量
offset = CGFloat(index) * self.view.frame.width
}
// 3. 隱藏狀態欄
override func prefersStatusBarHidden() -> Bool {
return true
}
// 4. 為TableView填充數據
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var reusedID: String!
if tableView.tag == 101 {
reusedID = "first"
}
else {
reusedID = "second"
}
let cell = tableView.dequeueReusableCellWithIdentifier(reusedID) as UITableViewCell!
if tableView.tag == 101 {
cell.textLabel!.text = "第一個TableView"
}
else {
cell.textLabel!.text = "第二個TableView"
}
return cell
}
}
為什么滑動操作不成功呢,網上看到有人說TableView繼承自ScrollView,那么滑動手勢很可能在TableView攔截了,因此為ScrollView增加兩個滑動手勢識別器.
在viewDidLoad()函數中添加以下代碼.
// 6. 為scrollView增加滑動手勢識別器
let swipeLeft = UISwipeGestureRecognizer(target: self, action: "swipe:")
swipeLeft.direction = .Left
swipeLeft.numberOfTouchesRequired = 1
let swipeRight = UISwipeGestureRecognizer(target: self, action: "swipe:")
swipeRight.direction = .Right
swipeRight.numberOfTouchesRequired = 1
scrollView.addGestureRecognizer(swipeLeft)
scrollView.addGestureRecognizer(swipeRight)
定義了兩個滑動的手勢識別器,方向分別向左和向右,numberOfTouchesRequired的意思是只要單點觸摸就可以完成滑動操作.
把swipe()函數添加到最后一個花括號的上方.
// 滑動手勢處理函數
func swipe(gesture: UISwipeGestureRecognizer) {
if gesture.direction == .Left {
// 向左滑時展示第二個tableview,同時設置選中的segmented item
offset = self.view.frame.width
segmented.selectedSegmentIndex = 1
}
else {
offset = 0.0
segmented.selectedSegmentIndex = 0
}
}
0k,代碼階段也結束了.
運行一下程序, 左右滑動可以呈現不同的TableView,選中的segmented item也會跟著改變.
圖片加載不出來的話, 這里有pdf格式的,提取碼:84e9