界面基础
Introduction
在
引入控制器有点像
Size
CGGeometry
数据类型 | 说明 |
---|---|
CGFloat | 浮点值的基本类型 |
CGPoint | 表示一个二维坐标系中的点 |
CGSize | 表示一个矩形的宽度和高度 |
CGRect | 表示一个矩形的位置和大小 |
typedef float CGFloat;// 32-bit
typedef double CGFloat;// 64-bit
struct CGPoint {
CGFloat x;
CGFloat y;
};
typedef struct CGPoint CGPoint;
struct CGSize {
CGFloat width;
CGFloat height;
};
typedef struct CGSize CGSize;
struct CGRect {
CGPoint origin;
CGSize size;
};
typedef struct CGRect CGRect;
注意:
使用值来创建几何元素的方法:
CGPoint CGPointMake (
CGFloat x,
CGFloat y
);
CGSize CGSizeMake (
CGFloat width,
CGFloat height
);
CGRect CGRectMake (
CGFloat x,
CGFloat y,
CGFloat width,
CGFloat height
);
CGFloat ten=10.0f;
CGPoint point = CGPointMake(0.0f, 0.0f);
CGSize size = CGSizeMake(10.0f, 10.0f);
CGRect rect = CGRectMake(point.x, point.y, size.width, size.height);
NSLog(@"ten: %f", ten);
NSLog(@"point: %@", NSStringFromCGPoint(point));
NSLog(@"size: %@", NSStringFromCGSize(size));
NSLog(@"rect: %@", NSStringFromCGRect(rect));
UIScreen
UIWindow
一般来说,在
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
levelViewController = [[LevelViewController alloc] init];
window.rootViewController = levelViewController;
// 类似于下面这句
//[window addSubView: levelViewController.view];
[window makeKeyAndVisible];
//将生成的窗口对象赋值给当前应用
self.window = window;
- Swift
//App第一次运行的时候被执行过一次,每次App从后台激活时都不执行该方法:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
var viewCtl:ViewController!
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window!.backgroundColor = UIColor.whiteColor()
viewCtl = ViewController(nibName: "ViewController", bundle: NSBundle.mainBundle())
self.window!.rootViewController = viewCtl//UIWindow有一个根视图控制器—负责显示的视图
self.window!.makeKeyAndVisible()//让包含视图控制器视图的Window窗口显示在屏幕上
var isKeyWindow = self.window!.keyWindow
var keyWinD:UIWindow = UIApplication.sharedApplication().keyWindow!
}
Main.StoryBoard
在创建一个新的
你定义的这个视图控制器被设定为初始视图控制器,但
`import UIKit`` ` `@UIApplicationMain``class AppDelegate: UIResponder, UIApplicationDelegate {`` ``var` `window: UIWindow?`` ` ` ``func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {`` ``// Override point for customization after application launch.`` ``return` `true`` ``}`
上面的 @UIApplicationMain
标记指定这个UIResponder
,必须含有 UIWindow
属性,几乎所有的方法都是空的,甚至 application(_:didFinishLaunchingWithOptions:)
也只是返回
秘密藏在

UIMainStoryboardFile
UIApplication
会加载对应名称的UIWindow
对象中。
在

如果我们希望入口界面不是默认的didFinishLaunchingWithOptions
方法中设置自定义的
Interface Builder
Xib
元素关联:动作与输出口
- 自动关联:依赖注入
参考文章
[iOS 操作(action ) 和输出口(Outlet )][3]
注意,对于
在使用
“And the last option I want to point out is the storage type, which can either be strong or weak. In general you should make your outlet strong, especially if you are connecting an outlet to a subview or to a constraint that’s not always going to be retained by the view hierarchy. The only time you really need to make an outlet weak is if you have a custom view that references something back up the view hierarchy and in general that’s not recommended.”
- 手动关联
StoryBoard
苹果官方是推荐我们将所有的
- 使用
Storyboard 可以更好地了解App 中所有的视图以及它们之间的关联的概况。掌控全局更加容易,因为所有的设计都包含在一个文件中,而不是分散在很多单独的nib 文件中。 Storyboard 可以描述不同视图之间的过渡,这种过渡叫做 “segue”( 译注:意为 “ 转场 ”,而 “Storyboard” 原意为 “ 分镜 ”,均源自电影术语) ,你可以直接在Storyboard 中通过连接不同的视图控制器来创建转场。多亏有了转场,打理界面的代码比以前要少了。Storyboard 通过新的原型表项(prototype cell ) 和静态表项(static cell ) 特性,让处理表视图(table view ) 的工作更加轻松。几乎完全可以在Storyboard 编辑器里搞定表视图的设计,同样也减少了代码量。Storyboard 使自动布局(Auto Layout ) 更易用。自动布局功能可以让你通过界面元素之间的数学关系定义来确定元素的位置和尺寸,极大简化了不同尺寸屏幕的适配工作。自动布局不在本教程范围之内,若想了解更多,请参阅自动布局入门。
Scene & Segue
一个视图控制器在
这里可以看到一个包含空视图的视图控制器。在这个视图控制器左边指向它的箭头表明它是这个
在
注:你会注意到默认场景是一个正方形。
自动布局由
在继续探索之前,先在当前


现在,场景变成了
从右下方的对象库里把一些控件拖到空的视图控制器上,感受一下

控件拖进来之后应该会在左边的文档大纲

如果没看到文档大纲,请点击

在场景上面还有一个缩小的文档大纲,称作

Auto Resize
UIView
LifeCycle
函数名 | 生命周期 |
---|---|
init | |
viewWillAppear | 视图即将可见时调用。默认情况下不执行任何操作 |
viewWillDisappear | 视图被驳回时调用,覆盖或以其他方式隐藏。默认情况下不执行任何操作 |
viewDidDisappear | 视图被驳回后调用,覆盖或以其他方式隐藏。默认情况下不执行任何操作 |
viewDidAppear | 视图已完全过渡到屏幕上时调用 |
viewDidLoad | 在视图加载后被调用,如果是在代码中创建的视图加载器,他将会在 |
viewDidUnload | 当系统内存吃紧的时候调用 |
初始化
视图加载
initWithFrame:
var rightView:UIView = UIView(frame:CGRectMake(260,0,40,40))
从Xib 文件加载
NSArray* nibView = [[NSBundle mainBundle]
loadNibNamed:@"CenterView" owner:self options:nil];
self =[nibView objectAtIndex:0];
Properties
Size & Position
在一个UIView中,最常见的用来描述其坐标的属性有Frame、Bounds以及Center。
属性 | 描述 |
---|---|
Frame(CGRect) | |
Bounds(CGRect) | |
Center(CGPoint) | 用于描述 |
基本的计算方式如下:
frame.origin = center - (bounds.size / 2.0)
center = frame.origin + (bounds.size / 2.0)
frame.size = bounds.size

// view1 will be positioned at x = 30, y = 20 starting the top left corner of [self view]
// [self view] could be the view managed by a UIViewController
UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(30.0f, 20.0f, 400.0f, 400.0f)];
view1.backgroundColor = [UIColor redColor];
[[self view] addSubview:view1];
Coordinate Transform: 坐标系转换
// 将像素point由point所在视图转换到目标视图view中,返回在目标视图view中的像素值
- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view;
// 将像素point从view中转换到当前视图中,返回在当前视图中的像素值
- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view;
// 将rect由rect所在视图转换到目标视图view中,返回在目标视图view中的rect
- (CGRect)convertRect:(CGRect)rect toView:(UIView *)view;
// 将rect从view中转换到当前视图中,返回在当前视图中的rect
- (CGRect)convertRect:(CGRect)rect fromView:(UIView *)view;
例把UITableViewCell中的subview(btn)的frame转换到 controllerA中
// controllerA 中有一个UITableView, UITableView里有多行UITableVieCell,cell上放有一个button
// 在controllerA中实现:
CGRect rc = [cell convertRect:cell.btn.frame toView:self.view];
或
CGRect rc = [self.view convertRect:cell.btn.frame fromView:cell];
// 此rc为btn在controllerA中的rect
或当已知btn时:
CGRect rc = [btn.superview convertRect:btn.frame toView:self.view];
或
CGRect rc = [self.view convertRect:btn.frame fromView:btn.superview];
SubViewTree:子视图与视图树
子视图索引
Index
Tag
var nameLabel:UILabel;
nameLabel.tag = 59;
self.view.addSubview(nameLabel);
nameLabel = self.view.viewWithTag(68) as UILabel;
VisibleRect:可见区域
CGRect visibleRect = CGRectIntersection(self.frame, superview.bounds);
UIViewController
在
LifeCycle
初始化
使用如下方法加载一个
levelViewController = [[LevelViewController alloc] init];
上面这句
视图加载
UIViewController更多的是负责iOS中的视图逻辑控制,
Xib
从
self = [[HSFriendListViewControllerTableViewController alloc] initWithNibName:@"HSFriendListView" bundle:nil];
常见错误
1.Loaded nib but the view outlet was not set
这种错误是因为在一个
Xib 文件中可能存在多个UIView ,在指定了FileOwner 之后,需要指定此状态下的根UIView ,如下图所示:
StoryBoard
UIStoryboard *storyboard = self.storyboard;
SpecialViewController *svc = [storyboard instantiateViewControllerWithIdentifier:@"SpecialViewController"];
// Configure the new view controller here.
[self presentViewController:svc animated:YES completion:nil];
loadView 中自定义视图
- ( void ) loadView {
UIView *view = [ [ UIView alloc]
initWithFrame:[UIScreen mainScreen].applicationFrame]
[ view setBackgroundColor:_color]
self.view = view;
[ view release]
}
-
如果你重载了这个方法,则必须创建必要的
view 并且将一个非nil 值传给UIViewController 的view 属性。 -
如果你没有重载这个函数,
UIViewController 会默认使用UIViewController 的nibName 和nibBundle 属性尝试从xib 文件加载view 。如果没有找到nib 文件,则ViewController 会通过以下两个步骤找到与其关联的nib 。
视图切换
模态视图
模态视图即类似于
简而言之,模态视图的跳转方式为:
PickImageViewController *ickImageViewController = [[PickImageViewController alloc] init];
[self presentModalViewController:ickImageViewController animated:YES];
//返回
[self dismissModalViewController Animated:YES];
在模态视图跳转时,可以通过
registerViewController.modalTransitionStyle =
UIModalTransitionStyleCoverVertical;
常见的常量值有:
常量值 | 描述 |
---|---|
UIModalTransitionStyleCoverVertical | 呈现时沿垂直方向由底向上退出,覆盖原来视图,关闭时从上往底部退回 |
UIModalTransitionStyleFlipHorizontal | 水平翻转,呈现的时候从右往左翻转,关闭的时候从左往右翻转回来, |
UIModalTransitionStyleCrossDissolve | 两个视图交叉淡入淡出, |
UIModalTransitionStylePartialCurl | 呈现时模态视图卷起一个边角翻页,关闭时模态视图翻回来, |
在页面进行跳转时,或者某个页面结束需要回传信息时,可以利用通知机制进行消息传递:
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(registerCompletion:)
name:@"RegisterCompletionNotification"
object:nil
];
}
-(void)registerCompletion:(NSNotification*)notification {
NSDictionary *theData = [notification userInfo];
NSString *username = [theData objectForKey:@"username"];
NSLog(@"username = %@",username);
}
修改
RegisterCompletionNotification,其中通知的参数放在字典
- (IBAction)done:(id)sender {
[self dismissViewControllerAnimated:YES completion:^{
NSLog(@"Modal View done");
NSDictionary *dataDict = [NSDictionary
dictionaryWithObject:self.txtUsername.text
forKey:@"username"];
[[NSNotificationCenter defaultCenter]
postNotificationName:@"RegisterCompletionNotification"
object:nil
userInfo:dataDict];
}];
}
childViewController:子视图控制器
View Controller中可以添加多个sub view,在需要的时候显示出来;可以通过viewController(parent)中可以添加多个child viewController;来控制页面中的sub view,降低代码耦合度;通过切换,可以显示不同的view;替代之前addSubView的管理。在转移到子ViewController之后,有几个方法被子ViewController托管了:
1- Appearance Methods:
- viewWillAppear:
- viewDidAppear:
- viewWillDisappear:
- viewDidDisappear:
2- Rotation Methods:
- willRotateToInterfaceOrientation:duration:
- willAnimateRotationToInterfaceOrientation:duration:
- didRotateFromInterfaceOrientation:
苹果
addChildViewController:
removeFromParentViewController
transitionFromViewController:toViewController:duration:options:animations:completion:
willMoveToParentViewController:
didMoveToParentViewController:
-
创建项目,changeViewController。
-
添加相应的
viewController ,MainViewController、FirstViewController、SecondViewController、ThirdViewController。 -
把
MainViewController 添加到window 中。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
MainViewController *mainViewController=[[MainViewController alloc] initWithNibName:@"MainViewController" bundle:nil];
self.window.rootViewController=mainViewController;
[self.window makeKeyAndVisible];
return YES;
}
-
在
MainViewController 中添加三个按钮,并且连接onClickbutton 方法。 -
在
MainViewController 中添加三个子controller
#pragma mark – View lifecycle - (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
FirstViewController *firstViewController=[[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil];
[self addChildViewController:firstViewController];
SecondViewController *secondViewController=[[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
[self addChildViewController:secondViewController];
ThirdViewController *thirdViewController=[[ThirdViewController alloc] initWithNibName:@"ThirdViewController" bundle:nil];
[self addChildViewController:thirdViewController];
[contentView addSubview:thirdViewController.view];
currentViewController=thirdViewController;
}
其中要把其中的一个子controller的view添加到根视图中,这样才能显示出相应的视图。
- 点击按钮,切换视图。
-(IBAction)onClickbutton:(id)sender
{
FirstViewController *firstViewController=[self.childViewControllers objectAtIndex:0];
ThirdViewController *thirdViewController=[self.childViewControllers objectAtIndex:2];
SecondViewController *secondViewController=[self.childViewControllers objectAtIndex:1];
if ((currentViewController==firstViewController&&[sender tag]==1)||(currentViewController==secondViewController&&[sender tag]==2) ||(currentViewController==thirdViewController&&[sender tag]==3) ) {
return;
}
UIViewController *oldViewController=currentViewController;
switch ([sender tag]) {
case 1:
{
[self transitionFromViewController:currentViewController toViewController:firstViewController duration:4 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
} completion:^(BOOL finished) {
if (finished) {
currentViewController=firstViewController;
}else{
currentViewController=oldViewController;
}
}];
}
break;
case 2:
{
[self transitionFromViewController:currentViewController toViewController:secondViewController duration:1 options:UIViewAnimationOptionTransitionFlipFromTop animations:^{
} completion:^(BOOL finished) {
if (finished) {
currentViewController=secondViewController;
}else{
currentViewController=oldViewController;
}
}];
}
break;
case 3:
{
NSLog(@"好友申请");
[self transitionFromViewController:currentViewController toViewController:thirdViewController duration:1 options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{
} completion:^(BOOL finished) {
if (finished) {
currentViewController=thirdViewController;
}else{
currentViewController=oldViewController;
}
}];
}
break;
default:
break;
}
}
Layout
AutoLayout & Size Classes
参考资料
[ 初探iOS8 中的Size Class][6]
- update constraints
- update layout
- update display
CustomControl
关于
1、layoutSubviews
在
1、
但是是用
2、
3、设置
4、滚动一个
5、旋转
6、改变一个
2、setNeedsLayout
此方法会将
3、layoutIfNeeded
使用此方法强制立即进行
基于约束的
1、setNeedsUpdateConstraints
当一个自定义updateConstraints
2、needsUpdateConstraints
updateConstraints
作为正常布局过程的一部分。
3、updateConstraintsIfNeeded
立即触发约束更新,自动更新布局。
4、updateConstraints
自定义[super updateConstraints]
Container View Controller
Navigation Controller
![Navigation Controller][7]
参考资料
[ iOS 学习之UINavigationController 详解与使用][8]
最左侧是根视图,当用户点击其中的
![Navigation Controller][9]
![enter description here][10]
UIBarButtonItem
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(selectLeftAction:)];
self.navigationItem.leftBarButtonItem = leftButton;
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(selectRightAction:)];
self.navigationItem.rightBarButtonItem = rightButton;
在添加
-(void)selectLeftAction:(id)sender
{
UIAlertView *alter = [[UIAlertView alloc] initWithTitle:@"提示" message:@"你点击了导航栏左按钮" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[alter show];
}
-(void)selectRightAction:(id)sender
{
UIAlertView *alter = [[UIAlertView alloc] initWithTitle:@"提示" message:@"你点击了导航栏右按钮" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[alter show];
}
Tab Bar Controller
![Tab Bar Controller][12]
Custom Controller
-
添加
View ```
-
(void) displayContentController: (UIViewController*) content;
{
[self addChildViewController:content]; // 1
content.view.frame = [self frameForContentController]; // 2
[self.view addSubview:self.currentClientView];
[content didMoveToParentViewController:self]; // 3
}
- 删除View
- (void) hideContentController: (UIViewController*) content
{
[content willMoveToParentViewController:nil]; // 1
[content.view removeFromSuperview]; // 2
[content removeFromParentViewController]; // 3
}
- 页面切换
-
(void) cycleFromViewController: (UIViewController*) oldC
toViewController: (UIViewController*) newC
{
[oldC willMoveToParentViewController:nil]; // 1
[self addChildViewController:newC];
newC.view.frame = [self newViewStartFrame]; // 2
CGRect endFrame = [self oldViewEndFrame];
[self transitionFromViewController: oldC toViewController: newC // 3
duration: 0.25 options:0
animations:^{
newC.view.frame = oldC.view.frame; // 4
oldC.view.frame = endFrame;
}
completion:^(BOOL finished) {
[oldC removeFromParentViewController]; // 5
[newC didMoveToParentViewController:self];
}];
}
# Theme
## MaterialDesign
### [CosmicMind - Material For Swift](https://github.com/CosmicMind/Material)

[1]: http://img.blog.csdn.net/20150701233641345?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2F1Y2h5d2VpZXJzdHJhc3M=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
[2]: http://img.blog.csdn.net/20150701234834234?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2F1Y2h5d2VpZXJzdHJhc3M=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
[3]: http://www.ziqiangxuetang.com/ios/ios-action-outlet.html
[4]: http://img.blog.csdn.net/20150701234853010?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2F1Y2h5d2VpZXJzdHJhc3M=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
[5]: http://i.stack.imgur.com/fzu7d.jpg
[6]: http://blog.csdn.net/yongyinmg/article/details/39315829
[7]: https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/Art/nav_object_diagram_2x.png
[8]: http://blog.csdn.net/totogo2010/article/details/7681879
[9]: http://my.csdn.net/uploads/201206/21/1340245120_7325.png
[10]: http://my.csdn.net/uploads/201206/21/1340243604_5347.png
[11]: http://my.csdn.net/uploads/201206/21/1340247778_6942.png
[12]: https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/Art/tab_bar_diagram_2x.png