Norway


Update note: Lea Marolt Sonnenschein updated this tutorial for iOS 12, Xcode and Swift 4.2. Ray Wenderlich wrote the original.

is one of those frameworks that’s easy to avoid as an iOS developer. It’s a little obscure, the syntax is not super modern and Apple doesn’t give it as much love at WWDC as they should! Plus, you can avoid it very easily by just using images instead.

However, Core Graphics is an insanely powerful tool to master! You can free yourself from the shackles of graphic designers and wield the mighty CG sword to create amazing UI beauty on your own.

- GlossyButtons graphic 2 - Core Graphics: How to Make a Glossy Button

In this tutorial, you’ll learn how to create a customizable, reusable glossy using only Core Graphics. Haven’t you heard skeuomorphism is back in style? ;]

In the process, you’ll learn how to draw rounded rectangles, how to easily tint your Core Graphics drawings and how to create gradient and gloss effects.

There are many options for customizing UIButtons already, from full-fledged custom UIButton classes to smaller extensions. But what’s been missing in this discussion is a detailed Core Graphics tutorial for how to customize the buttons yourself, from start to finish. It’s pretty simple; you can wield it to get the exact look you want in your app.

It’s to get started!

Getting Started

Use the Download Materials button at the top or bottom of this tutorial to download the starter project.

Open the starter project: CoolButton Starter.

The project structure is very simple, consisting of only the files created when choosing the Single View App Xcode template. The only two major exceptions are:

  • A couple of images in the Assets.xcassets catalog.
  • You can find a pre-designed UI for ViewController in Main.storyboard.

- xcode project structure - Core Graphics: How to Make a Glossy Button

Now go to File ▸ New ▸ File…, the iOS ▸ Cocoa Touch Class and click Next.

In the next menu, enter CoolButton as the class name. In the subclass field, type UIButton. For language, choose Swift. Now click Next and then Create.

Open CoolButton.swift and replace the class definition with the following:

class CoolButton: UIButton {
  var hue: CGFloat {
    didSet {
      setNeedsDisplay()
    }
  }
  
  var saturation: CGFloat {
    didSet {
      setNeedsDisplay()
    }
  }
  
  var brightness: CGFloat {
    didSet {
      setNeedsDisplay()
    }
  }
}

Here, you create three properties that you’ll use to customize the color’s hue, saturation and brightness.

When the properties are set, you trigger a call to setNeedsDisplay to force your UIButton to redraw the button when the user changes its color.

Now, paste the following code at the bottom of CoolButton, right before the last curly bracket:

required init?(coder aDecoder: NSCoder) {
  self.hue = 0.5
  self.saturation = 0.5
  self.brightness = 0.5
  
  super.init(coder: aDecoder)
  
  self.isOpaque = false
  self.backgroundColor = .clear
}

override func draw(_ rect: CGRect) {
  guard let context = UIGraphicsGetCurrentContext() else {
    return
  }

  let color = UIColor(hue: hue, 
    saturation: saturation, 
    brightness: brightness, 
    alpha: 1.0)

  context.setFillColor(color.cgColor)
  context.fill(bounds)
}

Here, you initialize the variables and fill the button with a pre-configured color to make sure everything’s working from the start.

Configuring the Button’s UI

Open Main.storyboard to configure the UI. There’s one view controller containing three sliders — one for hue, one for saturation and one for brightness.

- UI1 524x500 - Core Graphics: How to Make a Glossy Button

You’re missing the UIButton, so add that to the top of the screen. Go to Object Library, type in UIButton, and drag it into the screen.

- UI2 650x324 - Core Graphics: How to Make a Glossy Button

Time for some auto-layout! Control-drag from the button to the view and choose Center Horizontally in Safe Area.

- ui3 650x288 - Core Graphics: How to Make a Glossy Button

- ui4 - Core Graphics: How to Make a Glossy Button

Control-drag from the button to the hue label and choose Vertical Spacing.

- UI5 1 650x274 - Core Graphics: How to Make a Glossy Button

Now, resize the button to a size that you like. Control-drag left or right from the button and choose Width.

- ui6 1 650x367 - Core Graphics: How to Make a Glossy Button

Control-drag up or down from the button and choose Height.

- ui7 650x367 - Core Graphics: How to Make a Glossy Button

Note: If you have difficulty setting Width and Height constraints by dragging, select the button and click the Add New Contraints button in the lower right of the canvas. It looks a bit like a Tie fighter from Star Wars.

Next, delete the text that says “Button” by double clicking it and pressing the Delete key.

With the button still selected, go to the Inspectors sidebar on the right-hand side of the screen and click on the Identity inspector. In Custom Class ▸ Class, enter CoolButton to make your button an instance of the CoolButton class.

- UI8 - Core Graphics: How to Make a Glossy Button

With the button in place, you’re ready to start hooking the UI up to the code!

Making Your Button Functional

Open ViewController.swift and replace the class definition with the following:

class ViewController: UIViewController {
  @IBOutlet weak var coolButton: CoolButton!
  @IBAction func hueValueChanged(_ sender: Any) { }
  @IBAction func saturationValueChanged(_ sender: Any) { }
  @IBAction func brightnessValueChanged(_ sender: Any) { }
}

Here, you’re declaring a reference to the button that you just created in your storyboard. You’re also declaring the callbacks that occur when the values of the configuration sliders change.

Now, open Main.storyboard again and choose Assistant Editor in the top bar to show ViewController.swift and Main.storyboard side by side.

- ui9 650x251 - Core Graphics: How to Make a Glossy Button

Control-drag from the button in View Controller Scene ▸ ViewController on the left and connect it to the coolButton outlet.

- ui10 650x241 - Core Graphics: How to Make a Glossy Button

Similarly, control-drag from the sliders in View Controller Scene ▸ ViewController on the left and connect each one to the appropriate value-changed callback on the right.

- ui11 650x252 - Core Graphics: How to Make a Glossy Button

Next, switch to ViewController.swift and implement the value-changed callbacks of the sliders:

@IBAction func hueValueChanged(_ sender: Any) {
  guard let slider = sender as? UISlider else { return }
  coolButton.hue = CGFloat(slider.value)
}

@IBAction func saturationValueChanged(_ sender: Any) {
  guard let slider = sender as? UISlider else { return }
  coolButton.saturation = CGFloat(slider.value)
}

@IBAction func brightnessValueChanged(_ sender: Any) {
  guard let slider = sender as? UISlider else { return }
  coolButton.brightness = CGFloat(slider.value)
}

By default, UISliders have a range of 0.0 to 1.0. This is perfect for your hue, saturation and brightness values, which also range from 0.0 to 1.0, so you can just set them directly.

Phew, after all this work, it’s finally time to build and run! If all works well, you can play around with the sliders to fill the button with various colors:

- ui12 650x346 - Core Graphics: How to Make a Glossy Button

Drawing Rounded Rectangles

It’s true that you can easily create square buttons, but button styles come and go faster than the weather changes in Chicago!

In fact, since we originally released this tutorial, square buttons and rounded rectangle buttons have flip-flopped back and forth for the number-one spot in the button pageant, so it’s a good idea to know how to make both versions.

You can also argue that it’s quite easy to create rounded rectangles by simply changing the corner radius of a UIView, but where’s the fun in that? There’s so much more gratification, or maybe madness, in doing it the hard way. :]

One way to make rounded rectangles is to draw arcs using the CGContextAddArc API. Using that API, you can draw an arc at each corner and draw lines to connect them. But that’s cumbersome and requires a lot of geometry.

Fortunately, there’s an easier way! You don’t have to do as much math and it works well with drawing rounded rectangles. It’s the CGContextAddArcToPoint API.

Using the CGContextAddArcToPoint API

The CGContextAddArcToPoint API lets you describe the arc to draw by specifying two tangent lines and a radius. The following diagram from the Quartz2D Programming Guide shows how it works:

CGContextAddArcToPoint Diagram  - CGContextAddArcToPoint - Core Graphics: How to Make a Glossy Button

When you’re working with a rectangle, you know the tangent lines for each arc you want to draw — they are simply the edges of the rectangle! And you can specify the radius based on how rounded you want the rectangle to be — the larger the arc, the more rounded the corners will be.

The other neat thing about this function is that, if the current point in the path isn’t set to where you tell the arc to begin drawing, it will draw a line from the current point to the beginning of the path. So you can use this as a shortcut to draw a rounded rectangle in just a few calls.

Drawing Your Arcs

Since you’re going to create a bunch of rounded rectangles in this Core Graphics tutorial, and you want your code to be as reusable as possible, create a separate file for all of your drawing methods.

Go to File ▸ New ▸ File…, and choose iOS ▸ Swift File. Press Next, call it Drawing and click Create.

Now, replace import Foundation with the following:

import UIKit
import CoreGraphics

extension UIView {
  func createRoundedRectPath(for rect: CGRect, radius: CGFloat) -> CGMutablePath {
    let path = CGMutablePath()
    
    // 1
    let midTopPoint = CGPoint(x: rect.midX, y: rect.minY)
    path.move(to: midTopPoint)
    
    // 2
    let topRightPoint = CGPoint(x: rect.maxX, y: rect.minY)
    let bottomRightPoint = CGPoint(x: rect.maxX, y: rect.maxY)
    let bottomLeftPoint = CGPoint(x: rect.minX, y: rect.maxY)
    let topLeftPoint = CGPoint(x: rect.minX, y: rect.minY)
    
    // 3
    path.addArc(tangent1End: topRightPoint, 
      tangent2End: bottomRightPoint, 
      radius: radius)

    path.addArc(tangent1End: bottomRightPoint, 
      tangent2End: bottomLeftPoint, 
      radius: radius)

    path.addArc(tangent1End: bottomLeftPoint,
      tangent2End: topLeftPoint, 
      radius: radius)

    path.addArc(tangent1End: topLeftPoint,
      tangent2End: topRightPoint, 
      radius: radius)

    // 4
    path.closeSubpath()
    
    return path
  }
}

The code above creates a global extension for everything of type UIView, so you can use it for more than just UIButtons.

The code also instructs createRoundedRectPath(for:radius:) to draw the rounded rect in the following order:

How to draw a rounded rect with Core Graphics  - RoundedRect - Core Graphics: How to Make a Glossy Button

Here’s the breakdown of what’s going on in the code:

  1. You move to the center of the top line segment.
  2. You declare each corner as a local constant.
  3. You add each arc to the path:
    1. First, you add an arc for the upper right corner. Before drawing an arc, CGPathAddArcToPoint will draw a line from the current position in the middle of the rect to the beginning of the arc for you.
    2. Similarly, you add an arc for the lower right corner and the connecting line.
    3. Then you add an arc for the lower left corner and the connecting line.
    4. Last, you add an arc for the upper left corner and the connecting line.
  4. Finally, you connect the ending point of the arc with the starting point with closeSubpath().

Making Your Button Rounded

OK, now it’s time to put this method to work! Open CoolButton.swift and replace draw(_:) with the following:

override func draw(_ rect: CGRect) {
  guard let context = UIGraphicsGetCurrentContext() else {
    return
  }
  
  // 1
  let outerColor = UIColor(
    hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0)
  let shadowColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 0.5)
  
  // 2
  let outerMargin: CGFloat = 5.0
  let outerRect = rect.insetBy(dx: outerMargin, dy: outerMargin)
  // 3
  let outerPath = createRoundedRectPath(for: outerRect, radius: 6.0)
  
  // 4
  if state != .highlighted {
    context.saveGState()
    context.setFillColor(outerColor.cgColor)
    context.setShadow(offset: CGSize(width: 0, height: 2), 
      blur: 3.0, color: shadowColor.cgColor)
    context.addPath(outerPath)
    context.fillPath()
    context.restoreGState()
  }
}

To break this down:

  1. You define your two colors.
  2. Then you use insetBy(dx:dy:) to get a slightly smaller rectangle (5 pixels on each side) where you’ll draw the rounded rect. You’ve made it smaller so that you’ll have space to draw a shadow on the outside.
  3. Next, you call the function you just wrote, createRoundedRectPath(for:radius:), to create a path for your rounded rect.
  4. Finally, you set the fill color and shadow, add the path to your context and call fillPath() to fill it with your current color.

Note: You only want to run the code if your button isn’t currently highlighted; for example, it isn’t being tapped.

Build and run the app; if all works well, you should see the following:

- ui13 281x500 - Core Graphics: How to Make a Glossy Button

Adding a Gradient

All right, the button’s starting to look pretty good, but you can do even better! How about adding a gradient?

Add the following function to Drawing.swift, to make it universally available for any UIView:

func drawLinearGradient(
  context: CGContext, rect: CGRect, startColor: CGColor, endColor: CGColor) {
  // 1
  let colorSpace = CGColorSpaceCreateDeviceRGB()
  
  // 2
  let colorLocations: [CGFloat] = [0.0, 1.0]
  
  // 3
  let colors: CFArray = [startColor, endColor] as CFArray
  
  // 4
  let gradient = CGGradient(
    colorsSpace: colorSpace, colors: colors, locations: colorLocations)!

  // More to come...
}

It doesn’t look like much, but there’s a lot going on in this function!

  1. The first thing you need is to get a color space that you’ll use to draw the gradient.
  2. Note: There’s a lot you can do with color spaces, but 99% of the time you just want a standard device-dependent RGB color space. So simply use the function CGColorSpaceCreateDeviceRGB() to get the reference that you need.

  3. Next, you set up an array that tracks the of each color within the range of the gradient. A value of 0 means the start of the gradient, 1 means the end of the gradient. You only have two colors, and you want the first to be at the start and the second to be at the end, so you pass in 0 and 1.
  4. Note: You can have three or more colors in a gradient if you want, and you can set where each color begins in the gradient. This can be useful for certain effects.

  5. After that, you create an array with the colors that you passed into your function. You use a plain old array here for convenience, but you need to cast it as a CFArray, since that’s what the API requires.
  6. Then you create your gradient with CGGradient(colorsSpace:colors:locations:), passing in the color space, color array and locations you previously made.

You now have a gradient reference, but it hasn’t actually drawn anything yet. It’s just a pointer to the information you will use when actually drawing it later.

Complete the function by adding the following at the end of drawLinearGradient(context:rect:startColor:endColor:):

// 5
let startPoint = CGPoint(x: rect.midX, y: rect.minY)
let endPoint = CGPoint(x: rect.midX, y: rect.maxY)

context.saveGState()

// 6
context.addRect(rect)
// 7
context.clip()

// 8
context.drawLinearGradient(
  gradient, start: startPoint, end: endPoint, options: [])

context.restoreGState()
  1. The first thing you do is calculate the start and end point where you want to draw the gradient. You just set this as a line from the “top middle” to the “bottom middle” of the rectangle.

The rest of the code helps you draw a gradient into the provided rectangle, the key function being drawLinearGradient(_:start:end:options:).

Constraining a Gradient to a Sub-area

The weird thing about that function, though, is that it fills up the entire drawing region with the gradient — there’s no way to set it to only fill a sub-area with the gradient!

Well, without clipping, that is!

Clipping is an awesome feature of Core Graphics that lets you restrict drawing to an arbitrary shape. All you have to do is add the shape to the context, but then instead of filling it like you usually would, you call clip(). Now, you’ve restricted all future drawing to that region!

So that’s what you do here:

  1. You add your rectangle to the context.
  2. Clip to that region.
  3. Then call drawLinearGradient(_:start:end:options:), passing in all the variables that you set up before.

So what’s this stuff about saveGState()/restoreGState() all about?

Well, Core Graphics is a state machine. You configure a set of states you want, such as colors and line thickness, and then perform actions to actually draw them. That means that once you’ve set something, it stays that way until you change it back.

Well, you’ve just clipped to a region, so unless you do something about it, you’ll never be able to draw outside of that region again!

That’s where saveGState()/restoreGState() come to the rescue.

With these, you can the current setup of your context to a stack and then pop it back later when you’re done to get back to where you were.

That’s it, now try it out!

Open CoolButton.swift and add this to the bottom of draw(_:) :

// Outer Path Gradient:
// 1
let outerTop = UIColor(hue: hue, saturation: saturation, 
  brightness: brightness, alpha: 1.0)
let outerBottom = UIColor(hue: hue, saturation: saturation, 
  brightness: brightness * 0.8, alpha: 1.0)

// 2
context.saveGState()
context.addPath(outerPath)
context.clip()
drawLinearGradient(context: context, rect: outerRect, 
  startColor: outerTop.cgColor, endColor: outerBottom.cgColor)
context.restoreGState()

Build and run; you should see something like this:

- ui14 281x500 - Core Graphics: How to Make a Glossy Button

  1. First, you define the top and bottom colors.
  2. Then, you draw the gradient by the current graphics state on the stack, adding your path, clipping it, drawing the gradient and restoring the state again.

Hooray, your button is looking pretty snazzy! How about some extra pizazz?!

Adding a Gloss Effect

Now it’s time to make this button shiny, because skeuomorphism should never have gone out of style!

When you add a gloss effect to a button in Core Graphics, things can get pretty complicated. If you’re feeling hardcore, check out some great work by Matt Gallagher and Michael Heyeck on the matter.

But to my poor eyes, you can get a pretty good-looking approximation of a gloss effect just by applying a gradient alpha mask, which is much simpler to understand and code. So you’re going to go with that.

This is something that you can apply to UIViews across the board, so add the following function to the UIView extension in Drawing.swift:

func drawGlossAndGradient(
  context: CGContext, rect: CGRect, startColor: CGColor, endColor: CGColor) {

  // 1
  drawLinearGradient(
    context: context, rect: rect, startColor: startColor, endColor: endColor)
  
  let glossColor1 = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.35)
  let glossColor2 = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.1)
  
  let topHalf = CGRect(origin: rect.origin, 
    size: CGSize(width: rect.width, height: rect.height/2))
  
  drawLinearGradient(context: context, rect: topHalf, 
    startColor: glossColor1.cgColor, endColor: glossColor2.cgColor)
}

This function is basically drawing a gradient over a rectangle from a start to end color, and then adding a gloss to the top half. Here’s a breakdown of what’s happening:

  1. To draw the gradient, you call the function you wrote earlier.
  2. To draw the gloss, you then draw another gradient on top of that, from pretty transparent (white with 0.35 alpha) to very transparent (white with 0.1 alpha).

Simple, eh? Plug it in and see how it looks. Go back to CoolButton.swift and make a change in draw(_:). Replace this line, which is the second to last in draw(_:):

drawLinearGradient(context: context, rect: outerRect, 
  startColor: outerTop.cgColor, endColor: outerBottom.cgColor)

with:

drawGlossAndGradient(context: context, rect: outerRect, 
  startColor: outerTop.cgColor, endColor: outerBottom.cgColor)

In case you can’t spot the difference, you just changed drawLinearGradient(context:rect:startColor:endColor:) into drawGlossAndGradient(context:rect:startColor:endColor:), the newly added method in Drawing.swift.

Build and run, and your button should now look like this:

- ui15 281x500 - Core Graphics: How to Make a Glossy Button

- UI19 650x195 - Core Graphics: How to Make a Glossy Button

Oooh, shiny!

- GlossyButtons graphic 1 - Core Graphics: How to Make a Glossy Button

Styling the Button

Now for the super-fine, nit-picky details. If you’re making a 3D button, you might as well go all out. To do that, you need a bevel.

To create a bevel-type effect, add an inner path that has a slightly different gradient than the outer path. Add this to the bottom of draw(_:) in CoolButton.swift:

// 1: Inner Colors
let innerTop = UIColor(
  hue: hue, saturation: saturation, brightness: brightness * 0.9, alpha: 1.0)
let innerBottom = UIColor(
  hue: hue, saturation: saturation, brightness: brightness * 0.7, alpha: 1.0)

// 2: Inner Path
let innerMargin: CGFloat = 3.0
let innerRect = outerRect.insetBy(dx: innerMargin, dy: innerMargin)
let innerPath = createRoundedRectPath(for: innerRect, radius: 6.0)

// 3: Draw Inner Path Gloss and Gradient
context.saveGState()
context.addPath(innerPath)
context.clip()
drawGlossAndGradient(context: context, 
  rect: innerRect, startColor: innerTop.cgColor, endColor: innerBottom.cgColor)
context.restoreGState()

Here, you shrink the rectangle again with insetBy(dx:dy:), then get a rounded rectangle and run a gradient over it. Build and run and you’ll see a subtle improvement:

- UI17 1 650x195 - Core Graphics: How to Make a Glossy Button

Highlighting the Button

Your button looks pretty cool, but it doesn’t act like a button. There’s no indication of whether the user has pressed the button or not.

To handle this, you need to override the touch events to tell your button to redisplay itself, since it might need an update after a user selects it.

Add the following to CoolButton.swift:

@objc func hesitateUpdate() {
  setNeedsDisplay()
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
  super.touchesBegan(touches, with: event)
  setNeedsDisplay()
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
  super.touchesMoved(touches, with: event)
  setNeedsDisplay()
}

override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
  super.touchesCancelled(touches, with: event)
  setNeedsDisplay()
  
  perform(#selector(hesitateUpdate), with: nil, afterDelay: 0.1)
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
  super.touchesEnded(touches, with: event)
  setNeedsDisplay()
  
  perform(#selector(hesitateUpdate), with: nil, afterDelay: 0.1)
}

Build and run the project, and you’ll see that there’s a difference when you tap the button now — the highlight and bevel disappear.

But you can make the effect a bit better with one more change to draw(_:):

When a user presses the button, the overall button should become darker.

You can achieve this by creating a temporary variable for the brightness called actualBrightness, and then adjusting it appropriately based on the button’s state:

var actualBrightness = brightness

if state == .highlighted {
  actualBrightness -= 0.1
}

Then, inside draw(_:), replace all the instances of brightness with actualBrightness.

Altogether, the draw(_:) function now looks like this. It’s a little long, but the repetition is worth it:

override func draw(_ rect: CGRect) {
  guard let context = UIGraphicsGetCurrentContext() else {
    return
  }
  
  var actualBrightness = brightness
  
  if state == .highlighted {
    actualBrightness -= 0.1
  }
  
  let outerColor = UIColor(
    hue: hue, saturation: saturation, brightness: actualBrightness, alpha: 1.0)
  let shadowColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 0.5)
  
  let outerMargin: CGFloat = 5.0
  let outerRect = rect.insetBy(dx: outerMargin, dy: outerMargin)
  let outerPath = createRoundedRectPath(for: outerRect, radius: 6.0)
  
  if state != .highlighted {
    context.saveGState()
    context.setFillColor(outerColor.cgColor)
    context.setShadow(
      offset: CGSize(width: 0, height: 2), blur: 3.0, color: shadowColor.cgColor)
    context.addPath(outerPath)
    context.fillPath()
    context.restoreGState()
  }
  
  // Outer Path Gloss & Gradient
  let outerTop = UIColor(hue: hue, saturation: saturation, 
    brightness: actualBrightness, alpha: 1.0)
  let outerBottom = UIColor(hue: hue, saturation: saturation, 
    brightness: actualBrightness * 0.8, alpha: 1.0)
  
  context.saveGState()
  context.addPath(outerPath)
  context.clip()
  drawGlossAndGradient(context: context, rect: outerRect, 
    startColor: outerTop.cgColor, endColor: outerBottom.cgColor)
  context.restoreGState()
  
  // Inner Path Gloss & Gradient
  let innerTop = UIColor(hue: hue, saturation: saturation, 
    brightness: actualBrightness * 0.9, alpha: 1.0)
  let innerBottom = UIColor(hue: hue, saturation: saturation, 
    brightness: actualBrightness * 0.7, alpha: 1.0)

  let innerMargin: CGFloat = 3.0
  let innerRect = outerRect.insetBy(dx: innerMargin, dy: innerMargin)
  let innerPath = createRoundedRectPath(for: innerRect, radius: 6.0)
  
  context.saveGState()
  context.addPath(innerPath)
  context.clip()
  drawGlossAndGradient(context: context, rect: innerRect, 
    startColor: innerTop.cgColor, endColor: innerBottom.cgColor)
  context.restoreGState()
}

Build and run; now the button should look pretty good when you tap it!

- ui16 281x500 - Core Graphics: How to Make a Glossy Button

- UI21 650x195 - Core Graphics: How to Make a Glossy Button

Where to Go From Here?

Now that you’ve gone through all of the steps to create custom buttons from scratch, you should be intimately familiar with how to customize every aspect of the button to your liking for your project’s style!

Hopefully, this tutorial helped you become more comfortable with Core Graphics and sparked an interest in exploring the API further. :]

If this tutorial was a little hard to follow, or you want to make sure to cover your basics, check out our Beginning Core Graphics video series.

If you’re looking for something more advanced, take a look at the Intermediate Core Graphics course.

And if you don’t feel like you can commit to a full course yet, try the Core Graphics Article Series where you’ll learn how to draw an entire app, including graphs, from scratch with Core Graphics!

Plus there are many more Core Graphics tutorials, all recently updated for Xcode 10, on the .

If you have any questions or comments, please join the forum discussion below.



Source link

LEAVE A REPLY

Please enter your comment!
Please enter your name here