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

近期从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++里面的单冒号和双冒号

    c++ 中的单冒号与双冒号 1.冒号(:)用法 (1)表示机构内位域的定义(即该变量占几个bit空间) typedef struct _XXX{ unsigned char a:4; unsigned ...

  2. NYIST 1030 Yougth's Game[Ⅲ]

    Yougth's Game[Ⅲ]时间限制:3000 ms | 内存限制:65535 KB难度:4 描述有一个长度为n的整数序列,A和B轮流取数,A先取,每次可以从左端或者右端取一个数,所有数都被取完时 ...

  3. [React] Understanding setState in componentDidMount to Measure Elements Without Transient UI State

    In this lesson we'll explore using setState to synchronously update in componentDidMount. This allow ...

  4. Android性能优化之ListView缓存机制

    要想优化ListView首先要了解它的工作原理,列表的显示须要三个元素:ListView.Adapter.显示的数据. 这里的Adapter就是用到了适配器模式,无论传入的是什么View在ListVi ...

  5. Qt Quick 简单介绍

    Qt Quick 是 Qt 提供的一种高级用户界面技术.使用它可轻松地为移动和嵌入式设备创建流畅的用户界面. 在 Android 设备上, Qt Quick 应用默认使用 OpenGL ES ,渲染效 ...

  6. php设计模式之工厂方法模式

    php设计模式之工厂方法模式 工厂方法模式 工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Pol ...

  7. hdoj--1260--Tickets(简单dp)

    Tickets Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Su ...

  8. RAC IP 地址修改

    RAC 修改IP: 版本信息: REDHAT AS5 ORACLE 11G R2, 两个节点. 修改如下: 1.修改/etc/host(rac1,rac2) 192.168.3.205   rac-s ...

  9. [JZOJ 5437] [NOIP2017提高A组集训10.31] Sequence 解题报告 (KMP)

    题目链接: http://172.16.0.132/senior/#main/show/5437 题目: 题解: 发现满足上述性质并且仅当A序列的子序列的差分序列与B序列的差分序列相同 于是我们把A变 ...

  10. 3.多线程传参,以及tuple数组

    #include <Windows.h> #include <thread> #include <iostream> #include <tuple> ...