iOS梦工厂

iCocos——不战胜自己,何以改变未来!

cocoaPods简单粗暴

| Comments

直接上代码,不要问为什么,照着做就可以,我也是这么做的,具体的细节,请查看相关文档,网上太多!

1:移除ruby镜像(天朝的网你们懂的)

 $ gem sources --remove https://rubygems.org/ 

屏幕旋转的奥妙

| Comments

一,决定当前UIViewController显示方向的因素

1,全局控制

工程设置中设置支持的Device Orientation,如果这里没有设置其中的一个方向,即使后面的UIViewController中配置了改方向,也是不会起作用的。实际上就是设置工程plist文件的Supported interface orientations属性。

2,配置AppDelegate

配置AppDelegate的如下方法返回需要用到的全部方向集合,如果要支持多个方向,一般都返回UIInterfaceOrientationMaskAll

- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window{
    return UIInterfaceOrientationMaskAll;
}

似乎该方法默认值为Info.plist中配置的Supported interface orientations项的值。

3,自定义UIViewController,并实现如下orientation相关的三个方法(iOS6以后):

折叠复制内容到剪贴板

//是否支持多方向旋转屏,会考察当前设备方向和支持的方向。一些文档上说shouldAutorotate如果返回NO则不会执行下面两个方法纯属扯淡。  
-(BOOL)shouldAutorotate  
{  
    return YES;  
}  
//第二个方法返回支持的旋转方向  
-(UIInterfaceOrientationMask)supportedInterfaceOrientations  
{  
    return [self.viewControllers.lastObject supportedInterfaceOrientations];  
}  

返回最优先显示的屏幕方向,比如同时支持Portrait和Landscape方向,但想优先显示Landscape方向,那软件启动的时候就会先显示Landscape,在手机切换旋转方向的时候仍然可以在Portrait和Landscape之间切换;  

-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation  
{  
    return [self.viewControllers.lastObject preferredInterfaceOrientationForPresentation];  
}  

  以上三个规则在每一个UIViewController中都会得到一个方向的交集集合,就是最终显示的方向。如果交集为空,会抛出UIApplicationInvalidInterfaceOrientationException崩溃异常。

二,典型的控制方案

另外一个非常重要的点就是并不是每一个UIViewController都会主动执行以上三个方法,根据特酷吧的实验,发现:

  • 1,当UIViewController是rootViewController(Device Orientation方向变化时会主动执行)
  • 2,当UIViewController是UINavigationController(Device Orientation方向变化时会主动执行)
  • 3,当UIViewController以modal模态形式弹出时会主动执行。 一个典型的方案是,我们就可以在UINavigationController中这样写:

折叠复制内容到剪贴板

-(BOOL)shouldAutorotate  
{  
    return YES;  
}  
-(UIInterfaceOrientationMask)supportedInterfaceOrientations  
{  
    return [self.viewControllers.lastObject supportedInterfaceOrientations];//主动调用UIViewController对应的方法,达到在UIViewController中自定义的效果  
}  
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation  
{  
    return [self.viewControllers.lastObject preferredInterfaceOrientationForPresentation];  
}  

  接下来就只需要自定义各自的VC

-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;//根据需要
}
- (BOOL)shouldAutorotate
{
    return NO;//根据需要
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationPortrait;//根据需要
}

事实上在作为一个UINavigationController的堆栈系统,普通的UIViewController的orientation方法只是一个配置项,最终决定屏幕方向的还是UINavigationController控制器,也就是UINavigationController拿UIViewController得配置决定当前控制器的方向。

三,强制屏幕旋转

如果UIInterfaceOrientation和UIDeviceOrientation方向不一样,想强制将UIInterfaceOrientation旋转成UIDeviceOrientation的方向,可以通过l类方法attemptRotationToDeviceOrientation,但是如果想将interface强制旋转成任一指定方向,就不太好实现了。目前大致有以下几种方式:

1,使用私有方法

折叠复制内容到剪贴板

[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait];  

具体可以这样:  

         if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {  
        SEL selector = NSSelectorFromString(@"setOrientation:");  
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];  
        [invocation setSelector:selector];  
        [invocation setTarget:[UIDevice currentDevice]];  
        int val = UIInterfaceOrientationLandscapeRight;  
        [invocation setArgument:&val atIndex:2];  
        [invocation invoke];  
    }  

 

2,主动触发orientation相关方法

只要提前设置好想要支持的orientation,然后主动触发orientation机制,使新设置的orientation起作用便能实现将 interface orientation旋转至任意方向的目的。像这样:

UIViewController *vc = [[UIViewController alloc]init]; 
[self presentModalViewController:vc animated:NO]; 
[self dismissModalViewControllerAnimated:NO]; 
3、旋转view的transform

前两种都是试图触发orientation相关方法,第三种可能会造成一些不可预知的风险不推荐。



微信号:

clpaial10201119(Q Q:2211523682)

微博WB:

http://weibo.com/u/3288975567?is_hot=1

gitHub:

https://github.com/al1020119

博客

http://al1020119.github.io/


站在AFN上看ASI

| Comments

一、底层实现
  • 1> AFN的底层基于OC的NSURLConnection和NSURLSession

  • 2> ASI的底层基于纯C语言的CFNetwork框架

  • 3> ASI的运行性能 高于 AFN

底层开发之越狱开发

| Comments

做越狱开发也有一些时间了,有很多东西想总结一下,希望给他人一些借鉴,也是自己对过去开发经历的一些总结。个人不推荐使用盗版,这里主要以技术介绍为主。

这个系列里面主要介绍怎样进行越狱开发,涉及到以下几个方面:

谈谈KVC与KVO精髓

| Comments

Swift中使用KVC和KVO的类都必须必须继承自NSObject

由于ObjC主要基于Smalltalk进行设计,因此它有很多类似于Ruby、Python的动态特性,例如动态类型、动态加载、动态绑定等。今天我们着重介绍ObjC中的键值编码(KVC)、键值监听(KVO)特性:

  • 键值编码KVC
  • 键值监听KVO

消除警告

| Comments

前言:

现在你维护的项目有多少警告?看着几百条警告觉得心里烦么?你真的觉得警告又不是错误可以完全不管么? 如果你也被这些问题困惑,可以和我一起进行下面的操作。其实大部分的警告都是很好改的,把自己整个项目的警告撸一遍应该也就耗费半小时的时间,一次麻烦带来之后的清净这样不好么?

本文分为三个部分:

  • 1.简单粗暴的消除警告。
  • 2.详细科学的消除警告。(包括警告收录)
  • 3.添加警告。

Block实战

| Comments

说到block,相信大部分iOS开发者都会想到retain cycle或是__block修饰的变量。但是本文将忽略这些老生常谈的讨论,而是将重点放在美团iOS在实践中对block的应用,希望能对同行有所助益。本文假设读者对block有一定的了解。

从闭包说起 在Lisp这样的语言中,有一个概念叫做闭包(closure1),指的是一个函数以及它所处的词法作用域(lexical scope2)构成的整体。为了理解闭包,我们首先来看看什么是词法作用域。

分类深究

| Comments

摘要 无论一个类设计的多么完美,在未来的需求演进中,都有可能会碰到一些无法预测的情况。那怎么扩展已有的类呢?一般而言,继承和组合是不错的选择。但是在Objective-C 2.0中,又提供了category这个语言特性,可以动态地为已有类添加新行为。如今category已经遍布于Objective-C代码的各个角落,从Apple官方的framework到各个开源框架,从功能繁复的大型APP到简单的应用,catagory无处不在。本文对category做了比较全面的整理,希望对读者有所裨益。

简介 本文作者来自美团酒店旅游事业群iOS研发组。我们致力于创造价值、提升效率、追求卓越。欢迎大家加入我们(简历请发送到邮箱majia03@meituan.com)。 本文系学习Objective-C的runtime源码时整理所成,主要剖析了category在runtime层的实现原理以及和category相关的方方面面,内容包括:

  • 初入宝地-category简介
  • 连类比事-category和extension
  • 挑灯细览-category真面目
  • 追本溯源-category如何加载
  • 旁枝末叶-category和+load方法
  • 触类旁通-category和方法覆盖
  • 更上一层-category和关联对象

方法缓存

| Comments

摘要 只要用到Objective-C,我们每天都会跟方法调用打交道。我们都知道Objective-C的方法决议是动态的,但是在底层一个方法究竟是怎么找到的,方法缓存又是怎么运作的却鲜为人知。本文主要从源码角度探究了Objective-C在runtime层的方法决议(Method resolving)过程和方法缓存(Method cache)的实现。

简介 本文作者来自美团酒店旅游事业群iOS研发组。我们致力于创造价值、提升效率、追求卓越。欢迎大家加入我们(简历请发送到邮箱 majia03@meituan.com )。

本文系学习Objective-C的runtime源码时整理所成,主要剖析了Objective-C在runtime层的方法决议过程和方法缓存,内容包括:

  • 从消息决议说起
  • 缓存为谁而生
  • 追本溯源,何为方法缓存
  • 缓存和散列
  • 十万个为什么
  • 缓存 - 性能优化的万金油?
  • 优化,永无止境
  • 从消息决议说起

怎么封装一个控件

| Comments

一个控件从外在特征来说,主要是封装这几点:

  • 交互方式
  • 显示样式
  • 数据使用

对外在特征的封装,能让我们在多种环境下达到 PM 对产品的要求,并且提到代码复用率,使维护工作保持在一个相对较小的范围内;而一个好的控件除了有对外一致的体验之外,还有其内在特征:

  • 灵活性
  • 低耦合
  • 易拓展
  • 易维护