我们在项目中,往往会遇到两个 Navigation Bar 样式不同的问题,如果直接用苹果官方的控件,会出现各种各样的 bug,因为苹果官方的 Navigation Bar 是共用的,所以在两个不同样式的 Navigation Bar 中做转场操作的时候就会出现各种问题。
今天我们就用 Method Swizzling 的方式来修改一下系统的 Navigation Bar 转场时的样式,最终效果如下图所示:
设置导航栏的背景颜色
我们来为 UIViewController 添加一个扩展,用于存储与设置 Navigation Bar 各种属性。首先,我们来为我们的 UIViewController 添加一个 navBarBgColor 的计算属性。这里运用了 runtime 的关联方法 objc_getAssociatedObject: 和 objc_setAssociatedObject: 来存取所设置的背景颜色。
123456789101112131415extension UIViewController { /// 设置导航栏的背景颜色 public var n ...
最近做通知的时候需要对通知进行测试,之前没有做证书的经验,这次尝试了一下,写这篇文章备忘。
测试用的工具叫做 Pusher,下载地址:NWPusher。非常的好用。
创建测试用 Push 证书
1、打开苹果开发者页面:Developer,登录账户。
2、在账户的 Certificates, Identifiers & Profiles 页面找到 Identifiters,选择 App IDs。
3、找到自己 App,点击打开,能看到如下所示。
如果你没有配置 Push Notifications,那么它的 Development 和 Distribution 都是 Configurable 状态。点击 Edit 按钮。
我们要创建测试用的证书就点击 Development SSL Certificate 下面的 Create Certificate。
直接 Continue,接下来的页面需要我们上传 .certSigningRequest 的文件,这个文件需要在我们自己的电脑上制作。
制作 certSigningRequest 文件
1、打开电脑上的钥匙串应用。
2、点 ...
Swift 是一门面向协议的编程语言,为什么这么说,请看 WWDC 视频 Protocol-Oriented Programming in Swift。
通过闭包的方式为 UIControl 添加 action 的实现方式有很多种,例如:
123456789101112131415161718192021222324252627282930313233343536373839extension UIControl { func listen(_ action: @escaping () -> (), for controlEvents: UIControlEvents) -> AnyObject { let sleeve = ClosureSleeve(attachTo: self, closure: action, controlEvents: controlEvents) addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEv ...
今天在项目中遇到了隐藏 navigationbar 功能的问题,例如:从 A push到 B 页面,A 页面的 navigationbar 是隐藏的,但是 B 页面的 navigationbar 是需要显示的。
一开始我在 A 页面调用 setNavigationBarHidden(true, animated: true) 方法,在 B 页面调用 setNavigationBarHidden(false, animated: true) 方法,虽然能够达到想要的效果,但是对于项目来说是灾难性的。因为如果有多个地方出现这种情况的话,你的代码将会变得十分的杂乱臃肿。
一种好的解决方式是调用 navigationcontroller 的代理:
1navigationController(_:willShow:animated:)
将这个代理放在项目控制器的基类中,在这里我是放在我的基类 BaseViewController 中。为什么这么做?因为这样可以很好的去掉冗余的代码,不用写的到处都是,我的所有控制器都是继承自 BaseViewController 的,BaseViewContro ...
对 http 的抓包非常的简单,但是对 https 的抓包就有点麻烦了,主要麻烦在证书的安装与设置上。昨天由于有需要去抓https 的包,但是装好证书后,手机一直连不上,特此记录一下。
想要抓取 https 包,首先我们需要在电脑上安装一个 Charles Proxy 的证书
安装 Charles Root Certificate
1、依次点击:Help -> SSL Proxying -> Install Charles Root Certificate
2、打开我们系统的 钥匙串 应用,找到如下的证书(老版本的证书名字可能有所不同):
3、右键证书 -> 显示简介 -> 将信任设置成【始终信任】,如下所示:
至此,macOS 系统的证书安装完毕。
在 iOS 上安装证书
1、将手机 WiFi 的配置代理一项设置成手动,服务器一栏输入自己电脑的 IP 地址,端口一栏输入 8888,保存返回。
2、打开手机的浏览器,输入 chls.pro/ssl 打开这个网址,提示框选择允许,如下:
3、安装证书
4、信任证书【此步容易忘,注意】,设置 -> ...
尽管很多人了解 RxJava 的基本逻辑,但是在 Observable 链和操作符究竟运行在哪个线程,仍然会有许多困惑。
首先,让我们梳理清晰,在 RxJava 中 .subsribeOn() 和 .observeOn() 区别:
.subsribeOn() 操作符可以改变 Observable 应该在哪个调度器上执行任务。
.observeOn() 操作符可以改变 Observable 将在哪个调度器上发送通知。
另外,你需要知道,默认情况下,链上的操作符将会在调用 .subsribeOn() 的那个线程上执行任务。
一些例子
主线程或者 .subscribe() 所在线程如果在 Android 的 Activity下onCreate() 方法中,也就是主线程中使用如下代码:
12Observable.just(1,2,3) .subscribe( );
表现会像这样:
调用 .subscribeOn()尽管代码片段在主线程中,但是整个代码块将运行在 .subscribeOn() 定义的线程上:
123Observable.just(1,2,3) .subsc ...
好消息:Swift 4.2 现已在 Xcode 10 beta 中提供!此版本更新重要的 Swift 4.1 功能,并改进语言以准备 ABI 稳定性。
本教程介绍了 Swift 4.2 中最重要的变化。它需要 Xcode 10,因此请确保你在开始之前下载并安装 Xcode 的最新测试版。
前言
Swift 4.2 与 Swift 4.1 的源代码兼容,但与任何其他版本不兼容。 Apple 设计的 Swift 4.2 是在 Swift 5 中实现 ABI 稳定性的中间步骤,它应该能够在不同 Swift 版本编译的应用和库中保持二进制兼容。在集成到最终的 ABI 之前,ABI 功能会有大量的时间来获得来自社区的反馈。
本教程的部分包含 Swift Evolution 提案编号,如 [SE-0001] 。你可以通过点击每个提案的链接标签来浏览每个更改的详细信息。
如果你尝试了 playground 上的更改,你将从本教程中获得最大收益。启动 Xcode 10 并转到 File ▸ New ▸ Playgruond。选择 iOS 平台和 Blank 模版。把它命名为任何你喜欢的东西,然 ...
今天需要去打印店打印东西,但是 U 盘被我格式化成了 APFS 格式,用磁盘管理工具无法格式化成其他的格式,选项中只有 APFS 的选项。我用如下的命令格式化 U 盘:
1sudo diskutil eraseDisk JHFS+ san /dev/disk3
但是执行命令会报错,错误信息大致是,无法格式化 APFS 容器。
/dev/disk3 是我 U 盘的目录,在执行之前请先确认自己的目录,用如下的命令:
1diskutil list
APFS 格式是无法直接进行格式化的,我们需要首先删除 APFS 容器。执行如下命令:
1sudo diskutil apfs deleteContainer /dev/disk3
然后你就会发现,你的 U 盘格式自动变成了 Mac OS 扩展(日志式),之后就可以格式化成 exFAT 格式了。但是打印店识别不了,最后还是要在 windows 下格式化成 FAT32。
理解引用计数
Objective-C 语言使用引用计数来管理内存,也就是说,每个对象都有个可以递增或递减的计数器。如果想使某个对象继续存活,那就递增其引用计数;用完了之后,就递减其计数。计数变为 O,就表示没人关注此对象了,于是,就可以把它销毁。
引用计数工作原理Objective-C 中,调用 alloc 方法所返回的对象由调用者所拥有。也就是说,调用者已通过 alloc 方法表达了想令该对象继续存活下去的意愿。不过请注意,这并不是说对象此时的保留计数必定是 1。在 alloc 或。initWithInt: 方法的实现代码中,也许还有其他对象也保留了此对象,所以,其保留计数可能会大于 1。能够肯定的是:保留计数至少为 1。保留计数这个概念就应该这样来理解才对。绝不应该说保留计数一定是某个值,只能说你所执行的操作是递增了该计数还是递减了该计数。
123456789NSMutableArray *array = [[NSMutableArray alloc] init];NSNumber *number = [[NSNumber alloc] initWithInt:1337];[arr ...
在之前的一篇文章中【iOS 并发,锁,线程同步【一】GCD】,我们讨论了一下 GCD 的并发,锁和线程同步的问题,今天,我们来讨论一下 Operation 的并发与线程同步。
在 Operation 中,我们一般是将所有的 Operation 添加到 OperationQueue 中进行执行,这里需要注意一点,**Operation 添加到队列当中,默认就是执行的并发操作。我们可以设置队列的最大并发数 maxConcurrentOperationCount。如果我们在 OperationQueue 中想要执行串行任务的话,很简单,将 maxConcurrentOperationCount 设置成为1即可。 maxConcurrentOperationCount 的默认值为-1,那么默认情况下的并发数是多少呢?这个是由系统内存和 CPU 决定的,可能内存多久开多一点,内存少就开少一点。**最大并发数建议 2~3,如果并发数太多会导致 UI 卡顿。
不添加到队列当中的 Operation,我们可以调用 start() 方法开始一个操作,也可以调用 cancel() 取消等待中的操作,注意: ...