iOS面试资料搜集iOS面试

iOS | 面试知识整理 - UI 相关 (四)

2019-08-16  本文已影响0人  Leon_520

前言:

最近公司项目不怎么忙, 闲暇时间把iOS 在面试中可能会遇到的问题整理了一番, 一部分题目是自己面试遇到的,一部分题目则是网上收录的, 方便自己巩固复习, 也分享给大家! 知识点比较多,比较杂,这里做了分类,下面是分类链接地址;

面试知识点整理 - 目录:

iOS | 面试知识整理 - OC基础 (一)
iOS | 面试知识整理 - OC基础 (二)
iOS | 面试知识整理 - OC基础 (三)
iOS | 面试知识整理 - UI 相 关 (四)
iOS | 面试知识整理 - 内存管理 (五)
iOS | 面试知识整理 - 多 线 程 (六)
iOS | 面试知识整理 - 网络相关 (七)
iOS | 面试知识整理 - 数据持久化 (八)
iOS | 面试知识整理 - Swift 基础 (九)

iOS | 面试知识整理 - UI 相关 (四)

1.ViewController 生命周期

单个viewController的生命周期

- initWithCoder:(NSCoder *)aDecoder:(如果使用storyboard或者xib)
- loadView:加载view
- viewDidLoad:view加载完毕
- viewWillAppear:控制器的view将要显示
- viewWillLayoutSubviews:控制器的view将要布局子控件
- viewDidLayoutSubviews:控制器的view布局子控件完成  
- viewDidAppear:控制器的view完全显示
- viewWillDisappear:控制器的view即将消失的时候
- viewDidDisappear:控制器的view完全消失的时候
- dealloc 控制器销毁

两个控制器AB进行跳转调用顺序:

A控制器先展示调用

 - [ViewControllerA loadView]
 - [ViewControllerA viewWillAppear:]
 - [ViewControllerA viewWillLayoutSubviews]
 - [ViewControllerA viewDidLayoutSubviews]
 - [ViewControllerA viewDidAppear:]

B控制器跳转调用顺序

 - [ViewControllerB loadView]
 - [ViewControllerB viewDidLoad]
 - [ViewControllerA viewWillDisappear:]
 - [ViewControllerB viewWillAppear:]
 - [ViewControllerB viewWillLayoutSubviews]
 - [ViewControllerB viewDidLayoutSubviews]
 - [ViewControllerA viewDidDisappear:]
 - [ViewControllerB viewDidAppear:]

B控制器返回A顺序

 - [ViewControllerB viewWillDisappear:]
 - [ViewControllerA viewWillAppear:]
 - [ViewControllerB viewDidDisappear:]
 - [ViewControllerA viewDidAppear:]

2. CALayer 和 UIView

3.UIView 的frame,bounds,center

4.CALayer的frame,bounds,anchorPoint,position

5.iOS 为什么必须在主线程中操作UI

6. 如何处理UITableVier 中Cell 动态计算高度的问题,都有哪些方案

7. AutoLayout 中的优先级是什么?

AutoLayout中添加的约束也有优先级,优先级的数值是1~1000

8. 怎么高效的实现控件的圆角效果?

//直接对图片进行重绘 (使用Core Graphics),实际开发加异步处理,也可以给 SDWebImage 也做扩展;

 - (UIImage *)imageWithCornerRadius:(CGFloat)radius {
        CGRect rect = (CGRect){0.f, 0.f, self.size};
        UIGraphicsBeginImageContextWithOptions(self.size, NO, UIScreen.mainScreen.scale);
        CGContextAddPath(UIGraphicsGetCurrentContext(), [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius].CGPath);
        CGContextClip(UIGraphicsGetCurrentContext());
        [self drawInRect:rect];
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return image;
    }

// 利用CAShapeLayer圆角,替换原本的layer,达到圆角效果

 UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:self.bounds.size];
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
    maskLayer.frame = self.bounds;
    maskLayer.path = maskPath.CGPath;
    self.layer.mask = maskLayer;

9.CALayer如何添加点击事件

  1. 通过 touchesBegan: withEvent 方法,监听屏幕点击事件,在这个方法中通过 convertPoint 找到点击位置,进行判断,如果点击了 layer 视图内坐标,就触发点击事件
  2. 通过 hitTest方法找到包含坐标系的 layer 视图
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//  方法一,通过 convertPoint 转为为 layer 坐标系进行判断
    CGPoint point = [[touches anyObject]   locationInView:self.view];
    CGPoint redPoint = [self.redLayer  convertPoint:point fromLayer:self.view.layer];
    if ([self.redLayer containsPoint:redPoint]) {
    NSLog(@"点击了calayer");
    }
//  方法二 通过 hitTest 返回包含坐标系的 layer 视图
    CGPoint point1 = [[touches anyObject] locationInView:self.view];
    CALayer *layer = [self.view.layer hitTest:point1];
    if (layer == self.redLayer) {
       NSLog(@"点击了calayer");
    }
}

10.介绍下layoutSubview和drawRect

11. layoutIfNeeded , layoutSubViews和 setNeedsLayout区别?

12.假如Controller太臃肿,如何优化?

  1. 将网络请求抽象到单独的类中,方便在基类中处理公共逻辑;方便在基类中处理缓存逻辑,以及其它一些公共逻辑;方便做对象的持久化。
  2. 将界面的封装抽象到专门的类中, 构造专门的 UIView 的子类,来负责这些控件的拼装。这是最彻底和优雅的方式,不过稍微麻烦一些的是,你需要把这些控件的事件回调先接管,再都一一暴露回 Controller。
  3. 构造 ViewModel, 借鉴MVVM。具体做法就是将 ViewController 给 View 传递数据这个过程,抽象成构造 ViewModel 的过程。
  4. 专门构造存储类,专门来处理本地数据的存取。
  5. 整合常量

13.程序启动过程

main 函数执行前:

  1. 首先当程序启动时,系统会读取程序的可执行文件(mach-o), 从里面获取动态加载器(dylb)的路径;
  2. 加载dylb, dylb会初始化运行环境,配合ImageLoader将二进制文件加载到内存中去;
  3. 动态链接依赖库, 初始化依赖库,初始化 runtime;
  4. runtime 会对项目中的所有类进行类结构初始化,调用所有的 load 方法;
  5. 最后 dylb 会返回 main 函数地址,main 函数被调用,进入程序入口

main 函数执行后:

  1. 内部会调用 UIApplicationMain 函数,创建一个UIApplication对象和它的代理,就是我们项目中的 Appdelegate 类
  2. 开启一个事件循环(main runloop), 监听系统事件
  3. 程序启动完毕时,通知代理Appdelegate, 调用 didFinishLaunching 代理方法,在这里会创建 UIWindow,设置它的rootViewController,
  4. 最后调用 self.window makeKeyAndVisable显示窗口

14.渲染以及图像显示原理过程?

15.离屏渲染是什么

16. 那些情况会造成离屏渲染?

  1. 为图层设置遮罩(layer.mask)
  2. 将图层的layer.masksToBounds / view.clipsToBounds属性设置为true
  3. 将图层layer.allowsGroupOpacity属性设置为YES和layer.opacity小于1.0
  4. 为图层设置阴影(layer.shadow *)。
  5. 为图层设置layer.shouldRasterize=true
  6. 具有layer.cornerRadius,layer.edgeAntialiasingMask,layer.allowsEdgeAntialiasing的图层
  7. 文本(任何种类,包括UILabel,CATextLayer,Core Text等)。

17.手机适配方案

  1. 使用宏,针对不同的设备抽取导航,状态栏,以及 tabbar 高度信息
  2. 宽高等比适配(X 的特殊处理)
  3. 图片美工需要提供@2x,@3x进行适配
  4. 字体根据屏幕大小适配
  5. 权限针对不同系统进行适配
  6. api 适配

18. 什么是懒加载?

懒加载 也叫做 延迟加载,他的核心思想就是把对象的实例化尽量延迟,在需要使用的时候才会初始化,这样做的好处可以减轻大量对象实例化对资源的消耗.
另外懒加载把对象的实例化代码抽取出来独立出来,提高代码的可读性,以便代码更好的被组织

19.什么是响应者链?

响应者链是用于确定事件响应的一种机制, 事件主要是指触摸事件(touch Event),该机制与UIKIT中的UIResponder类密切相关,响应触摸事件的必须是继承自UIResponder的类,比如UIView 和UIViewController

一个事件响应者的完成主要分为2个过程: hitTest方法命中视图和响应者链确定响应者; hitTest的调用顺序是从UIWindow开始,对视图的每个子视图依次调用,也可以说是从显示最上面到最下面,直到找命中者; 然后命中者视图沿着响应者链往上传递寻找真正的响应者.

事件传递过程

// 返回能够相应该事件的视图
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event  
// 查看点击的位置是否在这个视图上
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 

响应链传递

无法响应的事件情况

20.动画相关有哪几种方式?

    [UIView animateWithDuration: 10 animations:^{
        // 动画操作
    }];
1. CABasicAnimation——基本动画
2. CAKeyframeAnimation——关键帧动画
     与CABasicAnimation的区别是:CABasicAnimation:只能从一个数值(fromValue)变到另一个数值(toValue)CAKeyframeAnimation:会使用一个NSArray保存这些数值
3. CAAnimationGroup——动画组
    动画组,是CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行
4. 转场动画——CATransition
    CATransition是CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。iOS比Mac OS X的转场动画效果少一点。

21. UIScrollView 原理

23. loadView 的作用?

24. IBOutlet 连出来的视图属性为什么可以被设 置成 weak?

25.请简述 UITableViewCell的复用机制

26.使用 drawRect 有什么影响?

27.能否在一个控制器 嵌入2个 TableViewController 控制器

28.一个 TableView 是否可以关联2个不同的dataSource?

29.masksToBounds 和clipsToBounds

30.tintColor 是什么?

31.imageNamed 和 imageWithContentsOfFile区别

32.View 和 View 传值方式有哪些

  1. 通过视图类对外提供的属性直接传值
  2. 通过代理传值
  3. 通过通知传值
  4. 通过 Block 传值
  5. 通过NSUserDefault, 不建议

33. 为什么iOS提供 UIView 和CAlayer 两个个平行的层级结构

34.UIWindow是什么,有什么特点?

35. 什么是隐式动画和显示动画

    [UIView animateWithDuration:1 animations:^{
        view.center = self.view.center;
    }];
CABasicAnimation *positionAnima = [CABasicAnimation animationWithKeyPath:@"position.y"];
positionAnima.duration = 0.8;
positionAnima.fromValue = @(self.imageView.center.y);
positionAnima.toValue = @(self.imageView.center.y-30);
positionAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
positionAnima.repeatCount = HUGE_VALF;
positionAnima.repeatDuration = 2;
positionAnima.removedOnCompletion = NO;
positionAnima.fillMode = kCAFillModeForwards;
[self.imageView.layer addAnimation:positionAnima forKey:@"AnimationMoveY"];

36. UIButton 和UITableView的层级结构

37. Storyboard/xib 和 纯代码UI相比,有哪些优缺点

优点:

缺点:

38.AutoLayout 和 Frame在UI布局和渲染上有什么区别?

39.SafeArea, SafeAreaLayoutGuide, SafeAreaInsets 关键词的比较说明?

由于 iphoneX 采用了刘海设计,iOS11引入了安全区域(SafeArea)概念

40.UIScrollView 的 contentView, contentInset, contentSize, contentOffset 关键字比较?

41. 图片png与jpg的区别是什么?

下一篇入口:

iOS | 面试知识整理 - 内存管理 (五)

上一篇下一篇

猜你喜欢

热点阅读