Skip to content
This repository was archived by the owner on Aug 19, 2020. It is now read-only.
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 157 additions & 0 deletions BSKeyboardControls/BSKeyboardControls.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
//
// BSKeyboardControls.swift
// bskeyboardcontrols
//
// Created by Ivan Milles on 09/02/15.
// Copyright (c) 2015 Mr Green. All rights reserved.
//

import UIKit

enum BSKeyboardControl: UInt8 {
case AllZeros = 0b00
case PreviousNext = 0b01
case Done = 0b10
case AllButtons = 0b11 // Needed for pretty weak Swift NSOption support
}

enum BSKeyboardControlsDirection: Int {
case Previous = 0
case Next = 1
}

protocol BSKeyboardControlsDelegate {
func keyboardControls(keyboardControls: BSKeyboardControls, selectedField field: UIView, inDirection direction: BSKeyboardControlsDirection);
func keyboardControlsDonePressed(keyboardControls: BSKeyboardControls)
}

class BSKeyboardControls: UIView {
var toolbar: UIToolbar!
var doneButton: UIBarButtonItem!
var previousButton: UIBarButtonItem!
var nextButton: UIBarButtonItem!

var delegate: BSKeyboardControlsDelegate?
var visibleControls: BSKeyboardControl = .AllZeros {
didSet {
updateToolbar()
}
}
var fields: [UIView] = [] {
didSet {
installOnFields()
}
}

var activeField: UIView? {
didSet {
activeField?.becomeFirstResponder()
updatePreviousNextEnabledStates()
}
}

var barStyle: UIBarStyle {
get {return toolbar.barStyle}
set {toolbar.barStyle = newValue}
}
var barTintColor: UIColor? {
get {return toolbar.barTintColor?}
set {toolbar.barTintColor = newValue}
}
var doneTintColor: UIColor? {
get {return doneButton.tintColor?}
set {doneButton.tintColor = newValue}
}
var doneTitle: String? {
get {return doneButton.title}
set {doneButton.title = newValue}
}

required convenience init(coder aDecoder: NSCoder) {
self.init(fields: [])
}

override convenience init(frame: CGRect) {
self.init(fields: [])
}

init(fields: [UITextField]) {
super.init(frame: CGRect(x: 0.0, y: 0.0, width: 320.0, height: 44.0))
toolbar = UIToolbar(frame: self.frame)
barStyle = .Default
toolbar.autoresizingMask = .FlexibleLeftMargin | .FlexibleRightMargin
addSubview(toolbar)

previousButton = UIBarButtonItem(image: UIImage(named: "backbutton"), style: .Plain, target: self, action: "selectPreviousField")
nextButton = UIBarButtonItem(image: UIImage(named: "nextbutton"), style: .Plain, target: self, action: "selectNextField")
doneButton = UIBarButtonItem(title: "Done", style: .Done, target: self, action: "doneButtonPressed")
visibleControls = BSKeyboardControl(rawValue: BSKeyboardControl.PreviousNext.rawValue | BSKeyboardControl.Done.rawValue)!

self.fields = fields

// didSet observers not called from init()
installOnFields()
updateToolbar()
}

func installOnFields() {
for field in fields {
if let field = field as? UITextView {
field.inputAccessoryView = self
} else if let field = field as? UITextField {
field.inputAccessoryView = self
} else {
println("Field is not TextView or TextField: \(field)")
}
}
}

func updateToolbar() {
toolbar.items = toolbarItems()
}

func toolbarItems() -> [AnyObject] {
var outItems = [AnyObject]()

if visibleControls.rawValue & BSKeyboardControl.PreviousNext.rawValue > 0 {
outItems.append(previousButton)
outItems.append(nextButton)
}

if visibleControls.rawValue & BSKeyboardControl.Done.rawValue > 0 {
outItems.append(UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target: nil, action: nil))
outItems.append(doneButton)
}

return outItems
}

func updatePreviousNextEnabledStates() {
if let index = find(fields, activeField!) {
previousButton.enabled = (index > 0)
nextButton.enabled = (index < fields.count - 1)
}
}

func selectPreviousField() {
if let index = find(fields, activeField!) {
if index > 0 {
activeField = fields[index - 1]
delegate?.keyboardControls(self, selectedField: activeField!, inDirection: .Previous)
}
}
}

func selectNextField() {
if let index = find(fields, activeField!) {
if index < fields.count - 1 {
activeField = fields[index + 1]
delegate?.keyboardControls(self, selectedField: activeField!, inDirection: .Next)
}
}
}

func doneButtonPressed() {
delegate?.keyboardControlsDonePressed(self)
}
}