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 ...
随机推荐
- [luogu] P4105 [HEOI2014]南园满地堆轻絮 (贪心)
P4105 [HEOI2014]南园满地堆轻絮 题目描述 小 Z 是 ZRP(Zombies' Republic of Poetry,僵尸诗歌共和国)的一名诗歌爱好者,最近 他研究起了诗词音律的问题. ...
- Win10和子系统Ubuntu简单共享
Win10和子系统Ubuntu简单共享 C:\Users\用户名\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp ...
- JavaScript中的常用的数组操作方法
JavaScript中的常用的数组操作方法 一.concat() concat() 方法用于连接两个或多个数组.该方法不会改变现有的数组,仅会返回被连接数组的一个副本. var arr1 = [1,2 ...
- java深克隆与浅克隆
2015.9.19 6:45 星期五 1
- ASP.NET-三种认证Authentication简介
ASP.NET 的 认证Authentication主要分为三种 1.Form Authentication 用于互联网的认证,自定性强,功能强大,可以用cookie和ssl 2.Window A ...
- HMM(隐马尔可夫),这篇讲的不错
http://www.cnblogs.com/skyme/p/4651331.html
- python学习之--安装IDE(eclipse+pydev)
First steps download eclipse url:http://www.eclipse.org/downloads/ select Help -> Install New Sof ...
- 棋盘覆盖问题python3实现
在2^k*2^k个方格组成的棋盘中,有一个方格被占用,用下图的4种L型骨牌覆盖全部棋盘上的其余全部方格,不能重叠. 代码例如以下: def chess(tr,tc,pr,pc,size): globa ...
- 如何让Java写的程序,脱离Eclipse在别人的电脑上运行?
Java程序运行,离不开JRE. 将JRE文件夹拷贝出来, 将编写程序的bin文件夹拷贝出来, 再编写一个bat文件. start jre\bin\javaw.exe -cp .\bin\ -Djav ...
- 解读HDFS(转载)
是蛮久木有写过关于hadoop的博客了额,虽然最近也看了一些关于linux的基础知识,但似乎把这个东西忘记了,其实时不时回顾一下以前的知识还是蛮有意思的,且行且忆! 我们Hadoop 主要由HDFS和 ...