目录
1. 程序运行流程
2. UIApplication
3. UIWindow
4. UIView
5. UIControl
6. UIViewController
7. UIResponder
8. 坐标系统
9. 屏幕旋转
10. UIColor
11. 跳转
12. 手势
13. 文本自适应
14. 自定义字体
15. emoji
16. 第三方键盘IQKeyboardManager
1. 程序运行流程
知道程序流程可以快速找到错误地方!!!
1.1 main.m
程序的入口函数(点击应用图标后进入)
初始化UIApplication对象,并设置dele为AppDelegate
UIApplication让AppDelegate代理自己去做具体实现(防止直接修改UIApplication不安全)
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
// 第三个参数nil 等价于 NSStringFromClass([UIApplication class])
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
1.2 生命周期
App生命周期
程序启动:X->A—>D—>E
Home: —>B—>C
再回来: —>D—>E
退出: —>B—>C—>F
// X
main函数:初始化UIApplication对象,并设置dele为AppDelegate
// A:应用加载完毕后调用(只被调用一次)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
// 1.初始化窗口,设置根视图
self.window=[[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
self.window.rootViewController=[self rootVC];
self.window.backgroundColor=[UIColor whiteColor];
[self.window makeKeyAndVisible];
// 2.初始化第三方或其他配置
[self setup];
}
// B:应用即将从前台到后台(用于:游戏降低帧率、暂停游戏)
- (void)applicationWillResignActive:(UIApplication *)application {
}
// C:应用进入后台后调用(用于:保存状态数据、销毁定时器)
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
// D:应用即将进入前台时调用(用于:恢复之前保存的状态数据)
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
// E:应用进入前台后调用(处于活跃状态)
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
// F:(由于内存紧张)应用销毁前调用(用于一些收尾工作)
- (void)applicationWillTerminate:(UIApplication *)application{
}
VC生命周期
进入页面:L->A->B
离开页面: ->C
返回页面: ->B
退出页面: ->C
// L:可选择性覆写-自定义self.view
-(void)loadView{
// 当controller的view为nil时(第一次被显示时),会调用loadView方法
// 会从xib、storyboard中查找并赋值给self.view,没有找到时会创建一个空的View并赋值给self.view
[super loadView];
.当覆写了loadView方法时会调用该方法(没有xib、storyboard时可覆写该方法创建View,此时不必调用[super loadView] ,可以减少不必要的开销),当没有覆写loadView方法时,会调用默认的loadView方法(会从xib、storyboard中查找,没有找到时会创建一个空的View)
}
// A:页面加载完毕后调用
-(void)viewDidLoad{
[super viewDidLoad];
}
// B:页面即将显示在屏幕上时调用
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
}
// C:页面即将消失时调用
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
}
// D:内存紧张时调用
-(void)didReceiveMemoryWarning{
}
2. UIApplication
一个应用对应一个UIApplication
// 获取 UIApplication(当前应用的单例)
UIApplication *sharedApplication=[UIApplication sharedApplication];
// 获取 UIWindow(主窗口,一般情况下:应用只有一个主窗口)
UIWindow *window=sharedApplication.keyWindow;
// 获取 AppDelegate
id<UIApplicationDelegate> dele=sharedApplication.delegate;
// 应用角标
[sharedApplication setApplicationIconBadgeNumber:-1]; // -1角标清0
//------------- 其他 -------------
// 忽略交互事件
[sharedApplication beginIgnoringInteractionEvents];
// 接受交互事件
[sharedApplication endIgnoringInteractionEvents];
// 获取 应用当前状态
UIApplicationState state=sharedApplication.applicationState;
/*
UIApplicationStateActive, 活跃状态(可交互)
UIApplicationStateInactive,
UIApplicationStateBackground 后台
*/
// 获取 应用后台存活时间(只读)
NSTimeInterval backTime=sharedApplication.backgroundTimeRemaining;
// 获取 应用后台刷新状态
UIBackgroundRefreshStatus status=sharedApplication.backgroundRefreshStatus;
/*
UIBackgroundRefreshStatusRestricted, //
UIBackgroundRefreshStatusDenied, // 不允许刷新
UIBackgroundRefreshStatusAvailable // 允许刷新
*/
跳转
// 是否允许打开其他应用
BOOL isCanOpen=[sharedApplication canOpenURL:[NSURL URLWithString:@""]];
// 打开其他应用
[sharedApplication openURL:[NSURL URLWithString:@""]];
[sharedApplication openURL:[NSURL URLWithString:@""] options:@{} completionHandler:^(BOOL success) {
}];
状态栏
状态栏字体颜色(默认:黑色)
navigationBar.barStyle 两种:
黑色(UIStatusBarStyleDefault,默认),状态栏字体白色
白色(UIStatusBarStyleLightContent),状态栏字体黑色。
改为白色:
方法一 info.plist
View controller-based status bar appearance :false // 默认为true
status bar style :UIStatusBarStyleLightContent // 默认为UIStatusBarStyleDefault
注意:
1. true 则 [UIApplication sharedApplication].statusBarStyle 无效(preferredStatusBarStyle方法有效,若需要设置个别页的状态栏颜色,则在willAppear willDisAppear中调用即可)
2. false 则 仅[UIApplication sharedApplication].statusBarStyle 设置有效(preferredStatusBarStyle方法无效)
方法二 preferredStatusBarStyle方法(前提:上述plist使用默认true)
// 状态栏(如果VC在navC中,则需在navC中添加该方法,否则无效)
// VC中
- (UIStatusBarStyle)preferredStatusBarStyle{
// 状态栏为白色. UIStatusBarStyleDefault:黑色
return UIStatusBarStyleLightContent;
}
// navC中
- (UIStatusBarStyle)preferredStatusBarStyle{
return [self.topViewController preferredStatusBarStyle];
}
注意:
// 会调用navC(没有navC 则VC)中的preferredStatusBarStyle。
[self setNeedsStatusBarAppearanceUpdate];
// 隐藏状态栏(已过期)
sharedApplication.statusBarHidden=true;
[sharedApplication setStatusBarHidden:true withAnimation:UIStatusBarAnimationFade];
// 设置 是否显示网络加载圈(状态栏中)
[sharedApplication setNetworkActivityIndicatorVisible:true];
// 获取 应用状态栏方向(readOnly)
UIInterfaceOrientation interfaceOrien=sharedApplication.statusBarOrientation;
/*
UIInterfaceOrientationUnknown = UIDeviceOrientationUnknown,
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait, Home在下
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown, Home在上
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight, Home在
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
*/
// 获取 应用状态栏动画时间(readOnly)
NSTimeInterval durTime=sharedApplication.statusBarOrientationAnimationDuration;
// 获取 应用状态栏frame(readOnly)
CGRect applicationFrame=sharedApplication.statusBarFrame;
通知
应用进入后台后
UIApplicationDidEnterBackgroundNotification
应用即将进入前台时
UIApplicationWillEnterForegroundNotification
应用加载完毕后
UIApplicationDidFinishLaunchingNotification
应用允许交互后
UIApplicationDidBecomeActiveNotification
应用即将不允许交互时
UIApplicationWillResignActiveNotification
应用收到内存紧张警告时
UIApplicationDidReceiveMemoryWarningNotification
应用即将销毁时
UIApplicationWillTerminateNotification;
应用
UIApplicationSignificantTimeChangeNotification;
应用状态栏方向即将改变时
UIApplicationWillChangeStatusBarOrientationNotification
应用状态栏方向改变后
UIApplicationDidChangeStatusBarOrientationNotification
应用状态栏即将改变frame
UIApplicationWillChangeStatusBarFrameNotification
应用状态栏改变frame后
UIApplicationDidChangeStatusBarFrameNotification
应用后台刷新状态改变
UIApplicationBackgroundRefreshStatusDidChangeNotification
3. UIWindow
// 应用加载完毕后调用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 设置 主窗口
self.window=[[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
// 设置 主窗口背景色
[self.window setBackgroundColor:[UIColor whiteColor]];
// 设置 主窗口可见(必须调用)
[self.window makeKeyAndVisible];
// 设置 主窗口根控制器(常用于切换两端)
[self.window setRootViewController:[[YTNavController alloc]initWithRootViewController:[YTVoiceViewController new]]];
// 初始化一些第三方
[self setupThird];
return YES;
}
UIWindow : UIView
// 屏幕。默认是[UIScreen mainScreen],改变会耗内存。
@property(nonatomic,strong) UIScreen *screen;
// 显示优先级(默认为0,大在上,相同也在上)
// UIWindowLevelNormal 0、UIWindowLevelAlert 2000、UIWindowLevelStatusBar 1000、自定义数字
@property(nonatomic) UIWindowLevel windowLevel;
// window是否是keyWindow
@property(nonatomic,readonly,getter=isKeyWindow) BOOL keyWindow;
// 使window变为keyWindow
[window makeKeyWindow];
// 主控制器。改变可以更换根界面。
@property(nullable, nonatomic,strong) UIViewController *rootViewController;
// 使主窗口可见
// 不同于View(会添加到其他View上),Window创建后使用 [myWindow makeKeyAndVisible];
[self.window makeKeyAndVisible];
// 可查看当前所有windows
[UIApplication sharedApplication].windows
// 分发事件
[window sendEvent:[UIEvent new]];
// 子类覆写,不能直接调用
- (void)becomeKeyWindow;
- (void)resignKeyWindow;
window间坐标转换
CGRect rect=[window convertRect:CGRectMake(0, 0, 0, 0) toWindow:window2];
CGPoint point=[window convertPoint:CGPointMake(0, 0) toWindow:window2];
CGRect rect=[window convertRect:CGRectMake(0, 0, 0, 0) fromWindow:window2];
CGPoint point=[window convertPoint:CGPointMake(0, 0) fromWindow:window2];
常用(弹窗)
// 主窗口添加子视图
[[UIApplication sharedApplication].keyWindow addSubview:[UIView new]];
通知
UIWindowDidBecomeVisibleNotification // window可见
UIWindowDidBecomeHiddenNotification // window隐藏
UIWindowDidBecomeKeyNotification // makekey后
UIWindowDidResignKeyNotification // resignKey后
// 键盘显示/隐藏通知
UIKeyboardWillShowNotification // 键盘即将显示
UIKeyboardDidShowNotification // 键盘已经显示
UIKeyboardWillHideNotification // 键盘即将隐藏
UIKeyboardDidHideNotification // 键盘已经隐藏
/*
UIKeyboardFrameBeginUserInfoKey // NSValue of CGRect
UIKeyboardFrameEndUserInfoKey // NSValue of CGRect 键盘显示后
UIKeyboardAnimationDurationUserInfoKey // NSNumber of double 动画时长
UIKeyboardAnimationCurveUserInfoKey // NSNumber of NSUInteger (UIViewAnimationCurve)
UIKeyboardIsLocalUserInfoKey // NSNumber of BOOL
// 举例:获取键盘的高度
NSDictionary *userInfo = [aNotification userInfo];
NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardRect = [aValue CGRectValue];
int height = keyboardRect.size.height;
*/
// 键盘frame改变通知
UIKeyboardWillChangeFrameNotification
UIKeyboardDidChangeFrameNotification
/*
UIKeyboardCenterBeginUserInfoKey
UIKeyboardCenterEndUserInfoKey
UIKeyboardBoundsUserInfoKey
*/
4. UIView
几乎所有控件都继承UIView(即拥有UIView的属性和方法)
父视图先于子视图渲染;
子视图在父视图上方;
视图后者居上;
子视图只有一个父视图,父视图可有多个子视图;
默认子视图可超出父视图
//
UIView *view=[UIView new];
[self.view addSubview:view];
[view autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero];
UIView *subView=[UIView new];
UIView *subView2=[UIView new];
//------------- 常用 -------------
// 设置 frame(基本不用)
[view setFrame:CGRectMake(0, 0, 0, 0)];
// 设置 tag(用于获取指定控件)
[view setTag:100];
// 获取 指定View(根据tag,不止可以从父视图中获取,还可以是从父父...View中获取)
UIView *cusView=[self.view viewWithTag:100];
// 设置 透明度
[view setAlpha:1.0];
// 设置 是否隐藏
[view setHidden:true];
// 设置 是否剪裁(子视图不会超过父视图的范围)
[view setClipsToBounds:true];
// 设置 背景色
[view setBackgroundColor:[UIColor blueColor]];
//------------- 子视图(添加/移除) -------------
// 获取所有一级子视图
NSArray *viewArr=[view subviews];
// 获取所在index
NSInteger index=[view.subviews indexOfObject:subView];
// 添加子视图
[view addSubview:subView];
// 插入子视图(0在最下边,超过最大值则相当于addSubView不会崩)
[view insertSubview:subView atIndex:0];
// 插入子视图(位于指定视图上方)
[view insertSubview:subView aboveSubview:subView2];
// 插入子视图(位于指定视图下方)
[view insertSubview:subView belowSubview:subView2];
// 从父视图中移除
[subView removeFromSuperview];
// 移除所有子视图
[view.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
// 移到最上(可见)
[view bringSubviewToFront:subView];
// 移到最下(可见)
[view sendSubviewToBack:subView];
// 交换视图(指定索引)
[view exchangeSubviewAtIndex:0 withSubviewAtIndex:1];
//------------- layer -------------
// 设置 圆角
[view.layer setCornerRadius:5.0];
// 设置 是否剪裁
[view.layer setMasksToBounds:true];
// 设置 阴影色
[view.layer setShadowColor:[UIColor blueColor].CGColor];
// 设置 阴影不透明度
[view.layer setShadowOpacity:1];
// 设置 阴影偏移
[view.layer setShadowOffset:CGSizeMake(0, 0)];
// 设置 阴影圆角
[view.layer setShadowRadius:10];
//------------- 其他 -------------
// 是否可以同时收到多于一个触摸
[view setMultipleTouchEnabled:true];
// 判断view 是否是 view2或View2的子View(包含孙子辈)
BOOL isSubsView=[view isDescendantOfView:view2];
// KVC模式设置属性
[view setValue:[UIColor blueColor] forKey:@"backgroundColor"];
5. UIControl : UIView
很多可交互的控件都继承了UIControl(即拥有它的属性和方法)
UIControl的属性
enable 控件是否禁用
selected 控件是否被选中
highlighted 控件是否高亮
contentVerticalAlignment 控件内容 垂直方向对齐方式
contentHorizontalAlignment 控件内容 水平方向对齐方式
state state(只读)
// 添加/移除 事件监听
- (void)addTarget:(nullable id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;
- (void)removeTarget:(nullable id)target action:(nullable SEL)action forControlEvents:(UIControlEvents)controlEvents;
控件主要响应的3种事件:
1.基于触摸的事件
UIControlEventTouchDown 触摸事件(单点)
UIControlEventTouchDownRepeat 触摸事件(多点)
UIControlEventTouchDragInside 在控件内拖动
UIControlEventTouchDragOutside 在控件外拖动
UIControlEventTouchDragEnter 由控件外到控件内拖动
UIControlEventTouchDragExit 由控件内到控件外拖动
UIControlEventTouchUpInside 点击事件
UIControlEventTouchUpOutside 件外抬起
UIControlEventTouchCancel 取消触摸事件
2.基于值改变的事件
UIControlEventValueChanged 值改变事件
3.基于编辑的事件
UIControlEventEditingDidBegin 开始编辑事件
UIControlEventEditingChanged 文本内容改变事件
UIControlEventEditingDidEnd 编辑结束事件
UIControlEventEditingDidOnExit 退出编辑事件
所有事件
UIControlEventAlltouchEvents 所有触摸事件
UIControlEventAllEditingEvents 所有编辑事件
UIControlEventAllEvents 所有事件
UIControlState
UIControlStateNormal
UIControlStateHighlighted
UIControlStateDisabled
UIControlStateSelected
UIControlStateFocused
UIControlStateApplication
UIControlStateReserved
UIControlContentHorizontalAlignment
UIControlContentHorizontalAlignmentCenter
UIControlContentHorizontalAlignmentLeft
UIControlContentHorizontalAlignmentRight
UIControlContentHorizontalAlignmentFill
UIControlContentVerticalAlignment
UIControlContentVerticalAlignmentCenter
UIControlContentVerticalAlignmentTop
UIControlContentVerticalAlignmentBottom
UIControlContentVerticalAlignmentFill
UIScreen
// 获取 屏幕
UIScreen *mainScreen=[UIScreen mainScreen];
// 获取 屏幕大小
CGRect rect=mainScreen.bounds;
UIDevice
// 获取 当前设备
UIDevice *currentDevice=[UIDevice currentDevice];
// 获取 设备昵称
NSString *deviceName=currentDevice.name;
// 获取 设备机型 (iPhone / iPod touch / iPad)
NSString *deviceModel=currentDevice.model;
// 获取 设备机型
NSString *deviceLModel=currentDevice.localizedModel;
// 获取 设备系统
NSString *deviceSysName=currentDevice.systemName;
// 获取 设备系统版本
NSString *deviceSysVersion=currentDevice.systemVersion;
// 获取 设备方向
UIDeviceOrientation deviceOrientation=currentDevice.orientation;
/*
UIDeviceOrientationUnknown,
UIDeviceOrientationPortrait, // Home键在下
UIDeviceOrientationPortraitUpsideDown, // Home键在上
UIDeviceOrientationLandscapeLeft, // Home键在左
UIDeviceOrientationLandscapeRight, // Home键在右
UIDeviceOrientationFaceUp, // 水平放置,正面朝上
UIDeviceOrientationFaceDown // 水平放置,正面朝下
*/
// ?UUID
NSString *deviceUUID=[currentDevice.identifierForVendor UUIDString];
// 是否检测电池
BOOL battoryMonitor=currentDevice.batteryMonitoringEnabled;
// 获取电池电量
float deviceBattoryLevel=currentDevice.batteryLevel;
// 获取电池状态
UIDeviceBatteryState state=currentDevice.batteryState;
/*
UIDeviceBatteryStateUnknown,
UIDeviceBatteryStateUnplugged, // 耗电中
UIDeviceBatteryStateCharging, // 充电中 小于100%
UIDeviceBatteryStateFull, // 充电中 等于100%
*/
// 获取 设备旋转时是否发送通知
BOOL isRoteNoti=currentDevice.generatesDeviceOrientationNotifications;
// 允许设备旋转时发送通知
[currentDevice beginGeneratingDeviceOrientationNotifications];
// 不允许设备旋转时发送通知
[currentDevice endGeneratingDeviceOrientationNotifications];
// 获取 设备近距离靠近时是否发送通知(例:用于通话时,放在耳朵旁界面变暗)
BOOL isProximityMonitor=currentDevice.proximityMonitoringEnabled;
// 获取 是否近距离靠近
BOOL isPro=currentDevice.proximityState;
// ?
BOOL isMultitaskingSupported=currentDevice.isMultitaskingSupported;
UIUserInterfaceIdiom interFace=currentDevice.userInterfaceIdiom;
6. UIViewController
7. UIResponder
UIView、UIViewController、UIWindow、UIApplication、AppDelegate继承自UIResponder
// UIResponder
// UIResponder *responder=[UIResponder new];
// 是否可以 成为/注销/是 第一响应者
[responder canBecomeFirstResponder];
[responder canResignFirstResponder];
[responder isFirstResponder];
// 成为/注销 第一响应者
[responder becomeFirstResponder];
[responder resignFirstResponder];
// 响应者链中的下一个响应者
UIResponder *nextResponder=[responder nextResponder];
触摸
// 开始触摸
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{}
// 触摸后移动
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{}
// 触摸取消
-(void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{}
// 触摸结束
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{}
按压
// 开始按压
-(void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event{}
// 按压值改变
-(void)pressesChanged:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event{}
// 按压结束
-(void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event{}
// 按压取消
-(void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event{}
移动
// 开始移动
-(void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event{}
// 结束移动
-(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event{}
// 取消移动
-(void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event{}
8. 坐标系统
frame :位置和大小(相对父控件)
bounds :位置和大小(相对本控件)
center :中心点(相对父控件)
CGFloat
在UIView的坐标系统中,使用CGFloat类型的数据而不是Double或者Float
let x=CGFloat(12.0) :将Double或者Float转换成CGFloat
CGPoint
var point=CGPoint(x:30.0,y:50.0)
CGSize
var size=CGSize(width:20.0,height:10.0)
CGRect
var rect=CGRect(origin:point,size:size)
var rect=CGRect(x:10.0,y:10.0,width:20.0,height:5.0)
使用:
minX minY midX midY maxX maxY rect1.intersects(rect2) 是否 相交
rect1.intersect(rect2) 返回相交部分
rect1.contains(rect2) 是否 包含
CGRectZero
CGRectIntersectsRect(rect1, rect2) // 是否有交集
CGRectIntersection(rect1, rect2) // 返回交集rect
CGRectEqualToRect(rect1, rect2) // 是否相同
CGRectContainsRect(rect1, rect2) // 是否包含
CGRectContainsPoint(rect, CGPointMake(0, 0)) // 是否包含某点
CGRectUnion(rect1, rect2) // 返回合集rect
CGRectFromString(NSStringFromCGRect(frame)) // frame<——>str
CGRectGetMidX() CGRectGetMinX() CGRectGetMaxX() CGRectGetMidY() CGRectGetMinX() CGRectGetMaxY() CGRectGetWidth()
9. 屏幕旋转
代码旋转
[[UIDevice currentDevice]setValue:[NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight] forKey:@"orientation"];
1.项目 | General | Deployment Info 下选择项目支持的方向
Portrait 正常方向 (Home键在下)
Landscape Left (Home键在左)
Landscape Right (Home键在右)
Upside Down (Home键在上)
勾选后整个项目都支持了旋转

2.VC
// IOS6前
// VC是否支持旋转屏幕(不支持则旋转屏幕时界面不动)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{
return toInterfaceOrientation==UIInterfaceOrientationPortrait;
}
// IOS6后
// 是否允许旋转
-(BOOL)shouldAutorotate{
return true;
}
// 那些方向允许旋转
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
// 最初-返回最优先使用的方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return UIInterfaceOrientationPortrait;
}
一般放在封装的UINavigationController中
某页面旋转,那它的上级页面也必须支持旋转
仅某个页面旋转
1.自定义UITabbarController中+
-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
return self.selectedViewController.supportedInterfaceOrientations;
}
-(BOOL)shouldAutorotate{
return self.selectedViewController.shouldAutorotate;
}
2.自定义基类VC中+
-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
-(BOOL)shouldAutorotate{
return false;
}
3.需要旋转的VC中+
-(BOOL)shouldAutorotate{
return true;
}
有Nav的话(一般都有)
-(BOOL)shouldAutorotate{
return self.topViewController.shouldAutorotate; // self.viewControllers.lastObject
}
-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
10. UIColor
通常控件.alpha是不改的,改背景色.alpha (如果改变label的alpha则它的标题也是透明的)
let c=UIColor.greenColor() // 创建
let c=UIColor.init(red: 120/255.0, green: 120/255.0, blue: 120/255.0, alpha: 1) // 创建
let c=UIColor.init(white: 0.5, alpha: 0.5) // white:红绿蓝0.5 alpha:0.5
let c=UIColor.init(patternImage:UIImage(named:”1.png”)). // 不对图片进行缩放,超出屏幕则裁剪,少则重复添加
let c=UIColor.clearColor() // 透明色
let c=UIColor.yellowColor().colorWithAlphaCompoent(0.5) // 创建(透明度0.0~1.0)
11. 跳到下一页(代码2种方式:)
push(从右侧弹出)
前提:在push栈中,[[UINavigationController alloc]initWithRootViewController:[UIViewController new]];
跳到下一页
// push 跳到下一页
[self.navigationController pushViewController:[UIViewController new] animated:true];
返回(3方式)
// pop 返回上一页
[self.navigationController popViewControllerAnimated:true];
// 返回到根页面
[self.navigationController popToRootViewControllerAnimated:true];
// 返回到指定页(页面必须在堆栈中)
[self.navigationController popToViewController:self.navigationController.viewControllers[0] animated:true];
present(从下方弹出)
// 跳到下一页
[self presentViewController:[UIViewController new] animated:true completion:^{
}];
// 返回上一页
[self dismissViewControllerAnimated:true completion:^{
}];
present---弹出气泡视图
// 1.:UIViewController
YTGrabOrderPopViewController *grabPopC=[YTGrabOrderPopViewController new];
// 设置pop视图显示大小
[grabPopC setPreferredContentSize:CGSizeMake(142, 160)];
// 设置presentVC的弹出方式为pop
[grabPopC setModalPresentationStyle:UIModalPresentationPopover];
// 2.
UIPopoverPresentationController *popVC=[grabPopC popoverPresentationController];
[popVC setDelegate:self]; // <UIPopoverPresentationControllerDelegate>
// 方式一:对于View
[popVC setSourceView:button]; //
[popVC setSourceRect:button.bounds]; // 位置:可调整
// 方式二:对于UIBarButtonItem
[popVC setBarButtonItem:[UIBarButtonItem new]];
// 3.弹出
[self presentViewController:grabPopC animated:true completion:^{
}];
12. 手势
单击手势 UITapGestureRecognizer
UITapGestureRecognizer *tapG=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTap:)];
tapG.numberOfTapsRequired=1; // 点击次数(默认:1)
tapG.numberOfTouchesRequired=1; // 点击手指数(默认:1)
[[UIImageView new]addGestureRecognizer:tapG];
-(void)handleTap:(UITapGestureRecognizer *)tapG{
//
UIImageView *imgV=(UIImageView *)tapG.view;
}
缩放手势 UIPinchGestureRecognizer
// 缩放手势
UIPinchGestureRecognizer *pinchG=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinch:)];
[pinchG setScale:0.5]; // 缩放比例
// pinchG.velocity(readOnly)
[[UIImageView new]addGestureRecognizer:pinchG];
-(void)handlePinch:(UIPinchGestureRecognizer *)pinchG{
//
UIImageView *imgV=(UIImageView *)pinchG.view;
// pinchG.scale
}
旋转手势 UIRotationGestureRecognizer
// 旋转手势
UIRotationGestureRecognizer *roteG=[[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(handleRote:)];
[roteG setRotation:M_PI_2]; // 旋转角度
// roteG.velocity
[[UIImageView new]addGestureRecognizer:roteG];
-(void)handleRote:(UIRotationGestureRecognizer *)roteG{
//
UIImageView *imgV=(UIImageView *)roteG.view;
// roteG.rotation
}
扫动手势 UISwipeGestureRecognizer
// 扫动手势
UISwipeGestureRecognizer *swipeG=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipe:)];
swipeG.numberOfTouchesRequired=1; // 默认:1
swipeG.direction=UISwipeGestureRecognizerDirectionLeft; // 如果多个方向,则添加多个手势
[[UIImageView new]addGestureRecognizer:swipeG];
-(void)handleSwipe:(UISwipeGestureRecognizer *)swipeG{
//
UIImageView *imgV=(UIImageView *)swipeG.view;
}
拖动手势 UIPanGestureRecognizer
// 拖动手势
UIPanGestureRecognizer *panG=[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePan:)];
[panG setMaximumNumberOfTouches:2]; // 最小手指数
[panG setMinimumNumberOfTouches:1]; // 最大手指数
[[UIImageView new]addGestureRecognizer:panG];
-(void)handlePan:(UIPanGestureRecognizer *)panG{
//
UIButton *itemButton=(UIButton *)panG.view;
CGPoint transP=[panG translationInView:self];
NSLog(@"%f %f",transP.x,transP.y);
//
if(transP.x>0&&transP.x<294-95){
[UIView animateWithDuration:0.1 animations:^{
[itemButton setTransform:CGAffineTransformMakeTranslation(transP.x, 0)];
}];
}else if(transP.x>=294){
[self.subject sendNext:@(100)];
}
//
if(panG.state==UIGestureRecognizerStateEnded){
[UIView animateWithDuration:0.1 animations:^{
[itemButton setTransform:CGAffineTransformIdentity];
}];
}
// [panG setTranslation:CGPointZero inView:self.view]; // reset
}
长按手势 UILongPressGestureRecognizer
// 长按手势
UILongPressGestureRecognizer *longPressG=[[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(handleLongPress:)];
longPressG.numberOfTouchesRequired=1; // 手指数(默认:1)
longPressG.numberOfTapsRequired=1; // 点击数(默认:0)
longPressG.minimumPressDuration=1; // 最小的长按时间(默认:0.5)
longPressG.allowableMovement=10; // 最大的移动距离(默认:10ps)
[[UIImageView new]addGestureRecognizer:longPressG];
-(void)handleLongPress:(UIPanGestureRecognizer *)longPressG{
//
UIImageView *imgV=(UIImageView *)longPressG.view;
}
自定义手势
#import <UIKit/UIKit.h>
@interface CustomGestureRecognizer : UIGestureRecognizer
@end
#import "CustomGestureRecognizer.h"
#import <UIkit/UIGestureRecognizerSubclass.h>
@implementation CustomGestureRecognizer
-(instancetype)initWithTarget:(id)target action:(SEL)action{
return [super initWithTarget:target action:action];
}
// 开始触摸时调用
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
}
// 触摸移动时调用
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
}
// 触摸结束时调用
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
}
// 触摸取消时调用
-(void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
}
@end
UIGestureRecognizerDelegate
#pragma mark dele -UIGestureRecognizerDelegate
// 解决有水平方向滚动的ScrollView时边缘返回手势失效的问题
// 是否支持多手势(默认:false,识别到第一个手势则停止识别第二个手势)(true,则识别到第一个手势,还会去识别第二个手势)
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
// 当第一个手势和第二个手势发生冲突时,第二个失效
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return [gestureRecognizer isKindOfClass:UIScreenEdgePanGestureRecognizer.class];
}
// 当第一个手势和第二个手势发生冲突时,第一个失效
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return true;
}
// 是否允许 手势识别(默认:true)
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
return false; // 禁止识别
}
// 开始识别手势时调用(可用于:控件某范围有效)
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
return true;
}
UIViewController 或 UIView 中可覆写
// UIViewController:UIResponder
// 开始触摸
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
}
// 触摸后移动
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
}
// 触摸结束
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
}
// 触摸取消
-(void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
}
当两个手势有冲突
// 当两个手势有冲突时,手势1只会在手势2失败时才会执行
[[UIGestureRecognizer new]requireGestureRecognizerToFail:[UIGestureRecognizer new]];
获取到侧滑手势(侧滑手势继承于:UIPanGestureRecognizer)
// 获取到侧滑手势
NSArray *gestureArray = self.navigationController.view.gestureRecognizers;
for (UIGestureRecognizer *gesture in gestureArray) {
if ([gesture isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
}
}
13. 宽度或高度自适应
label.numberOfLines=0 // 多行
// 获取文本高((最大宽:求高时必须和label宽度一致,最大高),,字体必须和label字体大小一致,nil)
labelHeight=str.boundingRectWithSize(CGSizeMake(300, 300), options: .UsesLineFragmentOrigin, attributes: [NSFontAttributeName:UIFont.systemFontOfSize(13)], context: nil).size.height
[cell]
思想一:
model中+ height:CGFloat!
str:String!{
didSet{
height=(str as NSString).boundingRectWithSize(CGSizeMake(300, 300), options: .UsesLineFragmentOrigin, attributes: [NSFontAttributeName:UIFont.systemFontOfSize(13)], context: nil).size.height
}
}
cell中 setModel()中重设label的frame(或使用 自动布局)
VC中 heightForCell中 return 没有此label时的高度+(dataArr[indexPath.row] as! model).height
思想二:
新建Frame文件:将frame全部放在此文件中计算,+ height、各种控件Frame、model
// 获取text高度2
[cell.texLabel textRectForBounds:CGRectMake(100, 5, RZSCREENWIDTH-120, 500) limitedToNumberOfLines:0];
14. 自定义字体
1. 导入字体文件
下载所需ttf文件,复制到项目中
Info.plist中 Fonts provided by application | 字体名.ttf …
项目 | Build Phases | Copy Bundle Resources 中导入字体
2. 寻找字体名
NSArray *familyNames = [UIFont familyNames];
for( NSString *familyName in familyNames ){
NSArray *fontNames = [UIFont fontNamesForFamilyName:familyName];
for( NSString *fontName in fontNames ){
printf( "\tFont: %s \n", [fontName UTF8String] );
}
}
打印所有字体名,找到相对应添加的字体名(不能直接使用ttf文件名作为字体名)
3. 使用
#define YTFont_YHS(x) [UIFont fontWithName:@"MicrosoftYaHei-Bold" size:(x)]
15. emoji
// 过滤emoji表情符号
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
// 限制苹果系统输入法 禁止输入表情
if ([[[UITextInputMode currentInputMode]primaryLanguage] isEqualToString:@"emoji"]) {
return NO;
}
// 禁止输入emoji表情
if ([self stringContainsEmoji:text]) {
return NO;
}
return YES;
}
// 判断是否输入了emoji 表情
- (BOOL)stringContainsEmoji:(NSString *)string{
__block BOOL returnValue = NO;
[string enumerateSubstringsInRange:NSMakeRange(0, [string length])
options:NSStringEnumerationByComposedCharacterSequences
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
const unichar hs = [substring characterAtIndex:0];
if (0xd800 <= hs && hs <= 0xdbff) {
if (substring.length > 1) {
const unichar ls = [substring characterAtIndex:1];
const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
if (0x1d000 <= uc && uc <= 0x1f77f) {
returnValue = YES;
}
}
} else if (substring.length > 1) {
const unichar ls = [substring characterAtIndex:1];
if (ls == 0x20e3) {
returnValue = YES;
}
} else {
if (0x2100 <= hs && hs <= 0x27ff) {
returnValue = YES;
} else if (0x2B05 <= hs && hs <= 0x2b07) {
returnValue = YES;
} else if (0x2934 <= hs && hs <= 0x2935) {
returnValue = YES;
} else if (0x3297 <= hs && hs <= 0x3299) {
returnValue = YES;
} else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
returnValue = YES;
}else if (hs == 0x200d){
returnValue = YES;
}
}
}];
return returnValue;
}
16. 第三方键盘IQKeyboardManager
pod 'IQKeyboardManager'
// 开启(默认开启)
[[IQKeyboardManager sharedManager] setEnable:true];
// 键盘距正在编辑的TF的距离
[[IQKeyboardManager sharedManager]setKeyboardDistanceFromTextField:10];
// 点击输入框以外收回键盘(默认:false)
[[IQKeyboardManager sharedManager]setShouldResignOnTouchOutside:true];
// 是否显示键盘上方工具条(默认:true)
[[IQKeyboardManager sharedManager]setEnableAutoToolbar:false];
// 键盘上方toolBar是否显示placeHoolder(默认:true)
[[IQKeyboardManager sharedManager]setShouldShowToolbarPlaceholder:false];
// 键盘上方toolBar文本填充色
[[IQKeyboardManager sharedManager]setToolbarTintColor:[UIColor blueColor]];
// 键盘上方toolBar的placeHolder字体
[[IQKeyboardManager sharedManager] setPlaceholderFont:[UIFont systemFontOfSize:18]];
// 管理TF(根据tag)上下箭头 (IQAutoToolbarBySubviews 根据添加顺序 IQAutoToolbarByPosition 根据坐标位置)
[[IQKeyboardManager sharedManager]setToolbarManageBehaviour:IQAutoToolbarByTag];
// 键盘右上角完成按钮 文本
[[IQKeyboardManager sharedManager]setToolbarDoneBarButtonItemText:@"右上方按钮文本"];
// 键盘右上角完成按钮 图片
[[IQKeyboardManager sharedManager] setToolbarDoneBarButtonItemImage:[UIImage imageNamed:@""]];
// 是否可以向下上,向下上
[[IQKeyboardManager sharedManager]canGoNext];
[[IQKeyboardManager sharedManager]canGoPrevious];
[[IQKeyboardManager sharedManager]goNext];
[[IQKeyboardManager sharedManager]goPrevious];
网友评论