手把手教你通過Quartz2D制作彩色涂鴉板和手勢解鎖

我們已經(jīng)學習完了Quartz2D的一些基本的用法硫豆,在實際開發(fā)過程中龙巨,經(jīng)常使用Quartz2D,可以幫助我們少使用蘋果自帶的控件熊响,直接畫圖到上下文旨别,對系統(tǒng)的性能是一個非常好的優(yōu)化方式。Quartz2D的功能強大汗茄,絕逼不是畫線秸弛,繪制圖片那么easy,今天講一下他在實際項目中的應用洪碳,順便將思路理清楚递览,方便大家看涂鴉板demo,還有手勢解鎖


文章中的幾個demo

  • 1.使用圖形上下文制作涂鴉板
  • 2.使用貝塞爾路徑制作涂鴉板
  • 3.手勢解鎖

下面詳細的介紹一下項目的思路

一.使用圖形上下文制作涂鴉板
效果圖
點擊保存偶宫,在相冊中的圖片

分析
1.涂鴉板實際上就是繪制很多的線條
2.保存線條非迹,使用可變數(shù)組
3.使用上下文繪制圖片,使用drawRect方法
4.和屏幕交互纯趋,應該使用touchesBegin方法

代碼分析

1.自定義一個DBPainterView
2.在view中生成一個可變數(shù)組作為變量,懶加載處理,可以供程序使用

    //MARK: - 懶加載屬性
    //用于盛放所有單個路徑的數(shù)組
    private lazy var pointArr:NSMutableArray = {
        return NSMutableArray()
    }()

3.實現(xiàn)touchesBegin吵冒,touchesMoved,touchesEnd方法

    //MARK: - 重寫touch三個方法
    //touchBegin
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let touch = touches.first
        let startPoint = touch?.locationInView(touch?.view)
        let linePathArr = NSMutableArray()
        
        linePathArr.addObject(NSValue.init(CGPoint: startPoint!))
        pointArr.addObject(linePathArr)
        
        setNeedsDisplay()
    }
    
    //touchMoved
    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let touch = touches.first
        let startPoint = touch?.locationInView(touch?.view)
        let lastLineArr = pointArr.lastObject
        lastLineArr!.addObject(NSValue.init(CGPoint: startPoint!))
        setNeedsDisplay()
    }
    
    //touchEnd
    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let touch = touches.first
        let startPoint = touch?.locationInView(touch?.view)
        let lastLineArr = pointArr.lastObject
        lastLineArr!.addObject(NSValue.init(CGPoint: startPoint!))
        setNeedsDisplay()
    }

代碼分析纯命,
3.1.touchesBegin就是開始繪制,現(xiàn)在沒有拿到路徑的具體的點痹栖,所以我們應該給每一個路勁用一個小數(shù)組保存所有點的數(shù)組** linePathArr(保存每一根line的數(shù)組)亿汞,每一次調(diào)用都應該是創(chuàng)建一個新的路徑(新的linePathArr),然后加到保存所有路徑的數(shù)組中( pointArr保存了所有l(wèi)ine的數(shù)組)揪阿,然后調(diào)用setNeedsDisplay方法疗我,繪制路徑
3.2.touchesMoved方法是手指在屏幕移動的時候調(diào)用的,頻率最高南捂,就是一直在添加point吴裤,說白了,就是給最新添加的那個路徑添加點溺健,所以應當找到數(shù)組中最后一個路徑麦牺,然后給這個路徑添加point,let lastLineArr = pointArr.lastObject,lastLineArr!.addObject(NSValue.init(CGPoint: startPoint!))
3.3.touchEnd方法和
2**的事情是一樣的鞭缭,所以可以提煉一下代碼剖膳,我就不寫了

4.繪制圖片 drawRect

    override func drawRect(rect: CGRect) {
        let ctx = UIGraphicsGetCurrentContext()
        for index in 0 ..< pointArr.count
        {
            //獲取單根線
            let linePathArr = pointArr.objectAtIndex(index)
              for j in 0 ..< linePathArr.count
              {
                let point = linePathArr.objectAtIndex(j).CGPointValue()
                if j == 0 {
                    CGContextMoveToPoint(ctx, point.x, point.y)
                }else
                {
                    CGContextAddLineToPoint(ctx, point.x, point.y)
                }
            }
         }
        //設置上下文的屬性
        CGContextSetLineWidth(ctx, 3)
        UIColor.redColor().set()
        CGContextSetLineCap(ctx, CGLineCap.Round)
        //渲染
        CGContextStrokePath(ctx)
    }

}

4.1 首先遍歷大數(shù)組A,獲取每一條線(所有點)的數(shù)組B岭辣,遍歷B中所有的點吱晒,但是B中的第一個b[0]應該是調(diào)用CGContextMoveToPoint,b[其他]應當調(diào)用CGContextAddLineToPoint方法,
4.2.可以設置一下圖形上下文的屬性沦童,最后渲染就好了.
4.3 可以設置好多種顏色枕荞,使用圖形上下文棧就可以實現(xiàn)

5.DBPainterView 對外實現(xiàn)的“上一步”,"清空",“保存”功能

//刪除
    func clear(){
       pointArr.removeAllObjects()
        setNeedsDisplay()
    }
    //上一步
    func preview()
    {
        pointArr.removeLastObject()
        setNeedsDisplay()
    }
    //保存到本地
    func saveToAbum() {
        //保存圖片的事件
        UIGraphicsBeginImageContextWithOptions(self.frame.size, false, 0.0)
        let ctx = UIGraphicsGetCurrentContext()
       self.layer.renderInContext(ctx!)
        //獲取圖片
        let image = UIGraphicsGetImageFromCurrentImageContext()
        //結(jié)束位圖上下文
        UIGraphicsEndImageContext()
        UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
    }

代碼太簡單搞动,就不解釋了哈

二.使用貝塞爾路徑制作涂鴉板
彩色畫板

剛才使用了圖形上下文繪制路徑躏精,感覺還行,但是可以簡化鹦肿,剛才說的將一個路徑的所有點放到路徑的數(shù)組中矗烛,然后根據(jù)點來繪制,可以理解箩溃,但是會很麻煩瞭吃,因為底層就是通過CGContextPathRef繪制路徑的,因為CGContextPathRef是C語言涣旨,大數(shù)組不能添加它歪架,所以我們放棄,然后選擇貝塞爾路徑,他是oc中對象霹陡,非常適合制作涂鴉板

     //繪制一條路徑的寫法和蚪,非常的簡單
        let path = UIBezierPath()
        path.moveToPoint(CGPoint.init(x: 9, y: 9))
        path.addLineToPoint(CGPoint.init(x: 40, y: 50))
        path.stroke()

使用貝塞爾路徑制作涂鴉板的步驟(和圖形上下文基本一致)

  • 1.懶加載一個用來橙裝所有路徑的數(shù)組pathArr
  • 2.touchesBegin的時候止状,生成一個路徑,調(diào)用moveToPoint方法攒霹,添加起點怯疤,將path保存到數(shù)組中
  • 3.更改線寬和更改線的顏色,要個自定義的view設置lineWidth催束,和lineColor這個屬性集峦,最后要去給path設置這兩個屬性
 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let touch = touches.first
        let startPoint = touch?.locationInView(touch?.view)
        //1.創(chuàng)建路徑
        let path = UIBezierPath()
       //2.設置起點
        path.moveToPoint(startPoint!)
        //3.將path,添加到pathArr上
        pathArr.addObject(path)
        //4.繪圖
        setNeedsDisplay()
    }
  • 3.touchesMovedtouchesEnd方法功能一致抠刺,就合二為一了塔淤,就是獲取大數(shù)組中最后一個路徑,然后調(diào)用addLineToPoint方法
    //touchMoved
    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
        addPointToPath(touches)
    }
    
    //touchEnd
    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        addPointToPath(touches)
    }
    
    //touchMoved和touchEnd統(tǒng)一的代碼
    private func addPointToPath(touches: Set<UITouch>){
        let touch = touches.first
        let movePoint = touch?.locationInView(touch?.view)
        //獲取最后一個path
        let path = pathArr.lastObject as! UIBezierPath;
        path.addLineToPoint(movePoint!)
        setNeedsDisplay()
    }
    

4.繪制路徑

    override func drawRect(rect: CGRect) {
     //繪制線條
        for index in 0 ..< pathArr.count
        {
            let path = pathArr[index] as! UIBezierPath
             path.stroke()
        }
    }

5.添加線寬和線顏色的屬性

  //設置一個變量速妖,用來存儲線寬
    var lineWidth:CGFloat = 2;
    //設置一個變臉高蜂,用來存儲線顏色
    var lineColor:UIColor = UIColor.blackColor();

5.1 我們要將顏色和寬的的屬性使用到以后的線上,不能影響到過去的买优,所以妨马,應該在生成一個path的時候,直接設置他的這兩個屬性杀赢,因為path中沒有l(wèi)ineColor這個屬性烘跺,所以自定義一個DBBezierPath

class DBBezierPath: UIBezierPath {
    var lineColor:UIColor?
}

5.2 重新修改一下touchesBegin方法

//touchBegin
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let touch = touches.first
        let startPoint = touch?.locationInView(touch?.view)
        //1.創(chuàng)建路徑
        let path = DBBezierPath()
        path.lineWidth = lineWidth
        //2.設置線條的顏色
        path.lineColor = lineColor
       //2.設置起點
        path.moveToPoint(startPoint!)
        //3.將path,添加到pathArr上
        pathArr.addObject(path)
        //4.繪圖
        setNeedsDisplay()
    }

5.3 在渲染的時候脂崔,我們要將自定義的lineColor取出來滤淳,渲染

  override func drawRect(rect: CGRect) {
     //繪制線條
        for index in 0 ..< pathArr.count
        {
            let path = pathArr[index] as! DBBezierPath
             path.lineColor!.set()
             path.stroke()
        }
    }

5.4 這樣就可以制作出彩色的畫板了,而且其他保存砌左,上一步等功能都可以正常使用

使用了貝塞爾路徑脖咐,遠離了兩個數(shù)組,運行和理解起來超級簡單汇歹?


三.手勢解鎖
要做這樣的手勢解鎖控件

思路和注意點

  • 1.創(chuàng)建基本的九宮格樣式UI
  • 2.抽取方法類和自定義一個button(注意btn.userInteractionEnabled = false
  • 3.提出工具方法
    3.1 獲取當前的觸摸點
    3.2 判斷當前點是不是在btn中
  • 4.保存選中的所有按鈕
  • 5.通過選中的按鈕連線
    5.1 防止數(shù)組中多次添加同一個button
  • 6.使用touchesEnd方法清空數(shù)組
    6.1 給drawRect方法添加判空的條件
    6.2 重新繪制狀態(tài)
    6.3 使用makeObjectsSelect方法讓所有的button的選中狀態(tài)為NO
  • 7.繪制最后一個按鈕和手指移動的地點的連線
    7.1 在touchesMoved方法中保存手指的所在的point
    7.2 在drawRect方法中鏈接最后一個按鈕和point
    7.3 設置bezierPath的基本屬性
    7.4 解決剛剛點擊第一個按鈕屁擅,但是連線到CGPointZore的bug(在TouchBegin中清空,在drawRect判斷)
  • 8.減小觸摸button的響應范圍
  • 9.拼接用戶的觸摸路徑
  • 10.添加代理方法产弹,讓外界知道用戶的觸摸路徑(給代理添加IBOut)
  • 11.修改連線的具體顏色

代碼講解分析

1.創(chuàng)建基本的九宮格樣式UI

基本目標
  • 1.1 自定義一個GULockView派歌,然后使用經(jīng)典九宮格算法實現(xiàn)
 //設置初始化函數(shù),創(chuàng)建9個按鈕
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setUpBsicUI()
    }
    
    //初始化函數(shù)
    private func setUpBsicUI()
    {
        //創(chuàng)建九個按鈕
        for index in 0 ..< 9
        {
            let btn = GUButton.init(type: UIButtonType.Custom);
            addSubview(btn)
            btn.tag = index
            btn.addTarget(self, action: "btnClick:", forControlEvents: UIControlEvents.TouchUpInside)
        }
    }
  • 1.2 布局UI
    //設置九個按鈕的位置
    override func layoutSubviews() {
        super.layoutSubviews()
        //經(jīng)典的九宮格算法
        let totalColume = 3
        let bWidth:CGFloat = 74
        let bHeight:CGFloat = bWidth
        let margin = (self.frame.width - bWidth * CGFloat(totalColume))/CGFloat(totalColume+1)
        //自己的高度是bHeight*3
        
        for index in 0 ..< self.subviews.count
        {
        let currentRow = index/totalColume
        let currentColumn = index%totalColume
        let bX = margin + (CGFloat(currentColumn) * (bWidth+margin))
        let bY = CGFloat(currentRow) * (bHeight+margin)
        let btn = self.subviews[index]
        btn.frame = CGRectMake(bX, bY, bWidth, bHeight)
        
        }
    }

2.抽取方法類和自定義一個button

  • 2.1 自定義一個GUButton,設置內(nèi)部的圖片等樣式,
        setImage(UIImage.init(named: "gesture_node_normal"), forState: UIControlState.Normal)
        setImage(UIImage.init(named: "gesture_node_highlighted"), forState: UIControlState.Selected)
        setImage(UIImage.init(named: "gesture_node_disable"), forState: UIControlState.Disabled)
        contentMode = UIViewContentMode.Center
        userInteractionEnabled = false
  • 2.2btn.userInteractionEnabled = false 一定要寫
userInteractionEnabled = false
userInteractionEnabled = ture

這個涉及到了時間傳遞痰哨,我們馬上要去實現(xiàn)觸摸的三個方法胶果,如果手勢路過btn,恰巧userInteractionEnabled = ture斤斧,那么手勢直接讓btn截獲早抠,那么GULockView獲取不到手勢,造成了問題撬讽,所以一定要設置為no蕊连,(如果就是不想設置為no悬垃,其實也可以在自定義的CGButton中實現(xiàn)touches三個方法,調(diào)用super.touches三個方法往上傳遞咪奖,不推薦)

3.提出工具方法盗忱,設置btn被選中的條件

3.1 獲取當前的觸摸點

    /**
     獲取是否當前觸摸點的坐標
     :returns: 所在的點的坐標
     */
    private func pointWithTouches(touches: Set<UITouch>) -> CGPoint?
    {
        let touch = touches.first
        let locPoint = touch?.locationInView(touch?.view)
        return locPoint
    }

3.2 判斷當前點是不是在btn中

    /**
     判斷是否選中的點的依據(jù)
     :param: point 當前點
     :returns: 所在的按鈕酱床,可能沒有
     */
    private func buttonWithPoint(point:CGPoint) -> UIButton?
    {
        //遍歷數(shù)組羊赵,看看是不是在9個按鈕的里面
        for index in 0 ..< self.subviews.count
        {
            let b = self.subviews[index] as! UIButton
           let isIn = CGRectContainsPoint(b.frame, point)
            if isIn {
                return b
            }
        }
        return nil
    }

3.2 設置btn被選中的狀態(tài)


   //touchesMoved 和 touchesBegin此刻的內(nèi)容都是這個
    override func touchesMoved(touches: Set<UITouch>,
                               withEvent event: UIEvent?) {
        let point = pointWithTouches(touches)
        let locBtn = buttonWithPoint(point!)
        if (locBtn != nil)  {
            locBtn?.selected = true
        }

        setNeedsDisplay()
    }

4.保存選中的所有按鈕

可以通過一個數(shù)組來保存所有的按鈕

    //MARK: - 懶加載數(shù)組
    private lazy var btns:NSMutableArray = NSMutableArray()

touchesBegantouchesMoved方法中添加所選擇的按鈕

   if (locBtn != nil) {
            locBtn?.selected = true
            //添加到數(shù)組中
           btns.addObject(locBtn!)
        }

5.通過選中的按鈕連線

5.1 防止數(shù)組中多次添加同一個button

出現(xiàn)了問題,數(shù)組中添加了重復的btn

解決方法

//在判斷的時候扇谣,添加一個條件昧捷,是否selected == false 
  if (locBtn != nil && locBtn?.selected == false) {
            locBtn?.selected = true
            //添加到數(shù)組中
           btns.addObject(locBtn!)
        }

6.使用touchesEnd方法清空數(shù)組

   //手勢釋放時,要做的事情
   //1.應當清空數(shù)組罐寨,
   //2.應當將所選中的按鈕全部設置為selected == false 
   //3.重新繪制
   
           //遍歷所有的數(shù)組靡挥,是他的select == false
        for index in 0 ..< btns.count
        {
           let btn = btns[index] as! UIButton
            btn.selected = false
        }
        btns.removeAllObjects()
        setNeedsDisplay()

6.1 給drawRect方法添加判空的條件

//算是優(yōu)化吧,已經(jīng)入drawRect方法鸯绿,首先去判斷一下是不是空的
        if btns.count == 0 {
            return
        }

6.2 重新繪制狀態(tài)

    override func drawRect(rect: CGRect) {
        
        if btns.count == 0 {
            return
        }
        //使用UIBezierPath繪制路徑
        let bezierPath = UIBezierPath()
       for index in 0 ..< btns.count
       {
                //獲取每一個點
                let btn = btns[index]
                if index == 0 {
                    bezierPath.moveToPoint(btn.center)
                }else{
                   bezierPath.addLineToPoint(btn.center)
                }
        }
        bezierPath.lineWidth = 10
        bezierPath.lineJoinStyle = CGLineJoin.Round
        UIColor.blueColor().set()
        bezierPath.stroke()
    }

7.繪制最后一個按鈕和手指移動的地點的連線

7.1 在touchesMoved方法中保存手指的所在的point

        /// 當前觸摸點,默認是零
    private var currentPoint:CGPoint = CGPointZero

7.2 在drawRect方法中鏈接最后一個按鈕和point

//drawRect方法中跋破,可以這樣實現(xiàn)
          bezierPath.addLineToPoint(currentPoint)

7.3 設置bezierPath的基本屬性

        bezierPath.lineWidth = 10
        bezierPath.lineJoinStyle = CGLineJoin.Round
        UIColor.blueColor().set()
currentPoint一直沒有清空,所以touchesBegin的時候瓶蝴,鏈接點都是過去的那個毒返,只要清空就好

7.4 解決剛剛點擊第一個按鈕,但是連線到CGPointZore的bug(在TouchBegin中清空舷手,在drawRect判斷)

//添加最后一個線的和最后一個
        if (CGPointEqualToPoint(CGPointZero,currentPoint) == false) {
            bezierPath.addLineToPoint(currentPoint)
        }

8.減小觸摸button的響應范圍

現(xiàn)在的項目拧簸,你的鼠標剛剛到一個btn的邊緣,就已經(jīng)鏈接了線男窟,這樣的體驗不好盆赤,我們想去設定當手勢到了btn的圓心才連線(減小鏈接線的響應范圍)

    /**
     判斷是否選中的點的依據(jù)
     :param: point 當前點
     :returns: 所在的按鈕,可能沒有
     */
    private func buttonWithPoint(point:CGPoint) -> UIButton?
    {
        //遍歷數(shù)組歉眷,看看是不是在9個按鈕的里面
        for index in 0 ..< self.subviews.count
        {
            let b = self.subviews[index] as! UIButton
            let wh:CGFloat = 24
            let frameX = b.center.x - wh * 0.5
            let frameY = b.center.y - wh * 0.5
            
            let isIn = CGRectContainsPoint(CGRectMake(frameX, frameY, wh, wh), point)
//            let isIn = CGRectContainsPoint(b.frame, point)
            if isIn {
                return b
            }
        }
        return nil
    }

9.拼接用戶的觸摸路徑

    //拼接字符串牺六,保存用戶的觸摸路徑
    private func appendCode()
    {
        
        let code = NSMutableString()
        for var btn in btns {
            code.appendString("\(btn.tag)")
        }
        print(code)
    }

10.添加代理方法,讓外界知道用戶的觸摸路徑(給代理添加IBOut)

protocol GULockViewDelegate: NSObjectProtocol{
  //獲取用戶的手勢密碼
  func lockViewWithUserCode(lockView:GULockView,code:String)
}

添加屬性

    //代理
    weak var  delegate:GULockViewDelegate?

11.修改連線的具體顏色

你隨意吧~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末汗捡,一起剝皮案震驚了整個濱河市淑际,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌凉唐,老刑警劉巖庸追,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異台囱,居然都是意外死亡淡溯,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門簿训,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咱娶,“玉大人米间,你說我怎么就攤上這事”煳辏” “怎么了屈糊?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵搭盾,是天一觀的道長谱仪。 經(jīng)常有香客問我服爷,道長怕犁,這世上最難降的妖魔是什么咽筋? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任们妥,我火速辦了婚禮拥刻,結(jié)果婚禮上潭辈,老公的妹妹穿的比我還像新娘所袁。我一直安慰自己盏档,他們只是感情好,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布燥爷。 她就那樣靜靜地躺著蜈亩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪前翎。 梳的紋絲不亂的頭發(fā)上稚配,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音鱼填,去河邊找鬼药有。 笑死,一個胖子當著我的面吹牛苹丸,可吹牛的內(nèi)容都是我干的愤惰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赘理,長吁一口氣:“原來是場噩夢啊……” “哼宦言!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起商模,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤奠旺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后施流,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體响疚,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年瞪醋,在試婚紗的時候發(fā)現(xiàn)自己被綠了忿晕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡银受,死狀恐怖践盼,靈堂內(nèi)的尸體忽然破棺而出鸦采,到底是詐尸還是另有隱情,我是刑警寧澤咕幻,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布渔伯,位于F島的核電站,受9級特大地震影響肄程,放射性物質(zhì)發(fā)生泄漏锣吼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一绷耍、第九天 我趴在偏房一處隱蔽的房頂上張望吐限。 院中可真熱鬧鲜侥,春花似錦褂始、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至舀寓,卻和暖如春胆数,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背互墓。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工必尼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人篡撵。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓判莉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親育谬。 傳聞我的和親對象是個殘疾皇子券盅,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Quartz2D以及drawRect的重繪機制字數(shù)1487 閱讀21 評論1 喜歡1一、什么是Quartz2D Q...
    PurpleWind閱讀 773評論 0 3
  • 前言:看了幾篇簡書膛檀,九宮格密碼解鎖锰镀,看著不錯,拿來學習一下咖刃。 一泳炉、實現(xiàn)效果 二、手勢解鎖實現(xiàn)過程 分析: 如圖所示...
    麥穗0615閱讀 7,282評論 14 62
  • --繪圖與濾鏡全面解析 概述 在iOS中可以很容易的開發(fā)出絢麗的界面效果嚎杨,一方面得益于成功系統(tǒng)的設計花鹅,另一方面得益...
    韓七夏閱讀 2,731評論 2 10
  • 追女孩是個很奇怪的事情。追說明兩個人的地位并不平等磕潮。被追到的一方默認不是獨立的個體翠胰,而更像一只被捕獲的小鳥容贝。 如何...
    玩兒_溫暖閱讀 129評論 0 0
  • 作者:Paul Allen譯者:吳果錦出版社:浙江人民出版社版本:2012年3月第1版第1次印刷來源:下載的PDF...
    馬文Marvin閱讀 542評論 0 0