iOS笔记055 - UI总结01
1、程序启动后的开始动画
程序启动后可以加载一个简单的动画界面来介绍程序或者用户信息。
可以使用一个xib来描述界面。并且如果想在程序加载完成后第一个加载这个xib文件,需要在Appdelegate中手动加载这个xib
// 通过stroyboard启动,跟控制器的view并不会在程序启动完成的时候添加到窗口,属于懒加载范畴
// 程序启动完成的时候调用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// 创建窗口
self.window = [[UIWindowalloc] initWithFrame:[UIScreenmainScreen].bounds];
// 加载storyboard
UIStoryboard *story = [UIStoryboardstoryboardWithName:@"Main"bundle:nil];
UIViewController *vc = [story instantiateInitialViewController];
self.window.rootViewController = vc;
// 显示窗口
[self.windowmakeKeyAndVisible];
// 加载欢迎界面
WelcomView *welcome = [WelcomView welcomView];
// 设置位置和尺寸
welcome.frame = self.window.bounds;
// 插入到最外层
[self.window addSubview:welcome];
returnYES;
}
在xib中如果想给内部子控件添加动画,并且动画和主界面的出现有延迟,需要在以下某个方法中实现。
// 视图添加到窗口时会调用方法didMoveToWindow 再调用didMoveToSuperview
- (void)didMoveToWindow
{
NSLog(@"%s",__func__);
}
// 视图添加到窗口时会调用这个方法
// 将后续控件的动画写道这个方法中
- (void)didMoveToSuperview
{
NSLog(@"%s",__func__);
}
2、LaunchScreen.xib
这个系统自动生成的xib 文件在应用启动时会自动加载,可以在里面添加一些控件,但是
注意:LaunchScreen比LaunchImage优先级高。
设置LaunchImage需要注意,默认模拟器的尺寸跟启动图片有关系。
// 加载类的时候调用
// 当程序一启动的时候就会调用
+ (void)load
{
NSLog(@"%s",__func__);
}
// 当前类或者他的子类第一次使用的时候才会调用
+ (void)initialize
{
NSLog(@"%s",__func__);
}
3、给插件添加自定义的提醒方式
自定义的分类,想让这个方法弹出加载图片提醒
#import "UIImage+SLQImage.h"
@implementation UIImage (SLQImage)
// 按照原始图片渲染照片,默认导航条渲染位蓝色
+ (instancetype)imageWithOriImage:(NSString *)imageName
{
UIImage *image = [UIImage imageNamed:imageName];
return [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}
@end
把这个方法添加到插件中再次编译运行就可。
打开插件工程,找到配置文件,是一个plist文件,然后添加需要的条目。
4、给分类添加属性的话,只会生成set和get方法
#import <UIKit/UIKit.h>
@interface UIView (SLQFrame)
// 分类里面不能生成成员属性
// 会自动生成get,set方法和成员属性
// @property如果在分类里面只会生成get,set方法的声明,并不会生成成员属性。
@property (nonatomic, assign) CGFloat height;
@property (nonatomic, assign) CGFloat width;
@property (nonatomic, assign) CGFloat x;
@property (nonatomic, assign) CGFloat y;
@end
5、如何抛出异常
NSInteger count = items.count; // 按钮个数
的倍数,如果不是就抛出异常
if(count % 3)
{
// 跑出异常
的倍数" userInfo:nil];
[excep raise];// 抛出异常
}
// 运行结果
的倍数'
6、自定义tabBar
// 模仿下UITabBar
// UITabBar里面的按钮由UITabBarController的子控制器
@interface SLQTabBar : UIView
// 模型数组(UITabBarItem),直接使用系统的模型即可
@property (nonatomic, strong) NSArray *items;
@end
6.2、模型数组只需在初始化时添加一次即可,所以使用懒加载方式.
@interfaceSLQTabBar ()
@property (nonatomic, weak) SLQTabBarButton *selected; // 按钮是否选中
@end
- (void)setItems:(NSArray *)items
{
_items = items;
// UITabBarItem保存按钮上的图片,按次序添加
for (UITabBarItem * bar in items) {
// 使用自定义的button,取消高亮状态
UIButton *btn = [SLQTabBarButtonbuttonWithType:UIButtonTypeCustom];
// 设置标签
btn.tag = self.subviews.count;
// 设置背景
[btn setBackgroundImage:bar.imageforState:UIControlStateNormal];
[btn setBackgroundImage:bar.selectedImageforState:UIControlStateSelected];
// 添加按钮按下响应事件
[btn addTarget:selfaction:@selector(btnClick:) forControlEvents:UIControlEventTouchDown];
[self addSubview:btn];
if (self.subviews.count == 1) {
// 默认选中第一个
[self btnClick:btn];
}
}
}
6.3、tabBar上是一排按钮排列而成,不过没有高亮状态,只有Normal和selected状态。
这个只需要重写 UIButton 的一个方法即可。新建一个继承自UIButton的类,重写 setHighlighted 方法
#import "SLQTabBarButton.h"
@implementation SLQTabBarButton
// 取消按钮高亮状态
- (void)setHighlighted:(BOOL)highlighted
{}
@end
6. 4、每次添加过按钮之后都要对按钮进行布局
- (void)layoutSubviews
{
[superlayoutSubviews];
int count = (int)self.subviews.count;
// 按照屏幕宽度计算按钮宽度
for (int i = 0 ; i < count; i ++) {
CGFloat x = 0;
CGFloat y = 0;
CGFloat w = [UIScreenmainScreen].bounds.size.width / count;
CGFloat h = self.bounds.size.height;
SLQTabBarButton *btn = self.subviews[i];
x = i * w;
btn.frame = CGRectMake(x, y, w, h);
}
}
定义
@classSLQTabBar;
// 添加代理,响应按钮点击
@protocol SLQTabBarDelegate <NSObject>
@optional
- (void)tabBar:(SLQTabBar *)tabBar didClickButton:(NSInteger ) index;
@end
声明
@property (nonatomic, weak) id<SLQTabBarDelegate> delegate;
使用
- (void)btnClick:(UIButton *)btn
{
// 取消选中上一个按钮
_selected.selected = NO;
// 选中当前按钮
btn.selected = YES;
// 记录选中的按钮
_selected = btn;
// 切换控制器,添加一个代理,先判断是否有这个方法
if ([self.delegate respondsToSelector:@selector(tabBar:didClickButton:)])
{
// 发送消息到代理,通过按钮tag判断是哪一个按钮
[self.delegate tabBar:self didClickButton:btn.tag];
}
}
6.6、具体使用方法,在控制器中设置tabBar
添加自定义的tabBar到tabBar,然后将系统生成的按钮删除.
//添加自定义的tabBar到tabBar,然后将系统生成的按钮删除
- (void)setAllTabBar
{
// 移除所有子控件
// [self.tabBar removeFromSuperview];
// 添加自定义tabBar
SLQTabBar *bar = [[SLQTabBar alloc] init];
// 传入模型数据
bar.items = self.items;
// 设置尺寸
bar.frame = self.tabBar.bounds;
// 设置代理,监听按钮点击
bar.delegate = self;
// 添加到tabBar,但是要把系统自带的按钮删除
[self.tabBar addSubview:bar];
}
移除系统按钮
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// 删除系统自带的tabBar
for (UIView *childView in self.tabBar.subviews) {
if (![childView isKindOfClass:[SLQTabBar class]]) {
[childView removeFromSuperview];
}
}
}
- (void)tabBar:(SLQTabBar *)tabBar didClickButton:(NSInteger)index
{
// NSLog(@"%s--%d",__func__,index);
// 切换控制器
self.selectedIndex = index;
}
7、手动添加pch文件都项目
pch文件中包含的东西在项目中每个文件中都可以使用。

8、load和initialize
// 当程序一启动的时候就会调用
+ (void)load
{
}
// 当前类或者他的子类第一次使用的时候才会调用
+ (void)initialize
{}
9、 给任意弹出的窗口添加遮盖
这个也比较常见,比如说弹出登陆界面时,程序其他部分都是灰色背景,且不能点击。
可以给程序添加一个灰色的View,而且要显示在所有界面之前,那么可以使用
[UIApplication sharedApplication].keyWindow;
添加到这个窗口上的窗口默认都在最前面。
自定义一个继承自UIView的类,添加两个方法即可。
// 屏幕尺寸
#define SLQScreenBounds [UIScreen mainScreen].bounds
// 主窗口
#define SLQKeyWindow [UIApplication sharedApplication].keyWindow
// 显示遮盖
+ (void)show
{
// 获取主窗口,添加一个view 到主窗口
UIView *view = [[SLQCoverView alloc] initWithFrame:SLQScreenBounds];
view.backgroundColor = [UIColorblackColor];
view.alpha = 0.4;
// 添加窗口到主窗口,显示在最上层
[SLQKeyWindow addSubview:view];
}
// 隐藏遮盖
+ (void)hide
{
// 取出子窗口移除,首先判断是不是SLQCoverView类型的view
for (UIView *childView in SLQKeyWindow.subviews) {
if ([childView isKindOfClass:self]) {
[childView removeFromSuperview];
}
}
}
10、loadView、viewDidLoad和viewDidUnLoad
loadView 苹果设计这个方法就是给我们自定义UIViewController的view用的
viewDidLoad 在创建过控制器的view后,向view中添加其他控件
viewDidUnLoad 系统发出内存警告时
关系
1.第一次访问UIViewController的view时,view为nil,然后就会调用loadView方法创建view
2.view创建完毕后会调用viewDidLoad方法进行界面元素的初始化
3.当内存警告时,系统可能会释放UIViewController的view,将view赋值为nil,并且调用viewDidUnload方法
4.当再次访问UIViewController的view时,view已经在3中被赋值为nil,所以又会调用loadView方法重新创建view
5.view被重新创建完毕后,还是会调用viewDidLoad方法进行界面元素的初始化

11、UINavigationBar 所生成的图片都是经过处理的view,为蓝色
原始图片

// 默认左右两遍的view都是蓝色的,所以要返回一个原始的图片
UIImage *image = [UIImageimageNamed:@"CS50_activity_image"] ;
// 设置图片的渲染方式为原始图片
image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:@selector(activeBtnClick)];
iOS笔记055 - UI总结01的更多相关文章
- iOS笔记057 - UI总结03
控制器的父子关系 1.控制器父子关系的建立原则 如果2个控制器的view是父子关系(不管是直接还是间接的父子关系),那么这2个控制器也应该为父子关系 [self.view addSubv ...
- iOS笔记056 - UI总结02
九宫格布局 UICollectionViewController 创建控制器一定要指定默认的布局样式. // 加载一个九宫格布局的控制器,必须指定布局样式 UICollectionViewFlowLa ...
- 荼菜的iOS笔记--UIView的几个Block动画
前言:我的第一篇文章荼菜的iOS笔记–Core Animation 核心动画算是比较详细讲了核心动画的用法,但是如你上篇看到的,有时我们只是想实现一些很小的动画,这时再用coreAnimation就会 ...
- iOS开发Swift篇(01) 变量&常量&元组
iOS开发Swift篇(01) 变量&常量&元组 说明: 1)终于要写一写swift了.其实早在14年就已经写了swift的部分博客,无奈时过境迁,此时早已不同往昔了.另外,对于14年 ...
- 免费素材下载:iOS 8 矢量 UI 素材套件
小伙伴们,苹果终于在今天凌晨推送了 iOS 8 的正式版.虽然该系统并未与 iPhone6 发布会同时亮相,但对于已经提前体验尝鲜过测试版的同学来说并不陌生.iOS 8 几乎每个图标都进行了重新设计, ...
- iOS之微博UI实例--拟物化设计(成功了90%)
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- IOS开发-UI学习-sqlite数据库的操作
IOS开发-UI学习-sqlite数据库的操作 sqlite是一个轻量级的数据库,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了,而且它的处理速度比Mysql.PostgreSQL这 ...
- 79.iOS 设备的UI规范和iOS各控件默认高度
iOS设备的UI 规范 iPhone界面尺寸 iPhone图标尺寸 iPad的设计尺寸 iPad图标尺寸 iPhone设备尺寸分辨率比例 iPhone各设备 launch image iOS 各种控件 ...
- Puppet学习笔记(CentOS6.3+Puppet3.01)
Puppet学习笔记(CentOS6.3+Puppet3.01) 技术 Add comments Oct262012 下了决心,好好学习puppet,周末专门去参加一个puppet的培训,难得朋友那 ...
随机推荐
- CRM, C4C和Hybris的后台作业
CRM 使用事务码SM36查看CRM系统的后台作业: 举一些例子: ABAP_TEXT_INDEX这个job执行的report是ABAP_DOCU_CREATE_TEXT_INDEX: 负责填充buf ...
- Invalid MyEclipse License - Discontinuing this MyEclipse operation. 出现这个错误怎么改正?
Invalid MyEclipse License - Discontinuing this MyEclipse operation这句话的意思是无效的许可证-停用此MyEclipse操作入门就是你的 ...
- MHA启动及关闭
MHA启动及关闭 #masterha_manager --global_conf=/etc/masterha/masterha_default.conf --conf=/etc/masterha/ap ...
- httpclient开启代理,获取java中请求的url
背景:在httpclent做post或者get请求时,请求返回的数据总是和预想的不一致,但是有不知道怎么排查问题,经同事说httpclient可以设置代理,就可以获取请求前数据的一些问题,帮助我排查问 ...
- 模拟停车POJ(3505)
题目链接:http://poj.org/problem?id=3505 解题报告: #include <stdio.h> #include <iostream> #includ ...
- nbu8.1配置群集SQL Server实例的备份
1.About SQL Server high availability (HA) environments SQL Server Intelligent policies support the f ...
- 如何将一个div水平垂直居中
方案一: div绝对定位水平垂直居中[margin:auto实现绝对定位元素的居中], 兼容性:,IE7及之前版本不支持 div{ width: 200px; height: 200px; backg ...
- ES6初识-解构赋值
数组解构赋值 [a,b]=[1,2]; . 方法返回 function f(){ return [1,2] } let a,b; [a,b]=f();//a=1,b=2 function f1() ...
- SpringMVC系列一
首先介绍一下SpringMVC的执行流程:如图 1.用户在客户端发送请求,经过前端控制器DispatcherServlet,请求处理器处理,返回ModelAndView返回结果到前端控制器: 2.前端 ...
- Docker自学纪实(六)搭建docker私有仓库
docker的镜像仓库分两种:一种是从官方公有仓库拉取:还有就是自己搭建私有仓库.官方的镜像仓库是面对整个应用市场的:私有仓库一般用于公司内部,就是公司项目自身所需的镜像.搭建私有仓库有什么好处?私有 ...