草帽Lee的博客


  • 首页

  • 分类

  • 归档

  • 标签

vi编辑工具常用命令

发表于 2019-03-13 | 分类于 Linux

vi常用命令

Charles抓取https请求 ssl证书问题

发表于 2018-08-21 | 分类于 iOS

如何使用Charles抓取https请求

设置Charles

1.Charles -> 工具栏 -> Proxy -> Proxy Setting

1.设置Port(默认8888)
2.勾选 Enable Transparent HTTP Proxying

设置Charles

2.Charles -> 工具栏 -> Proxy -> SSL Proxy Setting

1.勾选Enable SSL Proxying
2.在Location部份选择add,抓取任意站点、443端口的数据

设置Charles

设置手机代理

1.查看内网IP地址
Charles -> 工具栏 -> Help ->Local IP Addresses
2.手机设置代理端口
3.Safari中跳转 chls.pro/ssl 下载Charles证书
4.设置 -> 通用 -> 关于本机 -> 证书信任设置 -> 信任Charles证书

iOS响应者链、事件的传递

发表于 2018-06-21 | 分类于 iOS

##iOS响应者链、事件的传递

1、响应链的传递

Responder一点也不神秘————iOS用户响应者链完全剖析(建议全看)
看完上面一篇应该能完全熟悉了响应链的传递,自己可以打印一下响应链看看,代码如下:

- (IBAction)click:(id)sender {
    UIResponder *res = sender;

    while (res) {
        NSLog(@"*************************************\n%@",res);
        res = [res nextResponder];
    }
}

2、Hit-Test 机制

当用户触摸(Touch)屏幕进行交互时,系统首先要找到响应者(Responder)。系统检测到手指触摸(Touch)操作时,将Touch 以UIEvent的方式加入UIApplication事件队列中。UIApplication从事件队列中取出最新的触摸事件进行分发传递到UIWindow进行处理。UIWindow 会通过hitTest:withEvent:方法寻找触碰点所在的视图,这个过程称之为hit-test view。
hitTest 的顺序如下

UIApplication -> UIWindow -> Root View -> ··· -> subview

在顶级视图(Root View)上调用pointInside:withEvent:方法判断触摸点是否在当前视图内;

如果返回NO,那么hitTest:withEvent:返回nil;

如果返回YES,那么它会向当前视图的所有子视图发送hitTest:withEvent:消息,所有子视图的遍历顺序是从最顶层视图一直到到最底层视图,即从subviews数组的末尾向前遍历,直到有子视图返回非空对象或者全部子视图遍历完毕。

如果有subview的hitTest:withEvent:返回非空对象则A返回此对象,处理结束(注意这个过程,子视图也是根据pointInside:withEvent:的返回值来确定是返回空还是当前子视图对象的。并且这个过程中如果子视图的hidden=YES、userInteractionEnabled=NO或者alpha小于0.1都会并忽略);

如果所有subview遍历结束仍然没有返回非空对象,则hitTest:withEvent:返回self;

系统就是这样通过hit test找到触碰到的视图(Initial View)进行响应。

如果还不清楚Hit-Test 机制,看更加清晰的Hit-Test 机制(建议还不清楚的看)

3、手势的原理及与touches系列的关系,具体的可以看iOS触摸事件传递响应之被忽视的手势识别器工作原理(建议不看也没关系,结论在下面了。)

简而言之,就是下面这幅图了。触摸事件会优先分发给附在view的手势,在这段延迟的期间,如果手势被识别,那么view的touches系列将被立刻取消,如果没有被识别,那么会继续我们所熟知的touches系列流程。

4、实际开发中常见的相关问题

在实际开发中,经常会遇到视图没有响应的情况,特别是新手会经常搞不清楚状况。

一下是视图没有响应的几个情况:

1.userInteractionEnabled=NO;

2.hidden=YES;

3.alpha=0~0.01;

4.没有实现touchesBegan:withEvent:方法,直接执行touchesMove:withEvent:等方法;

5.目标视图点击区域不在父视图的Frame上 (superView背景色为clear Color的时候经常会忽略这个问题)。

5、手势代理

ios手势识别代理,看这个基本上就够了。引用文章中的一段话,如下:

  • 当时做项目时这个主控制器就是RootViewController,虽然用的是ScrollView但也没考虑到导航栏的手势返回的问题 ,现在做小区宝3.0的闪购订单,用之前的就有问题了。导航栏的返回手势用不了,根据响应者链和响应事件,手势被ScrollView识别了,就到不了导航的手势识别,所以导致无法手势返回。

我也曾经处理过这样的问题,不过我那时候是带有QQ的侧滑功能,主控制器用的View是ScrollView,导致不能侧滑。但是处理的方法都是一样的,自定义的ScrollView的代码重写gestureRecognizerShouldBegin方法如下,我是手势方向向右并且x轴起点小于60px的,让ScrollView的手势失效。这样就不会截获对应的事件了。但是其实看完上面,还有更简单的方法,就是让ScrollView的手势共存,但是这样可能会带来一些其它的问题。shouldRecognizeSimultaneouslyWithGestureRecognizer设置为true,不过应该要判断手势为UIScreenEdgePanGestureRecognizer时才return true,这样就可以了。

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    CGPoint velocity = [(UIPanGestureRecognizer *)gestureRecognizer velocityInView:self];
    CGPoint location = [gestureRecognizer locationInView:self];

    NSLog(@"velocity.x:%f----location.x:%d",velocity.x,(int)location.x%(int)[UIScreen mainScreen].bounds.size.width);
    if (velocity.x > 0.0f&&(int)location.x%(int)[UIScreen mainScreen].bounds.size.width<60) {
        return NO;
    }
    return YES;
} 

案例分析

案例一

下面这种做法,除非你很熟悉,否则不要这么干。因为 [super touchesBegan:touches withEvent:event];会执行原来默认的操作,如果按钮本来就没有添加对应的事件。那么[[self nextResponder] touchesBegan:touches withEvent:event];和[super touchesBegan:touches withEvent:event];将会向下一响应者发送两次事件。

-(void)touchesBegan:(NSSet<uitouch *> *)touches withEvent:(UIEvent *)event{
    if (self.enableNextResponder) {
        [[self nextResponder] touchesBegan:touches withEvent:event];
        [super touchesBegan:touches withEvent:event];
    }
}

案例二

Window
  -ViewA(能响应)
    -ButtonA
    -ViewB(不响应)

假设ViewB完全覆盖在ButtonA上,结果是:
ViewA能触发
Button没反应
ViewB没反应

简单来说,ViewB能阻隔ButtonA的响应,但是不能阻隔ViewA的响应。假设ViewB是个遮罩,那么并不是阻隔ViewA的事件触发。

案例三

一个按钮添加了点击事件到底发生了什么事儿。
我们有时候需要使用到一些特殊的情况,比如:
1、A包含B,AB都响应事件。
对于普通View,根据响应链,让B作为第一个响应者处理,然后B根据nextResponder传递触摸事件。
针对手势做分析:
手势不会走view的touches系列方法,但有自己的一系列touches方法,不过没有暴露出来。但是shouldRecognizeSimultaneouslyWithGestureRecognizer也可以做到。

针对UIButton的分析:
UIButton addTarget分析,addTarget是UIControl的方法,其实addTarget的方法原理是,UIControl对touches的触摸事件的封装。[super touchesBegan:touches withEvent:event];包括了对
事件的封装处理,如果重新了[super touchesBegan:touches withEvent:event];,并且里面什么都不实现,那么当前UIButton添加的addTarget所绑定的所有事件都不会触发。因为覆盖了父类UIControl的封装方法。
如果我想一个按钮的事件触发,并且它的下一响应者也能触发相应的事件。那么该怎么处理呢?
我们在按钮上处理,重写touchesBegan系列的方法,那么根据上面所说,必须要调用super的方法,并且主动像下一响应者[self nextResponder]发送touchesBegan系列的方法。

2、A包含B、C,C在B的上面,但是想让B接收事件,C不接收事件
这种可以这么处理,自定义C的View,重写hitTest:withEvent方法,返回nil,这样自定义C的View及其子类都不会拦截事件。这样B就可以顺利处理事件。
还可以把C的userInteractionEnabled设置为NO

3、A是B、C的父视图,C在B的上面,这时候,CB都处理事件。这样到底行不行?根据响应链,这样应该是不靠谱的了。在C的touches方法中调用C的touches方法,然后重写B的touches方法,但是这样怪怪的。有什么高招也请多多指教。貌似也没有这样的必要。

最后还发现了一篇一步到位的iOS响应者链的全过程:iOS触摸事件的流动(想有更清晰的了解的看)
直接引用里面的一张图:

iOS响应者链

参考资料:
响应者链及相关机制总结

iPhoneX适配

发表于 2017-10-23 | 分类于 iOS

一. iPhone手机各版本尺寸

机型 发布时的系统 屏幕尺寸 比例 pt 像素
iPhone4 iOS 4 3.5英寸 3:2 320*480pt 960X640
iPhone4S iOS 5 3.5英寸 3:2 320*480pt 960X640
iPhone5 iOS 6 4英寸 16:9 320*568pt 1136X640
iPhone5C/5S iOS 7 4英寸 16:9 320*568pt 1136X640
iPhone6 iOS 8 4.7英寸 16:9 375*667pt 1334X750
iPhone6Plus iOS 8 5.5英寸 16:9 414*736pt 1920X1080
iPhone6S iOS 9 4.7英寸 16:9 375*667pt 1334X750
iPhone6SPlus iOS 9 5.5英寸 16:9 414*736pt 1920X1080
iPhoneSE iOS 9 4英寸 16:9 320*568pt 1136X640
iPhone7 iOS 10 4.7英寸 16:9 375*667pt 1334X750
iPhone7Plus iOS 10 5.5英寸 16:9 414*736pt 1920X1080
iPhone8 iOS 11 4.7英寸 16:9 375*667pt 1334X750
iPhone8Plus iOS 11 5.5英寸 16:9 414*736pt 1920X1080
iPhoneX iOS 11 5.8英寸 18:9 375*812pt 2436X1125
iPhoneXs iOS 12 5.8英寸 18:9 375*812pt 2436X1125
iPhoneXr iOS 12 6.1英寸 18:9 414*896pt 1792X828
iPhoneXs Max iOS 12 6.5英寸 18:9 414*896pt 2688X1242
阅读全文 »

Library not loaded问题

发表于 2017-05-02 | 分类于 iOS

Xcode8报错 Library not loaded:

/System/Library/Frameworks/UserNotifications.framework/UserNotifications

调试时Xcode报错

低版本手机中 UserNotifications框架不支持
Target下的Build Phases标签里,找到Link Binary With Libraries,在里面找到UserNotifications.framework,把status由Required修改成Optional

WKWebView问题

发表于 2017-04-28 | 分类于 iOS

WKWebView无法响应H5页面中的location.href

根据WKWebView代理方法 WKNavigationDelegate拦截location.herf动作

1
2
3
4
5
6
7
8
9
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
if (![navigationAction.request.URL.absoluteString containsString:@"http://"] && ![navigationAction.request.URL.absoluteString containsString:@"https://"]) {

}
decisionHandler(WKNavigationActionPolicyCancel);
} else {
decisionHandler(WKNavigationActionPolicyAllow);
}
}

WKWebView如何使用JS调用原生方法

1.设置WKScriptMessageHandler,注册js方法

1
2
3
4
5
WKWebViewConfiguration *config = [WKWebViewConfiguration new];
self.userContent = [[WKUserContentController alloc] init];
[self.userContent addScriptMessageHandler:self name:@"JSFuncName"];
config.userContentController = self.userContent;
WKWebView *webv = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config];

2.实现WKWebView的WKScriptMessageHandler代理方法

1
2
3
4
5
6
7
8
9
10
-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
NSString *scriptName = message.name;
NSLog(@"%@", message.body);
if([scriptName isEqualToString:@"JSFuncName"]){
NSLog(@"To Do Something");
}


}

NSMutableArray删除时遇到的问题

发表于 2016-09-20 | 分类于 iOS

一. removeObjectAtIndex和removeObject的不同之处

removeObjectAtIndex:
删除指定NSMutableArray中指定index的对象,注意index不能越界。

removeObject:
删除NSMutableArray中所有isEqual:待删对象的对象

从API文档可以看出,两者之间的主要区别是removeObjectAtIndex:最多只能删除一个对象,而removeObject:可以删除多个对象(只要符合isEqual:的都删除掉)。

阅读全文 »

svn

发表于 2016-07-23 | 分类于 iOS

一. 查看当前文件下修改

1
svn status

二. 提交当前文件夹下修改文件

1
2
a. svn ci -m "还原confi.h文件 " Additions/heads/Config.h (单个文件)
b. svn ci -m “添加多个文件 “空格” 间隔 text1.h text2.h (多个文件)
阅读全文 »

markdown语法

发表于 2016-06-16 | 分类于 js

markdown是一种纯文本格式的标记语言。通过简单的标记语法,它可以使普通文本内容具有一定的格式。

一、标题

在想要设置为标题的文字前面加#来表示
一个#是一级标题,二个#是二级标题,以此类推。支持六级标题。

注:标准语法一般在#后跟个空格再写文字,貌似简书不加空格也行。

阅读全文 »

cocoaPods的使用

发表于 2016-05-19 | 分类于 iOS

一、什么是CocoaPods

每种语言发展到一个阶段,就会出现相应的依赖管理工具,例如 Java 语言的 Maven,nodejs 的 npm。随着 iOS 开发者的增多,业界也出现了为 iOS 程序提供依赖管理的工具,它的名字叫做:CocoaPods。

阅读全文 »
12
Lee

Lee

Nevermore

13 日志
4 分类
12 标签
RSS
Github Email
友情链接
  • liyilian
  • caomaolee
© 2020 Lee
由 Hexo 强力驱动
主题 - NexT.Pisces