有日子没写东西了,抽点时间练练笔头子,业精于勤荒于嬉~

近期从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的替代方案的更多相关文章

  1. swift 中关于open ,public ,fileprivate,private ,internal,修饰的说明

    关于 swift 中的open ,public ,fileprivate,private, internal的区别 以下按照修饰关键字的访问约束范围 从约束的限定范围大到小的排序进行说明 open,p ...

  2. 阿里巴巴最新开源项目 - [HandyJSON] 在Swift中优雅地处理JSON

    项目名称:HandyJSON 项目地址:https://github.com/alibaba/handyjson 背景 JSON是移动端开发常用的应用层数据交换协议.最常见的场景便是,客户端向服务端发 ...

  3. Swift中的可选链与内存管理(干货系列)

    干货之前:补充一下可选链(optional chain) class A { var p: B? } class B { var p: C? } class C { func cm() -> S ...

  4. 在Swift中实现单例方法

    在写Swift的单例方法之前可以温习一下Objective-C中单例的写法: + (instancetype)sharedSingleton{ static id instance; static d ...

  5. [翻译]理解Swift中的Optional

    原文出处:Understanding Optionals in Swift 苹果新的Swift编程语言带来了一些新的技巧,能使软件开发比以往更方便.更安全.然而,一个很有力的特性Optional,在你 ...

  6. 窥探Swift之使用Web浏览器编译Swift代码以及Swift中的泛型

    有的小伙伴会问:博主,没有Mac怎么学Swift语言呢,我想学Swift,但前提得买个Mac.非也,非也.如果你想了解或者初步学习Swift语言的话,你可以登录这个网站:http://swiftstu ...

  7. swift 中指针的使用UnsafeMutablePointer

    在swift中已经弱化了指针的使用,可以这么使用 let s: NSRange = NSMakeRange(, ) let at = UnsafeMutablePointer<NSRange&g ...

  8. swift 中数据类型那个的转换

    在swift中关于数据类型的转换,如果参数是可选类型? 那么打印或者转换的结果 会带有Optional 字样,,

  9. swift中Range的使用书名

    在swift中Range有两种用法 1.把字符串转换成NSString来使用 //这里是把swift的字符换转换成了nsstring 使用 let str :NSString = text.strin ...

随机推荐

  1. C语言实现将一个整形数转换为两个字节16进制

    有时候要用到这个转换,这里记录一下,例如把 int a = 164 转换储存在数组里为 uint8_t b[0]=0x00  , b[1]=0xA4 . 很简单,转换如下: b[0] = a > ...

  2. HDU 3073 Saving Beans

    Saving Beans Time Limit: 3000ms Memory Limit: 32768KB This problem will be judged on HDU. Original I ...

  3. HDU 5410(2015多校10)-CRB and His Birthday(全然背包)

    题目地址:HDU 5410 题意:有M元钱,N种礼物,若第i种礼物买x件的话.会有Ai*x+Bi颗糖果,现给出每种礼物的单位价格.Ai值与Bi值.问最多能拿到多少颗糖果. 思路:全然背包问题. dp[ ...

  4. 小胖说事30------iOS 强制转成横屏的方式

    一直遇到这个问题,今天最终找到了解决方法. 在我们的项目中常常遇到横竖屏切换,而又有某个特定的界面必须是特定的显示方式(横屏或竖屏).这就须要例如以下的处理了. 强制转成横屏: if ([[UIDev ...

  5. android学习笔记(5)Activity生命周期学习

    每一个activity都有它的生命周期,开启它,关闭它,跳转到其他activity等等,都会自己主动调用下面某种方法.对这些个方法覆写后观察学习. protected void onCreate(Bu ...

  6. hdu 4628 Pieces(状态压缩+记忆化搜索)

    Pieces Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total S ...

  7. 每一个JavaScript开发者都应该知道的10道面试题

    JavaScript十分特别.而且差点儿在每一个大型应用中起着至关关键的数据.那么,究竟是什么使JavaScript显得与众不同,意义非凡? 这里有一些问题将帮助你了解其真正的奥妙所在:   1.你能 ...

  8. WinForm容器内控件批量效验是否同意为空?设置是否仅仅读?设置是否可用等方法分享

    WinForm容器内控件批量效验是否同意为空?设置是否仅仅读?设置是否可用等方法分享 在WinForm程序中,我们有时须要对某容器内的全部控件做批量操作.如批量推断是否同意为空?批量设置为仅仅读.批量 ...

  9. 怎样訪问pcie整个4k的配置空间

    眼下用于訪问PCIe配置空间寄存器的方法须要追溯到原始的PCI规范. 为了发起PCI总线配置周期,Intel实现的PCI规范使用IO空间的CF8h和CFCh来分别作为索引和数据寄存器,这样的方法能够訪 ...

  10. Ruby学习笔记(一)

    在做实验的时候,由于每次都要手工修改文件夹的名字,实在是给自己添了太多的麻烦,为了摆脱手工修改的困恼,于是产生了一个使用程序批量修改文件夹名字的好主意.为了最终实现这个目标,自然需要选择一种合适的脚本 ...