Swift编程(六):Snapkit的启示录

Swift编程(六):Snapkit的启示录

写在前面(Github地址)

个人项目

个人站点:LN电影网
个人博客:L&N博客

欢迎大家关注我的个人博客:博客地址,这里主要是我在个人开发时候遇到的坑和挖完的坑,包括 PHP CentOS 以及 Swift 等相关只是

主要记录了,我在学习Snapkit中的一些整理记录

学习目标

  • 好好学习如何用代码来做自动布局
  • 使用SnapKit做了一个修改密码的表单

效果图

1. Snapkit的安装

  • Cocoapods安装

    在项目的Podfile下添加如下信息
    在终端中执行:pod install(注意路径是当前项目中Podfile锁在路径)

swift
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!pod 'SnapKit', '~> 0.15.0'
  • Carthage安装

    Carthage是一种分散式依赖管理库用来自动为你的Cocoa应用添加第三方框架

1) 通过下面命令行执行安装Carthage

swift
brew update
brew install carthage

2) 通过下面命令行继承SnapKit到你的项目中的Cartfile

swift
github "SnapKit/SnapKit" >= 0.15.0

3.)通过直接讲SnapKit的源代码拖放到自己的项目目录当中

这也是我比较喜欢的一种方式,这样可以比较自由的讲代码拖放到自己执行的目录下

2. SnapKit的兼容操作

如果希望SnapKit支持IOS7版本,需要在自己的项目的 Build Setting 中搜索的 OTHER_SWIFT_FLAGS,在其下面添加 -DSNAPKIT_DEPLOYMENT_LEGACY,如下图所示:(否则会报错!)


示意图

3. Snapkit官方文档翻译

通用模式:
swift
let box = UIView()
superview.addSubview(box)
box.snp_makeConstraints { (make) -> Void in
  //解释:box对象相对于父视图上边距为20像素
  make.top.equalTo(superview).offset(20) 
  make.left.equalTo(superview).offset(20) 
  make.bottom.equalTo(superview).offset(-20) 
  make.right.equalTo(superview).offset(-20)
}

注意:在SnapKit当中 X轴向右方向;Y轴向下方向 为正

缩写形式
swift
let box = UIView()
superview.addSubview(box)
box.snp_makeConstraints { (make) -> Void in 
    //注释:box距离父视图上下左右边距都是20像素
    make.edges.equalTo(superview).inset(UIEdgeInsetsMake(20, 20, 20, 20))
}

SnapKit还可以通过下面几个步骤来实现缩短代码和提高代码可读性

  • 确定最佳的普通视图安装限制。
  • 保持轨道的约束安装所以他们可以很容易地被删除后。
  • 在所有适当的视图上确保 setTranslatesAutoresizingMaskIntoConstraints(false)属性被设置
SnapKit中并不局限于 等于(equalTo)
  • .equalTo:等于
  • .lessThanOrEqualTo 小于等于
  • .greaterThanOrEqualTo 大于等于
1.视图属性
//当前视图对象的中心x坐标小于等于view视图的左边的x左边
make.centerX.lessThanOrEqualTo(view.snp_left)

视图属性:

上 :上边对应的Y轴 (top)
下: 下边对应的Y轴 (bottom)
左: 左边对应的Y轴 (left)
右: 右边对应的X轴 (right)

视图属性(ViewAttribute)布局属性 (NSLayoutAttribute)
view.snp_leftNSLayoutAttribute.Left
view.snp_rightNSLayoutAttribute.Right
view.snp_topNSLayoutAttribute.Top
view.snp_bottomNSLayoutAttribute.Bottom
view.snp_leadingNSLayoutAttribute.Leading
view.snp_trailingNSLayoutAttribute.Trailing
view.snp_widthNSLayoutAttribute.Width
view.snp_heightNSLayoutAttribute.Height
view.snp_centerXNSLayoutAttribute.CenterX
view.snp_centerYNSLayoutAttribute.CenterY
view.snp_baselineNSLayoutAttribute.Baseline
2.视图关系(UIView/NSView)

如果你想 视图 view.left 大于等于 label.left ,执行下面代码:

swift
//下面这两者的约束是完全一样的
make.left.greaterThanOrEqualTo(label)
make.left.greaterThanOrEqualTo(label.snp_left)
3.严格检测(Strick Checks)

自动布局允许将宽度和高度属性设置为常量值。如果你想对视图设置一个最小和最大宽度,你必须先给他一个初始的平等块:

swift
//设置宽度>= 200 && <= 400

你也可以用其他的约束和结构来建立你的约束,像这样:

swift
make.top.equalTo(42)
make.height.equalTo(20)
make.size.equalTo(CGSizeMake(50,100))
make.edges.equalTo(UIEdgeInsetsMake(10,0,10,0))
make.left.equalTo(view).offset(UIEdgeInsetsMake(10,0,10,0))
4.学习优先级
  • .priority: 允许您指定一个确切的优先级
  • .priorityHigh: 高优先级 等价于 UILayoutPriority.DefaultHigh
  • .priorityMedium:中优先级
  • .priorityLow:低优先级 UILayoutPriority.DefaultLow

优先级可以放在约束链的结束处,例如

swift
//当前视图的左边>=label的底部 低优先级
make.left.greaterThanOrEqualTo(label.snp_left).priorityLow()
//当前视图与label的顶部齐平,优先级:600
make.top.equalTo(label.snp_top).priority(600)
5.组成,组成,组成

SnapKit 也可以提供一些便利的方法来同时创建多约束

  1. edges(边缘)
swift
//让当前视图 的 上下左右(top,left,bottom,right) 等于 view2
make.edges.equalTo(view2)
// make top = superview.top + 5; left = superview.left +10
// bottom = superview.bottom -15; right = superview.right - 20
make.edges.equalTo(superView).inset(UIEdgeInsetsMake(5,10,15,20))

2.size(尺寸)

swift
//当前视图宽高 >= titleLabel
make.size.greaterThanOrEqualTo(titleLabel)
//make width = superview.width + 100; height = superview.height -50
//即 当前视图宽 = 父视图 + 100,高 = 父视图.高 - 50
make.size.equalTo(superview).offset(CGSizeMake(100, -50))

3.center(中心)

swift
//当前视图与 button1中心相同 (centerX 和 centerY)
make.center.equalTo(button1)
//make centerX = superview.centerX - 5; centerY = superview.centerY +10
make.center.equalTo(superview).offset(CGPointMake(-5,10))

您可以串连视图属性增加可读性

swift
//所有边缘除了top都等于父视图, top为20
make.left.right.bottom.equalTo(superview)
make.top.equalTo(20)
6.Hold on for dear life

有时候你需要修改已经存在的约束为了移动或者移除、代替约束。在SnapKit 有一些不同的方法更新约束

1.引用(References)
你可以通过将约束的结果赋值给一个局部变量或一个类属性来保持一个特定的约束的引用。您还可以将多个约束引用存储在数组中。

swift
var topConstraint: Constraint? = nil

//当制作约束时
view1.snp_makeConstraints{ (make) -> Void in
        self.topConstrain = make.top.equalTo(superview).offset(padding.top).constraint
        make.left.equalTo(superview).offset(padding.left)

// 然后接下来你可以这样
self.topConstraint.uninstall()

//或者如果你想要更新约束
self.topConstraint.updateOffset(5)

2.snp_updateConstraints(更新约束)
如果你仅仅想更新一个常数给一个约束,你可以使用方法snp_updateConstraints来代替snp_makeConstraints

swift
//这是一个苹果官方推荐的添加和更新约束的地方
//这个方法在响应<code>setNeedsUpdateConstraints</code>多次调用
//这个方法可以倍UIKit调用
override func updateConstraints() {
        self.growingButton.snp_updateConstraints{ (make) -> Void in
                make.center.equalTo(self);
                make.width.equalTo(self.buttonSize.width).priorityLow()
                make.height.equalTo(self.buttonSize.height).priorityLow()
                make.width.lessThanOrEqualTo(self)
                make.height.lessThanOrEqualTo(self)
        }

        //父类可以调用
        super.updateConstraints()
}

3.snp_remakeConstraints(重做约束)

snp_remakeConstraintssnp_makeConstraints类似,但是首先会先清除掉所有被SnapKit设置的约束

swift
func changeButtonPosition() {
        self.button.snp_remakeConstraints{ (make) -> Void in
                make.size.equalTo(self.buttonSize)
                if topLeft {
                        make.top.left.equalTo(10)
                } else {
                        make.bottom.equalTo(self.view).offset(-10)
                        make.right.equalTo(self.view).offset(-10)
                }
        }
}

4.Demo的具体代码(我的Github)

创建属性

swift
    var oldPassword: UITextField!
    var newPassword: UITextField!
    var confirmPassword: UITextField!
    var formView: UIView!
    var confirmButton:UIButton!

    var topConstraint: Constraint?

UI初始化

swift
    func initUI(){
        self.title = "修改密码"
        self.view.backgroundColor = UIColor.redColor()
        //登录框背景
        self.formView = UIView()
        self.formView.layer.borderWidth = 0.5
        self.formView.layer.borderColor = UIColor.lightGrayColor().CGColor
        self.formView.backgroundColor = UIColor.whiteColor()
        self.formView.layer.cornerRadius = 5
        self.view.addSubview(self.formView)
        //最常规的设置模式
        self.formView.snp_makeConstraints { (make) -> Void in
            make.left.equalTo(15)
            make.right.equalTo(-15)
            //存储top属性
            self.topConstraint = make.top.equalTo(200).constraint
            make.height.equalTo(220)

        }

        //密码图
        let imgLock1 =  UIImageView(frame:CGRectMake(11, 11, 22, 22))
        imgLock1.image = UIImage(named:"iconfont-password")

        //密码图
        let imgLock2 =  UIImageView(frame:CGRectMake(11, 11, 22, 22))
        imgLock2.image = UIImage(named:"iconfont-password")

        //密码图
        let imgLock3 =  UIImageView(frame:CGRectMake(11, 11, 22, 22))
        imgLock3.image = UIImage(named:"iconfont-password")

        //旧密码输入框
        self.oldPassword = UITextField()
        self.oldPassword.delegate = self
        self.oldPassword.tag = 100
        self.oldPassword.placeholder = "请输入旧密码"
        self.oldPassword.layer.cornerRadius = 5
        self.oldPassword.layer.borderColor = UIColor.lightGrayColor().CGColor
        self.oldPassword.layer.borderWidth = 0.5
        self.oldPassword.leftView = UIView(frame:CGRectMake(0, 0, 44, 44))
        self.oldPassword.leftViewMode = UITextFieldViewMode.Always
        self.oldPassword.returnKeyType = UIReturnKeyType.Next

        //密码输入框左侧图标
        self.oldPassword.leftView!.addSubview(imgLock1)
        self.formView.addSubview(self.oldPassword)

        //布局
        self.oldPassword.snp_makeConstraints { (make) -> Void in
            make.left.equalTo(30)
            make.top.equalTo(20)
            make.right.equalTo(-30)
            make.height.equalTo(44)
        }

        //新密码输入框
        self.newPassword = UITextField()
        self.newPassword.delegate = self
        self.newPassword.tag = 101
        self.newPassword.placeholder = "请输入新密码"
        self.newPassword.layer.cornerRadius = 5
        self.newPassword.layer.borderColor = UIColor.lightGrayColor().CGColor
        self.newPassword.layer.borderWidth = 0.5
        self.newPassword.leftView = UIView(frame:CGRectMake(0, 0, 44, 44))
        self.newPassword.leftViewMode = UITextFieldViewMode.Always
        self.newPassword.returnKeyType = UIReturnKeyType.Next

        //密码输入框左侧图标
        self.newPassword.leftView!.addSubview(imgLock2)
        self.formView.addSubview(self.newPassword)

        //布局
        self.newPassword.snp_makeConstraints { (make) -> Void in
            make.left.equalTo(30)
            make.top.equalTo(self.oldPassword.snp_bottom).offset(20)
            make.right.equalTo(-30)
            make.height.equalTo(44)
        }

        //确认新密码输入框
        self.confirmPassword = UITextField()
        self.confirmPassword.delegate = self
        self.confirmPassword.tag = 102
        self.confirmPassword.placeholder = "请重复新密码"
        self.confirmPassword.layer.cornerRadius = 5
        self.confirmPassword.layer.borderColor = UIColor.lightGrayColor().CGColor
        self.confirmPassword.layer.borderWidth = 0.5
        self.confirmPassword.leftView = UIView(frame:CGRectMake(0, 0, 44, 44))
        self.confirmPassword.leftViewMode = UITextFieldViewMode.Always
        self.confirmPassword.returnKeyType = UIReturnKeyType.Done

        //密码输入框左侧图标
        self.confirmPassword.leftView!.addSubview(imgLock3)
        self.formView.addSubview(self.confirmPassword)

        //布局
        self.confirmPassword.snp_makeConstraints { (make) -> Void in
            make.left.equalTo(30)
            make.top.equalTo(self.newPassword.snp_bottom).offset(20)
            make.right.equalTo(-30)
            make.height.equalTo(44)
        }

        self.confirmButton = UIButton()
        self.confirmButton.setTitle("确认修改", forState: UIControlState.Normal)
        self.confirmButton.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Normal)
        self.confirmButton.layer.cornerRadius = 5
        self.confirmButton.backgroundColor = UIColor(colorLiteralRed: 0.99, green: 0.82, blue: 0.04, alpha: 1)
        self.view.addSubview(self.confirmButton)
        self.confirmButton.snp_makeConstraints { (make) -> Void in
            make.left.equalTo(15)
            make.top.equalTo(self.formView.snp_bottom).offset(20)
            make.right.equalTo(-15)
            make.height.equalTo(44)
        }
    }

UITextField的代理

swift
 extension SnapkitViewController: UITextFieldDelegate {

    //输入框获取焦点开始编辑
    func textFieldDidBeginEditing(textField:UITextField)
    {
        let tag = textField.tag
        switch tag {
        case 100:
            UIView.animateWithDuration(0.5, animations: { () -> Void in
                self.topConstraint?.updateOffset(150)
                self.view.layoutIfNeeded()
            })
        case 101:
            UIView.animateWithDuration(0.5, animations: { () -> Void in
                self.topConstraint?.updateOffset(100)
                self.view.layoutIfNeeded()
            })
        case 102:
            UIView.animateWithDuration(0.5, animations: { () -> Void in
                self.topConstraint?.updateOffset(70)
                self.view.layoutIfNeeded()
            })
        default:
            print("error")
        }
    }

    //输入框返回时操作
    func textFieldShouldReturn(textField:UITextField) -> Bool
    {
        let tag = textField.tag
        switch tag {
        case 100:
            self.newPassword.becomeFirstResponder()
        case 101:
            //下一个
            self.confirmPassword.becomeFirstResponder()
        case 102:
            //收起键盘
            textField.resignFirstResponder()
            UIView.animateWithDuration(0.5, animations: { () -> Void in
                self.topConstraint?.updateOffset(200)
                self.view.layoutIfNeeded()
            })
        default:
            print(textField.text)
        }
        return true
    }
}

5.总结一下 UITextField

样式

swift
 UITextBorderStyle.None:无边框
 UITextBorderStyle.Line:直线边框
 UITextBorderStyle.RoundedRect:圆角矩形边框
 UITextBorderStyle.Bezel:边线+阴影

输入提示

```swift
textField.placeholder="请输入用户名"
````

内容设置

swift
//当文字超出文本框宽度时,自动调整文字大小
textField.adjustsFontSizeToFitWidth = true
//最小可缩小的字号
textField.minimumFontSize = 14

对齐方式

swift
 //水平右对齐
textField.textAlignment = .Right

 //水平居中对齐
textField.textAlignment = .Center

 //水平左对齐
textField.textAlignment = .Left

 //垂直向上对齐
textField.contentVerticalAlignment = .Top

  //垂直居中对齐
textField.contentVerticalAlignment = .Center

  //垂直向下对齐
textField.contentVerticalAlignment = .Bottom

设置清除按钮

swift
  //编辑时出现清除按钮
textField.clearButtonMode = UITextFieldViewMode.WhileEditing

  //编辑时不出现,编辑后才出现清除按钮
textField.clearButtonMode = UITextFieldViewMode.UnlessEditing

  //一直显示清除按钮
textField.clearButtonMode = UITextFieldViewMode.Always

设置键盘的类型

swift
Default:系统默认的虚拟键盘
ASCII Capable:显示英文字母的虚拟键盘
Numbers and Punctuation:显示数字和标点的虚拟键盘
URL:显示便于输入数字的虚拟键盘
Number Pad:显示便于输入数字的虚拟键盘
Phone Pad:显示便于拨号呼叫的虚拟键盘
Name Phone Pad:显示便于聊天拨号的虚拟键盘
Email Address:显示便于输入Email的虚拟键盘
Decimal Pad:显示用于输入数字和小数点的虚拟键盘
Twitter:显示方便些Twitter的虚拟键盘
Web Search:显示便于在网页上书写的虚拟键盘
//例子
textField.keyboardType = UIKeyboardType.NumberPad

焦点

swift
//获取焦点
textField.becomeFirstResponder()
//移除焦点
textField.resignfirstresponder()

设置返回return样式跟功能

swift
 //表示完成输入
textField.returnKeyType = UIReturnKeyType.Done

 //表示完成输入,同时会跳到另一页
textField.returnKeyType = UIReturnKeyType.Go

 //表示搜索
textField.returnKeyType = UIReturnKeyType.Search

 //表示注册用户或添加数据
textField.returnKeyType = UIReturnKeyType.Join

 //表示继续下一步
textField.returnKeyType = UIReturnKeyType.Next

 //表示发送
textField.returnKeyType = UIReturnKeyType.Send

代理

swift
//开始编辑时的操作
func textFieldDidBeginEditing()
//点击返回按钮时的操作
func textFieldShouldReturn()


文/zZ爱吃菜(简书作者)
原文链接:http://www.jianshu.com/p/bd67a4869b4d
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
接着分析 (result (type_ident (component id='Bool' bind=Swift.(file).Bool))) (brace_stmt range=[re.swift:1:59 - line:14:1] (pattern_binding_decl range=[re.swift:2:5 - line:2:33] (pattern_named type='[UInt8]' 'b') Original init: (call_expr type='[UInt8]' location=re.swift:2:19 range=[re.swift:2:13 - line:2:33] nothrow (constructor_ref_call_expr type='(String.UTF8View) -> [UInt8]' location=re.swift:2:19 range=[re.swift:2:13 - line:2:19] nothrow (declref_expr implicit type='(Array<UInt8>.Type) -> (String.UTF8View) -> Array<UInt8>' location=re.swift:2:19 range=[re.swift:2:19 - line:2:19] decl=Swift.(file).Array extension.init(_:) [with (substitution_map generic_signature=<Element, S where Element == S.Element, S : Sequence> (substitution Element -> UInt8) (substitution S -> String.UTF8View))] function_ref=single) (argument_list implicit (argument (type_expr type='[UInt8].Type' location=re.swift:2:13 range=[re.swift:2:13 - line:2:19] typerepr='[UInt8]')) )) (argument_list (argument (member_ref_expr type='String.UTF8View' location=re.swift:2:29 range=[re.swift:2:21 - line:2:29] decl=Swift.(file).String extension.utf8 (declref_expr type='String' location=re.swift:2:21 range=[re.swift:2:21 - line:2:21] decl=re.(file).check(_:_:).encoded@re.swift:1:14 function_ref=unapplied))) )) Processed init: (call_expr type='[UInt8]' location=re.swift:2:19 range=[re.swift:2:13 - line:2:33] nothrow (constructor_ref_call_expr type='(String.UTF8View) -> [UInt8]' location=re.swift:2:19 range=[re.swift:2:13 - line:2:19] nothrow (declref_expr implicit type='(Array<UInt8>.Type) -> (String.UTF8View) -> Array<UInt8>' location=re.swift:2:19 range=[re.swift:2:19 - line:2:19] decl=Swift.(file).Array extension.init(_:) [with (substitution_map generic_signature=<Element, S where Element == S.Element, S : Sequence> (substitution Element -> UInt8) (substitution S -> String.UTF8View))] function_ref=single) (argument_list implicit (argument (type_expr type='[UInt8].Type' location=re.swift:2:13 range=[re.swift:2:13 - line:2:19] typerepr='[UInt8]')) )) (argument_list (argument (member_ref_expr type='String.UTF8View' location=re.swift:2:29 range=[re.swift:2:21 - line:2:29] decl=Swift.(file).String extension.utf8 (declref_expr type='String' location=re.swift:2:21 range=[re.swift:2:21 - line:2:21] decl=re.(file).check(_:_:).encoded@re.swift:1:14 function_ref=unapplied))) ))) (var_decl range=[re.swift:2:9 - line:2:9] "b" type='[UInt8]' interface type='[UInt8]' access=private readImpl=stored writeImpl=stored readWriteImpl=stored)
06-10

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值