OC学习2021-08

4 篇文章 0 订阅

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];

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值