OC学习
navigationcontroller
不显示navigationBar
需要设置代理来控制navigation
@interface LoginViewController () <UINavigationControllerDelegate>
代理方法
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
// 判断要显示的控制器是否是自己
BOOL isShowHomePage = [viewController isKindOfClass:[self class]];
[self.navigationController setNavigationBarHidden:isShowHomePage animated:YES];
}
事件传递
**当前 UIView 的 alpha 值会被其所有 subview 继承。**因此,alpha 值会影响到 UIView 跟其所有 subview。
**设置 backgroundColor 的 alpha 值只影响当前 UIView 的背景,并不会影响其所有 subview。**这点是同 alpha 的区别,Clear Color 就是 backgroundColor 的 alpha 为 1.0。
HitTest
Hittest 要继承UIView
HitTest判断是否响应事件(调用顺序)
下面代码是四个条件不响应点击事件
1、view.userInteractionEnabled = NO;
2、view.hidden = YES;
3、view.alpha < 0.05
4、view 超出 superview 的 bounds
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
// 如果交互未打开,或者透明度小于0.05 或者 视图被隐藏
if (self.userInteractionEnabled == NO || self.alpha < 0.05 || self.hidden == YES) {
return nil;
}
// 如果 touch 的point 在 self 的bounds 内
if ([self pointInside:point withEvent:event]) {
for (UIView *subView in self.subviews) {
//进行坐标转化
CGPoint coverPoint = [subView convertPoint:point fromView:self];
// 调用子视图的 hitTest 重复上面的步骤。找到了,返回hitTest view ,没找到返回有自身处理
UIView *hitTestView = [subView hitTest:coverPoint withEvent:event];
if (hitTestView) {
return hitTestView;
}
}
return self;
}
return nil;
}
swift 写法
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if self.isUserInteractionEnabled == false || self.alpha < 0.05 || self.isHidden == true {
return nil
}
//如果touch的point在self里
if self.point(inside: point, with: event) {
for subView in self.subviews {
//进行坐标转换
let coverPoint = subView.convert(point, from: self)
//调用子视图的 hitTest 重复上面的步骤。找到了,返回hitTest view ,没找到返回有自身处理
let hitTestView: UIView? = subView.hitTest(coverPoint, with: event)
return hitTestView
}
return self
}
return nil
}
injectionIII(xcode模拟器热重载)
Appstore 有下载
github原址https://github.com/johnno1962/InjectionIII
使用教程https://www.jianshu.com/p/0720138ad6b7
生命周期
UlApplication
UlApplication作用
2.设置联网指示器的可见性
3.可以设置应用程序的状态栏
4.进行应用之间的跳转.
0.打开程序
1.执行main函数.
2.执行UIApplicationMain,创建UIApplication对象,并设置UIApplication它的代理,3.开启了一个事件循环.(主运行循环,死循环:保证应用程序不退出)
4.去加载info.plist.(判断info.plist当中有没有main,如果有,加载main.storyBoard) 5.应用程序启动完毕.(通知代理应用程序启动完毕)
SceneDelegate \ AppDelegate
ios 13在sceneDelegate
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
UIViewController *vc = [[UIViewController alloc]init];
vc.view.backgroundColor = [UIColor redColor];
self.window.rootViewController = vc;
//显示窗口
[self.window makeKeyAndVisible];
}
AppDelegate
.h申明UIWindow
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (nonatomic, strong) UIWindow * window;
.m实现
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
通过xib加载控制器的View
//initWithNibName:如果指定了特定的名称的xib,会去加载指定的xib
//如果指定是nil
//1.判断有没有当前控制器相同名称的xib,如果有,自动加载跟它相同名称的xib(ViewController.xib
//2.如果没有跟它相同名称的xib.自动加载跟它相同名称并且是去掉controller(View.xib)
//init底层自动调用initwithNibName
ViewController *vc3 = [[ViewController alloc]initWithNibName:nil bundle:nil];
vc3.view.backgroundColor = UIColor.grayColor;
self.window.rootViewController = vc3;
return YES;
}
ViewController
时间顺序向下
当控件在xib、stroyboard加载出来 调用一次
\- (**void**)awakeFromNib {
[**super** awakeFromNib];
// Initialization code
}
控制器有子控件时会调用两次
当控制器的view将要布局子控件的时候调用
//当控制器的view将要布局子控件的时候调用
-(void)viewLayoutSubviews {
[super viewWillLayoutSubviews];
}
[self loadView];
才是控制器更改的view
//用来创建控制器的view
//当控制器的view,第一次使用的时候调用
-(void)loadView{
//1先判断当前控制器是不是从storyBoard当中加载的,如果是从storyBoard加载的控制器,那么它就会从storyBoard当中加载的控制器的View,设置当前控制器的view。
//2.当前控制器是不是从xib当中加载的,如果是从xib当中加载的话,把xib当中指定的View,设置为当前控制器的View.
//3.如果也不是从xib加载的,它会创建空白的view.
//一但重写了loadView方法,就说明要自己定义View.
//一般使用的场景:当控制器的View一显示时,就是一张图片,或者UIWebView.
//节省内存
}
如果当一个控制器被销毁,那么它View的业务逻辑是没有办法处理
控制器被销毁,控制器的View不一定被销毁(只要有强指针指向就不会被销毁
当view显示的时候调用drawRect
/// 专门用来绘图
/// 当view显示的时候调用
/// -[ViewController viewDidLoad]
/// [ViewController viewWillAppear:]
/// -[DrawView drawRect:]
/// -[ViewController viewDidAppear:]
/// @param rect 当前view的bounds
- (void)drawRect:(CGRect)rect {
// Drawing code
NSLog(@"%s",__func__);
}
//注意:drawRect如果是手动调用的话,它是不会给你创建跟View相关联的上下文
//只有系统调用该方法时,才会创建跟View相关联的上下文.
[self drawRect:self.bounds];
Quartz
绘制动态圆环
- (void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGPoint center = CGPointMake(rect.size.width / 2, rect.size.height / 2);
CGFloat radius = rect.size.width / 2 - 10;
CGFloat startA = -M_PI_2;
CGFloat angle = self.progressValue * M_PI * 2;
CGFloat endA = startA + angle;
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:true];
CGContextAddPath(ctx, path.CGPath);
CGContextStrokePath(ctx);
}
图片添加水印
self.imageV = [[UIImageView alloc]initWithFrame:CGRectMake(100, 300, 200, 200)];
//10.加载图片
UIImage *image = [UIImage imageNamed:@"2"];
//1.开启一个跟图片原始大小的上下文
//opaque;不透明度
UIGraphicsBeginImageContextWithOptions(image.size, false, 0); //2.把图片绘制到上下文当中
[image drawAtPoint: CGPointZero];
//3.把文字绘制到上下文当中
NSString *str=@"littleGenius";
[str drawAtPoint:CGPointMake(10,20) withAttributes:nil]; //4.从上下文当中生成一张图片(把上下文当中绘制的所有内容,生成一张图片)
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); //5.关闭上下文,
UIGraphicsEndImageContext();
self.imageV.image = newImage;
[self.view addSubview:_imageV];
部分贝塞斯圆角(iOS11以下使用)
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.tipLabel.bounds byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(5, 5)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.tipLabel.bounds;
maskLayer.path = maskPath.CGPath;
self.view.layer.mask = maskLayer;
swift
/// 部分圆角
///
/// - Parameters:
/// - corners: 需要实现为圆角的角,可传入多个
/// - radii: 圆角半径
/// layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMaxYCorner]
func corner(byRoundingCorners corners: UIRectCorner, radii: CGFloat) {
let maskPath = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radii, height: radii))
let maskLayer = CAShapeLayer()
maskLayer.frame = self.bounds
maskLayer.path = maskPath.cgPath
self.layer.mask = maskLayer
}
coreAnimation
核心动画
第1种动画 CABasicAnimation
旋转
//创建动画对象
CABasicAnimation *anim2 = [CABasicAnimation animation];
//设置属性值 放大缩小
anim2.keyPath = @"transform.scale";
anim2.toValue = @0.2;
//动画执行顺序
anim2.repeatCount = MAXFLOAT;
//动画时长
anim2.duration = 0.7;
//自动反转
anim2.autoreverses = true;
[self.imageV.layer addAnimation:anim2 forKey:nil];
#define angle2Rad(angle) ((angle) / 180.0 * M_PI)
anim. keyPath = a"transform.rotation";
anim. vaiues = @[@(angle2Rad(-5)),@(angle2Rad(5))];
//设置属性值 放大缩小
anim2.keyPath = @"transform.scale";
//设置属性值 右移动
anim.keyPath = @"position.x";
右移动
CABasicAnimation *anim = [CABasicAnimation animation];
//设置属性值 右移动
anim.keyPath = @"position.x";
anim.toValue = @300;
anim.removedOnCompletion = false;
anim.fillMode = kCAFillModeForwards;
[self.redView.layer addAnimation:anim forKey:nil];
第2种动画(转场动画)CATransition
转场代码与转场动画必须得在同一个方法当中。
//添加转场动画
CATransition *anim3 = [CATransition animation];
anim.duration = 1;
//设置转场的类型
anim3.type = @"push";
[self.imageV.layer addAnimation:anim forKey:nil];
核心动画没有修改frame的真实值,当有值需要更改的的时候需要转场动画
[UIView transitionWithView:<#(nonnull UIView *)#> duration:<#(NSTimeInterval)#> options:<#(UIViewAnimationOptions)#> animations:<#^(void)animations#> completion:<#^(BOOL finished)completion#>]
斜向布局
self.btn.layer.anchorPoint = CGPointMake(0.5,1);
self.btn.layer.position = CGPointMake(self.bounds.size.width *0.5,self. bounds.size.height *0.5);
//让第一个按钮在上一个基础上面旋转30.
self.btn.transform = CGAffineTransformMakeRotation(angle2Rad());
angle= 30;
重复显示
//复制层
CAReplicatorLayer *repL = [CAReplicatorLayer layer];
repL.frame= self.contentV.bounds;
[self.contentV.layer addSublayer:repL];
repL.instanceCount = 5;
repL.instanceTransform = CATransform3DMakeTranslation(45,0,0);
//设置复制出来的子层动画的延时时长
repL.instanceDelay = 1;
//创建一个振动条
CALayer *layer = [CALayer layer];
layer.backgroundColor = [UIColor redColor].CGColor;
layer.bounds = CGRectMake(0,0,30,100);
layer.anchorPoint = CGPointMake(0,1);
layer.position = CGPointMake(0,self.contentV.bounds.size.height);
[repL addSublayer:layer];
//添加动画
CABasicAnimation *anim = [CABasicAnimation animation];
anim.keyPath = @"transform.scale.y";
anim.toValue =@0;
anim. repeatCount = MAXFLOAT;
anim.duration = 1;
anim. autoreverses = YES;
[layer addAnimation:anim forKey:nil];