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))]-|

假设说这么写有什么优点的话,我想至少应该是有两点的,一是避免了纯手写字符串造成的输入错误,二是通过重构更改变量名的时候省去了字符串替换的麻烦~在编写的时候因为方法和变量都是智能提示的,写起来没有看上去这么麻烦~除了变长了之外其它都挺好的~到底怎么写见仁见智吧。

时间: 2024-11-12 12:33:46

Swift中NSDictionaryOfVariableBindings的替代方案的相关文章

Swift 中AFNetworking 的替代方案 Alamofire

Alamofire 是 Swift 语言的 HTTP 网络开发工具包,功能强大,支持各种 HTTP Method.JSON.文件上传.文件下载和多种认证方法. AFNetworking的作者全新力作,原生Swfit语言编写,基本可以满足Swift中网络编程开发. github的URL为: https://github.com/Alamofire/Alamofire git clone的URL为 https://github.com/Alamofire/Alamofire.git

Swift 中的Range和NSRange不同

Swift中的Ranges和Objective-C中的NSRange有很大的不同,我发现在处理Swift中Ranges相关的问题的时候,总是要花费比我想象的更多的时间.不过,现在回过头来看看,发现Swift中的Ranges的使用还是比较合理的,但是想要正确的使用Ranges真的需要一些特别的技巧. 看一个例子,下面这段代码展示的是截取以指定的字符开头和以指定的字符结尾的子字符串: ? 1 2 3 4 5 6 var str = "Hello, playground"   let ran

Swift 中的基础语法(二)

1.Swift 中的函数 /// 函数的定义 /// /// - Parameters: /// - x: 形参 /// - y: 形参 /// - Returns: 返回值 func sum(x: Int, y: Int) -> Int { return x + y } print(sum(x: 10, y: 20))   /* 外部参数就是在形参前面加了一个字 外部参数不会影响函数内部的细节 外部参数会让外部调用看起来更加直观 外部参数如果使用了'_',在外部调用函数时,会忽略形参的名字 &qu

Swift中的错误处理

前言 任何代码都会发生错误,这些错误有些是可以补救的,有些则只能让程序崩溃.良好的错误处理能够让你的代码健壮性提高,提高程序的稳定性. 本文的Swift版本:Swift 3 Objective C 返回nil 如果出错了,就返回空是Objective C中的一种常见的处理方式.因为在Objective C中,向nil发送消息是安全的.比如: - (instancetype)init { self = [super init]; if (self) { } //如果初始化失败,会返回nil ret

swift中代理的使用

下面以自定义的UITableViewCell的代理为例,记录一下swift中代理的使用 controller中的代码如 1 // 2 // ViewController.swift 3 // simpleDemo 4 // 5 // Created by liubo on 16/7/25. 6 // Copyright © 2016年 liubo. All rights reserved. 7 // 8 9 import UIKit 10 11 class ViewController: UIV

SWIFT中的repeat...while

SWIFT中的repeat...while类似于JAVA\.NET中的 do while.大同小异只是把do换成了repeat var index = 10 repeat{ print(index) index-- } while(index>0)

Swift中的结构体,类,协议,扩展和闭包的用法以及? 和 !的区别

// MARK: - 1.结构体 //1.声明一个结构体 struct Rect {    // 声明结构体变量的属性(存储属性)    var x:Float    var y:Float    var width:Float    var height:Float    // 声明结构体属性,要使用static    static var description:String?        // 声明一个计算属性(是用来专门计算结构体变量属性的setter,和getter方法,其本身没有存

Swift中编写单例的正确方式

Swift中编写单例的正确方式 2015-12-07 10:23 编辑: yunpeng.hu 分类:Swift 来源:CocoaChina翻译活动 14 10647 Objective-CSwift单例 招聘信息: Cocos2d-x 工程师 cocos2dx手游客户端主程 wp开发 iOS开发工程师 iOS软件工程师 iOS研发工程师 iOS讲师 iOS开发工程师 iOS高级开发工程师 iOS 高级软件工程师 iOS高级开发工程师 本文由CocoaChina译者leon(社区ID)翻译自kr

[Swift中错误]missing argument label &#39;greeting:&#39; in call

Swift 中出现这个问题:从第二个参数起,自动加上lable func sayHello(name:String? ,greeting:String)->String { let result = greeting + "," + (name ?? "Guest") + "!" return result } var nickname:String? nickname = "yc" //“Goodmorning前面应该