Material Controls For iOS

Alexander Paterson
|
Posted over 6 years ago
|
5 minutes
Material Controls For iOS
Cover asset: http://manualcreative.com/project/google-design/
A shortcut to developing good-looking iOS apps

Material Design refers to a set of design principles used in most applications developed by Google, most notably the Android operating system. There exist Objective-C and Swift libraries of UIControls which allow us to easily develop iOS applications in such a style.

The most popular and fully-fleshed is Material, with roughly 6,000 stars on Github.

Material Swift Text Field

However, Material is written in Swift, and is yet to release a Swift 3 version. This should happen in less than a week, but in the meantime, there's another great package written in Objective-C: Material Controls For iOS, which has roughly 2,000 stars on Github. I've had good experiences using this package, and it's nice to worry about the Swift version.

Installing Material-Controls-For-iOS

I'll show you how to install this package with cocoapods (a dependency manager for XCode), and how to set up a simple text field.

If you don't have cocoapods installed already, you can get it with:

$ sudo gem install cocoapods

Now set up a new single-view Swift iOS XCode project, and create a file in the root directory called Podfile. This will have the following contents:

# Podfile

source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
platform :ios, '10.0'

target 'materialExample' do
    pod 'MaterialControls', '~> 1.1.0'
end

Now simply run pod install from the root of your project directory.

Running pod install

This has the effect of creating a new file: materialExample.xcworkspace. Close any .xcproject files you have open, and use the new .xcworkspace file from now on. Open it up, and we're ready to start using our controls

Getting A Material Text Field

In the sole view controller in main.storyboard, create a UIView constrained on the left, right, and top, and with a height of 80.

Constrained UIView

Now simply give this a class of MDTextField:

MDTextField Class

Now if you try to build and run as of the version I'm currently using, you'll actually get an error in the source code:

Material Controls Error

This has been an open but solved issue for a while now. The fix is to replace this method with the following code:

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
  if (anim == [self animationForKey:@"opacityAnim"]) {
    self.opacity = 0;
  } else if (flag) {
    if (_userIsHolding) {
      _effectIsRunning = false;
      if ([self.delegate conformsToProtocol:@protocol(MDLayerDelegate)] &&
          [self.delegate respondsToSelector:@selector(mdLayer:didFinishEffect:)]) {
        id delegate = (id)self.delegate;
        [delegate mdLayer:self didFinishEffect:anim.duration];
      }
    } else {
      [self clearEffects];
    }
  }
}

Now the application will build and run, and your interface builder should look a little more interesting. You can design the text field in the interface builder with IBDesignables:

MDTextField

Very cool. Let's add an outlet to our ViewController now, and set it as a delegate. I'll add a couple of delegate methods too; one called when we start editing, and one whenever we change a character. I'm going to use this second delegate method to prevent users from entering 'z', as an example.

//
//  ViewController.swift
//  materialExample
//

import UIKit
import MaterialControls

class ViewController: UIViewController, MDTextFieldDelegate {

    @IBOutlet weak var textField: MDTextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        textField.delegate = self
    }
    
    func textFieldDidBeginEditing(_ textField: MDTextField) {
        print("Began editing!")
    }
    
    func textField(_ textField: MDTextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        print(textField.text, string, range.location)
        if (string == "z") {
            return false
        }
        return true
    }

}

You now have a pretty Material text field with some very convenient delegate methods.

Any questions: ask below with Disqus.



-->
ALEXANDER
PATERSON