分类 CALayer 下的文章

模仿网易彩票

注意点:
1.在新建项目时,注意项目的目录结构
2.具有共同操作的类可以新建一个父类来完成公共的操作
3.把实现代码放在控制器类的不同生命周期时调用的方法中,可以避免做重复的操作
4.图片只显示某一部分
5.webView的使用
6.UICollectionViewController的使用
7.模态框的使用
8.自定义TabBarItem

1.目录结构就不说了,mvc
2.共同的父类,子类只要继承自父类,并完成自身的数据赋值即可
//
//  JinBaseTableViewController.swift
//  lottery
//
//  Created by admin on 16/2/4.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit
// 设置界面 UITableViewController 的父类,完成一些公共的操作
class JinBaseTableViewController: UITableViewController {
    // 存放设置选项模型数据
    var settings:[SettingGroup] = []
    override func viewDidLoad() {
        super.viewDidLoad()
        self.tableView.backgroundColor = UIColor(patternImage: UIImage(imageLiteral: "bg"))
    }

    // 重写构造方法,算是填了下坑吧
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName : nibNameOrNil, bundle : nibBundleOrNil)
    }
    override init(style: UITableViewStyle) {
        super.init(style: style)
        // 在这里设置背景色的话 viewDidload 方法会被调用两次
//        self.tableView.backgroundColor = UIColor(patternImage: UIImage(imageLiteral: "bg"))
    }
    required convenience init?(coder aDecoder: NSCoder) {
        //        fatalError("init(coder:) has not been implemented")
        self.init(style: UITableViewStyle.Grouped)
        //return nil
    }
    convenience init()
    {
        self.init(style: UITableViewStyle.Grouped)
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return self.settings.count
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return self.settings[section].settings.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = JinTableViewCell.instance(tableView, setingData: self.settings[indexPath.section].settings[indexPath.row])
        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        self.settings[indexPath.section].settings[indexPath.row].block?()
    }
    override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return self.settings[section].title
    }
    override func tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String? {
        return self.settings[section].footer
    }
}

子类代码

//
//  MyLotteryViewController.swift
//  lottery
//
//  Created by admin on 16/2/3.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class MyLotteryViewController: JinBaseTableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        self.navigationItem.title = "设置"

        let group1 = SettingGroup()
        group1.settings.append(Setting(title: "推送和提醒", titleImage: UIImage(imageLiteral: "handShake"), accessoryImage: UIImage(imageLiteral: "CellArrow"), block: {
            [unowned self] in
            let controller = PushAndRemindController()
            controller.navigationItem.title = "推送和提醒"
            self.navigationController?.pushViewController(controller, animated: true)
        }))

        group1.settings.append(Setting(title: "摇一摇机选", titleImage: UIImage(imageLiteral: "handShake"), accessory: UISwitch()))
        group1.settings.append(Setting(title: "声音和效果", titleImage: UIImage(imageLiteral: "handShake"), accessory: UISwitch()))
        self.settings.append(group1)
        let group2 = SettingGroup()
        group2.settings.append(Setting(title: "检查版本更新", titleImage: UIImage(imageLiteral: "handShake"), accessoryImage: UIImage(imageLiteral: "CellArrow"), block: {
                [unowned self] in
                let hud = MBProgressHUD.showHUDAddedTo(self.tableView, animated: true)
                hud.label.text = "正在检查更新"
                let time = dispatch_time(DISPATCH_TIME_NOW, Int64(UInt64(2) * NSEC_PER_SEC))
                dispatch_after(time, dispatch_get_main_queue(), {
                    let image = UIImage(imageLiteral: "Checkmark").imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
                    let imageView = UIImageView(image: image)
                    hud.customView = imageView
                    hud.mode = MBProgressHUDMode.CustomView
                    hud.label.text = "已是最新版本"
                    hud.hideAnimated(true, afterDelay: 1)
                })
            }))
        group2.settings.append(Setting(title: "帮助", titleImage: UIImage(imageLiteral: "handShake"), accessoryImage: UIImage(imageLiteral: "CellArrow"), block: {
            [unowned self] in
            let controller = HelpViewController()
            // 因为是自定义的 UITabBarItem 所以这里设置了也无效
//            controller.hidesBottomBarWhenPushed = false
            controller.navigationItem.title = "帮助"

            self.navigationController?.pushViewController(controller, animated: true)
            }))
        group2.settings.append(Setting(title: "分享", titleImage: UIImage(imageLiteral: "handShake"), accessoryImage: UIImage(imageLiteral: "CellArrow")))
        group2.settings.append(Setting(title: "查看消息", titleImage: UIImage(imageLiteral: "handShake"), accessoryImage: UIImage(imageLiteral: "CellArrow")))
        group2.settings.append(Setting(title: "产品推荐", titleImage: UIImage(imageLiteral: "handShake"), accessoryImage: UIImage(imageLiteral: "CellArrow"), block: {
            [unowned self] in
            let controller = ProductViewController(collectionViewLayout : UICollectionViewFlowLayout())
            controller.navigationItem.title = "产品推荐"
            self.navigationController?.pushViewController(controller, animated: true)
            }))
        group2.settings.append(Setting(title: "投信", titleImage: UIImage(imageLiteral: "handShake"), accessoryImage: UIImage(imageLiteral: "CellArrow")))
        self.settings.append(group2)
    }

}
3.在控制器特定的生命周期做操作,可以避免重复的操作
//
//  JinNavigationController.swift
//  lottery
//
//  Created by admin on 16/2/3.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class JinNavigationController: UINavigationController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // 修改navgation标题栏的样式,在这里改也行,但是这个方法会执行多次,所以最好使用 initialize
//        self.navigationBar.setBackgroundImage(UIImage(imageLiteral: "NavBar64"), forBarMetrics: UIBarMetrics.Default)
//        self.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName:UIColor.whiteColor(),NSFontAttributeName:UIFont.systemFontOfSize(20)]
        // Do any additional setup after loading the view.
    }
    override func preferredStatusBarStyle() -> UIStatusBarStyle {
        return UIStatusBarStyle.LightContent
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    // 当类第一次创建的时候调用这个方法,避免执行多次
    override class func initialize()
    {
        // 获取UINavigationBar对象
        weak var nav = UINavigationBar.appearance()
        // 设置背景图片
        nav!.setBackgroundImage(UIImage(imageLiteral: "NavBar64"), forBarMetrics: UIBarMetrics.Default)
        // 设置字体属性
        nav!.titleTextAttributes = [NSForegroundColorAttributeName:UIColor.whiteColor(),NSFontAttributeName:UIFont.systemFontOfSize(20)]
        // 设置返回按钮颜色
        nav!.tintColor = UIColor.whiteColor()
    }
}
4.图片显示某一部分
//
//  SquareViewController.swift
//  lottery
//
//  Created by admin on 16/2/4.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class SquareViewController: UIViewController {
    @IBOutlet weak var wheel: UIImageView!
    var link:CADisplayLink!
    var highlightedButton:UIButton!
    override func viewDidLoad() {
        // 转盘背景图片
        let imageView = UIImageView(image: UIImage(imageLiteral: "LuckyBackground"))
        imageView.frame = self.view.bounds
        self.view.insertSubview(imageView, atIndex: 0)
        // 获得屏幕scale,之后截取图片的时候会用到,不然图片截取之后是不规则的
        let scale = UIScreen.mainScreen().scale
        // 获得选项按钮背景图片
        let strology = UIImage(imageLiteral: "LuckyAstrology")
        let strologyPressed = UIImage(imageLiteral: "LuckyAstrologyPressed")
        // 获得截取图片的宽度
        let buttonW = strology.size.width / 12
        // 获得选项按钮的宽度
        let buttonFrame = CGRectMake(0, 0, buttonW, wheel.bounds.size.width * 0.5)
        // 设置图层的anchorPoint的值,旋转是围绕这个点旋转的
        let buttonLayerAnchorPoint = CGPointMake(0.5, 1)
        // 选项按钮放倒转盘中
        for var i = 0;i < 12;i++
        {
            let button = JinButton(type: UIButtonType.Custom)
            button.tag = i + 1
            button.frame = buttonFrame
            button.layer.anchorPoint = buttonLayerAnchorPoint
            button.center = CGPointMake(self.wheel.bounds.size.width * 0.5, self.wheel.bounds.size.width * 0.5)
            // 从大图片中截取一部分作为当前按钮的背景图片
            var buttonImage = CGImageCreateWithImageInRect(strology.CGImage, CGRectMake(buttonW * CGFloat(i) * scale, 0, buttonW * scale, strology.size.height * scale))
            button.setImage(UIImage(CGImage: buttonImage!), forState: UIControlState.Normal)
            buttonImage = CGImageCreateWithImageInRect(strologyPressed.CGImage, CGRectMake(buttonW * CGFloat(i) * scale, 0, buttonW * scale, strology.size.height * scale))
            // 设置选中状态下的图片
            button.setImage(UIImage(CGImage: buttonImage!), forState: UIControlState.Selected)
            button.setBackgroundImage(UIImage(imageLiteral: "LuckyRototeSelected"), forState: UIControlState.Selected)
            // 设置当前按钮的transform
            button.transform = CGAffineTransformMakeRotation(CGFloat(M_PI) / 6 * CGFloat(i))
            // 禁用高亮
            button.adjustsImageWhenHighlighted = false

            button.addTarget(self, action: "choiceNumber:", forControlEvents: UIControlEvents.TouchDown)
            self.wheel.addSubview(button)
        }
        // 添加开始选号按钮
        let choiceNumberButton = UIButton(type: UIButtonType.Custom)
        let choiceNumberButtonImage = UIImage(imageLiteral: "LuckyCenterButton")
        choiceNumberButton.bounds = CGRectMake(0, 0, choiceNumberButtonImage.size.width, choiceNumberButtonImage.size.height)
        choiceNumberButton.setBackgroundImage(choiceNumberButtonImage, forState: UIControlState.Normal)
        choiceNumberButton.setBackgroundImage(UIImage(imageLiteral: "LuckyCenterButtonPressed"), forState: UIControlState.Highlighted)
        choiceNumberButton.addTarget(self, action: "choiceNumberButtonClicked", forControlEvents: UIControlEvents.TouchDown)
        choiceNumberButton.center = self.wheel.center
        self.view.addSubview(choiceNumberButton)
        self.timer()
    }
    // 开始定时器
    func timer()
    {
        self.link = CADisplayLink(target: self, selector: "startRotation")
        self.link.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
    }
    // 旋转
    func startRotation()
    {
        self.wheel.transform = CGAffineTransformRotate(self.wheel.transform, CGFloat(M_PI) * 0.001)
    }
    // 选项按钮点击事件
    func choiceNumber(button:UIButton)
    {
        self.highlightedButton?.selected = false
        button.selected = true
        self.highlightedButton = button
    }
    func choiceNumberButtonClicked()
    {
        self.link?.invalidate()
        self.link = nil
        self.view.userInteractionEnabled = false
        UIView.transitionWithView(self.wheel, duration: 3, options: UIViewAnimationOptions.CurveEaseInOut, animations: {
                [unowned self] in
                self.wheel.transform = CGAffineTransformRotate(self.wheel.transform, CGFloat(M_PI * 0.9))
            }, completion: {
                [unowned self] bool in
                let tag = Int(arc4random_uniform(12)) + 1
                let button:UIButton = self.wheel.viewWithTag(tag) as! UIButton
                self.choiceNumber(button)
                self.view.userInteractionEnabled = true
                //这里设置下延时执行,之前没用过的一种方式,这个参数有一些特别,而且没有提示。。。。记录下
                let minseconds = 3 * Double(NSEC_PER_SEC)
                let dtime = dispatch_time(DISPATCH_TIME_NOW, Int64(minseconds))
                if self.link == nil
                {
                    dispatch_after(dtime, dispatch_get_main_queue(), { [unowned self] () -> Void in
                        self.timer()
                    })
                }
        })
    }
}
5.webView的使用
//
//  HtmlViewController.swift
//  lottery
//
//  Created by admin on 16/2/4.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class HtmlViewController: UIViewController,UIWebViewDelegate {
    weak var help:Help!
    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = self.help.title
        let webview = UIWebView(frame: UIScreen.mainScreen().bounds)
        webview.delegate = self
        // 获得html文件路径
        let path = NSBundle.mainBundle().pathForResource("help.html", ofType: nil)
        // 获得请求字串
        let request = NSURLRequest(URL: NSURL(fileURLWithPath: path!))
        // 使用webView加载html
        webview.loadRequest(request)
        // 因为是使用模态框加载的这个控制器,所以需要手动设置下返回按钮
        self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "返回", style: UIBarButtonItemStyle.Plain, target: self, action: "back")
        // 把webView添加进视图
        self.view.addSubview(webview)
    }
    // 返回之前的控制器
    func back()
    {
        self.dismissViewControllerAnimated(true, completion: nil)
    }
    // webView代理方法,加载完成时调用
    func webViewDidFinishLoad(webView: UIWebView) {
        // 执行js代码
        let jsCode = "window.location.href='#\(self.help.id)'"
        webView.stringByEvaluatingJavaScriptFromString(jsCode)
    }
}
6.UICollectionViewController的使用
//
//  ProductViewController.swift
//  lottery
//
//  Created by admin on 16/2/4.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit
let collectionIdentifier = "jinCollectionCell"
class ProductViewController: UICollectionViewController {
    // 产品数据模型数组
    lazy var products:[Product] = Product.instanceOfFile()
    // 重写构造方法
    override init(collectionViewLayout layout: UICollectionViewLayout) {
        // cell的大小是通过Layout来控制
        let layout = UICollectionViewFlowLayout()
        layout.itemSize = CGSizeMake(100, 120)
        super.init(collectionViewLayout : layout)
    }
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName : nibNameOrNil, bundle : nibBundleOrNil)
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        self.collectionView?.backgroundColor = UIColor.whiteColor()
        // 和tableView不同的是,需要先注册cell
//        self.collectionView?.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: collectionIdentifier)
        self.collectionView?.registerNib(UINib(nibName: "JinCollectionCell", bundle: NSBundle.mainBundle()), forCellWithReuseIdentifier: collectionIdentifier)
    }
    // 返回分组数
    override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }
    // 返回分组数据条数
    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.products.count
    }
    // 返回cell
    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        // 从缓冲池中获取cell
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(collectionIdentifier, forIndexPath: indexPath) as! JinCollectionCell
        cell.product = self.products[indexPath.row]
        return cell
    }
    override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        let appliction = UIApplication.sharedApplication()
        // 打开url
        appliction.openURL(NSURL(string: self.products[indexPath.row].url)!)
    }
}
7.模态框的使用
//
//  HelpViewController.swift
//  lottery
//
//  Created by admin on 16/2/4.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class HelpViewController: JinBaseTableViewController {
    var helps:[Help] = Help.instanceOfFile()
    override func viewDidLoad() {
        super.viewDidLoad()
        print(helps)
        let group1 = SettingGroup()
        helps.forEach({
            val in
            group1.settings.append(Setting(title: val.title!, accessoryImage: UIImage(imageLiteral: "CellArrow")))
        })

        self.settings.append(group1)
    }
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        // 创建要显示的控制器
        let html = HtmlViewController()
        html.help = self.helps[indexPath.row]
        // 创建导航控制器并把要显示的控制器作为根控制器
        let nav = UINavigationController(rootViewController: html)
        // 显示模态窗口
        self.presentViewController(nav, animated: true, completion: nil)
    }
}
8.自定义TabBarItem
//
//  JinTabBarItem.swift
//  lottery
//
//  Created by admin on 16/2/3.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit
// 自定义协议
@objc protocol JinTabBarItemDelegate
{
    optional func tabBarButtonClicked(index:Int)
}
// 自定义 tabbaritem 类
class JinTabBarItem: UIView {

    // 记录当前选中状态的按钮
    weak var selectedTabBarButton:UIButton!
    // 当前对象代理
    weak var tabBarButtonDelegate:JinTabBarItemDelegate!
    // 添加item按钮
    func addTabBarButton(normalImage:String,selectedImage:String)
    {
        let tabBarButton = UIButton(type: UIButtonType.Custom)
        // 设置图片
        tabBarButton.setBackgroundImage(UIImage(imageLiteral: normalImage), forState: UIControlState.Normal)
        tabBarButton.setBackgroundImage(UIImage(imageLiteral: selectedImage), forState: UIControlState.Selected)
        // 设置图片方法
        tabBarButton.addTarget(self, action: "changeTabBarButtonStatus:", forControlEvents: UIControlEvents.TouchDown)
        // button 没有 setHighlighted 方法啊  我去
        tabBarButton.adjustsImageWhenHighlighted = false
        self.addSubview(tabBarButton)
    }
    // 按钮被点击时的响应事件
    func changeTabBarButtonStatus(button:UIButton)
    {
        // 修改当前选中按钮状态
        self.selectedTabBarButton?.selected = false
        // 修改当前点击按钮状态
        button.selected = true
        // 修改当前被选中的按钮
        self.selectedTabBarButton = button
        // 执行代理方法
        self.tabBarButtonDelegate?.tabBarButtonClicked?(self.subviews.indexOf(button)!)
    }
    // 完成按钮的布局
    override func layoutSubviews() {
        // 获得当前的子按钮数量
        let buttonCount = self.subviews.count
        // 获得当前状态下按钮的宽度
        let buttonWidth = self.frame.size.width / CGFloat(buttonCount)
        for(var i = 0;i < buttonCount;i++)
        {
            let tabBarButton = self.subviews[i] as! UIButton
            // 默认第一个按钮为选中
            if i == 0
            {
                self.changeTabBarButtonStatus(tabBarButton)
            }
            // 设置按钮fram
            tabBarButton.frame = CGRectMake(CGFloat(i) * buttonWidth, 0, buttonWidth, self.frame.size.height)
        }
    }
}

代码网址:https://git.oschina.net/JinDev/lottory.git

动画总结

//
//  ViewController.swift
//  动画总结
//
//  Created by admin on 16/1/29.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var image: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // 控件的center和控件layer的position是默认相等的
        print(self.image.center)
        // anchorPoint相对于上级layer的坐标,注意anchorPoint和position的互相影响
        print(self.image.layer.position)
        print(self.image.layer.anchorPoint)
    }
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.animationD()
    }
    // 核心动画,需要知道的事,动画改编的position是假象,其实值并没有改变,只是看上去变了
    func animationD()
    {
        let animation = CABasicAnimation(keyPath: "position")
        animation.duration = 3
        animation.delegate = self
        self.image.layer.position = CGPointMake(100, 100)
        print("开始时的position")
        print(self.image.layer.position)
        self.image.layer.addAnimation(animation, forKey: nil)
    }
    override func animationDidStop(anim: CAAnimation, finished flag: Bool) {
        print("结束时的position")
        print(self.image.layer.position)
    }
    // 这个好。。
    func animationC()
    {
        UIView.transitionWithView(self.image, duration: 3, options: UIViewAnimationOptions.TransitionCurlDown, animations: {
                self.image.image = UIImage(imageLiteral: "2")
            }, completion: {
                _ in
            print("动画执行完成")
        })
    }
    //
    func animationB()
    {
        UIView.animateWithDuration(3, animations: {
            // 切换图片没有动态
            self.image.center = CGPointMake(100, 100)
        })
    }
    // UIView动画
    func animationA()
    {
        UIView.beginAnimations(nil, context: nil)
        // 设置事件
        UIView.setAnimationDuration(3)
        // 设置代理
        UIView.setAnimationDelegate(self)
        UIView.setAnimationDidStopSelector("stop")
        // 实现动画代码,切换图片没有效果。。。
        self.image.center = CGPointMake(100, 100)
        UIView.commitAnimations()
    }
    func stop()
    {
        print("动画结束啦")
    }
}

图层(CALayer)的基本使用

//
//  ViewController.swift
//  图层_layer基本使用
//
//  Created by admin on 16/1/27.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!
    weak var childLayer:CALayer!
    override func viewDidLoad() {
        super.viewDidLoad()
        // 设置圆角的同时设置阴影,需要先将图片切成圆角,再设置阴影
        // self.imageView.layer.contents = self.corrnerImage().CGImage
        // self.transform(self.imageView.layer)
        // self.position()
        self.animation()
    }
    // 隐式动画,注意根层layer是没有隐式动画的
    func animation()
    {
        self.imageView.layer.contents = self.corrnerImage().CGImage
        let layer = CALayer()
        layer.frame = CGRectMake(100, 100, 100, 100)
        layer.contents = self.corrnerImage().CGImage
        self.imageView.layer.addSublayer(layer)
        // 给变量属性,方便之后使用
        self.childLayer = layer
    }
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        CATransaction.begin()
        // 关闭子层的动画
//        CATransaction.setDisableActions(true)
        // 设置动画执行的时间
        CATransaction.setAnimationDuration(10)
        self.imageView.layer.transform = CATransform3DMakeScale(1.5, 1.5, 1.5)
        self.childLayer.transform = CATransform3DMakeScale(1.5, 1.5, 1.5)
        CATransaction.commit()
    }
    // 使用自定义layer
    func layer()
    {
        let layer = ViewController.MyLayer()
        layer.frame = CGRectMake(0, 0, 100, 100)
        self.view.layer.addSublayer(layer)
        // 和自定义view不同的是,自定义layer要显示,需要调用下 setNeedsDisplay 方法
        layer.setNeedsDisplay()
    }
    // 自定义layer
    class MyLayer: CALayer {
        // 渲染 layer 内容
        override func drawInContext(ctx: CGContext) {
            CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 100, 100))
            UIColor.redColor().set()
            CGContextFillPath(ctx)
        }
    }
    // position 和 anchorPoint
    func position()
    {
        let layer = CALayer()
        layer.frame = CGRectMake(0, 0, 100, 100)
        layer.backgroundColor = UIColor.blackColor().CGColor
        // 设置位置,这里的位置其实是设置锚点的坐标
        layer.position = CGPoint(x: 100, y: 100)
        // 设置锚点
        layer.anchorPoint = CGPoint(x: 0, y: 1)

        self.view.layer.addSublayer(layer)
    }
    // layer的形变属性
    func transform(layer:CALayer)
    {
        // 因为这里和之前的view的transform不一样,需要理解3d是什么样的,3d的有三个方向(正方体的一个角的三条棱可以作为参照),所以有三个坐标值,分别对应(x,y,z)
        // 平移,3d的有三个方向,所以有三个值,分别对应(x,y,z),注意这里最后一个是无效的
        layer.transform = CATransform3DMakeTranslation(10, 20, 0)
        // 缩放,最后一个属性无效
        layer.transform = CATransform3DMakeScale(1, 0.5, 10)
        // 旋转,参数分别对应(角度,x轴是否旋转,y轴是否旋转,z轴是否旋转)
        layer.transform = CATransform3DMakeRotation(CGFloat(M_PI * 0.3), 1, 1, 1)

        // kvc方式赋值,注意这里需要用 NSValue 转换下
        layer.setValue(NSValue.init(CATransform3D: CATransform3DMakeScale(1.5, 1, 0)), forKey: "transform")
        // kvc forKeyPath方式
        layer.setValue(1.1, forKeyPath: "transform.scale.x")
        // 不具体指定某个值
        layer.setValue(NSValue.init(CGPoint: CGPoint(x: 100, y: 10)), forKeyPath: "transform.translation")
    }
    // 获得圆角带边框图片
    func corrnerImage()->UIImage
    {
        let image = UIImage(imageLiteral: "3")
        UIGraphicsBeginImageContextWithOptions(image.size, false, 0)
        let layer = CALayer()
        layer.bounds = CGRectMake(0, 0, image.size.width, image.size.width)
        layer.contents = image.CGImage
        layer.cornerRadius = 10
        layer.masksToBounds = true
        layer.borderColor = UIColor.whiteColor().CGColor
        layer.borderWidth = 5
        layer.renderInContext(UIGraphicsGetCurrentContext()!)
        let resImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return resImage
    }
    // 图层常用属性
    func layerAttr()
    {
        //        self.imageView.image = UIImage(imageLiteral: "2")
        // 使用了auto layout下面的设置是无效的
        self.imageView.layer.frame = CGRectMake(self.imageView.frame.origin.x, self.imageView.frame.origin.y, 300, 200)
        self.imageView.layer.bounds = CGRectMake(0, 0, 300, 200)
        // 圆角,两个属性一起使用才有效
        self.imageView.layer.cornerRadius = 10
        //        self.imageView.layer.masksToBounds = true
        // 设置图层背景颜色
        //        self.imageView.layer.backgroundColor = UIColor.redColor().CGColor
        // 设置layer背景,一般是个图片,
        self.imageView.layer.contents = UIImage(imageLiteral: "2").CGImage
        // 设置阴影,注意color和opacity要同时使用才能看到阴影,再就是,如果使用了剪切的话,阴影设置是无效的
        self.imageView.layer.shadowColor = UIColor.blackColor().CGColor
        // 阴影起始位置相对于原view的位置
        self.imageView.layer.shadowOffset = CGSize(width: 10, height: 10)
        // 阴影的透明度,默认是完全透明的
        self.imageView.layer.shadowOpacity = 0.5
        // 阴影的圆角
        self.imageView.layer.shadowRadius = 10
        // 边框,注意两个属性要配合使用才有效
        self.imageView.layer.borderColor = UIColor.whiteColor().CGColor
        self.imageView.layer.borderWidth = 5
    }
}