ios中使用SegmentedControl来切换视图

[TOC]

From

ios中使用SegmentedControl来切换视图

效果图

run

设计图

run

结构与原理

视图结构

共有3个ViewController

  1. A 父视图
  2. B 子视图
  3. C 子视图

切换视图原理

A包含上下两个部分,

上面就是SegmentedControl, 来控制视图切换

下面的部分用来展示B, C子视图.

点击SegmentedControl时候通过addView和removeView来实现视图切换.

另外, 为了好看, 加了翻页的动画效果.

代码

注释比较多了, 应该一看就明白.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import UIKit

class SegmentViewController: UIViewController {

/// 容器view
@IBOutlet weak var containerView: UIView!

var leftViewController: LeftViewController!
var rightViewController: RightViewController!


override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.

if let sb = storyboard {
leftViewController = sb.instantiateViewControllerWithIdentifier("leftViewController") as! LeftViewController

switchViewController(from: nil, to: leftViewController)
} else {
print("storyboard is nil")
}
}

func switchViewController(from fromVC: UIViewController?, to toVC: UIViewController?) {
if let from = fromVC {
from.willMoveToParentViewController(nil) // 通知from即将从父ViewController移除
from.view.removeFromSuperview() // 移除from的view
from.removeFromParentViewController() // 移除from的ViewController
} else {
print("fromVC is nil")
}

if let to = toVC {
self.addChildViewController(to) // 添加to的ViewController到父ViewController
to.view.frame = CGRectMake(0, 0, containerView.frame.width, containerView.frame.height) // 计算视图大小
self.containerView.insertSubview(to.view, atIndex: 0) // 添加to的view到容器view
to.didMoveToParentViewController(self) // 通知to已经添加到父ViewController
} else {
print("toVC is nil")
}
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.

removeViewController()
}

/**
当收到内存警告时候, 移除不必要的ViewController
*/

func removeViewController() {
if let leftVC = leftViewController {
if let _ = leftVC.parentViewController {
print("leftVC is using")
} else {
print("set leftVC = nil")
leftViewController = nil
}
}

if let rightVC = rightViewController {
if let _ = rightVC.parentViewController {
print("rightVC is using")
} else {
print("set rightVC = nil")
rightViewController = nil
}
}
}


@IBAction func onSegmentValueChanged(sender: UISegmentedControl) {
UIView.beginAnimations("xxx", context: nil)
UIView.setAnimationDuration(0.4)
UIView.setAnimationCurve(.EaseInOut)

switch sender.selectedSegmentIndex {
case 0:
UIView.setAnimationTransition(.FlipFromRight, forView: self.containerView, cache: true)

if let leftVC = leftViewController {
switchViewController(from: rightViewController, to: leftVC)
} else {
if let sb = storyboard {
leftViewController = sb.instantiateViewControllerWithIdentifier("leftViewController") as! LeftViewController
switchViewController(from: rightViewController, to: leftViewController)
} else {
print("storyboard is nil")
}
}
default:
UIView.setAnimationTransition(.FlipFromLeft, forView: self.containerView, cache: true)

if let rightVC = rightViewController {
switchViewController(from: leftViewController, to: rightVC)
} else {
if let sb = storyboard {
rightViewController = sb.instantiateViewControllerWithIdentifier("rightViewController") as! RightViewController
switchViewController(from: leftViewController, to: rightViewController)
} else {
print("storyboard is nil")
}
}
}

UIView.commitAnimations()
}
}

Fork me on GitHub