Swift中NSDictionaryOfVariableBindings的替代方案
有日子没写东西了,抽点时间练练笔头子,业精于勤荒于嬉~
近期从OC转到了Swift2,因为Swift一直没有正经学正经用,所以对这门语言的理解基本算是个球。。。不得不感慨苹果的动作之快。Swift还没学呢。就2了。。
。于是意识到再不学起来可能就真2了~~花了些时间看了全本的《The Swift Programming Language》总算是能用他写点东西了~跟着问题就出来了
习惯了手写自己主动布局,还是那句老话,缩写是SB(StoryBoard)的东西能好用到哪去~~可也正由于这个遇到了一些问题~在对多个视图编写VFL时的词典怎么弄?由于Swift不支持宏定义,那个让人倍感亲切的`NSDictionaryOfVariableBindings`就直接这么废掉了,网上搜了一下,也没有什么正经的解决方式~~自己手写词典。
。
。这样的土锤的编码我也实在写不出来。霎时间有种要被逼良为娼的感觉。决定转用StoryBoard来做界面。
终于结果就是。
。。我的StoryBoard用的太不熟练也好又或Xcode7的StoryBoard还有Bug也好,每次开启Xcode部分加入了约束的控件会改变大小造成设计界面与执行界面显示效果不同的警告,同一时候随着SB内容的添加电脑会变卡(尽管无损播放器的贡献更大。
。。
),至于要找特定的内容就更是一场灾难了。。。至于在IB中针对ScrollView的设计更是无力吐槽。。。毕竟缩写是SB的东西。。。整体来说对效率的没有不论什么正面影响。
。。至少对我来说~
好吧,手写自己主动布局才是真爱。
。。
于是问题又回到了原点~在Swift中该怎么处理手写自己主动布局那个麻筋儿的地方。。
。
想了想,既然不能通过宏处理,那么方法你总拦不住我吧~思路就是把view数组传过去,再通过执行时推断出对象中这几个view的变量名,手动创建一个数组模拟一下宏的功能就好了~所以写了一个针对NSObject的Extension。
为什么是NSObject?原因非常easy,大部分的手写自己主动布局是针对UIViewController编写的。但仍然会有在UIView内部写自己主动布局的情况出现~所以NSObject更加合理一些
思路有了。内容就相对简单了~
<span style="font-size:14px;"> func dictForViews(views:[UIView]) -> [String : UIView] {
var count:UInt32 = 0
var dicts:[String : UIView] = [:] let ivars = class_copyIvarList(self.classForCoder, &count)
for var i = 0; i < Int(count); ++i{
let obj = object_getIvar(self, ivars[i])
if let temp = obj as? UIView{
views.contains(temp)
let name = String.fromCString(ivar_getName(ivars[i]))!
dicts[name] = temp
if dicts.count == views.count{ break }
}
} free(ivars) return dicts
}</span>
这样生成词典的代码就能够简单的写成
<span style="font-size:14px;">let views = dictForViews([view1,view2])</span>
打印出来:
[view2: <UIView: 0x7f8820fcb610; frame = (0 0; 0 0); layer = <CALayer: 0x7f8820fc1960>>,
view1: <UIView: 0x7f8820fe17b0; frame = (0 0; 0 0); layer = <CALayer: 0x7f8820fbe560>>]
ok,基本需求搞定
顺便的,由于写了这种方法又另外写了个东西搭配使用。也是个小玩意~简单说说,正常的VFL语句写出来大体是这个样子
|-[view1(==view2)][view2]-|
我本人不喜欢写纯字符串,由于有时候为了程序的可读性,变量名字会定义的特别长~而为了写VFL要一遍遍手写这个名字实在痛苦,即便复制粘贴也是个麻烦事,所以写了一个通过对象获取属性名的方法~配合Swift的字符串插入机制用起来还是不错的。尽管VFL本身会边长,甚至些许影响了可读性,但假设足够熟悉还是没什么问题的~
方法非常easy:
<span style="font-size:14px;"> func nameFor(view:UIView) -> String{
var count:UInt32 = 0
let ivars = class_copyIvarList(self.classForCoder, &count)
for var i = 0; i < Int(count); ++i{
let obj = object_getIvar(self, ivars[i])
if let temp = obj as? UIView{
if temp === view {
return String.fromCString(ivar_getName(ivars[i]))!
}
}
} free(ivars) return ""
}</span>
这里返回了`String`而不是`String?
`
对于正常的Swift方法来说`String?
`显然是更合理的方式,但问题在于这种方法相当于是一个inline方法。直接用返回值就好,假设用了`String?`就须要在每次使用时加个`!`,这就太痛苦了。。
。所以我无耻的妥协了~用了这种方法之后VFL就变成了
|-[\(nameFor(view1))(==\(nameFor(view2)))][\(nameFor(view2))]-|
假设说这么写有什么优点的话,我想至少应该是有两点的,一是避免了纯手写字符串造成的输入错误,二是通过重构更改变量名的时候省去了字符串替换的麻烦~在编写的时候因为方法和变量都是智能提示的,写起来没有看上去这么麻烦~除了变长了之外其它都挺好的~到底怎么写见仁见智吧。
Swift中NSDictionaryOfVariableBindings的替代方案的更多相关文章
- swift 中关于open ,public ,fileprivate,private ,internal,修饰的说明
关于 swift 中的open ,public ,fileprivate,private, internal的区别 以下按照修饰关键字的访问约束范围 从约束的限定范围大到小的排序进行说明 open,p ...
- 阿里巴巴最新开源项目 - [HandyJSON] 在Swift中优雅地处理JSON
项目名称:HandyJSON 项目地址:https://github.com/alibaba/handyjson 背景 JSON是移动端开发常用的应用层数据交换协议.最常见的场景便是,客户端向服务端发 ...
- Swift中的可选链与内存管理(干货系列)
干货之前:补充一下可选链(optional chain) class A { var p: B? } class B { var p: C? } class C { func cm() -> S ...
- 在Swift中实现单例方法
在写Swift的单例方法之前可以温习一下Objective-C中单例的写法: + (instancetype)sharedSingleton{ static id instance; static d ...
- [翻译]理解Swift中的Optional
原文出处:Understanding Optionals in Swift 苹果新的Swift编程语言带来了一些新的技巧,能使软件开发比以往更方便.更安全.然而,一个很有力的特性Optional,在你 ...
- 窥探Swift之使用Web浏览器编译Swift代码以及Swift中的泛型
有的小伙伴会问:博主,没有Mac怎么学Swift语言呢,我想学Swift,但前提得买个Mac.非也,非也.如果你想了解或者初步学习Swift语言的话,你可以登录这个网站:http://swiftstu ...
- swift 中指针的使用UnsafeMutablePointer
在swift中已经弱化了指针的使用,可以这么使用 let s: NSRange = NSMakeRange(, ) let at = UnsafeMutablePointer<NSRange&g ...
- swift 中数据类型那个的转换
在swift中关于数据类型的转换,如果参数是可选类型? 那么打印或者转换的结果 会带有Optional 字样,,
- swift中Range的使用书名
在swift中Range有两种用法 1.把字符串转换成NSString来使用 //这里是把swift的字符换转换成了nsstring 使用 let str :NSString = text.strin ...
随机推荐
- vue 表格数据编辑,点击取消或者完成按钮后,关闭编辑状态没有及时生效
点击编辑按钮: 编辑状态下,表格可以编辑.但是点击“确认”或者“取消”按钮,列数据编辑状态已经修改,但是视图没有改变. 页面代码: 获取当前行的index,并直接修改当前行用于判断是否编辑状态的数据为 ...
- 集成swagger2构建Restful API
集成swagger2构建Restful API 在pom.xml中进行版本管理 <swagger.version>2.8.0</swagger.version> 给taosir ...
- 华硕VX50V开机老是进入bios
问题:华硕VX50V开机老是进入bios 如图: 解决办法: 1.将 Boot 中的--->> Lunch CSM ---->>设置为 -->> ena ...
- POJ——T2421 Constructing Roads
http://poj.org/problem?id=2421 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 24132 ...
- 前端project师养成记:开发环境搭建(Sublime Text必备插件推荐)
为了让自己更像一个前端project师,决定从开发环境開始武装自己. 本文将介绍前段project师开发的一些利器的安装步骤,主要包含了: 1.Node.js的安装 2.Grunt的安装及经常使用插件 ...
- java web 服务器端处理json格式参数
前面我们说了传递参数的两种访书,第一是key-value形式,第二是json格式,对于第一种我们在服务器端直接使用 request.getParameter("key");就能获取 ...
- node10---GET请求和POST请求的参数
GET请求的参数在URL中,在原生Node中,需要使用url模块来识别参数字符串.在Express中,不需要使用url模块了.可以直接使用req.query对象. ● POST请求在express中不 ...
- mvc架构的简单登录系统,jsp
文件结构 三个jsp文件负责前段界面的实现 login.jsp <%@ page language="java" import="java.util.*" ...
- 关于AJAX异步请求的那些事儿(1)
1.什么事AJAX? Asynchronous Javascript And XML:异步的JS和XML,由Google2002年在GoogleSuggest应用提出,目标实现客户端和服务器“同时”运 ...
- (转)js document.all的用法
document.all用法 一. document.all是页面内所有元素的一个集合.例如: document.all(0)表示页面内第一个元素 二.document.all可以判断浏览器 ...