轩辕十四

探索科技与创新的个人博客

在将项目迁移到 Swift 3.1 后,我受到了几个警告的欢迎。它们似乎都没有特别难以修复,只是除了这个之外:

Method ‘initialize()’ defines Objective-C class method ‘initialize’, which is not guaranteed to be invoked by Swift and will be disallowed in future versions.

Ouch。一些类重写了 NSObjectinitialize() 函数,警告清楚地表明这已不在合适(或者至少,但它应该不会很快发生)。一个非常类似的方法 - load(),它自 Swift 1.2 以来一直没有,所以看起来初始化将很快跟进。它扮演着一个独特的角色,如 NSObject 文档所述:

The runtime sends initialize() to each class in a program just before the class, or any class that inherits from it, is sent its first message from within the program.

阅读全文 »


我有一个带有 largeTitlesearchcontrollernavigationBar ,我的 tableView 有一个 refreshcontrol

当我拉动刷新时,refreshcontrolactivityIndicator 消失了,但是刷新过程仍然在继续,即使进程完成并且我调用 UIRefreshControllendRefreshing() 方法,导航栏也不会恢复到正常大小。

有人遇到过同样的问题吗?

阅读全文 »

我们在项目中,往往会遇到两个 Navigation Bar 样式不同的问题,如果直接用苹果官方的控件,会出现各种各样的 bug,因为苹果官方的 Navigation Bar 是共用的,所以在两个不同样式的 Navigation Bar 中做转场操作的时候就会出现各种问题。

今天我们就用 Method Swizzling 的方式来修改一下系统的 Navigation Bar 转场时的样式,最终效果如下图所示:

设置导航栏的背景颜色


我们来为 UIViewController 添加一个扩展,用于存储与设置 Navigation Bar 各种属性。首先,我们来为我们的 UIViewController 添加一个 navBarBgColor 的计算属性。
这里运用了 runtime 的关联方法 objc_getAssociatedObject:objc_setAssociatedObject: 来存取所设置的背景颜色。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
extension UIViewController {
/// 设置导航栏的背景颜色
public var navBarBgColor: UIColor {
get {
if let color = objc_getAssociatedObject(self, &DefaultValue.navBarBgColor) as? UIColor {
return color
}
return DefaultValue.navBarBgColor
}
set {
objc_setAssociatedObject(self, &DefaultValue.navBarBgColor, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
navigationController?.navBarBackgroundColor(newValue)
}
}
}
阅读全文 »

最近做通知的时候需要对通知进行测试,之前没有做证书的经验,这次尝试了一下,写这篇文章备忘。

测试用的工具叫做 Pusher,下载地址:NWPusher。非常的好用。

创建测试用 Push 证书


1、打开苹果开发者页面:Developer,登录账户。

2、在账户的 Certificates, Identifiers & Profiles 页面找到 Identifiters,选择 App IDs

3、找到自己 App,点击打开,能看到如下所示。

如果你没有配置 Push Notifications,那么它的 DevelopmentDistribution 都是 Configurable 状态。点击 Edit 按钮。

我们要创建测试用的证书就点击 Development SSL Certificate 下面的 Create Certificate

阅读全文 »

Swift 是一门面向协议的编程语言,为什么这么说,请看 WWDC 视频 Protocol-Oriented Programming in Swift

通过闭包的方式为 UIControl 添加 action 的实现方式有很多种,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
extension 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: controlEvents)
return sleeve
}

func listenOnce(_ action: @escaping () -> (), for controlEvents: UIControlEvents) {
let sleeve = ClosureSleeve(attachTo: self, closure: action, controlEvents: controlEvents)
addTarget(sleeve, action: #selector(ClosureSleeve.invokeOnce), for: controlEvents)
}

func unlisten(sleeve: AnyObject) {
guard let sleeve = sleeve as? ClosureSleeve else { return }
self.removeTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: sleeve.controlEvents)
}
}

private class ClosureSleeve {
let closure: () -> ()
let controlEvents:UIControlEvents
let attachedTo: AnyObject

init(attachTo: AnyObject, closure: @escaping () -> (), controlEvents:UIControlEvents) {
self.attachedTo = attachTo
self.closure = closure
self.controlEvents = controlEvents
objc_setAssociatedObject(attachTo, "[\(arc4random())]", self, .OBJC_ASSOCIATION_RETAIN)
}

@objc func invoke() {
closure()
}

@objc func invokeOnce() {
closure()
attachedTo.unlisten(sleeve: self)
}
}
阅读全文 »

今天在项目中遇到了隐藏 navigationbar 功能的问题,例如:从 A push到 B 页面,A 页面的 navigationbar 是隐藏的,但是 B 页面的 navigationbar 是需要显示的。

一开始我在 A 页面调用 setNavigationBarHidden(true, animated: true) 方法,在 B 页面调用 setNavigationBarHidden(false, animated: true) 方法,虽然能够达到想要的效果,但是对于项目来说是灾难性的。因为如果有多个地方出现这种情况的话,你的代码将会变得十分的杂乱臃肿。

一种好的解决方式是调用 navigationcontroller 的代理:

1
navigationController(_:willShow:animated:)

将这个代理放在项目控制器的基类中,在这里我是放在我的基类 BaseViewController 中。为什么这么做?因为这样可以很好的去掉冗余的代码,不用写的到处都是,我的所有控制器都是继承自 BaseViewController 的,BaseViewController 继承自 UIViewController

下面到了 Show Code 的时候了

阅读全文 »

对 http 的抓包非常的简单,但是对 https 的抓包就有点麻烦了,主要麻烦在证书的安装与设置上。昨天由于有需要去抓https 的包,但是装好证书后,手机一直连不上,特此记录一下。

想要抓取 https 包,首先我们需要在电脑上安装一个 Charles Proxy 的证书

安装 Charles Root Certificate


1、依次点击:Help -> SSL Proxying -> Install Charles Root Certificate

阅读全文 »

尽管很多人了解 RxJava 的基本逻辑,但是在 Observable 链和操作符究竟运行在哪个线程,仍然会有许多困惑。

首先,让我们梳理清晰,在 RxJava 中 .subsribeOn().observeOn() 区别:

  1. .subsribeOn() 操作符可以改变 Observable 应该在哪个调度器上执行任务。
  2. .observeOn() 操作符可以改变 Observable 将在哪个调度器上发送通知。
  3. 另外,你需要知道,默认情况下,链上的操作符将会在调用 .subsribeOn() 的那个线程上执行任务。
阅读全文 »

好消息: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] 。你可以通过点击每个提案的链接标签来浏览每个更改的详细信息。

阅读全文 »

今天需要去打印店打印东西,但是 U 盘被我格式化成了 APFS 格式,用磁盘管理工具无法格式化成其他的格式,选项中只有 APFS 的选项。我用如下的命令格式化 U 盘:

1
sudo diskutil eraseDisk JHFS+ san /dev/disk3

但是执行命令会报错,错误信息大致是,无法格式化 APFS 容器。

/dev/disk3 是我 U 盘的目录,在执行之前请先确认自己的目录,用如下的命令:

1
diskutil list 
阅读全文 »
0%