Core Graphics Tutorial Part 3: Patterns and Playgrounds

Core Graphics Tutorial Part 3: Patterns and Playgrounds

**Update 04/15/2015:**Updated for Xcode 6.3 and Swift 1.2

Welcome back to the third and final part of the Core Graphics tutorial series! Flo, your water drinking tracking app, is ready for its final evolution, which you’ll make happen with Core Graphics.

In the part one, you drew three custom-shaped controls with UIKit. Then in the part two, you created a graph view to show the user’s water consumption over a week, and you explored transforming the context transformation matrix (CTM).

In this third and final part, you’ll take Flo to its
final form. Specifically, you’ll:

  • Create a repeating pattern for the background.
  • Draw a medal from start to finish to award the users for successfully drinking eight glasses of water a day.

If you don’t have it already, download a copy of the Flo project from the second part of this series.

歡迎回到Core Graphics 教學系列的第三部分和最後一部分!Flo,你的water drinking tracking app將使用Core Graphics 進行最終的改進。

在[在第一部分](part one),你畫了三個自定義形狀的控件以及UIKit,在第二部分你創建了一個視圖用來顯示用戶在過去一週的喝水量,並且研究了transforming the context transformation matrix (CTM)

在這第三部分和最後一部分,你將使用它的最終格式,特別的是你將使用:

  • 創建一個重複的圖案背景
  • 從開始到結束,爲成功每天喝掉8杯水的用戶畫一枚獎章

如果你不想做,從本系列的第二部分下載Flo工程

Background Repeating Pattern 背景重複模式

Your mission in this section is to use UIKit’s pattern methods to create this background pattern:

你在這部分的任務是使用UIKit的方式創建這個背景圖案:

~
Note: If you need to optimize for speed, then work through
Core Graphics Tutorial: Patterns which demonstrates a basic
way to create patterns with Objective-C and Core Graphics.
For most purposes, like when the background is only drawn
once, UIKit’s easier wrapper methods should be acceptable.
~

注意:如果你需要對速度進行優化,接下來的工作就是通過Core Graphics Tutorial
演示一個基本的方法去創建一個格局使用Object-c和Core Graphics.針對實用性問題,
當背景僅被描繪一次,使用UIKit封裝好的簡易方法應該是可以被接受的

Go to File\New\File…**and select the iOS **iOS\Source\Cocoa Touch Class**template to create a class called **BackgroundView with a subclass of UIView. Click Next and then Create.

Go to Main.storyboard, select the main view of ViewController, and change the class to BackgroundView in the Identity Inspector.

點擊File\New\File…並且選擇IOS iOS\Source\Cocoa Touch Class 模版創建一個累起名爲BackgroundView的UIView。點擊下一步然後創建

進入Main.storyboard,在 Identity Inspector選擇ViewController主界面,改變爲BackgroundView

Set up BackgroundView.swift and Main.storyboard so they are side-by-side, using the Assistant Editor.
Replace the code in BackgroundView.swift with:

建立BackgroundView.swiftMain.storyboard,所以他們是並排的,使用Assistant Editor
替換BackgroundView.swift的代碼:

import UIKit

@IBDesignable

class BackgroundView: UIView {

  //1 
  @IBInspectable var lightColor: UIColor = UIColor.orangeColor()
  @IBInspectable var darkColor: UIColor = UIColor.yellowColor()
  @IBInspectable var patternSize:CGFloat = 200

  override func drawRect(rect: CGRect) {
    //2
    let context = UIGraphicsGetCurrentContext()

    //3
    CGContextSetFillColorWithColor(context, darkColor.CGColor)

    //4
    CGContextFillRect(context, rect)
  }
}

The background view of your storyboard should now be yellow. More detail on the above code:

  1. ightColor and darkColor have @IBInspectable attributes so it’s easier to configure background colors later on. You’re using orange and yellow as temporary colors, just so you can see what’s happening. **patternSize**controls the size of the repeating pattern. It’s initially set to large, so it’s easy to see what’s happening.
  2. UIGraphicsGetCurrentContext() gives you the view’s context and is also where **drawRect(_:)**draws.
  3. Use the Core Graphics method CGContextSetFillColorWithColor() to set the current fill color of the context. Notice that you need to use CGColor, a property of darkColor when using Core Graphics.
  4. Instead of setting up a rectangular path,CGContextFillRect() fills the entire context with the current fill color.

You’re now going to draw these three orange triangles using UIBezierPath(). The numbers correspond to the points in the following code:

  1. ightColordarkColor擁有@IBInspectable屬性,所以他更容易去配置背景顏色。你使用橙色和黃色作爲臨時色,你可以看看發生了什麼。patternSize控件控制着重複形式的大小。它的初始值設置的大一些,所以更容易看清發生了什麼。
  2. UIGraphicsGetCurrentContext()讓你瞭解上下部分哪些drawRect(_:)被描述。
  3. 使用Core Graphics的方法CGContextSetFillColorWithColor() 去設置當前上下文的填充色。注意當你使用Core Graphics需要用到darkColor的一個屬性
  4. 而不是建立一個矩形路徑,CGContextFillRect()使用當前填充色填充當前上下文的整個背景

你現在需要使用UIBezierPath()畫三個橙色的三角形。數字對應一下代碼中的點

Still in BackgroundView.swift, add this code to the end of drawRect(_:):
仍然在BackgroundView.swift中操作,在 drawRect(_:)末尾添加如下代碼:

let drawSize = CGSize(width: patternSize, height: patternSize)

//insert code here


let trianglePath = UIBezierPath()
//1
trianglePath.moveToPoint(CGPoint(x:drawSize.width/2, 
                                 y:0)) 
//2
trianglePath.addLineToPoint(CGPoint(x:0, 
                                    y:drawSize.height/2)) 
//3
trianglePath.addLineToPoint(CGPoint(x:drawSize.width, 
                                    y:drawSize.height/2)) 

//4
trianglePath.moveToPoint(CGPoint(x: 0, 
                                 y: drawSize.height/2)) 
//5
trianglePath.addLineToPoint(CGPoint(x: drawSize.width/2, 
                                    y: drawSize.height)) 
//6
trianglePath.addLineToPoint(CGPoint(x: 0, 
                                    y: drawSize.height)) 

//7
trianglePath.moveToPoint(CGPoint(x: drawSize.width, 
                                 y: drawSize.height/2)) 
//8
trianglePath.addLineToPoint(CGPoint(x:drawSize.width/2, 
                                    y:drawSize.height)) 
//9
trianglePath.addLineToPoint(CGPoint(x: drawSize.width, 
                                    y: drawSize.height)) 

lightColor.setFill()
trianglePath.fill()

Notice how you use one path to draw three triangles. moveToPoint(_:) is just like lifting your pen from the paper when you’re drawing and moving it to a new spot.

注意你如何使用一個路徑畫三個三角形,就像在紙上擡起你的筆從一個地方繪製和移動到另一個地方

Your storyboard should now have an orange and yellow image at the top left of your background view.

你的storyboard現在應該有一個橙色和黃的的圖像在你背景的左上方

So far, you’ve drawn directly into the view’s drawing context. To be able to repeat this pattern, you need to create an image outside of the context, and then use that image as a pattern in the context.

到目前爲止,你已經直接描繪了視圖上下部分,可以重複此模式,你需要創建一個外部圖像,然後使用這個圖片作爲背景圖案

Find the following. It’s close to the top of drawRect(_:), but after:
找到一一下部分,它接近頂部,接着

et drawSize = CGSize(width: patternSize, height: patternSize)

Add the following code where it conveniently says Insert code here:

然後插入一下代碼

UIGraphicsBeginImageContextWithOptions(drawSize, true, 0.0)
let drawingContext = UIGraphicsGetCurrentContext()

//set the fill color for the new context
darkColor.setFill()
CGContextFillRect(drawingContext,
      CGRectMake(0, 0, drawSize.width, drawSize.height))

Hey! Those orange triangles disappeared from the storyboard. Where’d they go?
嘿,那些橘黃色三角形從面板中消失了,他們去哪了?

**UIGraphicsBeginImageContextWithOptions()**creates a new context and sets it as the current drawing context, so you’re now drawing into this new context. The parameters of this method are:

  • The size of the context.
  • Whether the context is opaque — if you need transparency, then this needs to be false.
  • The scale of the context. If you’re drawing to a retina screen, this should be 2.0, and if to an iPhone 6 Plus, it should be 3.0. However, this uses 0.0, which ensures the correct scale for the device is automatically applied.

UIGraphicsBeginImageContextWithOptions()創建了一個新的視圖,並且將其設置爲當前的繪圖。剛方法的參數爲:

  • context大小
  • 背景是否透明— 如果你需要透明的, 這裏設置爲false.
  • context的大小. 如果你話一個視網膜屏幕, 這裏應該設置爲2, 對於 iPhone 6 Plus, 他應該爲3.0. 然而這裏使用0將自動適配屏幕

Then you used UIGraphicsGetCurrentContext() to get a reference to this new context.

然後使用 UIGraphicsGetCurrentContext()得到這個新的context

You then filled the new context with yellow. You could have let the original background show through by setting the context opacity to false, but it’s faster to draw opaque contexts than it is to draw transparent, and that’s argument enough to go opaque.

將這個新的context設置爲黃色。你可以通過設這context的屬性opacity爲false讓原來的背景色顯示。

Add this code to the end of drawRect(_:):
drawRect(_:)添加一下代碼

let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

This extracts a UIImage from the current context. When you end the current context with UIGraphicsEndImageContext(), the drawing context reverts to the view’s context, so any further drawing in drawRect(_:) happens in the view.

在當前的context提取。當你使用UIGraphicsEndImageContext()結束context,描繪的context還原視圖的context,所以在任何未來在drawRect(_:) 中的的繪圖都發生在view

To draw the image as a repeated pattern, add this code to the end of drawRect(_:):

把圖像作爲重複圖案,在drawRect(_:)末尾添加代碼:

UIColor(patternImage: image).setFill()
CGContextFillRect(context, rect)

This creates a new UIColor by using an image as a color instead of a solid color.

創建了一個新的UIColor通過使用圖像作爲背景顏色,而不是固定色。

Build and run the app. You should now have a rather bright background for your app. :

構建並且運行app,你現在的app應該有一個明亮的背景:

Go to Main.storyboard, select the background view, and in the Attributes Inspector change the @IBInspectable values to the following:

去Main.storyboard,選擇background view,並且在Attributes Inspector改變IBInspectable屬性的值爲以下:

  • Light Color: RGB(255, 255, 242)
  • Dark Color: RGB(223, 255, 247)
  • Pattern Size: 30

Experiment a little more with drawing background patterns. See if you can get a polka dot pattern as a background instead of the triangles.

嘗試去畫一些背景圖案,看看能不能得到一個園作爲背景圖案,而不是三角形。

And of course, you can substitute your own non-vector images as repeating patterns.

當然,你可以使用自己的非矢量圖作爲背景圖案

Drawing Images 繪製圖像

In the final stretch of this tutorial, you’ll make a medal to handsomely reward users for drinking enough water. This medal will appear when the counter reaches the target of eight glasses.

在本教程的最後階段,你將爲和足夠水的人送上一個獎牌,當計數器紀錄的數量達到8杯的時候獎牌將出現

I know that’s certainly not a museum-worthy piece of art, so please know that I won’t be offended if you improve it, or even take it to the next level by draw a trophy instead of a medal. ;]

我知道那並會像博物館裏的一件藝術品,所以請你知道,如果你提升它,我並不會生氣,甚至你可以通過畫一個獎盃而不是獎牌

Instead of using @IBDesignable, you’ll draw it in a Swift Playground, and then copy the code to a UIImageView subclass. Though interactive storyboards are often useful, they have limitations; they only draw simple code, and storyboards often time out when you create complex designs.

你描繪它將使用swift,然後複製這段代碼到UIImageView子集。雖然與storyboards互動通長是很有用的,但他們有侷限性。他們僅能描繪簡單的代碼,storyboards通長很耗時間當你創建一個複雜的設計。

In this particular case, you only need to draw the image once when the user drinks eight glasses of water. If the user never reaches the target, there’s no need to make a medal.

在這種情況下,當用戶喝滿八杯水的時候僅需要畫一個圖像。如果用戶從來沒有到達到過目標,根本不需要繪製獎牌。

Once drawn, it also doesn’t need to be redrawn with drawRect(_:) and setNeedsDisplay().

一旦繪製,他也不需要使用drawRect(_:)和setNeedsDisplay().進行重繪。

Time to put the brush to the canvas. First return Xcode to single viewing, rather than side-by-side, by clicking the Standard Editor icon:

時間畫筆。首先返回Xcode界面點擊編輯圖標,操作並不是並行的。

Go to File\New\File… and choose the iOS Playground template. Click Next, name the playground MedalDrawing and then click Create.

進入 File\New\File…並且選擇IOS Playground 模版。點擊 Next 命名爲 playground 爲MedalDrawing 然後點擊Create

Replace the playground code with:
添加一下代碼:

import UIKit

let size = CGSize(width: 120, height: 200)

UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
let context = UIGraphicsGetCurrentContext()



//This code must always be at the end of the playground
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

This creates a drawing context, just as you did for the patterned image.

創建描繪一個context,就像你做了一個重疊圖片

Take note of these last two lines; you always need them at the bottom of the playground so you can preview the image in the playground.

注意最後兩行。你總是需要他們在playground底部,所以你可以預覽palyground的圖片。

Next, in the gray results column click the + button to the right of this code:

其次在灰色的結果欄中單擊代碼右邊的+按鈕:

this will place a preview image underneath the code. The image will update with every change that you make to the code.

這將在代碼的地步預覽你圖像。圖像將根據你代碼的每次更新而更新。

It’s often best to do a sketch to wrap your head around the order you’ll need to draw the elements — look at the “masterpiece” I made while conceptualizing this tutorial:

我麼最好做一個草圖,把頭命令藏在你需繪製的圖像中,看看“masterpiece”我構思的教程:

This is the order to draw the medal:

  1. The back ribbon (red)
  2. The medallion (gold gradient)
  3. The clasp (dark gold)
  4. The front ribbon (blue)
  5. The number 1 (dark gold)

這是爲了繪製獎牌:

  1. 回絲帶(紅色)
  2. 獎章(金梯)
  3. 釦子(暗金色)
  4. 前帶(藍色)
  5. 1號(暗金色)

Remember to keep the last two lines of the playground (where you extract the image from the context at the very end), and add this drawing code to the playground before those lines:

記住改變playground最後兩行(在你最後提取背景圖像的地方),並且在這之前添加描繪代碼到playground:

First, set up the non-standard colors you need.
首先設置你要下的非標準顏色。

//Gold colors
let darkGoldColor = UIColor(red: 0.6, green: 0.5, blue: 0.15, alpha: 1.0)
let midGoldColor = UIColor(red: 0.86, green: 0.73, blue: 0.3, alpha: 1.0)
let lightGoldColor = UIColor(red: 1.0, green: 0.98, blue: 0.9, alpha: 1.0)

This should all look familiar by now. Notice that the colors appear in the right margin of the playground as you declare them.

由現在看起開這應該很熟悉,當你聲明的時候,注意到的顏色出現在palyground右邊。

Add the drawing code for the red part of the ribbon:

在回絲帶部分添加繪圖帶代碼:

//Lower Ribbon
var lowerRibbonPath = UIBezierPath()
lowerRibbonPath.moveToPoint(CGPointMake(0, 0))
lowerRibbonPath.addLineToPoint(CGPointMake(40,0))
lowerRibbonPath.addLineToPoint(CGPointMake(78, 70))
lowerRibbonPath.addLineToPoint(CGPointMake(38, 70))
lowerRibbonPath.closePath()
UIColor.redColor().setFill()
lowerRibbonPath.fill()

Nothing too new here, just creating a path and filling it. You should see the red path appear in the right hand pane.

沒有什麼新東西,只是創建一個路徑並且填充它。你應該看見紅色的路徑出現在右側的窗格中。

Add the code for the clasp:

添加釦子描繪代碼:

//Clasp

var claspPath = UIBezierPath(roundedRect: 
                           CGRectMake(36, 62, 43, 20), 
                           cornerRadius: 5)
claspPath.lineWidth = 5
darkGoldColor.setStroke()
claspPath.stroke()

Here you make use of UIBezierPath(roundedRect:) with rounded corners by using the cornerRadius parameter. The clasp should draw in the right pane.

在這裏你將使用 UIBezierPath(roundedRect:) ,圓角半通過使用cornerRadius.
釦子應該在右側顯示。

Add the code for the medallion:

添加獎章代碼:

//Medallion

var medallionPath = UIBezierPath(ovalInRect: 
                    CGRect(origin: CGPointMake(8, 72), 
                             size: CGSizeMake(100, 100)))
//CGContextSaveGState(context)
//medallionPath.addClip()
let gradient = CGGradientCreateWithColors(
                      CGColorSpaceCreateDeviceRGB(), 
                      [darkGoldColor.CGColor, 
                       midGoldColor.CGColor, 
                       lightGoldColor.CGColor],
                      [0, 0.51, 1])
CGContextDrawLinearGradient(context,
                            gradient, 
                            CGPointMake(40, 40), 
                            CGPointMake(40,162), 
                             0)
//CGContextRestoreGState(context)

Notice the commented out the lines. These are here to temporarily show how the gradient is drawn:

注意註釋部分,這些都是暫時顯示梯度用的:

To put the gradient on a slant, so that it goes from top-left to bottom-right, change the end x coordinate of the gradient. Alter the CGContextDrawLinearGradient() code to:

把梯度斜着,使它從左上到右下,高變梯度,結束x座標。改變 CGContextDrawLinearGradient()

CGContextDrawLinearGradient(context,
                            gradient, 
                            CGPointMake(40, 40), 
                            CGPointMake(100,160), 
                             0)

Now uncomment those three lines in the medallion drawing code to create a clipping path to constrain the gradient within the medallion’s circle.

現在取消徽章那部分的三行註釋並且創建一個剪切路徑約束在獎章圈的梯度範圍內

Just as you did when drawing the graph in part two, you save the context’s drawing state before adding the clipping path, and restore it after the gradient is drawn so that the context is no longer clipped.

就像你在繪製圖形的第二部分的時候你保存了context之前的剪切路徑。恢復後的繪圖不會再重疊

To draw the solid internal line of the medal, use the medallion’s circle path, but scale it before drawing. Instead of transforming the whole context, you’ll just apply the transform to one path.

畫獎牌的內部線,使用獎牌的圓圈路徑,但是在之前規定的區域繪製,而不是轉變整個context。你只會應用變換的一個路徑。

Add this code after the medallion drawing code:

添加獎章繪製代碼:

//Create a transform
//Scale it, and translate it right and down
var transform = CGAffineTransformMakeScale(0.8, 0.8)
transform = CGAffineTransformTranslate(transform, 15, 30)

medallionPath.lineWidth = 2.0

//apply the transform to the path
medallionPath.applyTransform(transform)
medallionPath.stroke()

This scales the path down to 80 percent of its original size, and then translates the path to keep it centered within the gradient view.

這個尺寸的路徑爲原始尺寸的80%,然後將路徑保存爲中心梯度的內景色。

Add the upper ribbon drawing code after the internal line code:
添加絲帶編碼:

//Upper Ribbon

var upperRibbonPath = UIBezierPath()
upperRibbonPath.moveToPoint(CGPointMake(68, 0))
upperRibbonPath.addLineToPoint(CGPointMake(108, 0))
upperRibbonPath.addLineToPoint(CGPointMake(78, 70))
upperRibbonPath.addLineToPoint(CGPointMake(38, 70))
upperRibbonPath.closePath()

UIColor.blueColor().setFill()
upperRibbonPath.fill()

This is very similar to the code you added for the lower ribbon – making a bezier path and filling it.

對於添加低位絲帶是非常相似的代碼,製作一個bezier路徑並且填充他。

The last step is to draw the number one on the medal. Add this code after //Upper Ribbon:

最後一步是在絲帶上畫 1,代碼如下:

//Number One

//Must be NSString to be able to use drawInRect()
let numberOne = "1"
let numberOneRect = CGRectMake(47, 100, 50, 50)
let font = UIFont(name: "Academy Engraved LET", size: 60)
let textStyle = NSMutableParagraphStyle.defaultParagraphStyle()
let numberOneAttributes = [
  NSFontAttributeName: font!,
  NSForegroundColorAttributeName: darkGoldColor]
numberOne.drawInRect(numberOneRect, 
                     withAttributes:numberOneAttributes)

Here you define a String with text attributes, and draw it into the drawing context using drawInRect(_:).

在這裏你定義了一個字符串屬性,並且使用drawInRect(_:).在context進行了重繪

Looking good!

看上去不錯

You’re getting close, but it’s looking a little two-dimensional — it would be nice to have some drop shadows.

你已經很接近了,但他看起來有一些二維。它會有一些陰影會更好。

Shadows 陰影

To create a shadow, you need three elements: the color, the offset (distance and direction of the shadow) and the blur.

創建一個陰影,需要三個要素:顏色,偏移(陰影的距離和方向)和模糊

At the top of the playground, after defining the gold colors but just before the //Lower Ribbon, insert this shadow code:

在 playground 頂部,位於金色之後插入陰影。

//Add Shadow
let shadow:UIColor = UIColor.blackColor().colorWithAlphaComponent(0.80)
let shadowOffset = CGSizeMake(2.0, 2.0)
let shadowBlurRadius: CGFloat = 5

CGContextSetShadowWithColor(context, 
                            shadowOffset, 
                            shadowBlurRadius, 
                            shadow.CGColor)

Okay, that makes a shadow, but the result is probably not what you pictured. Why is that?

ok,做了一個陰影后,但結果並不是我們所想象的那樣。

When you draw an object into the context, this code creates a shadow for each object.

當你畫一個對象爲背景,該代碼創建了每一個物體的影子。

Ah-ha! Your medal comprises five objects. No wonder it looks a little fuzzy.
Fortunately, it’s pretty easy to fix. Simply group drawing objects with a transparency layer, and you’ll only draw one shadow for the whole group.

啊啊啊啊啊,你的獎章,包括五個物體,難怪看起來有點模糊。幸運的是我們更改起來比較容易。簡單的透明對象組對象,你只需要對整個對象組繪製一個陰影就可以。

Add the code to make the group after the shadow code. Start with this:

添加陰影代碼從這裏開始:

CGContextBeginTransparencyLayer(context, nil)

When you begin a group you also need to end it, so add this next block at the end of the playground, but still before retrieving the final image:

當你開始一組,你也需要結束它。所以在playground末端添加這一塊。但在這之前仍然需要檢索圖像。

CGContextEndTransparencyLayer(context)

Now you’ll have a completed medal image with clean, tidy shadows:

現在你將有一個完整的獎牌圖像,整潔的陰影。

Image View Using Core Graphics Image創建一個新的圖像視圖

Create a new file for the Image View.

Click File\New\File…**and choose the **Cocoa Touch Class template. Click Next , and name the class MedalView. Make it a subclass of UIImageView, then click Next, then click Create.

單擊File\New\File… ,並且選擇 Cocoa Touch Class 模版,單擊Next,並且將類命名爲
MedalView,子類爲UIImageView,然後點擊Next,點擊Creat

Go to Main.storyboard and add a UIImageView as a subview of Counter View. Select the UIImageView, and in the Identity Inspector change the class to MedalView.

進入Main.storyboard並且添加一個UIImageView Counter View視圖。選擇UIImageView,並且在Identity Inspector改編爲 MedalView

In the Size Inspector, give the Image View the coordinates X=76, Y=147, Width=80, and Height=80:

Size Inspector給視圖設置座標爲x=76,y=147,寬度爲80,高度爲80

In the Attributes Inspector, change Image Mode**to **Aspect Fit, so that the image automatically resizes to fit the view.

在Attributes Inspector,改變Image ModeAspect Fit,因此圖像自動調整大小適應視圖。

Go to MedalView.swift and add a method to create the medal:

去medalview.swift並添加一個方法用來創建的獎章:

func createMedalImage() -> UIImage {
  println("creating Medal Image")

}

This makes a log so that you know when the image is being created.
Go to MedalDrawing playground, highlight and copy the entire code except for the initial import UIKit.
Go back to MedalView.swift and paste the playground code into createMedalImage(),
At the end of createMedalImage(), add:

製作一個日誌,紀錄當圖像被開始創建的時候。

進入MedalDrawing playground,複製整個代碼出了出使導入的UIKit。

返回MedalView.swift並且粘貼代碼到playground代碼中的createMedalImage()

createMedalImage()尾部添加:

return image

That should squash the compile error.
At the top of the class, add a property to hold the medal image:

應該編譯錯誤。
在累的頂部添加一個屬性保持獎牌圖像:

lazy var medalImage:UIImage = self.createMedalImage()

Add a method to show the medal:

添加一個方法去顯示獎牌:

func showMedal(show:Bool) {
  if show {
    image = medalImage
  } else {
    image = nil
  }
}

Go to ViewController.swift and add an outlet at the top of the class:

ViewController.swift類頂部添加一個外部接口:

@IBOutlet weak var medalView: MedalView!

Go to Main.storyboard and connect the new MedalView to this outlet.

去Main.storyboard連接一個新MedalView通過這個外部接口

Go back to ViewController.swift and add this method to the class:

返回ViewController.swift並且添加這個方法:

func checkTotal() {
  if counterView.counter >= 8 {
    medalView.showMedal(true)
  } else {
    medalView.showMedal(false)
  }
}

This shows the medal if you drink enough water for the day.

如果你今天喝了足夠的水,這個獎牌將顯示。

Call this method at both the end of viewDidLoad() and btnPushButton(_:):

在結束的時候調用viewDidLoad()btnPushButton(_:)這兩個方法:

checkTotal()

Build and run the application. It should look like this:

構建並運行應用,他應該像這樣:

In the debug console, you’ll see the creating Medal Image log only outputs when the counter reaches eight and displays the medal, and this is because medalImage uses a lazy declaration.

在調試控制檯,當計數器達到8時,你僅僅能看見獎牌圖像日誌被輸出,這是因爲medalImage使用了一個lazy declaration。

Where to Go From Here? 何去何從

You’ve come a long way in this epic tutorial series. You’ve mastered the basics of Core Graphics: drawing paths, creating patterns and gradients, and transforming the context. To top it all off, you learned how to put it all together in a useful app.

你已經在這部系列教程中走了很長的路,你已經掌握了Core Graphics的基本知識,創建模式和梯度。並且轉換context,最高端的是,你學會了怎麼把它添加到app中使用。

Download the complete version of Flo right here. This version also includes extra sample data and radial gradients to give the buttons a nice UI touch so they respond when pressed.

下載完整的版本, Flo right here.。這個版本也包括提取簡單的數據和一個當你按下的時候有很好漸變的效果按鈕。

I hope you enjoyed making Flo, and that you’re now able to make some stunning UIs using nothing but Core Graphics and UIKit! If you have any questions, comments, or you want to hash out how to draw a trophy instead of a medal, please join the forum discussion below.

我希望你能很享受使用Flo,你現在可以使用Core Graphics和UIKit做一些漂亮的UI!你有任何問題,意見,或者你想討論如何繪製一個獎盃,而不是一個獎章,請加入論壇討論下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章