UIKit笔记

  • UIView与display相关的功能都在CALayer中,UIView仅给CALayer添上touch处理功能。 例如,UIView的位置相关信息保存在view.layer的四个属性中,view.frame根据它们导出:

    • view.layer.position == view.center
    • view.layer.bounds == view.bounds
    • view.layer.anchorPoint
    • view.layer.transform
  • view.layer.anchorPoint默认为(0.5,0.5),要将其设为view中另一点point:

    1
    2
    3
    CGSize viewSize = view.frame.size;
    view.layer.anchorPoint = CGPointMake(point.x/viewSize.width, point.y/viewSize.height);
    view.layer.position = point;

  • view.bounds指定view自己的坐标系统内正被观察到的矩形区域。比如,scrollView在scrolling时其实只是改变scrollView.bounds.origin (即scrollView.contentOffset),而scrollView.contentSize只是和scrollView.bound.size一起限制scrollView.bounds.origin的变动范围。参见:Understanding UIScrollView

    view.frame.origin是view在其父view的坐标系统内的位置(由view.center配合view.layer.anchorPoint、view.bounds.size导出),而view.frame.size就是view.bounds.size。

  • UIWindow含多个subview时,只有其root view才能自动处理autorotation。

  • [viewController presentViewController:animated:completion:]时会把presentingViewController.view加到viewController.view.superview中,这superview是个隐藏节点UITransitionView

  • ContainerViewController(iOS5起引入)继承UIViewController,添加childViewController时:

      1. [self addChildViewController:childViewController]; 
      // 1. will send [childViewController willMoveToParentViewController:self];  
      2. [self.view addSubview:childViewController.view];
      3. [childViewController didMoveToParentViewController:self];

    移除childViewController时:

      1. [childViewController willMoveToParentViewController:nil];
      2. [childViewController.view removeFromSuperview];
      3. [childViewController removeFromParentViewController];
      // 3. will send [childViewController didMoveToParentViewController:nil];

    参考:Implementing Container Containment – Sliding Menu Controller

  • 要是创建项目时没有勾选Use Storyboard,从程序中加载storyboard要在application:didFinishLaunchingWithOptions:中:

      // self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
      UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
      self.window.rootViewController = [storyboard instantiateInitialViewController];
      // [self.window makeKeyAndVisible];

    注:若打开第1行注释重设self.window,iOS8中需要在[YourApp]-Info.plist中去掉UIMainStoryboardFile值。

  • scrollViewWillEndDragging:withVelocity:targetContentOffset:targetContentOffset参数可以决定scrollView滑动停止在哪儿

RunloopMode

Runloop只会处理其mode中输入源:

  • default mode包含大部分输入源、定时器等
  • tracking mode处理UI事件(如scrollView滚动/减速等)
  • common modes = default mode | event mode

定时器运行在default mode,scrollView滚动等UI事件肯能block定时器准时执行,可把定时器设成common modes:

1
2
3
4
5
6
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 
target:self
selector:@selector(handleTimer:)
userInfo:nil
repeats:NO]
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
1
2
3
4
[self performsSelector:@selector(performDelayedWork)
withObject:nil
afterDelay:1.0
inModes:@[NSRunLoopCommonModes]];

参考: