滚动选择器控件, 不同于系统(框架)自带的 UISlider, iOSScrollPicker 支持:
- 甩动选择
- 点击选择
- 支持竖直(上下)滚动
- 支持水平(左右)滚动
这有点像 iPhone 系统里的时间设置控件(日历控件), 或者说老虎机效果. 一般的实现是用 UIScrollView 来实现, 但用 UITableView 来实现, 可以更简洁, 减少很多偏移量的数值计算.
代码下载: https://github.com/ideawu/iOSScrollPicker
截图:
滚动选择器控件, 不同于系统(框架)自带的 UISlider, iOSScrollPicker 支持:
这有点像 iPhone 系统里的时间设置控件(日历控件), 或者说老虎机效果. 一般的实现是用 UIScrollView 来实现, 但用 UITableView 来实现, 可以更简洁, 减少很多偏移量的数值计算.
代码下载: https://github.com/ideawu/iOSScrollPicker
截图:
iOS 上的 NSURLConnection 一般能处理绝大部分的 HTTP 请求场景, 不过, 对于一种情况, 它无法处理, 那便是接收 HTTP chunked data. NSURLConnectionDataDelegate 有一个方法, 可以在读取到部分响应时进行回调, 但是, 数据不是按 HTTP chunked data 来接收的, 它会将多个 chunk 合并到一起.
@protocol NSURLConnectionDataDelegate- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data; @end
没办法, 只能使用 cURL for iOS, 在 iComet 的 iOS 例子里有介绍.
首先, 下载 cURL for iOS: http://seiryu.home.comcast.net/~seiryu/libcurl-ios.html
然后, 把里面的 libcurl.a 引入你的项目, 还要把它的头文件引入. 注意, cURL 依赖 libz.dylib.
CocoaUI 是一个强大的 iOS UI 框架, 使用 Web 开发者熟悉的 HTML+CSS 流式布局方式, 轻松地开发 iOS 原生 App 的界面.
CocoaUI 的特性主要包括:
最简单的流式布局模型, 其实就是: 靠左, 靠右, 或者堆叠. 根据这个简单的理论, 可以用两个栈(Stack)数据结构, 一个表示靠左边的控件列表, 另一个表示靠右边的控件列表, 即可实现流式布局模型.
用伪代码表示如下:
// 视图控件 class View{ private FlowLayouter layouter; // 当控件发生 frame 改变后, 调用此方法标记为需要重新布局 void setNeedsLayout(){ View view = this; while(view){ view.markNeedsLayout(); // 当控件需要重新布局时, 一般地, 它的父节点也需要重新布局 view = view.parent; } } void layout(){ for(View child in this.children){ this.layouter.place(child); } } } // 流式布局管理器 class FlowLayouter{ private Stack leftViews; private Stack rightViews; void place(View child){ Position pos; child.layout(); // 子节点先进行布局 while(!this.spaceFits(child)){ if(child.floatLeft){ View view = this.leftViews.pop(); pos = view.pos; // 当被移除的节点比其它节点更高时, 继续移除 while(pos.y > this.leftViews.last.y){ View view = this.leftViews.pop(); pos = view.pos; } } if(child.floatRight){ View view = this.rightViews.pop(); pos = view.pos; // 当被移除的节点比其它节点更高时, 继续移除 while(pos.y > this.rightViews.last.y){ View view = this.rightViews.pop(); pos = view.pos; } } } // place child here child.pos = pos; if(child.floatLeft){ this.leftViews.push(child.pos); } if(child.floatRight){ this.rightViews.push(child.pos); } } }
这段代码最重要的是两点:
1. 当某个控件发生改变时, 它需要重新布局. 同时, 它的父节点, 以及父节点的父节点, 一直到节点树的根节点, 都需要重新布局. 当然, 这是性能最差的方案, 优化的思路就是减少需要重新布局的节点的数量, 这需要发动每个人的聪明才智来想.
2. 用两个 Stack 来分别表示靠左的和靠右节点列表. 如果当前的空白空间不足以放下一个控件, 那么, 尝试从节点列表中移除一个节点, 这样, 这个布局区域就空出来了一些空间. 当然, 这个空间应该往下移, 不能和被移除的节点所占据的空间重叠. 因为流式布局的基本原理就是不重叠(除非通过特殊设定, 如负数的偏移量).
有了这个简单的流式布局模型, 你可以在所有最基本的绝对定位的 GUI 库上面实现功能强大的流式布局, 例如, iOS 的 UIKit 不支持流式布局, 你可以根据上面的代码扩展, 给 iOS 界面开发加上流式布局功能.
流式布局其实是非常有趣的一项功能, 它的模型很简洁, 但功能强大且应用广泛. GUI 界面的本质是树, 树是简洁而优美的, 而流式布局使用的数据结构是 Stack, 又是一种非常基础的数据结构.
说句题外话, 我已经实现了 iOS 系统上面的 UI 流式布局 - CocoaUI, 你可以试用下.
iPhone 手机的成功, iOS 操作系统功不可没. 而 iOS 操作系统的成功, 与早期 iPhone 单一的屏幕分辨率也有极大的关系. 不客气地说, 正因为早期 iPhone 手机只有一个分辨率, iOS 操作系统和其上面的 App 才不需要关心所谓的"响应式布局", "流式布局", "自动布局"这些技术, 它们只使用绝对定位的布局 - 每一个控件的大小和位置都是定死的, 几乎不变. 这样, iOS 应用开发者把精力放在了界面外观和交互体验, 最终促成了 iPhone/iOS 的成功.
不过, 从 iPad 的出现, 到 iPhone 5 发布, 以及后面的 iPhone 6/6+, iPhone/iOS 手机的屏幕分辨率开始多样化了, 这时, 界面布局便不能死守着绝对定位布局了.
为了解决这个问题, 苹果的方案是"Auto Resizing"和"Auto Layout", 特别是后者, 解决了界面动态布局的问题.
在 iOS 上, 加密被和安全性进行了强绑定, 所以, 你不能只做加密(至少公开文档不告诉你如何只做加密). 但事实上, 很多时候我们加密, 并不是要求 100% 的安全, 只是希望能得到加密本身所带来的安全, 既不考虑数据重放, 也不考虑第三者攻击, 也不考虑身份伪装. 我们仅仅是需要 - 加密, RSA 非对称加密. 物理上的和系统上的安全我们会想尽全部办法来解决, 不需要加密模块来管.
但是, 苹果不公开允许这样做, 所以 iOS 上的 Cocoa API 就没有简单的这样的加密函数:
ret = rsa_encrypt(src_data, public_key);
例如, 苹果的 SecKeyEncrypt()
函数需要 .der 证书, 而公钥只是证书的一部分. 所以, 如果你只有公钥, 你是不能直接使用这个函数的. 幸运的是, iOS 可以使用自己产生的公钥, 所以, 你要做的是把你的公钥伪装成是 iOS 产生的.
这篇文章, 介绍了如何伪装公钥. 伪装完后, 你就可以直接使用 SecKeyEncrypt()
函数来进行 RSA 公钥加密了.
完整的代码我放在 GitHub 上了.