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 ...
随机推荐
- 小学生都能学会的python(函数)
小学生都能学会的python(函数) 神马是函数 函数: 对功能或者动作的封装 函数的定义 def 函数名(形参列表): 函数体(return) ret = 函数名(实参列表) 函数的返回值 retu ...
- Qt之设置应用程序图标
简述 应用程序图标,通常显示在应用程序的顶层窗口的左上角,通过调用QWindow:setWindowIcon()函数来实现. 为了改变可执行程序文件本身的图标,因为它被呈现在桌面上,它必须采用另一种依 ...
- Android Material Design-Getting Started(入门)-(一)
转载请注明出处:http://blog.csdn.net/bbld_/article/details/40400343 翻译自:http://developer.android.com/trainin ...
- 2016 ICPC CAMP Recording
等了好久终于等到今天 马上能和群巨们一起学习了 希望不要暴露我太弱的本质............ 北京不冷,就是风大~~~ 1.24 8点准时起床了,准备下楼吃早饭 (这个宾馆好多美美的空姐对面就是东 ...
- m_Orchestrate learning system---十一、thinkphp查看临时文件的好处是什么
m_Orchestrate learning system---十一.thinkphp查看临时文件的好处是什么 一.总结 一句话总结:可以知道thinkphp的标签被smarty引擎翻译而来的php代 ...
- SSH Key的生成和使用(for git)
SSH Key的生成和使用 一.总结 1.用git base生成ssh,会生成id_rsa.pub文件,还有一个私钥文件. $ ssh-keygen -t rsa -C “youremailn ...
- java web项目中资源国际化
有一些网站会有语言栏选项: 选择英文,内容就显示为英文: 选择中文,内容就显示文中文. 这里就用到了国际化资源. 先看效果图: 步骤: 1.建立资源包: mess_en_US.properties ( ...
- win10关闭更新
计算机--管理: 找到windows update 服务关闭:
- 3DS MAX玩家必看!70个提高渲染速度的小技巧
3DS MAX玩家必看!70个提高渲染速度的小技巧 (注:节省RAM不一定会加快渲染速度.请同学们根据实际情况加以利用.) 1. 尽量限制Ploygon数量,越少渲染速度越快 2. 如果使用Vray, ...
- No mapping found for HTTP request with URI [/spring_liu/hello.do] in DispatcherServlet with name 'SpringMVC'
控制台一直报No mapping found for HTTP request with URI [/spring_liu/hello.do] in DispatcherServlet with na ...