Customize a Text View

In this tutorial, you learn how to customize a textView as follows:

➤ Make the textview’s corners round
➤ Add a placeholder in the textView
➤ Draw horizontal lines in the textview, just like a notebook
➤ Draw a vertical line on the left side of the textView

custom-textview-fig05

Before You Begin

I created a starter project for this tutorial. So download it now. Once you’ve unzipped the file, move the CustomTextView folder to the Interactive Swift Programming folder.

download-excodeproj

Code presented on this page assume you are using Xcode 7.1 and Swift version 2.1. So if you are using a older or newer version of Swift, it may produce errors. Fix them by using Xcode’s Fix-it tool. Also, I assume you aren’t a newbie to the Swift Programming Language and you know your way around Xcode Integrated Development Editor.

The CustomTextView have one scene and it is connected to a class file called ViewController.swift.

custom-textview-fig00

Add a Class in The Project

The first step to customizing the CustomTextView project’s textView is to add a Cocoa Touch Class in the project.

  1. Click the + button at the button of the Project Navigator, and select File from the pop up menu.

xcode7-add-class-file-step1

2. In the template window, select the Cocoa Touch Class template and click Next.

xcode7-add-class-file-step2

3. In the class options window, enter LinedTextView in the Class field. Select UITextView from the Subclass of menu and make sure you select Swift from the Language menu.

xcode7-add-class-file-step3

4. On the final window click the Create button.

xcode7-add-class-file-step4

Now that you’ve added a Cocoa Touch Class in the project, I want you to modify the class so it look like this:

custom-textview-fig01

Round Text View Corners Code

To make the textView’s corners round like this:

custom-textview-fig03

You’ll have to add highlighted code shown below, in the LinedTextView.swift file.

import UIKit

class LinedTextView: UITextView {

  required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)!
        
    // Make the textView's borders round
    let borderColor : UIColor = UIColor(red: 0.50, green: 0.25, blue: 0.00, alpha: 1.00)
    self.layer.borderColor = borderColor.CGColor
    self.layer.borderWidth = 0.6
    self.layer.cornerRadius = 5.0
    
  override func drawRect(rect: CGRect) {
        
  }
}

Next, connect the textView control to the LinedTextView class via the Identity inspector.

custom-textview-fig02

You can programmatically set some properties of the textView and change the cursor color. Just enter this code in the required init() function.

// Set some properties of the textView
self.backgroundColor = UIColor(red: 0.92, green: 0.92, blue: 0.67, alpha: 1.00) //yellow
self.font = UIFont(name: "MarkerFelt-Thin", size: 19) //text font name and size
        
// Change the cursor color
self.tintColor = UIColor.brownColor()

The Text View Placeholder Code

When the textView is empty, a placeholder label should appear inside the textView. When you tap inside the textView, the placeholder label should disappear. When you enter text in the textView and remove it; the placeholder label should reappear in the textView.

custom-textview-fig04

In order to show and hide a placeholder label in the textView, enter this code in the ViewController.swift file.

var placeholder: UILabel!

override func viewDidLoad() {
  super.viewDidLoad()
  ...
  //1. Create and add a light gray placeholder label inside the textView
  placeholder = UILabel(frame: CGRectMake(6, 10, 100, 21))
  placeholder.textColor = UIColor.lightGrayColor()
  placeholder.font = UIFont.boldSystemFontOfSize(17.0)
  placeholder.textAlignment = NSTextAlignment.Left
  placeholder.text = "Your Notes"
  textView.addSubview(placeholder)
}

func textViewShouldBeginEditing(textView: UITextView) -> Bool {
  if textView.tag == 0 {
    //2. Show the placeholder label
    placeholder.hidden = true
    textView.tag == 1
  }
  return true
}

func textViewDidEndEditing(theTextView: UITextView) {
  if textView.text.isEmpty == true {
    //3 Hide the placeholder label
    placeholder.hidden = false
    textView.tag = 0
  }
}

Draw Horizontal lines in The Text View

To make horizontal lines appear in the textView, you have to add code in the LinedTextView.swift file to draw the lines.

custom-textview-fig05b

Here’s the code to enter in the LinedTextView.swift file.

override func drawRect(rect: CGRect) {
  // Get the current drawing context
  let context: CGContextRef = UIGraphicsGetCurrentContext()!
    
  // Set the line color and width
  CGContextSetStrokeColorWithColor(context, UIColor(red:0.0, green:0.0, blue:0.0, alpha:0.2).CGColor)
  CGContextSetLineWidth(context, 1.0);
    
  // Start a new Path
  CGContextBeginPath(context)
    
  //Find the number of lines in our textView + add a bit more height to draw lines in the empty part of the view
    let numberOfLines = (self.contentSize.height + self.bounds.size.height) / self.font!.lineHeight
    
  // Set the line offset from the baseline.
  let baselineOffset:CGFloat = 5.0
    
  // Iterate over numberOfLines and draw a line in the textView
  for var x = 1; x < Int(numberOfLines); x++ {
    //0.5f offset lines up line with pixel boundary
    CGContextMoveToPoint(context, self.bounds.origin.x, self.font!.lineHeight * CGFloat(x) + baselineOffset)
        
    CGContextAddLineToPoint(context, CGFloat(self.bounds.size.width), self.font!.lineHeight * CGFloat(x) + baselineOffset)
  }
    
  //Close our Path and Stroke (draw) it
  CGContextClosePath(context)
  CGContextStrokePath(context)
}

Draw a Vertical Line in The Text View

To draw a vertical line in down the left side of the textView.

custom-textview-fig06

You have to first, enter highlighted code in the LinedTextView.swift file.

 // Draw a vertical line on the left side of the textView's context
CGContextMoveToPoint(context, 8, 0);
CGContextAddLineToPoint(context, 8, self.frame.size.height);
        
//Close our Path and Stroke (draw) it
CGContextClosePath(context)
CGContextStrokePath(context)

Next, enter this statement in the ViewController.swift file’s viewDidLoad() function.

// Add padding in the textView
textView.textContainerInset = UIEdgeInsets(top: 8.5, left: 7, bottom: 4, right: 0)

Fix The Scroll View Problem

The last thing you have to do is fix the scroll view problem by adding this function in the ViewController.swift file. When you are done, run the app on your device, enter text in the textView, and test the scrollViewDidScroll() function’s code.

func scrollViewDidScroll(scrollView: UIScrollView) {
  textView.setNeedsDisplay()
}

That’s pretty much it. The CustomTextView project’s textView look and function very much like a notebook page. Comments are welcome 🙂